Files
pta/app/Views/partials/planning_editor.php
Loic Masi 5fbf76868f pour prod
2026-08-07 16:13:43 +02:00

331 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<section id="editor-view" class="app-view page-content">
<?php if (($accessProfile['role'] ?? '') === 'RESPONSABLE_STRUCTURE'): ?>
<div class="message message-info role-page-notice">
Vous pouvez saisir et corriger les horaires et motifs de votre lieu. Les modifications sont enregistrées en <strong>brouillon</strong> ; seul le Service Enfance peut les valider.
</div>
<?php endif; ?>
<section class="card selection-card">
<h2>1. Sélection du planning</h2>
<div class="selection-grid">
<label class="field">
<span>Lieu daffectation <strong>*</strong></span>
<select id="structure" required>
<option value="">Choisir un lieu daffectation</option>
<?php foreach ($structures as $structure): ?>
<option value="<?= (int) $structure['id_structure'] ?>">
<?= htmlspecialchars($structure['nom']) ?> — <?= ($structure['type_affectation'] ?? 'PERISCOLAIRE') === 'EXTRASCOLAIRE' ? 'Extrascolaire' : 'Périscolaire' ?>
</option>
<?php endforeach; ?>
</select>
</label>
<label class="field">
<span>Agent <strong>*</strong></span>
<select id="agent" required disabled>
<option value="">Choisir dabord un lieu daffectation</option>
</select>
</label>
<label class="field">
<span>Semaine <strong>*</strong></span>
<input id="week" type="week" value="<?= htmlspecialchars($currentWeek) ?>" required disabled>
</label>
</div>
</section>
<section class="quota-strip" id="editor-quota" hidden>
<article class="quota-card">
<span>Quotité</span>
<strong id="quota-rate">100 %</strong>
</article>
<article class="quota-card">
<span>Quota de la période</span>
<strong id="quota-target">1 607 h 00</strong>
<small id="quota-period">Année civile</small>
</article>
<article class="quota-card">
<span>Déjà affecté</span>
<strong id="quota-used">0 h 00</strong>
<small id="quota-used-detail">Validé + brouillon</small>
</article>
<article class="quota-card quota-card-emphasis">
<span>Reste à affecter</span>
<strong id="quota-remaining">1 607 h 00</strong>
</article>
</section>
<section class="card" id="entry-card" aria-disabled="true">
<div class="section-heading">
<div>
<h2>2. Saisir ou modifier les affectations</h2>
<p class="section-subtitle">Chaque plage horaire possède son propre motif et sa propre règle de décompte du quota annuel.</p>
</div>
</div>
<div class="weekly-entry-toolbar">
<p class="weekly-entry-help">Les horaires déjà enregistrés sont rechargés automatiquement. Modifiez-les directement, puis appliquez les horaires avant denregistrer.</p>
</div>
<div class="weekly-entry-scroll">
<table class="weekly-entry-table" aria-label="Affectations du lundi au vendredi">
<thead>
<tr>
<th>Jour</th>
<th>Affectations et plages horaires</th>
</tr>
</thead>
<tbody id="weekly-entry-body">
<tr>
<td colspan="2" class="weekly-entry-placeholder">Sélectionnez dabord un lieu daffectation, un agent et une semaine.</td>
</tr>
</tbody>
</table>
</div>
<div class="weekly-entry-actions">
<button id="add-entry" class="button button-primary button-add" type="button" disabled>
Appliquer les horaires renseignés
</button>
</div>
<p class="hint">Chaque plage peut avoir un motif différent : par exemple Travail le matin puis Formation laprès-midi. Les heures sont saisies par pas de 15 minutes. Les créneaux déjà affectés à lagent dans un autre lieu apparaissent dans le planning global et bloquent toute nouvelle saisie qui les chevaucherait.</p>
</section>
<section class="card">
<div class="section-heading">
<div>
<h2>3. Planning global de lagent</h2>
<p id="week-label" class="section-subtitle">Toutes les affectations de lagent sur la semaine, quel que soit le lieu daffectation. Cliquez sur un créneau pour le déplacer ou le dupliquer, ou glissez-le directement vers un autre jour.</p>
</div>
<div class="planning-summary-actions">
<div class="totals">
<span>Total semaine décompté</span>
<strong id="work-total">0 h 00</strong>
</div>
<?php if (!empty($permissions['can_use_templates'])): ?>
<button id="save-week-template" class="button button-secondary" type="button" disabled>
Enregistrer comme semaine type
</button>
<button id="apply-week-template" class="button button-secondary" type="button" disabled>
Importer une semaine type
</button>
<button id="apply-week-template-period" class="button button-secondary" type="button" disabled>
Appliquer sur une période
</button>
<?php endif; ?>
<button id="open-agent-pdf" class="button button-secondary button-pdf" type="button" disabled>
Voir le PDF de lagent (7 semaines)
</button>
</div>
</div>
<div id="empty-state" class="empty-state">Aucune affectation pour le moment.</div>
<div id="planning-board" class="planning-board" hidden></div>
</section>
<section class="actions-bar">
<div id="message" class="message" role="status" aria-live="polite"></div>
<div class="action-buttons">
<?php if (!empty($permissions['can_edit_draft'])): ?>
<button id="modify-planning" class="button button-warning" type="button" hidden>Modifier le planning</button>
<button id="save-draft" class="button button-secondary" type="button" disabled>Enregistrer le brouillon</button>
<?php endif; ?>
<?php if (!empty($permissions['can_validate'])): ?>
<button id="validate-planning" class="button button-success" type="button" disabled>Valider le planning</button>
<?php endif; ?>
</div>
</section>
</section>
<div id="planning-entry-action-modal" class="modal-backdrop" hidden>
<section class="modal-card planning-entry-action-card" role="dialog" aria-modal="true" aria-labelledby="planning-entry-action-title">
<div class="section-heading modal-heading">
<div>
<h2 id="planning-entry-action-title">Déplacer ou dupliquer un créneau</h2>
<p id="planning-entry-action-summary" class="section-subtitle"></p>
</div>
<button id="close-planning-entry-action-modal" type="button" class="button button-ghost modal-close" aria-label="Fermer">×</button>
</div>
<form id="planning-entry-action-form" class="admin-form">
<fieldset class="entry-action-mode">
<legend>Action à effectuer</legend>
<label class="entry-action-option">
<input type="radio" name="planning-entry-action" value="move" checked>
<span><strong>Déplacer</strong><small>Le créneau change de jour.</small></span>
</label>
<label class="entry-action-option">
<input type="radio" name="planning-entry-action" value="duplicate">
<span><strong>Dupliquer</strong><small>Le créneau dorigine est conservé.</small></span>
</label>
</fieldset>
<label class="field">
<span>Jour cible</span>
<select id="planning-entry-target-date" required></select>
</label>
<p class="hint">Astuce : vous pouvez aussi glisser-déposer directement un créneau vers un autre jour. Maintenez <strong>Ctrl</strong> (ou <strong>⌘</strong> sur Mac) pendant le dépôt pour le dupliquer.</p>
<div id="planning-entry-action-message" class="message" role="status" aria-live="polite"></div>
<div class="admin-form-actions modal-actions">
<button id="cancel-planning-entry-action" type="button" class="button button-secondary">Annuler</button>
<button id="confirm-planning-entry-action" type="submit" class="button button-primary">Appliquer</button>
</div>
</form>
</section>
</div>
<div id="save-week-template-modal" class="modal-backdrop" hidden>
<section class="modal-card week-template-modal-card" role="dialog" aria-modal="true" aria-labelledby="save-week-template-title">
<div class="section-heading modal-heading">
<div>
<h2 id="save-week-template-title">Enregistrer une semaine type</h2>
<p class="section-subtitle">Le modèle mémorisera toutes les affectations de lagent sur la semaine, tous lieux confondus.</p>
</div>
<button id="close-save-week-template-modal" type="button" class="button button-ghost modal-close" aria-label="Fermer">×</button>
</div>
<form id="save-week-template-form" class="admin-form">
<label class="field">
<span>Nom de la semaine type <strong>*</strong></span>
<input id="week-template-name" type="text" maxlength="120" placeholder="Ex. Semaine scolaire classique" required>
</label>
<div class="week-template-context" id="save-week-template-context"></div>
<div id="save-week-template-message" class="message" role="status" aria-live="polite"></div>
<div class="admin-form-actions modal-actions">
<button id="cancel-save-week-template" type="button" class="button button-secondary">Annuler</button>
<button type="submit" class="button button-primary">Enregistrer le modèle</button>
</div>
</form>
</section>
</div>
<div id="apply-week-template-modal" class="modal-backdrop" hidden>
<section class="modal-card week-template-modal-card" role="dialog" aria-modal="true" aria-labelledby="apply-week-template-title">
<div class="section-heading modal-heading">
<div>
<h2 id="apply-week-template-title">Importer une semaine type</h2>
<p class="section-subtitle">Le modèle sera appliqué à la semaine actuellement sélectionnée pour cet agent.</p>
</div>
<button id="close-apply-week-template-modal" type="button" class="button button-ghost modal-close" aria-label="Fermer">×</button>
</div>
<form id="apply-week-template-form" class="admin-form">
<label class="field">
<span>Semaine type <strong>*</strong></span>
<select id="week-template-select" required>
<option value="">Chargement...</option>
</select>
</label>
<div id="week-template-details" class="week-template-details"></div>
<fieldset class="entry-action-mode week-template-mode">
<legend>Mode dimport</legend>
<label class="entry-action-option">
<input type="radio" name="week-template-mode" value="merge" checked>
<span><strong>Compléter la semaine</strong><small>Conserve les affectations existantes. Limport est refusé en cas de chevauchement.</small></span>
</label>
<label class="entry-action-option">
<input type="radio" name="week-template-mode" value="replace">
<span><strong>Remplacer la semaine</strong><small>Supprime les affectations existantes de lagent sur cette semaine avant dappliquer le modèle.</small></span>
</label>
</fieldset>
<div class="week-template-danger" id="week-template-replace-warning" hidden>
Le mode « Remplacer » efface les affectations actuelles de lagent sur la semaine sélectionnée, tous lieux confondus.
</div>
<div id="apply-week-template-message" class="message" role="status" aria-live="polite"></div>
<div class="admin-form-actions modal-actions week-template-modal-actions">
<button id="delete-week-template" type="button" class="button button-danger" disabled>Supprimer ce modèle</button>
<span class="modal-action-spacer"></span>
<button id="cancel-apply-week-template" type="button" class="button button-secondary">Annuler</button>
<button type="submit" class="button button-primary">Importer le modèle</button>
</div>
</form>
</section>
</div>
<div id="apply-week-template-period-modal" class="modal-backdrop" hidden>
<section class="modal-card week-template-period-modal-card" role="dialog" aria-modal="true" aria-labelledby="apply-week-template-period-title">
<div class="section-heading modal-heading">
<div>
<h2 id="apply-week-template-period-title">Appliquer une semaine type sur une période</h2>
<p class="section-subtitle">Les périodes de vacances déjà validées dans PTA sont prises en compte avant toute création de planning.</p>
</div>
<button id="close-apply-week-template-period-modal" type="button" class="button button-ghost modal-close" aria-label="Fermer">×</button>
</div>
<form id="apply-week-template-period-form" class="admin-form">
<div class="week-template-period-grid">
<label class="field">
<span>Semaine type <strong>*</strong></span>
<select id="week-template-period-select" required>
<option value="">Chargement...</option>
</select>
</label>
<label class="field">
<span>Date de début <strong>*</strong></span>
<input id="week-template-period-start" type="date" required>
</label>
<label class="field">
<span>Date de fin <strong>*</strong></span>
<input id="week-template-period-end" type="date" required>
</label>
</div>
<fieldset class="entry-action-mode week-template-mode">
<legend>Périodes à appliquer</legend>
<label class="entry-action-option">
<input type="radio" name="week-template-period-filter" value="all" checked>
<span><strong>Toutes les semaines</strong><small>Répète la semaine type sur toutes les dates de la période, quelles soient scolaires ou pendant les vacances.</small></span>
</label>
<label class="entry-action-option">
<input type="radio" name="week-template-period-filter" value="school">
<span><strong>Uniquement les périodes scolaires</strong><small>Applique le modèle uniquement aux jours situés hors des vacances enregistrées dans PTA.</small></span>
</label>
<label class="entry-action-option">
<input type="radio" name="week-template-period-filter" value="extra">
<span><strong>Uniquement les périodes extrascolaires</strong><small>Applique le modèle uniquement aux jours compris dans les vacances scolaires enregistrées dans PTA.</small></span>
</label>
</fieldset>
<div class="week-template-period-rule-note">
<strong>Calendrier :</strong>
le caractère scolaire ou extrascolaire dune date est déterminé à partir des périodes de vacances validées dans PTA.
Le choix ci-dessus pilote lapplication du modèle ; il nest pas déduit du lieu daffectation.
</div>
<fieldset class="entry-action-mode week-template-mode">
<legend>Mode dapplication</legend>
<label class="entry-action-option">
<input type="radio" name="week-template-period-mode" value="merge" checked>
<span><strong>Compléter les plannings</strong><small>Conserve les affectations déjà existantes. Lapplication est bloquée si un chevauchement est détecté.</small></span>
</label>
<label class="entry-action-option">
<input type="radio" name="week-template-period-mode" value="replace">
<span><strong>Remplacer les jours concernés</strong><small>Supprime les affectations existantes uniquement sur les dates où le modèle doit réellement sappliquer, puis recrée le planning.</small></span>
</label>
</fieldset>
<div class="week-template-danger" id="week-template-period-replace-warning" hidden>
Les journées exclues par le filtre de calendrier ne seront pas effacées. Seules les dates sur lesquelles le modèle crée au moins un créneau seront remplacées.
</div>
<div class="week-template-period-preview-actions">
<button id="preview-week-template-period" type="button" class="button button-secondary">Prévisualiser lapplication</button>
</div>
<div id="week-template-period-preview" class="week-template-period-preview" hidden></div>
<div id="apply-week-template-period-message" class="message" role="status" aria-live="polite"></div>
<div class="admin-form-actions modal-actions">
<button id="cancel-apply-week-template-period" type="button" class="button button-secondary">Annuler</button>
<button id="confirm-apply-week-template-period" type="submit" class="button button-primary" disabled>Appliquer sur la période</button>
</div>
</form>
</section>
</div>