{% extends 'sam/layout.html.twig' %} {% block title %}{{ moodleUser.fullname }} - Stagiaire - SAM{% endblock %} {% block sam_body %}
{# ══════════════════════════════════════════════════════════════ BREADCRUMB ══════════════════════════════════════════════════════════════ #} {% include '_molecules/breadcrumb/breadcrumb.html.twig' with { showHome: false, items: [ { label: 'Dashboard', href: path('app_sam_index') }, { label: 'Stagiaires', href: path('app_sam_users') }, { label: moodleUser.fullname } ], class: 'mb-6' } %} {# ══════════════════════════════════════════════════════════════ HERO CARD — identité + actions + KPI strip (pattern course_detail) ══════════════════════════════════════════════════════════════ #}
{# Identité + actions #}
{% include '_atoms/avatar/avatar.html.twig' with { initials: (moodleUser.firstname|slice(0,1) ~ moodleUser.lastname|slice(0,1))|upper, size: 'xl', rounded: 'xl', variant: moodleUser.suspended ? 'gray' : 'primary' } only %}

{{ moodleUser.fullname }}

{% if moodleUser.suspended %} {% include '_atoms/badge/badge.html.twig' with { label: 'Inactif', variant: 'error', dot: true, size: 'sm' } %} {% else %} {% include '_atoms/badge/badge.html.twig' with { label: 'Actif', variant: 'success', dot: true, size: 'sm' } %} {% endif %}
{% include '_atoms/icon/icon.html.twig' with { name: 'mail', size: 'sm', color: 'gray' } only %} {{ moodleUser.email }} {% include '_atoms/icon/icon.html.twig' with { name: 'user', size: 'sm', color: 'gray' } only %} @{{ moodleUser.username }}
{% if userCohorts|length > 0 %} {% endif %}
{# Actions — même style que course_detail (h-10, soft colors) #}
{# Sync #} {# Toggle #} {# Modifier — icon only #} {# Supprimer — icon only #}
{# KPI strip — intégré dans le hero card, même pattern que course_detail #}
{% include '_atoms/icon/icon.html.twig' with { name: 'book', size: 'md', color: 'gray' } only %}
{{ globalProgress.courses_count }}
Cours inscrits
{% include '_atoms/icon/icon.html.twig' with { name: 'check-circle', size: 'md', color: 'success' } only %}
{{ globalProgress.completed }}/{{ globalProgress.total }}
Activités validées
{% include '_atoms/icon/icon.html.twig' with { name: 'clock', size: 'md', color: 'warning' } only %}
{{ totalTimeFormatted ?: '—' }}
Apprentissage
{% include '_atoms/icon/icon.html.twig' with { name: 'chart', size: 'md', color: 'primary' } only %}
{{ globalProgress.percentage|number_format(0) }}%
Progression globale
{# ══════════════════════════════════════════════════════════════ GRAPHIQUES ══════════════════════════════════════════════════════════════ #} {% embed '_molecules/section-divider/section-divider.html.twig' with { title: 'Analyse de l\'apprentissage', subtitle: 'Activité récente et progression par cours', icon: 'presentation-graph', iconColor: 'success' } %} {% block right %}{% endblock %} {% endembed %}
{% include '_atoms/icon/icon.html.twig' with { name: 'chart', size: 'sm', color: 'gray' } only %}

Progression journalière

Complétions d'activités jour par jour

{{ render_chart(dailyChart, {'data-controller': ''}) }}
{% include '_atoms/icon/icon.html.twig' with { name: 'presentation-graph', size: 'sm', color: 'gray' } only %}

Évolution de la progression

60 derniers jours · par cours

{% if hiddenCoursesCount > 0 %} +{{ hiddenCoursesCount }} autre{{ hiddenCoursesCount > 1 ? 's' : '' }} {% endif %}
{{ render_chart(progressionLineChart, {'data-controller': ''}) }}
{# ══════════════════════════════════════════════════════════════ ACCORDÉON DES COURS Le data-controller englobe le section-divider pour que les boutons dans {% block right %} soient dans le scope Stimulus ══════════════════════════════════════════════════════════════ #} {% if coursesData|length == 0 %} {% embed '_molecules/section-divider/section-divider.html.twig' with { title: 'Détail des cours', subtitle: '0 cours inscrits', icon: 'book', iconColor: 'warning' } %} {% block right %}{% endblock %} {% endembed %}
{% include '_molecules/empty-state/empty-state.html.twig' with { title: 'Aucune inscription', description: 'Cet utilisateur n\'est inscrit à aucun cours', icon: 'book' } %}
{% else %}
{% embed '_molecules/section-divider/section-divider.html.twig' with { title: 'Détail des cours', subtitle: coursesData|length ~ ' cours inscrits', icon: 'book', iconColor: 'warning' } %} {% block right %} {% endblock %} {% endembed %}
{% for courseData in coursesData %} {% set course = courseData.course %} {% set progress = courseData.progress %} {% set progressPercent = progress.percentage|default(0) %} {% set progressColor = progressPercent >= 75 ? 'success' : (progressPercent >= 40 ? 'warning' : 'error') %}
{# Course header #}
{% include '_atoms/icon/icon.html.twig' with { name: 'book', size: 'sm', color: 'primary' } only %}

{{ course.fullname }}

{{ course.shortname }}
{# Sections count #} {{ courseData.sections|length }} section{{ courseData.sections|length > 1 ? 's' : '' }} {# Completed activities #} {% set completedColor = progress.completed == progress.total and progress.total > 0 ? 'text-success bg-success/10 border-success/20' : 'text-gray-500 bg-gray-50 border-gray-100' %} {{ progress.completed }}/{{ progress.total }} {# Time spent #} {% if courseData.timeSpent is defined and courseData.timeSpent > 0 %} {{ courseData.timeFormatted|default('0 min') }} {% endif %}
{% include '_molecules/progress-ring/progress-ring.html.twig' with { value: progressPercent, size: 'sm', variant: progressColor, thickness: 'normal', animate: false } only %}
{# Course content — sections #}
{% if courseData.sections|length == 0 %}
{% include '_atoms/icon/icon.html.twig' with { name: 'info', size: 'sm', color: 'gray' } only %} Aucune section
{% else %} {% if courseData.sections|length > 1 %}
{% endif %}
{% for sectionData in courseData.sections %} {% include '_molecules/section-accordion-item/section-accordion-item.html.twig' with { section: sectionData.section, sectionProgress: sectionData.progress, activities: sectionData.activities } only %} {% endfor %}
{% endif %}
{% endfor %}
{% endif %} {# ══════════════════════════════════════════════════════════════ DERNIÈRES ACTIVITÉS COMPLÉTÉES ══════════════════════════════════════════════════════════════ #} {% if recentCompletions|length > 0 %} {% embed '_molecules/section-divider/section-divider.html.twig' with { title: 'Dernières activités complétées', subtitle: recentCompletions|length ~ ' activités récentes', icon: 'check-circle', iconColor: 'success' } %} {% block right %}{% endblock %} {% endembed %}
{% for completion in recentCompletions %}
{% include '_atoms/icon/icon.html.twig' with { name: 'check', size: 'xs', color: 'success' } only %}
{{ completion.activity.name }}
{{ completion.course.fullname }}
{{ completion.completedAt ? completion.completedAt|date('d/m/Y à H:i') : '-' }}
{% endfor %}
{% endif %} {# Footer #}
© Bubul {{ "now"|date("Y") }} — Synchronisé le {{ moodleUser.syncedAt|date('d/m/Y à H:i') }}
{# ══════════════════════════════════════════════════════════════ MODAL ÉDITION ══════════════════════════════════════════════════════════════ #} {# ══════════════════════════════════════════════════════════════ MODAL SUPPRESSION ══════════════════════════════════════════════════════════════ #}
{% endblock %}