{% extends '@App/app.html.twig' %} {% block title %}Mon planning{% endblock %} {% block page_header %}{% endblock %} {% block content %} {% set day_names = ['LUN', 'MAR', 'MER', 'JEU', 'VEN', 'SAM', 'DIM'] %} {% set full_day_names = ['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche'] %} {% set month_names = ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'] %} {% set total_hours = calendar.totalMinutes / 60 %} {% set contract_hours = calendar.weeklyContractMinutes / 60 %} {% set pending_count = calendar.assignments|length - calendar.acknowledgedCount %} {% set next = calendar.nextAssignment %} {% set schedule = calendar.currentSchedule %} {% set manager = calendar.manager %} {% set manager_photo = manager and manager.photo ? manager.photo|trim : null %} {% set manager_avatar = manager_photo ? (manager_photo starts with 'http://' or manager_photo starts with 'https://' ? manager_photo : asset(manager_photo starts with '/' ? manager_photo|slice(1) : manager_photo)) : null %} {% set active_tab = active_tab|default('planning') %} {% set change_requests_enabled = change_requests_enabled|default(true) %} {% set availability_enabled = availability_enabled|default(true) %} {% set availability_locked = availability_locked|default(false) %} {% if active_tab == 'change_requests' and not change_requests_enabled %} {% set active_tab = 'planning' %} {% endif %} {% if active_tab == 'availability' and not availability_enabled %} {% set active_tab = 'planning' %} {% endif %} {% set availability_view = availability_view|default({days: {}, slots: {}, selected: {}, exceptions: [], availableMinutes: 0, minimumMinutes: 1500, compliancePercent: 0}) %} {% set change_request_view = change_request_view|default({requests: [], total: 0, pending: 0, accepted30: 0}) %} {% set request_type_labels = {swap: 'Échange', time_change: 'Modification', unavailable: 'Indisponibilité', other: 'Autre'} %} {% set request_type_tones = {swap: 'swap', time_change: 'time', unavailable: 'unavailable', other: 'other'} %} {% set request_status_labels = {submitted: 'En attente', pending: 'En attente', in_review: 'En cours', approved: 'Acceptée', refused: 'Refusée', cancelled: 'Annulée'} %} {% set request_status_tones = {submitted: 'pending', pending: 'pending', in_review: 'pending', approved: 'approved', refused: 'refused', cancelled: 'cancelled'} %}
{% if active_tab == 'change_requests' and change_requests_enabled %} Nouvelle demande {% elseif active_tab == 'availability' and availability_enabled %} {% if availability_locked %} {% else %} Ajouter une dispo {% endif %} {% else %} Demande d'absence {% endif %}

{{ active_tab == 'change_requests' ? 'Demandes de changement' : 'Mon planning' }}

{% if active_tab == 'change_requests' and change_requests_enabled %} Consultez et suivez l'état de vos demandes de modification de planning. {% elseif active_tab == 'availability' and availability_enabled %} Définissez vos préférences horaires pour aider vos managers à organiser les shifts. {% else %} Gérez votre emploi du temps et vos disponibilités hebdomadaires. {% endif %}

{% if active_tab == 'availability' and availability_enabled %} {% endif %}
{% if active_tab == 'change_requests' and change_requests_enabled %}
Demandes totales {{ change_request_view.total }}
En attente {{ change_request_view.pending }}
Acceptées (30j) {{ change_request_view.accepted30 }}
{% elseif active_tab == 'planning' %}
Prochain shift {% if next %} {{ full_day_names[next.plannedStartAt|date('N') - 1]|capitalize }} {{ next.plannedStartAt|date('d') }} {{ month_names[next.plannedStartAt|date('n') - 1] }} {{ next.plannedStartAt|date('H:i') }} — {{ next.plannedEndAt|date('H:i') }} {% else %} Aucun shift Cette semaine {% endif %}
Heures prévues {{ total_hours|number_format(total_hours == total_hours|round ? 0 : 1, ',', ' ') }} h {{ total_hours >= contract_hours ? 'Temps plein' : 'Planifié' }}
Shifts à confirmer {{ pending_count }}{% if pending_count > 0 %} Action requise{% endif %}
Repos hebdomadaire Conforme
{% endif %}
{% if active_tab == 'change_requests' and change_requests_enabled %}
{% for request in change_request_view.requests|slice(0, 4) %} {% set assignment = request.assignment %} {% set shift = assignment ? assignment.shift : null %} {% set type_tone = request_type_tones[request.type]|default('other') %} {% set status_tone = request_status_tones[request.status]|default('pending') %} {% else %} {% endfor %}
Date demande Shift concerné Motif Type Statut Actions
{{ request.createdAt|date('d/m/Y') }} {% if assignment %} {{ full_day_names[assignment.plannedStartAt|date('N') - 1]|capitalize|slice(0, 3) }}. {{ assignment.plannedStartAt|date('d') }} {{ month_names[assignment.plannedStartAt|date('n') - 1]|capitalize }} {{ assignment.plannedStartAt|date('H:i') }} — {{ assignment.plannedEndAt|date('H:i') }}{% if shift %} ({{ shift.title }}){% endif %} {% else %} Shift non renseigné {% endif %} {{ request.reason|default('Aucun motif')|length > 52 ? request.reason|slice(0, 52) ~ '...' : request.reason|default('Aucun motif') }} {{ request_type_labels[request.type]|default(request.type|capitalize) }} {{ request_status_labels[request.status]|default(request.status|capitalize) }} {% if request.status in ['submitted', 'pending'] %} {% endif %}
Aucune demande de changement.
Affichage de 1 à {{ change_request_view.total > 4 ? 4 : change_request_view.total }} sur {{ change_request_view.total }} demandes

Comment ça marche ?

Vos demandes sont transmises directement à {{ manager ? manager : 'votre manager' }}. Vous recevrez une notification dès qu'une décision sera prise. Pour les échanges, le collègue concerné doit également confirmer.

Délais de traitement

Les demandes de changement doivent être soumises au moins 48 heures à l'avance pour être traitées dans les temps. Pour les urgences de dernière minute, veuillez appeler le standard.

{% elseif active_tab == 'availability' and availability_enabled %}

Préférences hebdomadaires

Cochez vos créneaux de disponibilité souhaités.

{% if availability_locked %}

Vos disponibilités sont verrouillées par votre manager.

{% endif %}
Disponible Indisponible
Jour
{% for slot in availability_view.slots %}
{{ slot.label }}
{% endfor %} {% for day_number, day_label in availability_view.days %}
{{ day_label }}
{% for slot_key, slot in availability_view.slots %} {% set preference = availability_view.selected[day_number][slot_key]|default(null) %} {% set preference_type = preference ? preference.type : '' %}
{% endfor %} {% endfor %}
Annuler

Indisponibilités exceptionnelles

Ajoutez des dates spécifiques où vous ne serez pas disponible (hors congés).

{% if availability_locked %} Ajout verrouillé {% else %} Ajouter une exception {% endif %}
{% for exception in availability_view.exceptions %}
{{ exception.comment ?: (exception.type == 'unavailable' ? 'Indisponibilité' : 'Disponibilité') }} {{ full_day_names[exception.startAt|date('N') - 1]|capitalize }} {{ exception.startAt|date('d') }} {{ month_names[exception.startAt|date('n') - 1] }} {% if exception.startAt|date('Y-m-d') == exception.endAt|date('Y-m-d') %} · {{ exception.startAt|date('H:i') }} - {{ exception.endAt|date('H:i') }} {% else %} · jusqu'au {{ exception.endAt|date('d/m') }} {% endif %}
{% else %}

Aucune exception à venir.

{% endfor %}
{% else %}

Semaine du {{ calendar.start|date('d') }} au {{ calendar.end|date('d') }} {{ month_names[calendar.end|date('n') - 1] }} {{ calendar.end|date('Y') }}

{% if pending_count > 0 %}
{% endif %}
{% for day in calendar.days %} {% set key = day|date('Y-m-d') %} {% set cell = calendar.cells[key] %}
{{ day_names[day|date('N') - 1] }} {{ day|date('d') }}
{% for assignment in cell.assignments %} {% set shift = assignment.shift %} {% set title = shift ? shift.title|lower : '' %} {% set tone = shift and shift.startTime and shift.startTime|date('H') >= 20 ? 'night' : (title matches '/après|apres|soir/' ? 'afternoon' : 'morning') %}
{{ shift ? shift.title : 'Shift' }} {% if assignment.employeeAcknowledgedAt %} {% else %} À confirmer {% endif %}
{{ assignment.plannedStartAt|date('H:i') }} — {{ assignment.plannedEndAt|date('H:i') }} {% if shift and shift.breakDurationMinutes > 0 %} Pause {{ shift.breakDurationMinutes }} min
{% endif %} {{ shift and shift.etablissement ? shift.etablissement.nom : 'Établissement non renseigné' }} {% if shift and shift.service %} · {{ shift.service.nom }}{% endif %}
{% endfor %} {% for interview in cell.interviews %} Entretien RH {{ interview.type.nom }} {{ interview.scheduledAt|date('H:i') }} {{ interview.location ?: (interview.remoteLink ? 'Visioconférence' : 'Lieu à définir') }}{% if interview.campaign %}
{{ interview.campaign.nom }}{% endif %}
{% endfor %} {% for availability in cell.availabilities %}
{{ availability.type == 'unavailable' ? 'Indisponibilité' : 'Disponibilité' }}
{% endfor %} {% if cell.assignments is empty and cell.interviews is empty and cell.availabilities is empty %}
Repos
{% endif %}
{% endfor %}
{% endif %}
{% if active_tab != 'change_requests' %} {% endif %}
{% endblock %}