2026-04-11 20:45:51 +02:00
|
|
|
{% extends 'Game/index.html.twig' %}
|
|
|
|
|
|
2026-04-18 22:12:07 +02:00
|
|
|
{% macro stat_val(value, suffix) %}
|
|
|
|
|
{%- set abbr = value >= 1000 -%}
|
2026-04-21 22:46:44 +02:00
|
|
|
<span
|
|
|
|
|
class="profile-stat__value"{% if abbr %} title="{{ value }}"{% endif %}>{% if abbr %}{{ (value / 1000)|round(1, 'floor') }}k{% else %}{{ value }}{% endif %}{% if suffix %}
|
|
|
|
|
<small>{{ suffix }}</small>{% endif %}</span>
|
2026-04-18 22:12:07 +02:00
|
|
|
{% endmacro %}
|
|
|
|
|
|
2026-04-11 20:45:51 +02:00
|
|
|
{% block title %} - Profile{% endblock %}
|
|
|
|
|
|
2026-04-14 18:54:44 +02:00
|
|
|
{% block metas %}
|
2026-04-16 11:56:10 +02:00
|
|
|
{%- set _ogImage = 'https://' ~ app.request.host ~ asset('/images/mine-1600x627.png') -%}
|
2026-04-14 18:54:44 +02:00
|
|
|
<meta name="robots" content="noindex,nofollow"/>
|
2026-04-16 10:40:56 +02:00
|
|
|
<meta property="og:url" content="{{ url('MineSeekerBundle_profile') | replace({'http://': 'https://'}) }}"/>
|
2026-04-14 18:54:44 +02:00
|
|
|
<meta property="og:type" content="profile"/>
|
|
|
|
|
<meta property="og:site_name" content="MineSeeker"/>
|
|
|
|
|
<meta property="og:title" content="{{ app.user.username }} · MineSeeker"/>
|
|
|
|
|
<meta property="og:description"
|
|
|
|
|
content="View {{ app.user.username }}'s battle stats, win rate and recent games on MineSeeker."/>
|
|
|
|
|
<meta property="og:image" content="{{ _ogImage }}"/>
|
|
|
|
|
<meta property="og:image:width" content="1600"/>
|
|
|
|
|
<meta property="og:image:height" content="627"/>
|
|
|
|
|
<meta name="twitter:card" content="summary_large_image"/>
|
|
|
|
|
<meta name="twitter:title" content="{{ app.user.username }} · MineSeeker"/>
|
|
|
|
|
<meta name="twitter:description"
|
|
|
|
|
content="View {{ app.user.username }}'s battle stats, win rate and recent games on MineSeeker."/>
|
|
|
|
|
<meta name="twitter:image" content="{{ _ogImage }}"/>
|
|
|
|
|
{% endblock %}
|
|
|
|
|
|
2026-04-11 20:45:51 +02:00
|
|
|
{% block body %}
|
2026-04-12 08:49:47 +02:00
|
|
|
<div class="profile-page">
|
|
|
|
|
<div class="profile-header">
|
2026-04-13 15:50:28 +02:00
|
|
|
<div id="profile-avatar-root"
|
|
|
|
|
data-upload-url="{{ path('MineSeekerBundle_profile_avatar') }}"
|
2026-04-21 22:46:44 +02:00
|
|
|
data-thumb-url="{{ app.user.avatarPath ? path('liip_imagine_filter', {path: app.user.avatarPath, filter: 'avatar_thumb'}) : '' }}"
|
2026-04-13 15:50:28 +02:00
|
|
|
data-initials="{{ app.user.username|slice(0, 2)|upper }}">
|
2026-04-12 08:49:47 +02:00
|
|
|
</div>
|
|
|
|
|
<div class="profile-info">
|
|
|
|
|
<h1 class="profile-name">{{ app.user.username }}</h1>
|
|
|
|
|
{% if app.user.email %}
|
|
|
|
|
<p class="profile-email">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-envelope"></i>
|
2026-04-12 08:49:47 +02:00
|
|
|
{{ app.user.email }}
|
|
|
|
|
</p>
|
|
|
|
|
{% endif %}
|
|
|
|
|
<p class="profile-role">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-shield"></i> Registered commander
|
2026-04-12 08:49:47 +02:00
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-stats">
|
|
|
|
|
<div class="profile-stat">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-gamepad profile-stat__icon"></i>
|
2026-04-18 22:12:07 +02:00
|
|
|
{{ _self.stat_val(stats.total) }}
|
2026-04-12 08:49:47 +02:00
|
|
|
<span class="profile-stat__label">Games played</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-stat profile-stat--win">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-trophy profile-stat__icon"></i>
|
2026-04-18 22:12:07 +02:00
|
|
|
{{ _self.stat_val(stats.wins) }}
|
2026-04-12 08:49:47 +02:00
|
|
|
<span class="profile-stat__label">Victories</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-stat profile-stat--loss">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-flag profile-stat__icon"></i>
|
2026-04-18 22:12:07 +02:00
|
|
|
{{ _self.stat_val(stats.losses) }}
|
2026-04-12 08:49:47 +02:00
|
|
|
<span class="profile-stat__label">Defeats</span>
|
|
|
|
|
</div>
|
2026-04-12 20:03:20 +02:00
|
|
|
<div class="profile-stat profile-stat--draw">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-minus profile-stat__icon"></i>
|
2026-04-18 22:12:07 +02:00
|
|
|
{{ _self.stat_val(stats.draws) }}
|
2026-04-12 20:03:20 +02:00
|
|
|
<span class="profile-stat__label">Draws</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-stat profile-stat--rate">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-percent profile-stat__icon"></i>
|
2026-04-18 22:12:07 +02:00
|
|
|
{{ _self.stat_val(stats.winRate, '%') }}
|
2026-04-12 20:03:20 +02:00
|
|
|
<span class="profile-stat__label">Win rate</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-stat profile-stat--avg">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-chart-line profile-stat__icon"></i>
|
2026-04-18 22:12:07 +02:00
|
|
|
{{ _self.stat_val(stats.avgScore) }}
|
2026-04-12 20:03:20 +02:00
|
|
|
<span class="profile-stat__label">Avg score</span>
|
|
|
|
|
</div>
|
2026-04-12 08:49:47 +02:00
|
|
|
<div class="profile-stat profile-stat--bomb">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-bomb profile-stat__icon"></i>
|
2026-04-18 22:12:07 +02:00
|
|
|
{{ _self.stat_val(stats.minesHit) }}
|
2026-04-12 08:49:47 +02:00
|
|
|
<span class="profile-stat__label">Mines hit</span>
|
|
|
|
|
</div>
|
2026-04-18 22:12:07 +02:00
|
|
|
<div class="profile-stat profile-stat--bonus">
|
|
|
|
|
<i class="fas fa-star profile-stat__icon"></i>
|
|
|
|
|
{{ _self.stat_val(stats.bonusPoints) }}
|
|
|
|
|
<span class="profile-stat__label">Bonus points</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-stat profile-stat--avg-bonus">
|
|
|
|
|
<i class="fas fa-chart-simple profile-stat__icon"></i>
|
|
|
|
|
{{ _self.stat_val(stats.avgBonus) }}
|
|
|
|
|
<span class="profile-stat__label">Avg bonus</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-stat profile-stat--chain">
|
|
|
|
|
<i class="fas fa-link profile-stat__icon"></i>
|
|
|
|
|
{{ _self.stat_val(stats.bestChain) }}
|
|
|
|
|
<span class="profile-stat__label">Best chain</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-stat profile-stat--blind">
|
|
|
|
|
<i class="fas fa-bullseye profile-stat__icon"></i>
|
|
|
|
|
{{ _self.stat_val(stats.blindHits) }}
|
|
|
|
|
<span class="profile-stat__label">Blind hits</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-stat profile-stat--edge">
|
|
|
|
|
<i class="fas fa-border-style profile-stat__icon"></i>
|
|
|
|
|
{{ _self.stat_val(stats.edgeMines) }}
|
|
|
|
|
<span class="profile-stat__label">Edge mines</span>
|
|
|
|
|
</div>
|
2026-04-12 08:49:47 +02:00
|
|
|
</div>
|
2026-04-11 20:45:51 +02:00
|
|
|
|
2026-04-12 20:03:20 +02:00
|
|
|
{% if stats.total > 0 %}
|
|
|
|
|
<div id="profile-charts-root" data-chart-data="{{ chartData|json_encode|e('html') }}"></div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
|
|
|
|
|
<div id="profile-battle-root" data-games="{{ gamesData|json_encode|e('html') }}"></div>
|
2026-04-12 08:49:47 +02:00
|
|
|
{% if recent|length > 0 %}
|
|
|
|
|
<div class="profile-section">
|
|
|
|
|
<h2 class="profile-section__title">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-clock-rotate-left"></i> Recent battles
|
2026-04-12 08:49:47 +02:00
|
|
|
</h2>
|
2026-04-19 22:11:58 +02:00
|
|
|
<div class="profile-games__filter-wrap">
|
|
|
|
|
<i class="fas fa-search profile-games__filter-icon"></i>
|
|
|
|
|
<input type="text" class="profile-games__filter" data-filter
|
|
|
|
|
placeholder="Filter by opponent…" autocomplete="off">
|
|
|
|
|
</div>
|
|
|
|
|
<div class="profile-games" data-batch-size="5">
|
2026-04-12 08:49:47 +02:00
|
|
|
{% for game in recent %}
|
2026-04-20 21:08:15 +02:00
|
|
|
{% set is_red = game.isRed %}
|
2026-04-12 08:49:47 +02:00
|
|
|
{% set my_points = is_red ? game.redPoints : game.bluePoints %}
|
|
|
|
|
{% set opp_points = is_red ? game.bluePoints : game.redPoints %}
|
2026-04-20 21:08:15 +02:00
|
|
|
{% set opp_name = is_red ? game.blueName : game.redName %}
|
|
|
|
|
{% set result = game.result %}
|
2026-04-11 20:45:51 +02:00
|
|
|
|
2026-04-20 21:08:15 +02:00
|
|
|
{% set is_finished = game.resign is not null
|
2026-04-21 22:46:44 +02:00
|
|
|
or (my_points is not null and opp_points is not null
|
|
|
|
|
and (my_points > 25 or opp_points > 25)) %}
|
2026-04-20 21:08:15 +02:00
|
|
|
{% set is_anonymous = game.oppIsGuest %}
|
2026-04-11 20:45:51 +02:00
|
|
|
|
2026-04-21 22:46:44 +02:00
|
|
|
<div
|
|
|
|
|
class="profile-game profile-game--{{ result }}{% if not is_finished and not is_anonymous %} profile-game--ongoing{% elseif is_anonymous %} profile-game--abandoned{% endif %}{% if loop.index0 >= 5 %} profile-game--hidden{% endif %}"
|
|
|
|
|
data-game-index="{{ loop.index0 }}">
|
2026-04-19 18:04:01 +02:00
|
|
|
<span class="profile-game__badge">
|
|
|
|
|
{% if is_finished %}
|
|
|
|
|
{{ result == 'win' ? 'Win' : (result == 'loss' ? 'Loss' : 'Draw') }}
|
|
|
|
|
{% elseif is_anonymous %}
|
|
|
|
|
Abandoned
|
|
|
|
|
{% else %}
|
|
|
|
|
Ongoing
|
|
|
|
|
{% endif %}
|
|
|
|
|
</span>
|
2026-04-12 08:49:47 +02:00
|
|
|
<span class="profile-game__score">
|
|
|
|
|
{{ my_points ?? '—' }} : {{ opp_points ?? '—' }}
|
|
|
|
|
</span>
|
|
|
|
|
<span class="profile-game__vs">vs</span>
|
2026-04-20 21:08:15 +02:00
|
|
|
<span class="profile-game__opponent">{{ opp_name }}</span>
|
2026-04-12 08:49:47 +02:00
|
|
|
<span class="profile-game__color">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-circle" style="color: {{ is_red ? '#c0392b' : '#2980b9' }}"></i>
|
2026-04-12 08:49:47 +02:00
|
|
|
</span>
|
|
|
|
|
<span class="profile-game__date">
|
|
|
|
|
{{ game.updated ? game.updated|date('Y-m-d') : '' }}
|
|
|
|
|
</span>
|
2026-04-11 20:45:51 +02:00
|
|
|
</div>
|
2026-04-12 08:49:47 +02:00
|
|
|
{% endfor %}
|
|
|
|
|
</div>
|
2026-04-19 22:11:58 +02:00
|
|
|
{% if recent|length > 5 %}
|
|
|
|
|
<button type="button" class="profile-games__load-more" data-load-more>
|
|
|
|
|
<i class="fas fa-chevron-down"></i> Load more
|
|
|
|
|
</button>
|
|
|
|
|
{% endif %}
|
2026-04-12 08:49:47 +02:00
|
|
|
</div>
|
|
|
|
|
{% else %}
|
|
|
|
|
<div class="profile-empty">
|
2026-04-13 20:38:22 +02:00
|
|
|
<i class="fas fa-inbox"></i>
|
2026-04-12 08:49:47 +02:00
|
|
|
<p>No games recorded yet. <a href="{{ path('MineSeekerBundle_gamePlay') }}">Start playing!</a></p>
|
|
|
|
|
</div>
|
|
|
|
|
{% endif %}
|
|
|
|
|
</div>
|
|
|
|
|
{% endblock %}
|
2026-04-12 20:03:20 +02:00
|
|
|
|
|
|
|
|
{% block javascripts %}
|
|
|
|
|
{{ parent() }}
|
2026-04-18 17:53:02 +02:00
|
|
|
{{ vite_entry_script_tags('profile', { dependency: 'react' }) }}
|
2026-04-12 20:03:20 +02:00
|
|
|
{% endblock %}
|