{% extends 'layout/backEndLayout.html.twig' %}
{% block stylesheets %}
{{ parent() }}
<style>
:root {
--sb-card : #ffffff;
--sb-border : rgba(0,0,0,.08);
--sb-border-hi: rgba(0,0,0,.15);
--sb-ink : #111827;
--sb-dim : #4b5563;
--sb-muted : #9ca3af;
--sb-blue : #1d4ed8;
--sb-blue-lt: rgba(29,78,216,.1);
--sb-teal : #0d9488;
--sb-teal-lt: rgba(13,148,136,.1);
--sb-amber : #b45309;
--sb-amber-lt:rgba(180,83,9,.1);
--sb-rose : #be123c;
--sb-rose-lt: rgba(190,18,60,.1);
--sb-green : #15803d;
--sb-green-lt:rgba(21,128,61,.1);
--sb-violet : #7c3aed;
--sb-violet-lt:rgba(124,58,237,.1);
--sb-r : 12px; --sb-rs: 8px;
--sb-shadow: 0 1px 4px rgba(0,0,0,.06), 0 6px 20px rgba(0,0,0,.07);
}
.sb-page { font-family:'DM Sans','Segoe UI',sans-serif; color:var(--sb-ink); }
/* topbar */
.sb-topbar { display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px;margin-bottom:20px; }
.sb-topbar__title { font-size:20px;font-weight:700;display:flex;align-items:center;gap:10px; }
.sb-topbar__title i { color:var(--sb-blue); }
.sb-topbar__sub { font-size:13px;color:var(--sb-muted);margin-top:2px; }
/* kpis */
.sb-kpis { display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-bottom:20px; }
.sb-kpi { background:var(--sb-card);border:1px solid var(--sb-border);border-radius:var(--sb-r);padding:14px 16px;display:flex;align-items:center;gap:12px;box-shadow:var(--sb-shadow);transition:transform .2s; }
.sb-kpi:hover { transform:translateY(-2px); }
.sb-kpi__icon { width:38px;height:38px;border-radius:var(--sb-rs);display:flex;align-items:center;justify-content:center;font-size:15px;flex-shrink:0; }
.ki-blue { background:var(--sb-blue-lt);color:var(--sb-blue); }
.ki-green { background:var(--sb-green-lt);color:var(--sb-green); }
.ki-amber { background:var(--sb-amber-lt);color:var(--sb-amber); }
.ki-violet { background:var(--sb-violet-lt);color:var(--sb-violet); }
.sb-kpi__val { font-size:20px;font-weight:700;color:var(--sb-ink);line-height:1; }
.sb-kpi__lbl { font-size:11.5px;color:var(--sb-muted);margin-top:2px; }
/* table card */
.sb-table-card { background:var(--sb-card);border:1px solid var(--sb-border);border-radius:var(--sb-r);overflow:hidden;box-shadow:var(--sb-shadow); }
.sb-table-head { display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;padding:14px 20px;border-bottom:1px solid var(--sb-border);background:#fafbfc; }
.sb-table-head__title { font-size:14px;font-weight:600;display:flex;align-items:center;gap:8px; }
.sb-dot { width:8px;height:8px;border-radius:50%;background:var(--sb-blue);box-shadow:0 0 6px var(--sb-blue); }
/* bouton ajout */
.btn-add { display:inline-flex;align-items:center;gap:6px;padding:8px 18px;background:var(--sb-blue);color:#fff;border-radius:var(--sb-rs);font-size:13px;font-weight:600;text-decoration:none;border:none;cursor:pointer;transition:background .18s; }
.btn-add:hover { background:#1e40af;color:#fff; }
/* table */
table.sb-tbl { width:100%;border-collapse:collapse;font-size:13px; }
table.sb-tbl thead th { padding:10px 14px;color:var(--sb-muted);font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;background:#fafbfc;border-bottom:1px solid var(--sb-border);white-space:nowrap; }
table.sb-tbl tbody td { padding:11px 14px;border-bottom:1px solid rgba(0,0,0,.04);vertical-align:middle; }
table.sb-tbl tbody tr:last-child td { border-bottom:none; }
table.sb-tbl tbody tr:hover td { background:rgba(29,78,216,.025); }
/* student cell */
.std-cell { display:flex;align-items:center;gap:9px; }
.std-avatar { width:30px;height:30px;border-radius:50%;background:linear-gradient(135deg,#1d4ed8,#0d9488);color:#fff;font-size:10px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0; }
.std-name { font-weight:600;font-size:13px; }
.std-mat { font-size:11px;color:var(--sb-muted); }
/* chips */
.chip { display:inline-block;padding:3px 10px;border-radius:20px;font-size:11.5px;font-weight:600; }
.chip-teal { background:var(--sb-teal-lt);color:var(--sb-teal);border:1px solid rgba(13,148,136,.2); }
.chip-violet { background:var(--sb-violet-lt);color:var(--sb-violet);border:1px solid rgba(124,58,237,.2); }
/* montant */
.amount-cell { font-weight:700;font-size:14px;color:var(--sb-blue); }
/* résultat examen */
.exam-chip { display:inline-block;padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600;border:1px solid; }
.ec-success { background:rgba(21,128,61,.1);color:var(--sb-green);border-color:rgba(21,128,61,.25); }
.ec-fail { background:var(--sb-rose-lt);color:var(--sb-rose);border-color:rgba(190,18,60,.25); }
.ec-neutral { background:rgba(0,0,0,.05);color:var(--sb-muted);border-color:var(--sb-border); }
/* actions */
.row-actions { display:flex;align-items:center;gap:4px;justify-content:flex-end; }
.ra-btn { display:inline-flex;align-items:center;gap:4px;padding:5px 9px;border-radius:7px;font-size:11.5px;font-weight:500;text-decoration:none;border:1px solid var(--sb-border);cursor:pointer;background:#fff;color:var(--sb-dim);transition:background .15s,border-color .15s,color .15s; }
.ra-btn:hover { border-color:var(--sb-border-hi); }
.ra-blue { background:var(--sb-blue-lt);color:var(--sb-blue);border-color:rgba(29,78,216,.25); } .ra-blue:hover { background:var(--sb-blue);color:#fff; }
.ra-amber { background:var(--sb-amber-lt);color:var(--sb-amber);border-color:rgba(180,83,9,.25); } .ra-amber:hover { background:var(--sb-amber);color:#fff; }
.ra-rose { background:var(--sb-rose-lt);color:var(--sb-rose);border-color:rgba(190,18,60,.25); } .ra-rose:hover { background:var(--sb-rose);color:#fff; }
/* pagination */
.pag-bar { display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;padding:14px 20px;border-top:1px solid var(--sb-border);background:#fafbfc; }
.pag-info { font-size:12.5px;color:var(--sb-muted); }
.pag-list { display:flex;align-items:center;gap:4px;list-style:none;margin:0;padding:0; }
.pag-list li a,.pag-list li span { display:inline-flex;align-items:center;justify-content:center;min-width:34px;height:34px;padding:0 6px;border-radius:8px;border:1px solid var(--sb-border);font-size:13px;font-weight:500;color:var(--sb-dim);text-decoration:none;background:#fff;transition:background .15s,border-color .15s,color .15s; }
.pag-list li a:hover { border-color:var(--sb-blue);color:var(--sb-blue); }
.pag-list li.pg-on span { background:var(--sb-blue);color:#fff;border-color:var(--sb-blue);font-weight:700; }
.pag-list li.pg-off span { opacity:.4;pointer-events:none; }
.pag-list li.pg-dots span { border:none;background:transparent;color:var(--sb-muted);min-width:auto; }
/* vide */
.sb-empty { text-align:center;padding:64px 24px;color:var(--sb-muted); }
.sb-empty i { font-size:40px;margin-bottom:12px;display:block; }
.sb-empty strong { display:block;font-size:15px;color:var(--sb-dim);margin-bottom:6px; }
@keyframes fadeUp { from{opacity:0;transform:translateY(10px)} to{opacity:1;transform:none} }
.sb-table-card { animation:fadeUp .4s ease both; }
</style>
{% endblock %}
{% block content %}
<div class="sb-page">
{# ── Topbar ─────────────────────────────────────────────────── #}
<div class="sb-topbar">
<div>
<div class="sb-topbar__title"><i class="fa fa-exchange"></i> Inscriptions</div>
<div class="sb-topbar__sub">
Gestion des inscriptions{% if year is defined %} — Année {{ year.code }}{% endif %}
</div>
</div>
{% if is_granted('ROLE_ADMIN') %}
<a href="{{ path('admin_subscriptions_new') }}" class="btn-add">
<i class="fa fa-plus"></i> Nouvelle inscription
</a>
{% endif %}
</div>
{# ── KPIs ────────────────────────────────────────────────────── #}
{% set total = subscriptions.totalItemCount %}
{% set total_amount = 0 %}
{% for sub in subscriptions %}
{% set total_amount = total_amount + sub.amount %}
{% endfor %}
<div class="sb-kpis">
<div class="sb-kpi">
<div class="sb-kpi__icon ki-blue"><i class="fa fa-exchange"></i></div>
<div><div class="sb-kpi__val">{{ total }}</div><div class="sb-kpi__lbl">Total inscriptions</div></div>
</div>
<div class="sb-kpi">
<div class="sb-kpi__icon ki-green"><i class="fa fa-money"></i></div>
<div><div class="sb-kpi__val">{{ total_amount|number_format(0, ',', ' ') }}</div><div class="sb-kpi__lbl">Montant encaissé (page)</div></div>
</div>
<div class="sb-kpi">
<div class="sb-kpi__icon ki-violet"><i class="fa fa-graduation-cap"></i></div>
<div><div class="sb-kpi__val">{{ subscriptions.currentPageNumber }}/{{ subscriptions.pageCount }}</div><div class="sb-kpi__lbl">Page courante</div></div>
</div>
</div>
{# ── Table ───────────────────────────────────────────────────── #}
<div class="sb-table-card">
<div class="sb-table-head">
<div class="sb-table-head__title">
<span class="sb-dot"></span>
Liste des inscriptions
<span style="font-size:11.5px;color:var(--sb-muted);font-weight:400">({{ total }} au total)</span>
</div>
<span style="font-size:12px;color:var(--sb-muted)">Page {{ subscriptions.currentPageNumber }}/{{ subscriptions.pageCount }}</span>
</div>
{% if total == 0 %}
<div class="sb-empty">
<i class="fa fa-inbox"></i>
<strong>Aucune inscription enregistrée</strong>
Commencez par inscrire un élève.
</div>
{% else %}
<div style="overflow-x:auto">
<table class="sb-tbl">
<thead>
<tr>
<th style="width:4%">#</th>
<th style="width:24%">Élève</th>
<th style="width:14%">Classe</th>
<th style="width:14%">Année scolaire</th>
<th style="width:11%" class="text-right">Montant</th>
<th style="width:14%" class="text-center">Résultat examen</th>
<th style="width:12%" class="text-center">Date</th>
<th style="width:10%" class="text-right">Actions</th>
</tr>
</thead>
<tbody>
{% set offset = (subscriptions.currentPageNumber - 1) * subscriptions.itemNumberPerPage %}
{% for sub in subscriptions %}
{% set initials = sub.student.lastname|slice(0,1)|upper ~ sub.student.firstname|slice(0,1)|upper %}
{% set exam = sub.officialExamResult %}
<tr>
<td style="color:var(--sb-muted);font-size:12px">{{ offset + loop.index }}</td>
<td>
<div class="std-cell">
<div class="std-avatar">{{ initials }}</div>
<div>
<div class="std-name">
<a href="{{ path('admin_students_show', {id: sub.student.id}) }}"
style="color:var(--sb-ink);text-decoration:none">
{{ sub.student.lastname }} {{ sub.student.firstname }}
</a>
</div>
<div class="std-mat">{{ sub.student.matricule }}</div>
</div>
</div>
</td>
<td>
<a href="{{ path('admin_classrooms_show', {id: sub.classRoom.id}) }}" style="text-decoration:none">
<span class="chip chip-teal">{{ sub.classRoom.name }}</span>
</a>
</td>
<td>
<span class="chip chip-violet">{{ sub.schoolYear.code }}</span>
</td>
<td class="text-right">
<span class="amount-cell">{{ sub.amount|number_format(0, ',', ' ') }} F</span>
</td>
<td class="text-center">
{% if exam == '0' %}
<span class="exam-chip ec-fail">ÉCHEC</span>
{% elseif exam starts with '1' %}
<span class="exam-chip ec-success">{{ sub.verbalOfficialExamResult }}</span>
{% else %}
<span class="exam-chip ec-neutral">{{ sub.verbalOfficialExamResult }}</span>
{% endif %}
</td>
<td class="text-center" style="font-size:12px;color:var(--sb-dim)">
{% if sub.createdAt is defined and sub.createdAt %}
{{ sub.createdAt|date('d/m/Y') }}
{% else %}—{% endif %}
</td>
<td>
<div class="row-actions">
<a class="ra-btn ra-blue" href="{{ path('admin_subscriptions_show', {id: sub.id}) }}" title="Voir">
<i class="fa fa-eye"></i>
</a>
{% if is_granted('ROLE_ADMIN') %}
<a class="ra-btn ra-amber" href="{{ path('admin_subscriptions_edit', {id: sub.id}) }}" title="Modifier">
<i class="fa fa-pencil"></i>
</a>
<form method="post" action="{{ path('admin_subscriptions_delete', {id: sub.id}) }}"
onsubmit="return confirm('Supprimer cette inscription ?')" style="display:inline">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="csrf_token" value="{{ csrf_token('subscriptions_deletion' ~ sub.id) }}">
<button class="ra-btn ra-rose" type="submit" title="Supprimer"><i class="fa fa-trash"></i></button>
</form>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{# ── Pagination ───────────────────────────────────────────── #}
{% set pg = subscriptions.currentPageNumber %}
{% set pgTotal = subscriptions.pageCount %}
{% set perPage = subscriptions.itemNumberPerPage %}
{% set from = (pg - 1) * perPage + 1 %}
{% set to = (pg * perPage) < total ? (pg * perPage) : total %}
<div class="pag-bar">
<div class="pag-info">Affichage {{ from }}–{{ to }} sur {{ total }} inscription{{ total > 1 ? 's' : '' }}</div>
<ul class="pag-list">
<li class="{{ pg <= 1 ? 'pg-off' : '' }}">
{% if pg > 1 %}<a href="{{ path('admin_subscriptions', {page: pg - 1}) }}"><i class="fa fa-chevron-left"></i></a>
{% else %}<span><i class="fa fa-chevron-left"></i></span>{% endif %}
</li>
{% for p in 1..pgTotal %}
{% if p == pg %}
<li class="pg-on"><span>{{ p }}</span></li>
{% elseif p == 1 or p == pgTotal or (p >= pg - 2 and p <= pg + 2) %}
<li><a href="{{ path('admin_subscriptions', {page: p}) }}">{{ p }}</a></li>
{% elseif p == pg - 3 or p == pg + 3 %}
<li class="pg-dots"><span>…</span></li>
{% endif %}
{% endfor %}
<li class="{{ pg >= pgTotal ? 'pg-off' : '' }}">
{% if pg < pgTotal %}<a href="{{ path('admin_subscriptions', {page: pg + 1}) }}"><i class="fa fa-chevron-right"></i></a>
{% else %}<span><i class="fa fa-chevron-right"></i></span>{% endif %}
</li>
</ul>
</div>
{% endif %}
</div>
</div>
{% endblock %}