DIS_IPL / templates /dashboard.html
Jay-Rajput's picture
Admin panel imprvmnts
47370ee
{% extends 'base.html' %}
{% block title %}Dashboard – {{ app_brand }}{% endblock %}
{% block content %}
<div class="page">
<!-- Header -->
<div class="page-header">
<div style="display:flex; align-items:flex-start; justify-content:space-between; flex-wrap:wrap; gap:1rem;">
<div>
<div class="page-title">HEY, {{ (current_user.display_name or current_user.username)|upper }} 👋</div>
<div class="page-subtitle">
{{ today|format_date_weekday }} ·
{% if todays_matches %}
{% set n = todays_matches|length %}
{% if n == 1 %}
<span style="color:var(--gold); font-weight:600;">One match</span> on today’s card.
{% else %}
<span style="color:var(--gold); font-weight:600;">{{ n }} matches</span> on today’s card.
{% endif %}
{% else %}
<span style="color:var(--muted2);">No IPL fixtures today — next games are below.</span>
{% endif %}
</div>
</div>
<div style="display:flex; gap:0.75rem; flex-wrap:wrap;">
<div class="stat-box" style="min-width:160px;">
<div class="stat-value">{{ '%.0f'|format(current_user.points) }}</div>
<div class="stat-label">Your Points</div>
<div style="font-size:0.78rem; color:var(--muted2); margin-top:0.4rem;">#{{ rank }} on leaderboard</div>
</div>
<div class="stat-box" style="min-width:160px;">
<div class="stat-value" style="font-size:1.75rem;">{{ my_streak }}🔥</div>
<div class="stat-label">Best win streak</div>
<div style="font-size:0.78rem; color:var(--muted2); margin-top:0.4rem;">Last 5 IPL results</div>
<div style="display:flex; justify-content:center; gap:4px; margin-top:0.5rem;">
{% for c in my_last5 %}
<span title="{% if c=='green' %}Correct{% elif c=='red' %}Wrong{% else %}No pick / pending{% endif %}" style="width:12px;height:12px;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>
</div>
</div>
</div>
</div>
<!-- Today's Matches -->
<div class="section-title">
🗓️ TODAY'S MATCHES
<a href="{{ url_for('matches') }}" style="font-size:0.85rem; color:var(--orange); font-family:var(--font-body); font-weight:600; letter-spacing:0; text-decoration:none;">View All →</a>
</div>
{% if todays_matches %}
<div class="grid grid-auto" style="margin-bottom:2rem;">
{% for match in todays_matches %}
{% set pred = user_preds.get(match.id) %}
<div class="match-card {% if pred %}predicted{% endif %}">
<!-- Status + match number -->
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:0.75rem;">
<span class="badge badge-{{ match.status }}">
{% if match.status == 'live' %}<span class="status-dot dot-live"></span>{% endif %}
{{ match.status|upper }}
</span>
{% if match.match_number %}<span style="font-size:0.8rem; color:var(--muted);">Match #{{ match.match_number }}</span>{% endif %}
</div>
<!-- Teams -->
<div class="match-vs">
<div class="team-block">
<div class="team-abbr" style="color:{{ match.team1_color }};">{{ match.team1_abbr }}</div>
<div class="team-name">{{ match.team1 }}</div>
</div>
<div class="vs-divider">VS</div>
<div class="team-block">
<div class="team-abbr" style="color:{{ match.team2_color }};">{{ match.team2_abbr }}</div>
<div class="team-name">{{ match.team2 }}</div>
</div>
</div>
<!-- Meta -->
<div class="match-meta">
<span>🕐 {{ match.match_time }}</span>
{% if match.venue %}<span>📍 {{ match.venue }}{% if match.city %}, {{ match.city }}{% endif %}</span>{% endif %}
</div>
{% if match.status == 'completed' and match.winner %}
<div style="margin-top:0.75rem; padding:0.5rem 0.75rem; background:rgba(34,197,94,0.08); border-radius:8px; border:1px solid rgba(34,197,94,0.2);">
<div style="font-size:0.78rem; color:var(--muted2);">RESULT</div>
<div style="font-weight:700; color:var(--green);">🏆 {{ match.winner }}</div>
{% if match.man_of_match %}<div style="font-size:0.8rem; color:var(--muted2);">⭐ MOTM: {{ match.man_of_match }}</div>{% endif %}
</div>
{% endif %}
<!-- User Prediction -->
{% if pred %}
<div style="margin-top:0.75rem; padding:0.5rem 0.75rem; background:rgba(249,115,22,0.08); border-radius:8px; border:1px solid rgba(249,115,22,0.2);">
<div style="font-size:0.78rem; color:var(--muted2);">YOUR PREDICTION</div>
<div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:0.5rem;">
<div>
<span style="font-weight:700; color:var(--orange);">{{ pred.predicted_winner }}</span>
{% if pred.predicted_motm %}<span style="font-size:0.8rem; color:var(--muted2);"> · ⭐ {{ pred.predicted_motm }}</span>{% endif %}
</div>
<div style="font-family:var(--font-mono); font-size:0.85rem;">
Bid: <strong style="color:var(--gold);">{{ '%.0f'|format(pred.bid_amount) }}</strong>
{% if pred.is_settled %}
· <span class="{{ pred.points_earned|delta_class }}">{{ pred.points_earned|delta_sign }} pts</span>
{% endif %}
</div>
</div>
{% if pred.is_settled %}
<div style="display:flex; gap:0.75rem; margin-top:0.3rem; font-size:0.78rem;">
<span>Winner: {% if pred.winner_correct %}✅{% else %}❌{% endif %}</span>
{% if pred.motm_correct is not none %}<span>MOTM: {% if pred.motm_correct %}✅{% else %}❌{% endif %}</span>{% endif %}
</div>
{% endif %}
</div>
{% endif %}
<!-- CTA -->
<div style="margin-top:0.75rem;">
{% if match.can_predict and not pred %}
<a href="{{ url_for('predict', match_id=match.id) }}" class="btn btn-primary" style="width:100%; justify-content:center;">🎯 Make Prediction</a>
{% elif match.can_predict and pred and not pred.is_settled %}
<a href="{{ url_for('predict', match_id=match.id) }}" class="btn btn-ghost" style="width:100%; justify-content:center;">✏️ Edit Prediction</a>
{% elif match.status in ('upcoming',) and not match.is_match_today %}
<div style="text-align:center; font-size:0.82rem; color:var(--muted); padding:0.5rem;">📆 Opens on {{ match.match_date|format_date }}</div>
{% elif match.locked or match.status == 'locked' %}
<div style="text-align:center; font-size:0.82rem; color:var(--muted); padding:0.5rem;">🔒 Predictions locked</div>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="card" style="margin-bottom:2rem; text-align:center; padding:3rem;">
<div style="font-size:3rem; margin-bottom:1rem;">🏏</div>
<div style="color:var(--muted2);">No matches today. Check the <a href="{{ url_for('matches') }}" style="color:var(--orange);">full schedule</a>.</div>
</div>
{% endif %}
{% if upcoming_other %}
<div class="section-title" style="font-size:1.1rem; margin-top:0.25rem;">🔜 COMING UP NEXT</div>
<div class="grid grid-auto" style="margin-bottom:2rem;">
{% for m in upcoming_other %}
<a href="{{ url_for('matches') }}?date={{ m.match_date }}" class="match-card" style="text-decoration:none; color:inherit;">
<div style="font-size:0.75rem; color:var(--muted);">{{ m.match_date|format_date }} · {{ m.match_time }}</div>
<div style="display:flex; align-items:center; justify-content:space-between; margin-top:0.5rem; gap:0.5rem;">
<span style="font-family:var(--font-display); font-size:1.25rem; color:{{ m.team1_color }};">{{ m.team1_abbr }}</span>
<span style="color:var(--muted); font-size:0.75rem;">vs</span>
<span style="font-family:var(--font-display); font-size:1.25rem; color:{{ m.team2_color }};">{{ m.team2_abbr }}</span>
</div>
{% if m.venue %}<div style="font-size:0.78rem; color:var(--muted2); margin-top:0.4rem;">📍 {{ m.venue }}</div>{% endif %}
</a>
{% endfor %}
</div>
{% endif %}
<!-- Bottom Grid -->
<div class="grid grid-2">
<!-- Leaderboard snapshot -->
<div class="card">
<div class="card-title">🏆 TOP PLAYERS</div>
{% for p in leaders %}
<div style="display:flex; align-items:center; gap:0.75rem; padding:0.6rem 0; {% if not loop.last %}border-bottom:1px solid var(--border);{% endif %}">
<div style="font-family:var(--font-display); font-size:1.5rem; color:{% if loop.index==1 %}var(--gold){% elif loop.index==2 %}var(--muted2){% elif loop.index==3 %}#cd7f32{% else %}var(--muted){% endif %}; min-width:28px;">
{{ loop.index }}
</div>
<div style="flex:1;">
<div style="font-weight:600;">{{ p.display_name or p.username }}</div>
</div>
<div style="font-family:var(--font-mono); font-weight:700; color:{% if p.username == current_user.username %}var(--orange){% else %}var(--text){% endif %};">
{{ '%.0f'|format(p.points) }}
</div>
</div>
{% endfor %}
<div style="margin-top:1rem;">
<a href="{{ url_for('leaderboard') }}" class="btn btn-ghost btn-sm" style="width:100%; justify-content:center;">Full Leaderboard →</a>
</div>
</div>
<!-- Recent activity -->
<div class="card">
<div class="card-title">📊 RECENT ACTIVITY</div>
<div style="font-size:0.7rem; font-weight:700; letter-spacing:0.08em; color:var(--muted2); margin-bottom:0.35rem;">🎯 PREDICTIONS</div>
{% if recent_predictions %}
{% for r in recent_predictions %}
<div style="padding:0.45rem 0; {% if not loop.last %}border-bottom:1px solid var(--border);{% endif %}">
<div style="display:flex; justify-content:space-between; align-items:flex-start; gap:0.5rem;">
<div style="flex:1; min-width:0;">
<div style="color:var(--muted2); font-size:0.72rem;">{{ r.match_date|format_date }}{% if r.match_number %} · #{{ r.match_number }}{% endif %}</div>
{% set a1 = team_abbr.get(r.team1, r.team1[:3].upper() if r.team1 else '?') %}
{% set a2 = team_abbr.get(r.team2, r.team2[:3].upper() if r.team2 else '?') %}
<div style="font-size:0.82rem; font-weight:600; margin-top:0.15rem;">
<span style="color:{{ team_colors.get(a1, '#888') }};">{{ a1 }}</span>
<span style="color:var(--muted); font-weight:500;"> vs </span>
<span style="color:{{ team_colors.get(a2, '#888') }};">{{ a2 }}</span>
</div>
<div style="font-size:0.78rem; color:var(--muted2); margin-top:0.2rem;">
Pick <strong style="color:var(--orange);">{{ team_abbr.get(r.predicted_winner, r.predicted_winner[:3] if r.predicted_winner else '—') }}</strong>
{% if r.predicted_motm %} · ⭐ {{ r.predicted_motm }}{% endif %}
· Bid {{ '%.0f'|format(r.bid_amount) }}
</div>
</div>
<div style="text-align:right; flex-shrink:0;">
{% if r.is_settled %}
<div style="font-family:var(--font-mono); font-weight:700; font-size:0.85rem;" class="{{ r.points_earned|delta_class }}">{{ r.points_earned|delta_sign }}</div>
<div style="font-size:0.68rem; color:var(--muted); margin-top:0.15rem;">
{% if r.winner_correct %}✅{% else %}❌{% endif %} W
{% if r.motm_correct is not none %} {% if r.motm_correct %}✅{% else %}❌{% endif %} M{% endif %}
</div>
{% else %}
<span class="badge badge-upcoming" style="font-size:0.62rem;">{{ r.match_status|upper }}</span>
{% endif %}
</div>
</div>
</div>
{% endfor %}
<div style="margin:0.65rem 0 1.1rem;">
<a href="{{ url_for('history') }}#prediction-history" class="btn btn-ghost btn-sm" style="width:100%; justify-content:center;">Full prediction history →</a>
</div>
{% else %}
<div style="font-size:0.82rem; color:var(--muted2); padding:0.5rem 0 1rem;">No predictions yet. <a href="{{ url_for('matches') }}" style="color:var(--orange);">Pick a match</a>.</div>
{% endif %}
<div style="font-size:0.7rem; font-weight:700; letter-spacing:0.08em; color:var(--muted2); margin-bottom:0.35rem;">💰 POINTS</div>
{% if history %}
{% for h in history %}
<div style="display:flex; justify-content:space-between; align-items:center; padding:0.5rem 0; {% if not loop.last %}border-bottom:1px solid var(--border);{% endif %}">
<div style="font-size:0.85rem; flex:1; padding-right:0.5rem; min-width:0;">
<div style="color:var(--muted2); font-size:0.78rem;">{{ h.created_at[:10]|format_date }}{% if h.created_at and h.created_at|string|length > 10 %} · {{ h.created_at[11:16] }}{% endif %}</div>
<div style="line-height:1.35;">{{ h.reason or 'Adjustment' }}</div>
</div>
<div style="text-align:right; flex-shrink:0;">
<div style="font-family:var(--font-mono); font-weight:700; white-space:nowrap;" class="{{ h.change_amount|delta_class }}">
{{ h.change_amount|delta_sign }}
</div>
{% if h.balance_after is not none %}
<div style="font-size:0.7rem; color:var(--muted); font-family:var(--font-mono); margin-top:0.15rem;">bal {{ '%.0f'|format(h.balance_after) }}</div>
{% endif %}
</div>
</div>
{% endfor %}
<div style="margin-top:0.65rem;">
<a href="{{ url_for('history') }}#points-history" class="btn btn-ghost btn-sm" style="width:100%; justify-content:center;">Full points history →</a>
</div>
{% else %}
<div class="empty-state" style="padding:1.25rem;">
<div style="font-size:0.88rem; color:var(--muted2);">No points movements yet.</div>
</div>
{% endif %}
</div>
</div>
<!-- Points Config Info -->
<div class="card mt-3" style="padding:1rem 1.5rem;">
<div style="font-size:0.8rem; color:var(--muted); display:flex; flex-wrap:wrap; gap:1.5rem;">
<span>🎯 Correct winner: <strong style="color:var(--green);">+bid pts</strong></span>
<span>❌ Wrong winner: <strong style="color:var(--red);">−bid pts</strong></span>
<span>⭐ Correct MOTM: <strong style="color:var(--green);">+{{ points_config.correct_motm }} pts</strong></span>
<span>🚫 Wrong MOTM: <strong style="color:var(--red);">−{{ points_config.wrong_motm|abs }} pts</strong></span>
<span>🔒 Match day only · {% if points_config.lock_minutes_before %}{{ points_config.lock_minutes_before }} min before start{% else %}lock at start{% endif %}</span>
</div>
</div>
</div>
{% endblock %}