Spaces:
Sleeping
Sleeping
| {% extends 'base.html' %} | |
| {% block title %}Leaderboard – {{ app_brand }}{% endblock %} | |
| {% block head %} | |
| <style> | |
| .leaderboard-table-wrap { | |
| max-height: min(70vh, 640px); | |
| overflow: auto; | |
| -webkit-overflow-scrolling: touch; | |
| } | |
| .leaderboard-table-wrap thead th { | |
| position: sticky; | |
| top: 0; | |
| z-index: 2; | |
| background: var(--card); | |
| box-shadow: 0 1px 0 var(--border); | |
| } | |
| </style> | |
| {% endblock %} | |
| {% block content %} | |
| <div class="page"> | |
| <div class="page-header"> | |
| <div class="page-title">🏆 LEADERBOARD</div> | |
| <div class="page-subtitle">Who's dominating the predictions game?</div> | |
| </div> | |
| <!-- Podium (top 3) --> | |
| {% if players|length >= 3 %} | |
| <div style="display:flex; align-items:flex-end; justify-content:center; gap:1rem; margin-bottom:2.5rem; flex-wrap:wrap;"> | |
| <!-- 2nd --> | |
| <div style="text-align:center; flex:0 0 180px;"> | |
| <div style="font-size:2rem;">🥈</div> | |
| <div style="background:var(--card); border:1px solid var(--border); border-radius:12px 12px 0 0; padding:1rem 0.75rem; border-bottom:none;"> | |
| <div style="font-family:var(--font-display); font-size:1.1rem; color:var(--muted2);">{{ players[1].display_name or players[1].username }}</div> | |
| <div style="font-family:var(--font-mono); font-size:1.5rem; color:var(--muted2); font-weight:700;">{{ '%.0f'|format(players[1].points) }}</div> | |
| <div style="font-size:0.75rem; color:var(--muted);">pts</div> | |
| {% if players[1].settled_count > 0 %} | |
| <div style="font-size:0.75rem; color:var(--muted); margin-top:0.5rem;">{{ players[1].correct_winners }}/{{ players[1].settled_count }} wins</div> | |
| {% endif %} | |
| </div> | |
| <div style="background:var(--bg3); border:1px solid var(--border); height:80px; border-radius:0 0 8px 8px;"></div> | |
| </div> | |
| <!-- 1st --> | |
| <div style="text-align:center; flex:0 0 200px;"> | |
| <div style="font-size:2.5rem;">🥇</div> | |
| <div style="background:linear-gradient(135deg,var(--card),rgba(251,191,36,0.08)); border:1px solid rgba(251,191,36,0.3); border-radius:12px 12px 0 0; padding:1.25rem 0.75rem; border-bottom:none;"> | |
| <div style="font-family:var(--font-display); font-size:1.3rem; color:var(--gold);">{{ players[0].display_name or players[0].username }}</div> | |
| <div style="font-family:var(--font-mono); font-size:2rem; color:var(--gold); font-weight:700;">{{ '%.0f'|format(players[0].points) }}</div> | |
| <div style="font-size:0.75rem; color:var(--muted);">pts</div> | |
| {% if players[0].settled_count > 0 %} | |
| <div style="font-size:0.75rem; color:var(--muted); margin-top:0.5rem;">{{ players[0].correct_winners }}/{{ players[0].settled_count }} wins</div> | |
| {% endif %} | |
| </div> | |
| <div style="background:linear-gradient(to bottom, rgba(251,191,36,0.1), var(--bg3)); border:1px solid var(--border); height:110px; border-radius:0 0 8px 8px;"></div> | |
| </div> | |
| <!-- 3rd --> | |
| <div style="text-align:center; flex:0 0 180px;"> | |
| <div style="font-size:2rem;">🥉</div> | |
| <div style="background:var(--card); border:1px solid var(--border); border-radius:12px 12px 0 0; padding:1rem 0.75rem; border-bottom:none;"> | |
| <div style="font-family:var(--font-display); font-size:1.1rem; color:#cd7f32;">{{ players[2].display_name or players[2].username }}</div> | |
| <div style="font-family:var(--font-mono); font-size:1.5rem; color:#cd7f32; font-weight:700;">{{ '%.0f'|format(players[2].points) }}</div> | |
| <div style="font-size:0.75rem; color:var(--muted);">pts</div> | |
| {% if players[2].settled_count > 0 %} | |
| <div style="font-size:0.75rem; color:var(--muted); margin-top:0.5rem;">{{ players[2].correct_winners }}/{{ players[2].settled_count }} wins</div> | |
| {% endif %} | |
| </div> | |
| <div style="background:var(--bg3); border:1px solid var(--border); height:55px; border-radius:0 0 8px 8px;"></div> | |
| </div> | |
| </div> | |
| {% endif %} | |
| <!-- Full Table --> | |
| <div class="card"> | |
| <div class="table-wrap leaderboard-table-wrap"> | |
| <table> | |
| <thead> | |
| <tr> | |
| <th>Rank</th> | |
| <th>Player</th> | |
| <th style="text-align:right;">Points</th> | |
| <th style="text-align:center;">Predictions</th> | |
| <th style="text-align:center;">Winner %</th> | |
| <th style="text-align:center;">MOTM Hits</th> | |
| <th style="text-align:center;" title="Last 5 completed IPL matches: green=correct, red=wrong, white=no pick">Form</th> | |
| <th style="text-align:center;">Streak</th> | |
| <th style="text-align:right;">P/L</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| {% for p in players %} | |
| {% set is_me = p.username == current_user.username %} | |
| <tr style="{% if is_me %}background:rgba(249,115,22,0.05);{% endif %}"> | |
| <td> | |
| <span style="font-family:var(--font-display); font-size:1.4rem; color: | |
| {% if loop.index == 1 %}var(--gold) | |
| {% elif loop.index == 2 %}var(--muted2) | |
| {% elif loop.index == 3 %}#cd7f32 | |
| {% else %}var(--muted){% endif %};"> | |
| {{ loop.index }} | |
| </span> | |
| </td> | |
| <td> | |
| <div style="font-weight:{% if is_me %}700{% else %}600{% endif %}; color:{% if is_me %}var(--orange){% else %}var(--text){% endif %};"> | |
| {{ p.display_name or p.username }} | |
| {% if is_me %}<span style="font-size:0.75rem; color:var(--muted2); margin-left:0.3rem;">(you)</span>{% endif %} | |
| </div> | |
| </td> | |
| <td style="text-align:right;"> | |
| <div style="font-family:var(--font-mono); font-weight:700; font-size:1.1rem; color:{% if is_me %}var(--orange){% else %}var(--text){% endif %};"> | |
| {{ '%.0f'|format(p.points) }} | |
| </div> | |
| {% set delta = p.points - initial_points %} | |
| <div style="font-size:0.78rem;" class="{{ delta|delta_class }}">{{ delta|delta_sign }}</div> | |
| </td> | |
| <td style="text-align:center; font-family:var(--font-mono);"> | |
| {{ p.total_predictions }} | |
| </td> | |
| <td style="text-align:center;"> | |
| {% if p.settled_count > 0 %} | |
| {% set pct = (p.correct_winners / p.settled_count * 100)|int %} | |
| <div style="font-family:var(--font-mono);">{{ pct }}%</div> | |
| <div style="font-size:0.75rem; color:var(--muted);">{{ p.correct_winners }}/{{ p.settled_count }}</div> | |
| {% else %}—{% endif %} | |
| </td> | |
| <td style="text-align:center; font-family:var(--font-mono);"> | |
| {{ p.correct_motms or 0 }} | |
| </td> | |
| <td style="text-align:center;"> | |
| <div style="display:flex; justify-content:center; gap:3px; flex-wrap:nowrap;"> | |
| {% for c in p.last5 %} | |
| <span title="{% if c=='green' %}Correct{% elif c=='red' %}Wrong{% else %}No pick{% endif %}" style="width:11px;height:11px;border-radius:50%;display:inline-block;border:1px solid var(--border);{% if c=='green' %}background:var(--green);border-color:var(--green);{% elif c=='red' %}background:var(--red);border-color:var(--red);{% else %}background:var(--bg3);{% endif %}"></span> | |
| {% endfor %} | |
| </div> | |
| </td> | |
| <td style="text-align:center; font-family:var(--font-mono); font-size:0.9rem;"> | |
| {{ p.best_streak }}🔥 | |
| </td> | |
| <td style="text-align:right;"> | |
| {% set earned = p.total_earned %} | |
| <div style="font-family:var(--font-mono); font-weight:700;" class="{{ earned|delta_class }}">{{ earned|delta_sign }}</div> | |
| </td> | |
| </tr> | |
| {% endfor %} | |
| </tbody> | |
| </table> | |
| </div> | |
| </div> | |
| <!-- Recent Results --> | |
| {% if recent_results %} | |
| <div style="margin-top:2rem;"> | |
| <div class="section-title" style="font-size:1.2rem;">📋 RECENT RESULTS</div> | |
| <div class="grid grid-auto"> | |
| {% for m in recent_results %} | |
| <div class="card card-sm"> | |
| <div style="display:flex; justify-content:space-between; margin-bottom:0.5rem;"> | |
| <span style="font-size:0.78rem; color:var(--muted);">Match #{{ m.match_number or '?' }}</span> | |
| <span style="font-size:0.78rem; color:var(--muted);">{{ m.match_date|format_date }}</span> | |
| </div> | |
| <div style="display:flex; align-items:center; gap:0.75rem; justify-content:center;"> | |
| <span style="font-family:var(--font-display); font-size:1.2rem; color:{{ m.team1_color }}; {% if m.winner == m.team1 %}text-shadow:0 0 12px {{ m.team1_color }};{% endif %}">{{ m.team1_abbr }}</span> | |
| <span style="color:var(--muted); font-size:0.8rem;">vs</span> | |
| <span style="font-family:var(--font-display); font-size:1.2rem; color:{{ m.team2_color }}; {% if m.winner == m.team2 %}text-shadow:0 0 12px {{ m.team2_color }};{% endif %}">{{ m.team2_abbr }}</span> | |
| </div> | |
| <div style="text-align:center; margin-top:0.5rem; font-size:0.85rem; color:var(--green); font-weight:700;">🏆 {{ m.winner }}</div> | |
| {% if m.man_of_match %}<div style="text-align:center; font-size:0.78rem; color:var(--muted2);">⭐ {{ m.man_of_match }}</div>{% endif %} | |
| </div> | |
| {% endfor %} | |
| </div> | |
| </div> | |
| {% endif %} | |
| </div> | |
| {% endblock %} | |