Files
boker/templates/player_detail.html
T

242 lines
9.5 KiB
HTML

{% extends "base.html" %}
{% block title %}{{ player.player_name }} · Poker Portal{% endblock %}
{% block content %}
<section class="hero-card compact">
<div>
<p class="eyebrow">Player profile</p>
<h1>{{ player.player_name }}</h1>
<p class="muted-text">A quick read on lifetime performance, hit rate, and session-by-session movement.</p>
</div>
</section>
<section class="grid three-col">
<article class="panel stat-card"><span>Total Net</span><strong class="{{ 'positive' if player.total_net_cents > 0 else 'negative' if player.total_net_cents < 0 else 'neutral' }}">{{ player.total_net_cents | money }}</strong></article>
<article class="panel stat-card"><span>Win %</span><strong>{{ "%.1f"|format(player.win_pct) }}%</strong></article>
<article class="panel stat-card"><span>ROI</span><strong>{{ "%.1f"|format(player.roi_pct) }}%</strong></article>
<article class="panel stat-card"><span>Total invested</span><strong>{{ player.total_invested_cents | money }}</strong></article>
<article class="panel stat-card"><span>Paid Buy-in</span><strong>{{ player.total_buy_in_cents | money }}</strong></article>
<article class="panel stat-card"><span>Fronted</span><strong>{{ player.total_front_cents | money }}</strong></article>
<!--<article class="panel stat-card"><span>Rolled in</span><strong>{{ player.total_rollover_in_cents | money }}</strong></article>-->
<article class="panel stat-card"><span>Cash-outs</span><strong>{{ player.total_cash_out_cents | money }}</strong></article>
<article class="panel stat-card"><span>Sessions</span><strong>{{ player.sessions_played }}</strong></article>
<article class="panel stat-card">
<span>Current Streak</span>
<strong>
{% if player.current_win_streak > 0 %}
W{{ player.current_win_streak }}
{% elif player.current_loss_streak > 0 %}
L{{ player.current_loss_streak }}
{% else %}
-
{% endif %}
</strong>
</article>
<!--<article class="panel stat-card"><span>Longest win streak</span><strong>{{ player.longest_win_streak }}</strong></article>
<article class="panel stat-card"><span>Longest loss streak</span><strong>{{ player.longest_loss_streak }}</strong></article>-->
</section>
<section class="grid one-col">
<div class="panel chart-panel">
<div class="panel-header">
<div>
<p class="eyebrow">Trend</p>
<h2>Cumulative profit</h2>
</div>
</div>
<div class="chart-frame">
<canvas id="playerCumulativeChart"></canvas>
</div>
</div>
</section>
<section class="grid two-col">
<div class="panel chart-panel">
<div class="panel-header">
<div>
<p class="eyebrow">Volatility</p>
<h2>Session results</h2>
</div>
</div>
<div class="chart-frame">
<canvas id="playerSessionChart"></canvas>
</div>
</div>
<div class="panel chart-panel">
<div class="panel-header">
<div>
<p class="eyebrow">Breakdown</p>
<h2>Result mix</h2>
</div>
</div>
<div class="chart-frame chart-frame-small">
<canvas id="playerBreakdownChart"></canvas>
</div>
</div>
</section>
<section class="panel">
<div class="panel-header">
<div>
<p class="eyebrow">Breakdown</p>
<h2>Detailed stats</h2>
</div>
</div>
<div class="table-wrap">
<table>
<tbody>
<tr><th>Paid Buy-ins</th><td>{{ player.total_buy_in_cents | money }}</td></tr>
<tr><th>Fronted</th><td>{{ player.total_front_cents | money }}</td></tr>
<tr><th>Rolled In</th><td>{{ player.total_rollover_in_cents | money }}</td></tr>
<tr><th>Total Invested</th><td>{{ player.total_invested_cents | money }}</td></tr>
<tr><th>Rolled Out</th><td>{{ player.total_rollover_out_cents | money }}</td></tr>
<tr><th>Winning Sessions</th><td>{{ player.winning_sessions }}</td></tr>
<tr><th>Losing Sessions</th><td>{{ player.losing_sessions }}</td></tr>
<tr><th>Break-even Sessions</th><td>{{ player.break_even_sessions }}</td></tr>
<tr><th>Average Win</th><td>{{ player.avg_win_cents | money }}</td></tr>
<tr><th>Average Loss</th><td>{{ player.avg_loss_cents | money }}</td></tr>
<tr><th>Biggest Win</th><td>{{ player.biggest_win_cents | money }}</td></tr>
<tr><th>Biggest Loss</th><td>{{ player.biggest_loss_cents | money }}</td></tr>
<tr><th>Current Win Streak</th><td>{{ player.current_win_streak }}</td></tr>
<tr><th>Current Loss Streak</th><td>{{ player.current_loss_streak }}</td></tr>
<tr><th>Longest Win Streak</th><td>{{ player.longest_win_streak }}</td></tr>
<tr><th>Longest Loss Streak</th><td>{{ player.longest_loss_streak }}</td></tr>
<tr>
<th>Best Session</th>
<td>
{{ player.best_session_net_cents | money }}
{% if player.best_session_date %}
<span class="muted-text small">on {{ player.best_session_date | pretty_date }}</span>
{% endif %}
</td>
</tr>
<tr>
<th>Worst Session</th>
<td>
{{ player.worst_session_net_cents | money }}
{% if player.worst_session_date %}
<span class="muted-text small">on {{ player.worst_session_date | pretty_date }}</span>
{% endif %}
</td>
</tr>
</tbody>
</table>
</div>
</section>
<script>
const playerChartData = {{ chart_data | tojson }};
const rootStyles = getComputedStyle(document.documentElement);
const textMuted = rootStyles.getPropertyValue('--text-muted').trim();
const lineColor = rootStyles.getPropertyValue('--line').trim();
const sharedScaleOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
color: textMuted,
usePointStyle: true,
boxWidth: 10,
boxHeight: 10,
padding: 18,
},
},
},
scales: {
x: {
ticks: { color: textMuted, maxRotation: 0 },
grid: { color: lineColor },
},
y: {
ticks: { color: textMuted },
grid: { color: lineColor },
},
},
};
const cumulativeCtx = document.getElementById('playerCumulativeChart');
if (cumulativeCtx) {
new Chart(cumulativeCtx, {
type: 'line',
data: {
labels: playerChartData.labels,
datasets: [{
label: 'Cumulative Profit',
data: playerChartData.cumulative_values,
borderColor: playerChartData.color,
backgroundColor: playerChartData.color,
borderWidth: 2.5,
pointRadius: 3,
pointHoverRadius: 5,
tension: 0.22,
}]
},
options: sharedScaleOptions,
});
}
const sessionCtx = document.getElementById('playerSessionChart');
if (sessionCtx) {
new Chart(sessionCtx, {
type: 'bar',
data: {
labels: playerChartData.labels,
datasets: [{
label: 'Session Net',
data: playerChartData.net_values,
backgroundColor: playerChartData.net_colors,
borderColor: playerChartData.net_colors,
borderRadius: 8,
borderSkipped: false,
}]
},
options: sharedScaleOptions,
});
}
</script>
<script>
const breakdownCtx = document.getElementById('playerBreakdownChart');
if (breakdownCtx) {
new Chart(breakdownCtx, {
type: 'doughnut',
data: {
labels: ['Wins', 'Losses', 'Break-even'],
datasets: [{
data: [
{{ player.winning_sessions }},
{{ player.losing_sessions }},
{{ player.break_even_sessions }}
],
backgroundColor: [
'#59d98e',
'#f06c72',
'#e4bf65'
],
borderWidth: 0,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
color: textMuted,
usePointStyle: true,
boxWidth: 10,
boxHeight: 10,
padding: 18,
},
},
},
},
});
}
</script>
{% endblock %}