{% extends 'layout/frontEndLayout.html.twig' %}
{% block name %}Classrooms of Bethesda{% endblock %}
{% block stylesheets %}
{{ parent() }}
<style>
/* ── Hero Banner ──────────────────────────────────────── */
.classrooms-hero {
background:
linear-gradient(135deg, rgba(10,22,40,0.92) 0%, rgba(17,34,68,0.78) 100%),
url("{{ asset('assets/images/slider-02.jpg') }}") center / cover no-repeat;
padding: 5rem 1rem 4rem;
text-align: center;
position: relative;
overflow: hidden;
}
.classrooms-hero::after {
content: '';
position: absolute;
bottom: 0; left: 0; right: 0;
height: 3px;
background: linear-gradient(90deg, var(--gold), var(--accent), var(--gold));
}
.classrooms-hero .hero-tag {
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.35em;
text-transform: uppercase;
color: var(--gold);
display: inline-block;
margin-bottom: 1rem;
padding: 0.3rem 0.9rem;
border: 1px solid rgba(201,168,76,0.35);
}
.classrooms-hero h1 {
font-family: var(--font-display);
font-size: clamp(2rem, 5vw, 3.2rem);
font-weight: 900;
color: var(--white);
margin: 0 0 1rem;
line-height: 1.15;
}
.classrooms-hero h1 em { font-style: italic; color: var(--gold); }
.hero-meta {
display: inline-flex;
align-items: center;
gap: 1.5rem;
flex-wrap: wrap;
justify-content: center;
}
.hero-meta-item {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 0.78rem;
letter-spacing: 0.1em;
text-transform: uppercase;
color: rgba(255,255,255,0.5);
padding: 0.3rem 0.9rem;
border: 1px solid rgba(255,255,255,0.1);
}
.hero-meta-item i { color: var(--gold); }
/* ── Section wrapper ──────────────────────────────────── */
.classrooms-section {
background: var(--cream);
padding: 4rem 0 5rem;
}
/* ── Classroom Card ───────────────────────────────────── */
.classroom-card {
background: var(--white);
border: 1px solid rgba(0,0,0,0.06);
overflow: hidden;
position: relative;
margin-bottom: 1.75rem;
transition: transform 0.32s ease, box-shadow 0.32s ease;
display: flex;
flex-direction: column;
}
.classroom-card::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0;
height: 3px;
background: linear-gradient(90deg, var(--gold), var(--accent));
transform: scaleX(0);
transition: transform 0.32s ease;
}
.classroom-card:hover {
transform: translateY(-6px);
box-shadow: 0 20px 48px rgba(10,22,40,0.11);
}
.classroom-card:hover::before { transform: scaleX(1); }
/* Teacher photo header */
.classroom-img-wrap {
position: relative;
height: 160px;
overflow: hidden;
background: var(--navy);
}
.classroom-img-wrap img {
width: 100%;
height: 100%;
object-fit: cover;
object-position: top;
transition: transform 0.42s ease, filter 0.42s ease;
filter: brightness(0.85);
}
.classroom-card:hover .classroom-img-wrap img {
transform: scale(1.05);
filter: brightness(0.7);
}
/* Class name badge over image */
.classroom-name-badge {
position: absolute;
bottom: 0; left: 0; right: 0;
padding: 1.5rem 1rem 0.85rem;
background: linear-gradient(to top, rgba(10,22,40,0.92), transparent);
}
.classroom-name-badge h2 {
font-family: var(--font-display);
font-size: 1.2rem;
font-weight: 700;
color: var(--white);
margin: 0;
line-height: 1.2;
}
.classroom-name-badge h2 a {
color: inherit;
text-decoration: none;
transition: color 0.25s;
}
.classroom-name-badge h2 a:hover { color: var(--gold); }
/* APC exam results block */
.exam-block {
padding: 0 1rem;
flex: 1;
}
.exam-block-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.9rem 0 0.6rem;
border-bottom: 1px solid rgba(0,0,0,0.06);
margin-bottom: 0.6rem;
}
.exam-block-label {
font-size: 0.68rem;
font-weight: 600;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--text-muted);
}
.exam-success-rate {
font-family: var(--font-display);
font-size: 1.4rem;
font-weight: 700;
color: var(--gold);
line-height: 1;
}
/* Student list */
.student-list {
list-style: none;
padding: 0;
margin: 0 0 0.75rem;
max-height: 260px;
overflow-y: auto;
scrollbar-width: thin;
scrollbar-color: var(--gold-light) transparent;
}
.student-list::-webkit-scrollbar { width: 4px; }
.student-list::-webkit-scrollbar-thumb { background: var(--gold-light); }
.student-row {
display: grid;
grid-template-columns: 36px 1fr auto;
align-items: center;
gap: 0.65rem;
padding: 0.55rem 0;
border-bottom: 1px solid rgba(0,0,0,0.04);
}
.student-row:last-child { border-bottom: none; }
.student-avatar {
width: 36px;
height: 36px;
border-radius: 50%;
object-fit: cover;
border: 1px solid rgba(201,168,76,0.25);
}
.student-name {
font-size: 0.82rem;
font-weight: 500;
color: var(--navy);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.student-result {
font-size: 0.72rem;
font-weight: 600;
padding: 0.2rem 0.55rem;
text-transform: capitalize;
white-space: nowrap;
}
.student-result.success {
background: rgba(29,138,110,0.1);
color: #1D8A6E;
}
.student-result.fail {
background: rgba(217,83,79,0.1);
color: var(--danger);
}
.student-result.pending {
background: rgba(201,168,76,0.1);
color: #9A7A2A;
}
/* Card footer */
.classroom-card-footer {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.85rem 1rem;
background: rgba(10,22,40,0.03);
border-top: 1px solid rgba(0,0,0,0.05);
margin-top: auto;
}
.classroom-meta-item {
display: flex;
align-items: center;
gap: 0.45rem;
font-size: 0.75rem;
color: var(--text-muted);
font-weight: 500;
}
.classroom-meta-item i { color: var(--gold); font-size: 0.78rem; }
/* ── Pagination ───────────────────────────────────────── */
.pagination-wrap {
display: flex;
justify-content: center;
padding: 2.5rem 0 0;
}
.pagination-wrap .pagination .page-item .page-link {
border: 1px solid rgba(0,0,0,0.1);
color: var(--navy);
font-size: 0.85rem;
padding: 0.55rem 0.95rem;
border-radius: 0 !important;
transition: all 0.25s;
}
.pagination-wrap .pagination .page-item.active .page-link,
.pagination-wrap .pagination .page-item .page-link:hover {
background: var(--gold);
border-color: var(--gold);
color: var(--navy);
font-weight: 700;
}
/* ── Empty state ──────────────────────────────────────── */
.empty-state {
text-align: center;
padding: 5rem 2rem;
}
.empty-icon {
width: 72px;
height: 72px;
border: 2px solid rgba(201,168,76,0.3);
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--gold);
font-size: 1.8rem;
margin-bottom: 1.5rem;
}
.empty-state h2 {
font-family: var(--font-display);
font-size: 1.6rem;
color: var(--navy);
margin-bottom: 0.75rem;
}
.empty-state p {
color: var(--text-muted);
font-size: 0.95rem;
margin-bottom: 1.8rem;
}
</style>
{% endblock %}
{% block body %}
{# ── Hero Banner ──────────────────────────────────────────── #}
<div class="classrooms-hero">
<span class="hero-tag">{{ french_school_name }}</span>
<h1>
Liste des <em>Classes</em><br>
& Résultats aux examens officiels
</h1>
<div class="hero-meta">
<div class="hero-meta-item">
<i class="fa fa-calendar"></i>
Session {{ year.code ?? '2022-2023' }}
</div>
{% if rooms|length > 0 %}
<div class="hero-meta-item">
<i class="fa fa-door-open"></i>
{{ rooms|length }} {{ rooms|length > 1 ? 'classes' : 'classe' }}
</div>
{% endif %}
</div>
</div>
{# ── Classrooms Grid ──────────────────────────────────────── #}
{% if rooms|length > 0 %}
<section class="classrooms-section" id="overviews">
<div class="container">
{# Section header #}
<div class="section-header" style="padding-top:0; padding-bottom:2.5rem;">
<span class="section-tag">Résultats officiels</span>
<h2 class="section-title">
Nos classes & <em>performances</em>
</h2>
<div class="section-divider"></div>
<p class="section-sub">
Résultats détaillés par classe pour la session officielle {{ year.code ?? '2022-2023' }}.
</p>
</div>
{% for row in rooms|batch(3) %}
<div class="row">
{% for room in row %}
{# ── Pre-compute stats ── #}
{% set success = 0 %}
{% set candidats = 0 %}
{% if room.apc %}
{% for sub in subscriptions %}
{% if sub.classRoom.id == room.id %}
{% set candidats = candidats + 1 %}
{% if sub.officialExamResult != "0" %}
{% set success = success + 1 %}
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
<div class="col-lg-4 col-md-6 col-12">
<div class="classroom-card">
{# ── Teacher photo + class name ── #}
<div class="classroom-img-wrap">
{% if room.id in mainTeachersMap|keys %}
<img src="{{ mainTeachersMap[room.id].avatar(300) }}"
alt="{{ room.name }}" loading="lazy">
{% else %}
<img src="{{ asset('assets/images/teacher_default.png') }}"
alt="{{ room.name }}" loading="lazy">
{% endif %}
<div class="classroom-name-badge">
<h2><a href="#">{{ room.name }}</a></h2>
</div>
</div>
{# ── APC exam results ── #}
{% if room.apc and candidats > 0 %}
<div class="exam-block">
<div class="exam-block-header">
<span class="exam-block-label">Résultats examen officiel</span>
<span class="exam-success-rate">
{{ (100 * success / candidats)|round(1, 'floor') }}%
</span>
</div>
<ul class="student-list">
{% for sub in subscriptions %}
{% if sub.classRoom.id == room.id %}
{% set resultLower = sub.verbalOfficialExamResult|lower %}
{% set resultClass = 'pending' %}
{% if sub.officialExamResult != "0" %}
{% set resultClass = 'success' %}
{% elseif sub.officialExamResult == "0" and sub.verbalOfficialExamResult %}
{% set resultClass = 'fail' %}
{% endif %}
<li class="student-row">
<img class="student-avatar"
src="{{ sub.student.imageName
? asset('assets/images/student/' ~ sub.student.imageName)
: (sub.student.gender
? asset('assets/images/student/female-default-avatar.jpg')
: asset('assets/images/student/male-default-avatar.jpg'))
}}"
alt="{{ sub.student.lastname }}"
loading="lazy">
<span class="student-name">
{{ sub.student.lastname|title }}
{{ sub.student.firstname|title }}
</span>
<span class="student-result {{ resultClass }}">
{{ resultLower ?: '—' }}
</span>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
{# ── Card footer ── #}
<div class="classroom-card-footer">
<span class="classroom-meta-item">
<i class="fa fa-book"></i>
{{ room.modules|length }}
{{ room.modules|length > 1 ? 'modules' : 'module' }}
</span>
{% if room.apc and candidats > 0 %}
<span class="classroom-meta-item">
<i class="fa fa-users"></i>
{{ candidats }}
{{ candidats > 1 ? 'candidats' : 'candidat' }}
</span>
<span class="classroom-meta-item">
<i class="fa fa-check-circle"></i>
{{ success }} reçu{{ success > 1 ? 's' : '' }}
</span>
{% endif %}
</div>
</div>{# end classroom-card #}
</div>
{% endfor %}
</div>{# end row #}
{% endfor %}
{# ── Pagination ── #}
<div class="pagination-wrap">
{{ knp_pagination_render(rooms) }}
</div>
</div>{# end container #}
</section>
{% else %}
{# ── Empty state ── #}
<section class="classrooms-section">
<div class="container">
<div class="empty-state">
<div class="empty-icon">
<i class="fa fa-building"></i>
</div>
<h2>Aucune classe pour le moment</h2>
<p>Les salles de classe n'ont pas encore été configurées.</p>
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
<a href="{{ path('admin_classrooms_new') }}" class="btn-gold">
<i class="fa fa-plus"></i> Créer la première classe
</a>
{% endif %}
</div>
</div>
</section>
{% endif %}
{% endblock %}