{% extends 'sam/layout.html.twig' %} {% block title %}Formations - SAM{% endblock %} {% block sam_body %}
{# ══════════════════════════════════════════════════════════════ BREADCRUMB ══════════════════════════════════════════════════════════════ #} {% include '_molecules/breadcrumb/breadcrumb.html.twig' with { showHome: false, items: [ { label: 'Dashboard', href: path('app_sam_index') }, { label: 'Formations' } ], class: 'mb-6' } %} {# ══════════════════════════════════════════════════════════════ PAGE HEADER ══════════════════════════════════════════════════════════════ #}
{% include '_atoms/icon/icon.html.twig' with { name: 'book', size: 'xl', color: 'cohorts' } only %}

Gestion des formations

{{ total }} formations Moodle synchronisées {% if allCohorts|length > 0 %} · {{ allCohorts|length }} cohortes{% endif %} {% if search %} · Recherche : "{{ search }}"{% endif %} {% if cohortFilter %} · Filtre cohorte actif{% endif %}

{# Sync button — keeps custom SVG for spin animation via Stimulus target #} {% if hasMoodiaAccess %} {% include '_atoms/button/button.html.twig' with { label: 'Créer une formation', variant: 'cohorts', size: 'md', icon: 'plus', href: path('app_moodia_new'), radius: 'lg' } only %} {% endif %}
{# ══════════════════════════════════════════════════════════════ FILTERS BAR ══════════════════════════════════════════════════════════════ #}
{# ── Search input ── #}
{% include '_atoms/icon/icon.html.twig' with { name: 'search', size: 'md', color: 'muted' } only %}
{% if cohortFilter %} {% endif %} {% if statusFilter %} {% endif %}
{% if search and courses|length > 0 %} {% include '_atoms/icon/icon.html.twig' with { name: 'x', size: 'sm' } only %} {% endif %}
{# ── Cohort dropdown ── #} {% if allCohorts|length > 0 %}
{% endif %} {# ── Masques toggle ── #} {# ── Reset filters ── #} {% if search or cohortFilter or hideHidden %} {% include '_atoms/icon/icon.html.twig' with { name: 'x', size: 'sm' } only %} Réinitialiser {% endif %}
{# ══════════════════════════════════════════════════════════════ CONTENT — DATA TABLE ══════════════════════════════════════════════════════════════ #} {% if courses|length == 0 %}
{% if search %} {% include '_molecules/empty-state/empty-state.html.twig' with { title: 'Aucune formation trouvée pour "' ~ search ~ '"', description: 'Essayez avec d\'autres termes de recherche.', icon: 'search', variant: 'minimal', size: 'sm' } %} {% else %} {% include '_molecules/empty-state/empty-state.html.twig' with { title: 'Aucune formation disponible', description: 'Cliquez sur "Synchroniser" pour récupérer les formations depuis Moodle.', icon: 'book' } %} {% endif %}
{% else %}
{# ── Status filter tabs ── #} {% set excellentCnt = statusCounts.excellent %} {% set inProgressCnt = statusCounts.inProgress %} {% set atRiskCnt = statusCounts.atRisk %} {% set noCohortCnt = courses|filter(c => (courseCohorts[c.id] ?? [])|length == 0)|length %} {% set tabBase = {cohort: cohortFilter, search: search, hideHidden: hideHidden ? 1 : null} %} {# ── No results (hidden by default, shown by JS filter) ── #} {# ── Data table ── #}
{# Table header #}
Formation Cohortes Stagiaires Progression
{# Table body #} {% for course in courses %} {% set stats = courseStats[course.id] ?? {enrolled: 0, completed: 0, inProgress: 0, atRisk: 0, percentage: 0} %} {% set pct = stats.percentage|default(0)|round %} {% set cohorts = courseCohorts[course.id] ?? [] %} {% set courseStatus = pct >= 75 ? 'excellent' : (pct > 0 ? 'in-progress' : 'at-risk') %} {# Course column: avatar + name + hidden badge #}
{% include '_atoms/avatar/avatar.html.twig' with { initials: course.fullname|slice(0, 2)|upper, size: 'sm', rounded: 'lg', variant: 'cohorts' } only %}
{{ course.fullname }} {% if not course.visible %} {% include '_atoms/badge/badge.html.twig' with { label: 'Masqué', variant: 'warning', size: 'xs' } %} {% endif %}
{% if course.shortname is defined and course.shortname %} {{ course.shortname }} {% endif %}
{# Cohorts column: badge atoms #}
{% if cohorts|length > 0 %} {% for cohort in cohorts|slice(0, 2) %} {% include '_atoms/badge/badge.html.twig' with { label: cohort.name|slice(0, 18) ~ (cohort.name|length > 18 ? '…' : ''), variant: 'cohorts', size: 'xs' } %} {% endfor %} {% if cohorts|length > 2 %} {% include '_atoms/badge/badge.html.twig' with { label: '+' ~ (cohorts|length - 2), variant: 'neutral', size: 'xs' } %} {% endif %} {% else %} Aucune {% endif %}
{# Enrolled column #}
{% include '_atoms/badge/badge.html.twig' with { label: stats.enrolled|default(0), icon: 'users', variant: stats.enrolled|default(0) > 0 ? 'cohorts' : 'neutral', size: 'sm' } %}
{# Progress column: progress ring #} {% set progressVariant = stats.enrolled == 0 ? 'muted' : (pct >= 75 ? 'success' : (pct > 0 ? 'warning' : 'error')) %}
{% include '_molecules/progress-ring/progress-ring.html.twig' with { value: pct, size: 'sm', variant: progressVariant, thickness: 'normal' } %}
{# Arrow column #}
{% include '_atoms/icon/icon.html.twig' with { name: 'chevron-right', size: 'sm', color: 'muted' } only %}
{% endfor %} {# Table footer #}
{{ total }} formations {% if totalPages > 1 %} {% include '_molecules/pagination/pagination.html.twig' with { currentPage: page, totalPages: totalPages, baseUrl: path('app_sam_courses', {search: search, cohort: cohortFilter, hideHidden: hideHidden ? 1 : null, status: statusFilter}), size: 'sm', showFirstLast: false } %} {% endif %}
{% endif %} {# Footer #}

© Bubul {{ "now"|date("Y") }} {% if lastSyncedAt is defined and lastSyncedAt %} · Synchronisé le {{ lastSyncedAt|date('d/m/Y à H:i') }} {% else %} · Non synchronisé {% endif %}

{% endblock %}