<?php use App\Core\Csrf;$days=['lundi'=>'Lun','mardi'=>'Mar','mercredi'=>'Mer','jeudi'=>'Jeu','vendredi'=>'Ven','samedi'=>'Sam','dimanche'=>'Dim'];$dayFromIso=[1=>'lundi',2=>'mardi',3=>'mercredi',4=>'jeudi',5=>'vendredi',6=>'samedi',7=>'dimanche'];$remote_work_items=(array)($remote_work_items??[]);$planning_events=(array)($planning_events??['events'=>[],'requests'=>[]]);$teleworkAllowed=!empty($professor['teletravail_autorise']);$h=static fn($v)=>htmlspecialchars((string)$v,ENT_QUOTES,'UTF-8');$success=(string)($success??'');$error=(string)($error??'');$canManage=(bool)($canManage??false);$planning_validated=(bool)($planning_validated??false);$contract_hours=(float)($contract_hours??0);$course_hours=(float)($course_hours??$planned_hours??0);$remote_work_hours=(float)($remote_work_hours??0);$planned_hours=$course_hours+$remote_work_hours;$active_year=(array)($active_year??[]);$yearStart=(string)($active_year['date_debut']??date('Y-m-d'));$yearEnd=(string)($active_year['date_fin']??'');$gap=$contract_hours-$planned_hours;$planning_block_reason=$contract_hours<=0?'Aucun contrat actif avec un volume horaire n’est renseigné.':($planned_hours<=0?'Aucun cours ni télétravail n’est planifié.':(abs($gap)>0.01?'La somme des cours et du télétravail doit correspondre exactement au volume contractuel.':'')); ?>
<link rel="stylesheet" href="/public/assets/css/cda-professor-planner-9646.css?v=9.6.48">
<link rel="stylesheet" href="/public/assets/css/cda-professor-planner-interactions-9651.css?v=9.6.55">
<style>.pp-event-list{display:grid;gap:.7rem;margin:1rem 0}.pp-event{padding:1rem;border-radius:12px;color:#fff}.pp-event.meeting{background:linear-gradient(135deg,#f59e0b,#b45309)}.pp-request-box{margin:1rem 0;padding:1rem;border:1px solid #dbe3f0;border-radius:12px;background:#fff}.pp-request-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.7rem}.pp-request-grid label{display:grid;gap:.3rem}.pp-meeting-form{display:grid;gap:.7rem}.pp-meeting-form select{min-height:130px}@media(max-width:700px){.pp-request-grid{grid-template-columns:1fr}}</style>
<style>.pp-waiting-help{padding:.8rem;border-radius:.7rem;background:#f1f5ff;color:#344563}.pp-waiting-list{display:grid;gap:.45rem;margin:1rem 0}.pp-waiting-list div{display:flex;justify-content:space-between;gap:1rem;padding:.7rem .8rem;border:1px solid #dce5f5;border-radius:.7rem;background:#fff}.pp-waiting-list span{color:#64748b}.pp-waiting-empty{padding:1rem;border-radius:.7rem;background:#fff7e6;color:#8a5a00}.pp-assignment-submit:disabled{opacity:.45;cursor:not-allowed}.pp-remote-button{background:#7c3aed!important;color:#fff!important;border-color:#6d28d9!important}.pp-slot.remote-work{background:linear-gradient(135deg,#7c3aed,#5b21b6);border-color:#4c1d95;color:#fff;z-index:4}.pp-slot.remote-work em{color:#ede9fe}.pp-remote-form textarea{min-height:95px;resize:vertical}.pp-remote-form .pp-save{background:#7c3aed}.pp-remote-help{padding:.8rem 1rem;border-radius:.75rem;background:#f5f3ff;color:#5b21b6;margin:.8rem 0}@media(max-width:600px){.pp-waiting-list div{flex-direction:column;gap:.2rem}}</style>
<main class="pp-page">
 <header class="pp-hero"><div><span><?=$planning_validated?'PLANNING PRÉVISIONNEL VALIDÉ':'PLANNING PRÉVISIONNEL'?></span><h1><?=$h($professor['prenom'].' '.$professor['nom'])?></h1><p><?=$canManage?($planning_validated?'Ce planning est validé. Les affectations passent maintenant par la file d’attente.':'La Direction construit et fixe le planning prévisionnel de l’année.'):'Consultez le planning fixé par la Direction et formulez une demande si un déplacement est nécessaire.'?></p></div><div><a href="/public/professeurs-pro/attente?professeur=<?=rawurlencode((string)$professor['public_token'])?>">Affecter un élève en attente →</a><?php if($teleworkAllowed):?><a href="/public/professeurs-pro/teletravail?professeur=<?=rawurlencode((string)$professor['public_token'])?><?=$canManage?'&mode=direction':''?>"><?=$canManage?'Gérer le télétravail':'Mes tâches en télétravail'?> →</a><?php endif?><a href="/public/professeurs-pro/voir?professeur=<?=rawurlencode((string)$professor['public_token'])?>">← Retour au profil</a></div></header>
 <?php if($success):?><div class="pp-alert ok"><?=$h($success)?></div><?php endif?><?php if($error):?><div class="pp-alert error"><?=$h($error)?></div><?php endif?>
 <?php if($planning_block_reason):?><div class="pp-alert error"><b>Validation impossible.</b> <?=$h($planning_block_reason)?></div><?php endif?>
 <section class="pp-metrics"><article><b><?=number_format($contract_hours,2,',',' ')?> h</b><span>contractuelles</span></article><article><b><?=number_format($planned_hours,2,',',' ')?> h</b><span>planifiées · <?=number_format($course_hours,2,',',' ')?> h cours + <?=number_format($remote_work_hours,2,',',' ')?> h télétravail</span></article><article class="<?=$gap<0?'over':($gap>0?'warn':'ok')?>"><b><?=number_format(abs($gap),2,',',' ')?> h</b><span><?=$gap<0?'en dépassement':($gap>0?'restantes':'cohérent')?></span></article></section>
 <section class="pp-toolbar"><div class="pp-days"><?php foreach($days as $key=>$label):?><button type="button" data-day="<?=$key?>" class="<?=$key==='lundi'?'active':''?>"><?=$label?></button><?php endforeach?></div><button type="button" id="pp-week">Vue semaine</button><?php if($canManage&&!$planning_validated):?><button type="button" id="pp-new">＋ Ajouter un cours</button><?php if($teleworkAllowed):?><button type="button" id="pp-new-remote" class="pp-remote-button">⌂ Ajouter du télétravail</button><?php endif?><?php endif?></section>
 <section class="pp-calendar" id="pp-calendar">
  <div class="pp-time-axis"><?php for($hour=8;$hour<=22;$hour++):?><span style="top:<?=($hour-8)*60?>px"><?=sprintf('%02d:00',$hour)?></span><?php endfor?></div>
  <?php foreach($days as $key=>$label):?><div class="pp-day <?=$key==='lundi'?'active':''?>" data-day-column="<?=$key?>"><header><?=$label?></header><div class="pp-grid" data-day="<?=$key?>" data-editable="<?=$canManage&&!$planning_validated?'1':'0'?>" aria-label="Planning du <?=$h($label)?>"><?php foreach($slots as $slot):if($slot['jour_semaine']!==$key)continue;$start=((int)substr($slot['heure_debut'],0,2)-8)*60+(int)substr($slot['heure_debut'],3,2);$length=max(25,(strtotime($slot['heure_fin'])-strtotime($slot['heure_debut']))/60);?><article class="pp-slot <?=$h($slot['statut'])?>" style="top:<?=$start?>px;height:<?=$length?>px" tabindex="0" data-slot-id="<?=(int)$slot['id']?>" data-discipline-id="<?=(int)$slot['discipline_id']?>" data-room-id="<?=(int)($slot['salle_id']??0)?>" data-day="<?=$h($slot['jour_semaine'])?>" data-start="<?=substr($slot['heure_debut'],0,5)?>" data-end="<?=substr($slot['heure_fin'],0,5)?>" data-type="<?=$h($slot['type_cours'])?>" data-capacity="<?=(int)$slot['capacite_max']?>" data-date-start="<?=$h($slot['date_debut'])?>" data-date-end="<?=$h($slot['date_fin'])?>" data-assignment="<?=$planning_validated?'1':'0'?>" title="<?=$planning_validated?'Cliquer pour proposer un élève':'Cliquer pour modifier ou déplacer'?>"><b><?=$h($slot['discipline_libelle'])?></b><span><?=substr($slot['heure_debut'],0,5)?>–<?=substr($slot['heure_fin'],0,5)?></span><em><?=$slot['type_cours']==='individuel'?'Libre · individuel':'Collectif · '.$slot['capacite_max'].' places'?></em><?php if($canManage&&!$planning_validated):?><i class="pp-resize-handle" title="Étirer la plage"></i><?php endif?></article><?php endforeach?><?php foreach($remote_work_items as $remote):$remoteDay=$dayFromIso[(int)date('N',strtotime((string)$remote['date_teletravail']))]??'';if($remoteDay!==$key)continue;$remoteStart=((int)substr($remote['heure_debut'],0,2)-8)*60+(int)substr($remote['heure_debut'],3,2);$remoteLength=max(25,(strtotime($remote['heure_fin'])-strtotime($remote['heure_debut']))/60);?><article class="pp-slot remote-work" style="top:<?=$remoteStart?>px;height:<?=$remoteLength?>px" title="<?=$h('Télétravail du '.date('d/m/Y',strtotime($remote['date_teletravail'])).' — '.($remote['consignes_direction']??''))?>"><b>⌂ Télétravail</b><span><?=substr($remote['heure_debut'],0,5)?>–<?=substr($remote['heure_fin'],0,5)?></span><em><?=date('d/m/Y',strtotime($remote['date_teletravail']))?> · <?=$h($remote['statut'])?></em></article><?php endforeach?></div></div><?php endforeach?>
 </section>
 <?php if(!empty($planning_events['events'])):?><section class="pp-request-box"><h2>Réunions ajoutées par la Direction</h2><div class="pp-event-list"><?php foreach($planning_events['events'] as$event):?><article class="pp-event meeting"><b>Réunion · <?=$h($event['titre'])?></b><div><?=date('d/m/Y',strtotime($event['date_evenement']))?> · <?=substr($event['heure_debut'],0,5)?>–<?=substr($event['heure_fin'],0,5)?></div><?php if($event['description']):?><small><?=$h($event['description'])?></small><?php endif?></article><?php endforeach?></div></section><?php endif?>
<?php if(!empty($canAddMeeting)):?><details class="pp-request-box"><summary><b>＋ <?=$canManage?'Ajouter une réunion et inviter des professeurs':'Ajouter une réunion à mon planning'?></b></summary><form method="post" action="/public/professeurs-pro/planning/reunion" class="pp-meeting-form"><?=Csrf::field()?><input type="hidden" name="professeur_id" value="<?=(int)$professor['id']?>"><label>Objet<input name="titre" required></label><label>Date<input type="date" name="date_evenement" required></label><div class="pp-request-grid"><label>Début<input type="time" name="heure_debut" required></label><label>Fin<input type="time" name="heure_fin" required></label></div><?php if($canManage):?><label>Professeurs invités<select name="professeur_ids[]" multiple required><?php foreach($all_professors as$p):?><option value="<?=(int)$p['id']?>" <?=(int)$p['id']===(int)$professor['id']?'selected':''?>><?=$h($p['prenom'].' '.$p['nom'])?></option><?php endforeach?></select></label><?php else:?><p>Cette réunion sera ajoutée uniquement à votre planning. Seule la Direction peut inviter plusieurs professeurs.</p><?php endif?><label>Informations<textarea name="description"></textarea></label><button>Ajouter la réunion au planning</button></form></details><?php endif?>
 <?php if(!$canManage):?><details class="pp-request-box"><summary><b>Demander le déplacement d’un cours</b></summary><form method="post" action="/public/professeurs-pro/planning/deplacement/demander"><?=Csrf::field()?><input type="hidden" name="professeur_id" value="<?=(int)$professor['id']?>"><label>Cours<select name="slot_id" required><option value="">Choisir le cours</option><?php foreach($slots as$s):?><option value="<?=(int)$s['id']?>"><?=$h($s['discipline_libelle'].' · '.ucfirst($s['jour_semaine']).' '.substr($s['heure_debut'],0,5).'–'.substr($s['heure_fin'],0,5))?></option><?php endforeach?></select></label><div class="pp-request-grid"><label>Nouveau jour<select name="nouveau_jour"><?php foreach($days as$key=>$label):?><option value="<?=$key?>"><?=ucfirst($key)?></option><?php endforeach?></select></label><label>Début<input type="time" name="nouvelle_heure_debut" required></label><label>Fin<input type="time" name="nouvelle_heure_fin" required></label></div><label>Motif<textarea name="motif" required></textarea></label><button>Envoyer à la Direction</button></form></details><?php endif?>
 <?php if(!empty($planning_events['requests'])):?><section class="pp-request-box"><h2>Demandes de déplacement</h2><?php foreach($planning_events['requests'] as$r):?><article><b><?=$h($r['discipline_libelle'])?></b> — <?=$h($r['statut'])?> · vers <?=ucfirst($h($r['nouveau_jour']))?> <?=substr($r['nouvelle_heure_debut'],0,5)?>–<?=substr($r['nouvelle_heure_fin'],0,5)?><p><?=$h($r['motif'])?></p><?php if($canManage&&$r['statut']==='en_attente'):?><form method="post" action="/public/professeurs-pro/planning/deplacement/decider"><?=Csrf::field()?><input type="hidden" name="professeur_id" value="<?=(int)$professor['id']?>"><input type="hidden" name="request_id" value="<?=(int)$r['id']?>"><textarea name="commentaire" placeholder="Commentaire ou motif du refus"></textarea><button name="decision" value="valider">Valider</button><button name="decision" value="refuser">Refuser</button></form><?php endif?></article><?php endforeach?></section><?php endif?>
 <section class="pp-help"><b><?=$planning_validated?'Planning validé':'Prochaine étape'?></b><span><?=$planning_validated?'Cliquez directement sur un créneau pour choisir un élève en attente. La Direction devra confirmer l’affectation.':'La Direction doit valider le planning avant toute affectation d’élève.'?></span></section>
 <?php if($canManage&&!$planning_validated):?><form method="post" action="/public/professeurs-pro/planning/valider" class="pp-validate"><?=Csrf::field()?><input type="hidden" name="professeur_id" value="<?=(int)$professor['id']?>"><button <?=$planning_block_reason?'disabled aria-disabled="true" title="'.$h($planning_block_reason).'"':''?>>Valider définitivement le planning</button></form><?php endif?>
 <?php if($canManage&&$assignment_proposals):?><section class="pp-proposals"><h2>Affectations proposées à valider</h2><?php foreach($assignment_proposals as$p):?><article><span><b><?=$h($p['eleve_nom'])?></b><small><?=$h($p['statut'])?></small></span><?php if($p['statut']==='en_attente'):?><form method="post" action="/public/professeurs-pro/planning/affectation/decider"><?=Csrf::field()?><input type="hidden" name="proposal_id" value="<?=(int)$p['id']?>"><button name="decision" value="valider">Valider</button><button name="decision" value="refuser">Refuser</button></form><?php endif?></article><?php endforeach?></section><?php endif?>
</main>
<?php if($canManage&&!$planning_validated):?><dialog id="pp-dialog"><form method="post" action="/public/professeurs-pro/planning/creneau" data-create-action="/public/professeurs-pro/planning/creneau" data-update-action="/public/professeurs-pro/planning/creneau/modifier" class="pp-form"><?=Csrf::field()?><input type="hidden" name="professeur_id" value="<?=(int)$professor['id']?>"><input type="hidden" name="slot_id" id="pp-slot-id"><header><div><span id="pp-dialog-kicker">NOUVELLE DISPONIBILITÉ</span><h2 id="pp-dialog-title">Choisir la discipline</h2></div><button type="button" id="pp-close">×</button></header><div class="pp-selection-summary"><b id="pp-selected-day">Lundi</b><strong id="pp-selected-hours">15:00–17:00</strong><span>Cliquez sur une plage pour modifier son contenu ; déplacez-la ou étirez sa poignée basse.</span></div><label class="pp-day-field">Jour<select name="jour_semaine" id="pp-day-select"><?php foreach($days as $key=>$label):?><option value="<?=$key?>"><?=ucfirst($key)?></option><?php endforeach?></select></label><label>Discipline<select name="discipline_id" id="pp-discipline" required><?php foreach($disciplines as $d):?><option value="<?=$d['id']?>" data-individual="<?=(int)$d['duree_individuelle_minutes']?>" data-collective="<?=(int)$d['duree_collective_minutes']?>"><?=$h($d['libelle'])?></option><?php endforeach?></select></label><label>Salle *<select name="salle_id" id="pp-room" required><option value="">Choisir une salle</option><?php foreach($rooms as $room):?><option value="<?=(int)$room['id']?>"><?=$h($room['libelle'].(!empty($room['code'])?' — '.$room['code']:''))?></option><?php endforeach?></select></label><label>Format<select name="type_cours" id="pp-type"><option value="individuel">Cours individuel</option><option value="collectif">Cours collectif / groupe</option></select></label><div class="pp-duration" id="pp-duration"></div><div class="pp-time-fields"><label>Heure de début<input type="time" name="heure_debut" id="pp-start" value="15:00" step="300" required></label><label>Heure de fin<input type="time" name="heure_fin" id="pp-end" value="17:00" step="300" required></label></div><label id="pp-capacity-wrap">Capacité du groupe<input type="number" id="pp-capacity" name="capacite_max" min="1" value="8"></label><div class="pp-form-row"><label>À partir du<input type="date" id="pp-date-start" name="date_debut" value="<?=date('Y-m-d')?>" required></label><label>Jusqu’au<input type="date" id="pp-date-end" name="date_fin"></label></div><div class="pp-preview" id="pp-preview"></div><button class="pp-save" id="pp-save">Créer les créneaux</button><button type="submit" formaction="/public/professeurs-pro/planning/creneau/archiver" id="pp-archive" hidden onclick="return confirm('Archiver ce créneau ?')">Archiver ce créneau</button></form></dialog><?php endif?>
<?php if($canManage&&!$planning_validated):?><dialog id="pp-remote-dialog"><form method="post" action="/public/professeurs-pro/teletravail/accorder" class="pp-form pp-remote-form"><?=Csrf::field()?><input type="hidden" name="professeur_id" value="<?=(int)$professor['id']?>"><header><div><span>NOUVELLE PLAGE</span><h2>Accorder du télétravail</h2></div><button type="button" id="pp-remote-close">×</button></header><p class="pp-remote-help">Choisissez une journée ponctuelle ou une récurrence sur une période, comme pour les cours. Le professeur devra déclarer les tâches réalisées pour chaque occurrence.</p><label>Mode<select name="mode_teletravail" id="pp-remote-mode"><option value="ponctuel">Ponctuel — une date</option><option value="annualise">Annualisé — chaque semaine sur une période</option></select></label><div id="pp-remote-once" class="pp-form-row"><label>Date du télétravail<input type="date" id="pp-remote-date" name="date_teletravail" min="<?=$h($yearStart)?>" max="<?=$h($yearEnd)?>"></label></div><div id="pp-remote-series" hidden><div class="pp-form-row"><label>Du<input type="date" name="date_debut" min="<?=$h($yearStart)?>" max="<?=$h($yearEnd)?>"></label><label>Au<input type="date" name="date_fin" min="<?=$h($yearStart)?>" max="<?=$h($yearEnd)?>"></label></div><label>Jour de la semaine<select name="jour_semaine"><?php foreach(['1'=>'Lundi','2'=>'Mardi','3'=>'Mercredi','4'=>'Jeudi','5'=>'Vendredi','6'=>'Samedi','7'=>'Dimanche'] as $n=>$label):?><option value="<?=$n?>"><?=$label?></option><?php endforeach?></select></label><label><input type="checkbox" name="exclude_holidays" value="1" checked> Exclure les vacances, jours fériés et fermetures du calendrier CDA</label></div><div class="pp-time-fields"><label>Heure de début<input type="time" id="pp-remote-start" name="heure_debut" step="300" required></label><label>Heure de fin<input type="time" id="pp-remote-end" name="heure_fin" step="300" required></label></div><label>Consignes de la direction<textarea name="consignes_direction" placeholder="Objectifs, travaux attendus ou informations utiles"></textarea></label><button class="pp-save">Accorder et ajouter au planning</button></form></dialog><script>document.addEventListener('DOMContentLoaded',()=>{const m=document.querySelector('#pp-remote-mode'),once=document.querySelector('#pp-remote-once'),series=document.querySelector('#pp-remote-series');if(!m)return;const sync=()=>{const annual=m.value==='annualise';once.hidden=annual;series.hidden=!annual;once.querySelector('input').required=!annual;series.querySelectorAll('input[type=date]').forEach(i=>i.required=annual)};m.addEventListener('change',sync);sync()});</script><?php endif?>
<dialog id="pp-assignment"><form method="post" action="/public/professeurs-pro/planning/affectation"><?=Csrf::field()?><input type="hidden" name="professeur_id" value="<?=(int)$professor['id']?>"><input type="hidden" name="slot_id"><h2>File d’attente compatible</h2><p class="pp-waiting-help">Le professeur voit uniquement cette liste pédagogique. Le dossier adhérent et les informations de facturation restent inaccessibles.</p><div class="pp-waiting-list"></div><label>Élève à proposer<select name="demande_inscription_id" required><option value="">Choisir un élève</option></select></label><p class="pp-waiting-empty" hidden>Aucun élève n’est actuellement en file d’attente pour cette discipline.</p><footer><button type="button" data-close>Annuler</button><button class="pp-assignment-submit">Envoyer à la Direction</button></footer></form></dialog>
<?php if($canManage&&!$planning_validated):?><script>window.CDA_PLANNING_YEAR={start:<?=json_encode($yearStart)?>,end:<?=json_encode($yearEnd)?>};</script><script src="/public/assets/js/cda-professor-planner-9680.js?v=9.6.80"></script><?php else:?><script>
const assignment=document.querySelector('#pp-assignment');
const waiting=<?=json_encode(array_values($waiting_students),JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES)?>;
document.querySelectorAll('.pp-slot[data-assignment="1"]').forEach(slot=>slot.addEventListener('click',()=>{
 const compatible=waiting.filter(student=>Number(student.discipline_id)===Number(slot.dataset.disciplineId));
 assignment.querySelector('[name=slot_id]').value=slot.dataset.slotId;
 const select=assignment.querySelector('[name=demande_inscription_id]');
 select.innerHTML='<option value="">Choisir un élève</option>'+compatible.map(student=>`<option value="${Number(student.id)}">${String(student.eleve_nom).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]))}</option>`).join('');
 assignment.querySelector('.pp-waiting-list').innerHTML=compatible.map(student=>`<div><b>${String(student.eleve_nom).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]))}</b><span>${student.disponibilites?String(student.disponibilites).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c])):'Disponibilités non précisées'}</span></div>`).join('');
 assignment.querySelector('.pp-waiting-empty').hidden=compatible.length>0;
 assignment.querySelector('.pp-assignment-submit').disabled=compatible.length===0;
 assignment.showModal();
}));
assignment.querySelector('[data-close]').onclick=()=>assignment.close();
</script><?php endif?>
