Files
yrtv/web/templates/matches/list.html

215 lines
13 KiB
HTML

{% extends "base.html" %}
{% block content %}
<!-- Team Stats Summary (Party >= 2) -->
{% if summary_stats %}
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
<!-- Left Block: Map Stats -->
<div class="bg-white dark:bg-slate-800 shadow rounded-lg p-6">
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4 flex items-center">
<span class="mr-2">🗺️</span>
地图表现 (Party ≥ 2)
</h3>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-slate-700">
<tr>
<th class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase">Map</th>
<th class="px-4 py-2 text-right text-xs font-medium text-gray-500 uppercase">Matches</th>
<th class="px-4 py-2 text-right text-xs font-medium text-gray-500 uppercase">Win Rate</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200 dark:divide-gray-700">
{% for stat in summary_stats.map_stats[:6] %}
<tr>
<td class="px-4 py-2 text-sm font-medium dark:text-white">{{ stat.label }}</td>
<td class="px-4 py-2 text-sm text-right text-gray-500 dark:text-gray-400">{{ stat.count }}</td>
<td class="px-4 py-2 text-sm text-right">
<div class="flex items-center justify-end gap-2">
<span class="font-bold {% if stat.win_rate >= 50 %}text-green-600{% else %}text-red-500{% endif %}">
{{ "%.1f"|format(stat.win_rate) }}%
</span>
<div class="w-16 h-1.5 bg-gray-200 dark:bg-slate-600 rounded-full overflow-hidden">
<div class="h-full {% if stat.win_rate >= 50 %}bg-green-500{% else %}bg-red-500{% endif %}" style="width: {{ stat.win_rate }}%"></div>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<!-- Right Block: Context Stats -->
<div class="bg-white dark:bg-slate-800 shadow rounded-lg p-6">
<h3 class="text-lg font-bold text-gray-900 dark:text-white mb-4 flex items-center">
<span class="mr-2">📊</span>
环境胜率分析
</h3>
<div class="space-y-6">
<!-- ELO Stats -->
<div>
<h4 class="text-xs font-bold text-gray-500 uppercase mb-2">ELO 层级表现</h4>
<div class="grid grid-cols-7 gap-2">
{% for stat in summary_stats.elo_stats %}
<div class="bg-gray-50 dark:bg-slate-700 p-2 rounded text-center">
<div class="text-[9px] text-gray-400 truncate" title="{{ stat.label }}">{{ stat.label }}</div>
<div class="text-xs font-bold dark:text-white">{{ "%.0f"|format(stat.win_rate) }}%</div>
<div class="text-[9px] text-gray-400">({{ stat.count }})</div>
</div>
{% endfor %}
</div>
</div>
<!-- Duration Stats -->
<div>
<h4 class="text-xs font-bold text-gray-500 uppercase mb-2">时长表现</h4>
<div class="grid grid-cols-3 gap-2">
{% for stat in summary_stats.duration_stats %}
<div class="bg-gray-50 dark:bg-slate-700 p-2 rounded text-center">
<div class="text-[10px] text-gray-400">{{ stat.label }}</div>
<div class="text-sm font-bold dark:text-white">{{ "%.0f"|format(stat.win_rate) }}%</div>
<div class="text-[10px] text-gray-400">({{ stat.count }})</div>
</div>
{% endfor %}
</div>
</div>
<!-- Round Stats -->
<div>
<h4 class="text-xs font-bold text-gray-500 uppercase mb-2">局势表现 (总回合数)</h4>
<div class="grid grid-cols-4 gap-2">
{% for stat in summary_stats.round_stats %}
<div class="bg-gray-50 dark:bg-slate-700 p-2 rounded text-center border {% if 'Stomp' in stat.label %}border-green-200{% elif 'Close' in stat.label %}border-orange-200{% elif 'Choke' in stat.label %}border-red-200{% else %}border-gray-200{% endif %}">
<div class="text-[9px] text-gray-400 truncate" title="{{ stat.label }}">{{ stat.label }}</div>
<div class="text-sm font-bold dark:text-white">{{ "%.0f"|format(stat.win_rate) }}%</div>
<div class="text-[9px] text-gray-400">({{ stat.count }})</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endif %}
<div class="bg-white dark:bg-slate-800 shadow rounded-lg p-6">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">比赛列表</h2>
<!-- Filters (Simple placeholders) -->
<div class="flex space-x-2">
<!-- <input type="text" placeholder="Map..." class="border rounded px-2 py-1"> -->
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead class="bg-gray-50 dark:bg-slate-700">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">时间</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">地图</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">比分</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">ELO</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Party</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">时长</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">操作</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-slate-800 divide-y divide-gray-200 dark:divide-gray-700">
{% for match in matches %}
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
<script>document.write(new Date({{ match.start_time }} * 1000).toLocaleString())</script>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white font-medium">
{{ match.map_name }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-white">
<div class="flex items-center space-x-2">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {% if match.winner_team == 1 %}bg-green-100 text-green-800 border border-green-200{% else %}bg-gray-100 text-gray-500{% endif %}">
{{ match.score_team1 }}
{% if match.winner_team == 1 %}
<svg class="ml-1 h-3 w-3" fill="currentColor" viewBox="0 0 20 20"><path d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z" /></svg>
{% endif %}
</span>
<span class="text-gray-400">-</span>
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {% if match.winner_team == 2 %}bg-green-100 text-green-800 border border-green-200{% else %}bg-gray-100 text-gray-500{% endif %}">
{{ match.score_team2 }}
{% if match.winner_team == 2 %}
<svg class="ml-1 h-3 w-3" fill="currentColor" viewBox="0 0 20 20"><path d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z" /></svg>
{% endif %}
</span>
<!-- Our Team Result Badge -->
{% if match.our_result %}
{% if match.our_result == 'win' %}
<span class="ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-bold bg-green-500 text-white">
VICTORY
</span>
{% elif match.our_result == 'loss' %}
<span class="ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-bold bg-red-500 text-white">
DEFEAT
</span>
{% elif match.our_result == 'mixed' %}
<span class="ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-bold bg-yellow-500 text-white">
CIVIL WAR
</span>
{% endif %}
{% endif %}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
{% if match.avg_elo and match.avg_elo > 0 %}
<span class="font-mono">{{ "%.0f"|format(match.avg_elo) }}</span>
{% else %}
<span class="text-xs text-gray-300">-</span>
{% endif %}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
{% if match.max_party and match.max_party > 1 %}
{% set p = match.max_party %}
{% set party_class = 'bg-gray-100 text-gray-800' %}
{% if p == 2 %} {% set party_class = 'bg-indigo-100 text-indigo-800 border border-indigo-200' %}
{% elif p == 3 %} {% set party_class = 'bg-blue-100 text-blue-800 border border-blue-200' %}
{% elif p == 4 %} {% set party_class = 'bg-purple-100 text-purple-800 border border-purple-200' %}
{% elif p >= 5 %} {% set party_class = 'bg-orange-100 text-orange-800 border border-orange-200' %}
{% endif %}
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium {{ party_class }}">
👥 {{ match.max_party }}
</span>
{% else %}
<span class="text-xs text-gray-300">Solo</span>
{% endif %}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
{{ (match.duration / 60) | int }} min
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<a href="{{ url_for('matches.detail', match_id=match.match_id) }}" class="text-yrtv-600 hover:text-yrtv-900">详情</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
<div class="mt-4 flex justify-between items-center">
<div class="text-sm text-gray-700 dark:text-gray-400">
Total {{ total }} matches
</div>
<div class="flex space-x-2">
{% if page > 1 %}
<a href="{{ url_for('matches.index', page=page-1) }}" class="px-3 py-1 border rounded bg-white text-gray-700 hover:bg-gray-50 dark:bg-slate-700 dark:text-white dark:border-slate-600 dark:hover:bg-slate-600">Prev</a>
{% endif %}
{% if page < total_pages %}
<a href="{{ url_for('matches.index', page=page+1) }}" class="px-3 py-1 border rounded bg-white text-gray-700 hover:bg-gray-50 dark:bg-slate-700 dark:text-white dark:border-slate-600 dark:hover:bg-slate-600">Next</a>
{% endif %}
</div>
</div>
</div>
{% endblock %}