2026-08-23 12:13:47 +02:00
{% extends "base.html" %}
{% block title %}Ma journée{% endblock %}
{% block content %}
< div class = "container-fluid py-3" >
< div class = "d-flex flex-wrap justify-content-between align-items-center gap-2 mb-3" >
< div >
< h1 class = "h3 mb-1" > < i class = "bi bi-calendar2-week" > < / i > Ma journée< / h1 >
< p class = "text-muted mb-0" > Une proposition de tâches pour le {{ target_date.strftime('%d/%m/%Y') }}. Vous gardez la main sur les changements.< / p >
< / div >
< div class = "btn-group" role = "group" aria-label = "Navigation entre les jours" >
< a class = "btn btn-outline-secondary" href = "{{ url_for('planning.my_day', date=previous_date.isoformat()) }}" > ← Jour précédent< / a >
< a class = "btn btn-outline-primary" href = "{{ url_for('planning.my_day') }}" > Aujourd'hui< / a >
< a class = "btn btn-outline-secondary" href = "{{ url_for('planning.my_day', date=next_date.isoformat()) }}" > Jour suivant →< / a >
< / div >
< / div >
{% if not hours_configured %}
< div class = "alert alert-warning" role = "alert" >
< strong > Horaires de travail non configurés pour cette journée.< / strong >
La proposition automatique reste désactivée. Configurez les horaires du
technicien ou utilisez la planification manuelle existante.
2026-08-23 13:41:31 +02:00
< a class = "alert-link d-block mt-1" href = "{{ url_for('planning.time_tracking') }}" > Configurer les horaires de travail< / a >
2026-08-23 12:13:47 +02:00
< / div >
{% endif %}
{% if candidates %}
2026-08-23 13:05:31 +02:00
< div class = "d-flex flex-wrap gap-2 mb-3" aria-label = "Résumé de la journée" >
< span class = "badge text-bg-primary" > {{ candidates|length }} tâche(s)< / span >
< span class = "badge text-bg-warning" > {{ candidates|selectattr('status', 'equalto', 'à replanifier')|list|length }} à replanifier< / span >
< span class = "badge text-bg-danger" > {{ candidates|selectattr('task_type', 'equalto', 'emergency')|list|length }} urgence(s)< / span >
< span class = "badge text-bg-danger" > {{ candidates|selectattr('status', 'equalto', 'conflit')|list|length }} conflit(s)< / span >
< / div >
2026-08-23 12:13:47 +02:00
< div class = "timeline d-grid gap-3" aria-label = "Tâches proposées" >
{% for item in candidates %}
< article class = "card shadow-sm border-start border-{{ 'danger' if item.task_type == 'emergency' else 'primary' }} border-4" >
< div class = "card-body" >
< div class = "d-flex flex-wrap justify-content-between gap-2" >
< div >
< div class = "text-muted small" >
{% if item.proposed_start and item.proposed_end %}
{{ item.proposed_start.strftime('%H:%M') }} – {{ item.proposed_end.strftime('%H:%M') }}
{% else %}Horaire à définir{% endif %}
· {{ item.duration_minutes }} min
< / div >
< h2 class = "h5 mb-1 mt-1" > {{ item.title }}< / h2 >
< div class = "small text-muted" > {{ item.location_label }}< / div >
< / div >
< div class = "text-end" >
< span class = "badge text-bg-secondary" > {{ item.type_label }}< / span >
< span class = "badge text-bg-light border" > {{ item.constraint_label }}< / span >
< div class = "small mt-1" > {{ item.status|capitalize }}< / div >
< / div >
< / div >
{% if item.explanation %}< p class = "mb-0 mt-2 small" > < i class = "bi bi-info-circle" > < / i > {{ item.explanation }}< / p > {% endif %}
2026-08-23 13:05:31 +02:00
{% set item_alternatives = alternatives.get((item.source_type, item.source_id), []) %}
{% if item_alternatives and item.status != 'conflit' %}
< details class = "mt-2" >
< summary class = "small text-primary" style = "cursor:pointer" > Replanifier cette tâche< / summary >
< form method = "post" action = "{{ url_for('planning.my_day_reschedule') }}" class = "row g-2 mt-1 align-items-end" >
< input type = "hidden" name = "source_type" value = "{{ item.source_type }}" >
< input type = "hidden" name = "source_id" value = "{{ item.source_id }}" >
< input type = "hidden" name = "date" value = "{{ target_date.isoformat() }}" >
< div class = "col-8 col-sm-5" > < label class = "form-label small" for = "slot-{{ item.source_type }}-{{ item.source_id }}" > Créneau compatible< / label >
< select class = "form-select form-select-sm" id = "slot-{{ item.source_type }}-{{ item.source_id }}" name = "slot" required >
{% for start, end in item_alternatives %}< option value = "{{ start.strftime('%H:%M') }}|{{ end.strftime('%H:%M') }}" > {{ start.strftime('%H:%M') }} – {{ end.strftime('%H:%M') }}< / option > {% endfor %}
< / select >
< / div >
< div class = "col-auto" > < button class = "btn btn-sm btn-outline-primary" type = "submit" > Enregistrer< / button > < / div >
< / form >
< / details >
{% endif %}
2026-08-23 12:13:47 +02:00
< / div >
< / article >
{% endfor %}
< / div >
{% else %}
< div class = "card border-0 bg-light" >
< div class = "card-body py-5 text-center" >
< i class = "bi bi-calendar-check fs-1 text-muted" > < / i >
< h2 class = "h5 mt-3" > Aucune tâche à afficher< / h2 >
< p class = "text-muted mb-0" > Les interventions, maintenances préventives et tâches administratives du jour apparaîtront ici.< / p >
2026-08-23 13:41:31 +02:00
{% if hours_configured %}< a class = "btn btn-outline-primary btn-sm mt-3" href = "{{ url_for('planning.room_schedules') }}" > Vérifier le planning des salles< / a > {% endif %}
2026-08-23 12:13:47 +02:00
< / div >
< / div >
{% endif %}
< / div >
{% endblock %}