{% extends 'base.html.twig' %} {% block title %}Annonces - Admin{% endblock %} {% set statusBadges = { 'published': { label: 'En ligne', variant: 'success', dot: true }, 'scheduled': { label: 'Programmée', variant: 'info', dot: true }, 'expired': { label: 'Expirée', variant: 'neutral', dot: false }, 'hidden': { label: 'Masquée', variant: 'neutral', dot: false } } %} {% block body %}
{# Header #}
{% include '_molecules/page-header/page-header.html.twig' with { title: 'Annonces', subtitle: 'La modale de nouveauté affichée aux utilisateurs. Une seule annonce est en ligne à la fois.', icon: 'bell', backHref: path('app_dashboard'), backLabel: 'Retour au dashboard' } only %} {% include '_atoms/button/button.html.twig' with { label: 'Nouvelle annonce', variant: 'primary', size: 'lg', icon: 'plus', href: path('admin_announcement_new') } only %}
{# Compteur #}
{{ announcements|length }} annonce{{ announcements|length > 1 ? 's' : '' }} enregistrée{{ announcements|length > 1 ? 's' : '' }}
{# Tableau #}
{% for announcement in announcements %} {% set status = announcement.status %} {% set seen = viewCounts[announcement.id] ?? 0 %} {# Annonce #} {# Fenêtre #} {# Statut #} {# Lectures #} {# Actions #} {% else %} {% endfor %}
Annonce Fenêtre Statut Lectures Actions
{% if announcement.imagePath %} {% else %}
{% include '_atoms/icon/icon.html.twig' with { name: 'palette-2', size: 'sm', color: 'gray' } only %}
{% endif %}
{% if announcement.badge %} {% include '_atoms/badge/badge.html.twig' with { label: announcement.badge, variant: 'primary', size: 'xs' } only %} {% endif %}

{{ announcement.title }}

{{ announcement.body }}

{{ announcement.startsAt|date('d/m/Y') }}

au {{ announcement.endsAt|date('d/m/Y') }}

{% include '_atoms/badge/badge.html.twig' with { label: statusBadges[status].label, variant: statusBadges[status].variant, dot: statusBadges[status].dot, size: 'sm' } only %} {% if seen > 0 %} {{ seen }} / {{ userCount }}

{{ userCount > 0 ? (seen / userCount * 100)|round : 0 }} %

{% else %} {% endif %}
{# Publier / masquer #}
{% include '_atoms/button/button.html.twig' with { label: announcement.published ? 'Masquer' : 'Publier', variant: announcement.published ? 'ghost' : 'primary', size: 'sm', icon: announcement.published ? 'close' : 'eye', type: 'submit' } only %}
{% include '_atoms/button/button.html.twig' with { variant: 'ghost', size: 'sm', icon: 'edit', href: path('admin_announcement_edit', {id: announcement.id}), attr: { title: 'Modifier' } } only %} {# |e('js') et non l'échappement HTML implicite : le titre atterrit dans du JavaScript porté par un attribut, et le navigateur décode les entités HTML *avant* de livrer le code au moteur JS — un ' y redeviendrait une apostrophe fermante. #}
{% include '_atoms/button/button.html.twig' with { variant: 'ghost', size: 'sm', icon: 'trash', type: 'submit', attr: { title: 'Supprimer', class: 'text-error hover:text-error' } } only %}
{% include '_molecules/empty-state/empty-state.html.twig' with { title: 'Aucune annonce', description: 'Créez une annonce pour présenter une nouveauté aux utilisateurs à leur prochaine connexion.', icon: 'bell', variant: 'minimal', actions: [{ label: 'Créer une annonce', href: path('admin_announcement_new'), variant: 'primary', icon: 'plus' }] } only %}
{% endblock %}