Import initial de Vivier depuis l'hebergement OVH

This commit is contained in:
Yann PILLA committed 2026-10-16 21:52:44 +02:00
commit 839e5e57c5
126 files changed
+22447

No files matched your search

+762
View File
@@ -0,0 +1,762 @@
<?php
/*
* Fiche d'un profil.
* Un bandeau fixe (identité, statut, repères commerciaux, choses à faire), puis quatre onglets :
* Profil : qui est le candidat (lecture)
* Suivi : entretiens, relances, commentaires (le travail de l'équipe)
* Missions : données commerciales et besoins clients
* Dossier : documents, mots-clés, photo, données personnelles, historique, gestion
* Sans JavaScript, les quatre onglets s'affichent l'un sous l'autre.
*/
$fr = static fn ($n): string => $n === null ? '' : nombre($n);
$mois = static fn (?string $d): string => $d ? (new DateTimeImmutable($d))->format('m/Y') : t('en cours');
$adresse = implode(', ', array_filter([$c['rue'], trim(($c['code_postal'] ?? '') . ' ' . ($c['ville'] ?? '')), $c['pays']]));
$taille = static fn (int $o): string => $o >= 1048576 ? number_format($o / 1048576, 1, ',', '') . ' Mo' : max(1, (int) round($o / 1024)) . ' Ko';
$categories = array_map('t', [
'langage' => 'Langage', 'framework' => 'Framework', 'base_de_donnees' => 'Base de données', 'outil' => 'Outil',
'cloud' => 'Cloud', 'methode' => 'Méthode', 'autre' => 'Autre',
]);
$archive = $c['archive_le'] !== null;
$dateHeure = static fn (string $d): string => date_fr($d, !str_ends_with($d, '00:00:00'));
$aujourdhui = date('Y-m-d');
$nonRenseigne = static fn (string $texte = 'non renseigné'): string => '<em>' . e(t($texte)) . '</em>';
// Ce qui demande une action : alimente la ligne « À faire » du bandeau et les pastilles des onglets
$relancesOuvertes = array_values(array_filter($c['relances'], static fn ($r) => $r['fait_le'] === null));
$relancesEchues = array_filter($relancesOuvertes, static fn ($r) => $r['echeance'] <= $aujourdhui);
$entretiensAVenir = array_filter($c['entretiens'], static fn ($x) => substr($x['date_entretien'], 0, 10) >= $aujourdhui);
$prochainEntretien = $entretiensAVenir ? min(array_column($entretiensAVenir, 'date_entretien')) : null;
$avisADonner = array_filter($c['entretiens'], static fn ($x) => substr($x['date_entretien'], 0, 10) < $aujourdhui && !$x['avis']);
$conservationDepassee = $c['conserver_jusqu_au'] !== null && $c['conserver_jusqu_au'] < $aujourdhui;
$aSuivre = count($relancesEchues) + count($avisADonner);
// Disponibilité : la valeur choisie dans la liste ; à défaut, le texte du CV
$disponibilite = libelle_disponibilite($c) ?: (string) $c['disponibilite'];
// Permis de travail : non requis avec une nationalité UE, EEE ou suisse ; sinon le texte saisi et la date de fin du titre
$nationalites = implode(', ', array_map(static fn ($code) => nom_pays($code), $c['nationalites_codes']));
$permisLibre = $c['hors_ue'] !== null && (int) $c['hors_ue'] === 0;
$titreExpire = !$permisLibre && $c['permis_expire_le'] !== null && $c['permis_expire_le'] < $aujourdhui;
$titreBientot = !$permisLibre && $c['permis_expire_le'] !== null && !$titreExpire && $c['permis_expire_le'] <= date('Y-m-d', strtotime('+2 months'));
// Traduction du contenu dans la langue de l'interface
$tr = $c['traduction'];
$langueNom = ['fr' => t('en français'), 'en' => t('en anglais')][langue_courante()] ?? langue_courante();
// Repli : les plus récents d'abord, le reste se déplie
$nbExperiences = 3;
$nbTechnologies = 10;
$experiencesVisibles = array_slice($c['experiences'], 0, $nbExperiences);
$experiencesAnciennes = array_slice($c['experiences'], $nbExperiences);
$technologiesVisibles = array_slice($c['technologies'], 0, $nbTechnologies);
$technologiesAutres = array_slice($c['technologies'], $nbTechnologies);
$onglets = [
'profil' => ['libelle' => t('Profil'), 'pastille' => 0, 'titre' => ''],
'suivi' => ['libelle' => t('Suivi'), 'pastille' => $aSuivre, 'titre' => t('Relances en retard et avis à donner')],
'missions' => ['libelle' => t('Missions'), 'pastille' => 0, 'titre' => ''],
'dossier' => ['libelle' => t('Dossier'), 'pastille' => $conservationDepassee ? 1 : 0, 'titre' => t('Conservation dépassée')],
];
$compteurs = ['suivi' => count($c['entretiens']) + count($c['commentaires']), 'missions' => count($c['besoins']), 'dossier' => count($c['documents'])];
/** Une expérience professionnelle. */
$experience = static function (array $x) use ($mois): void { ?>
<article class="experience">
<p class="periode"><?= e($mois($x['date_debut'])) ?> → <?= e($mois($x['date_fin'])) ?> · <?= e(t(TYPES_EXPERIENCE[$x['type']] ?? $x['type'])) ?></p>
<h3><?= e($x['poste']) ?></h3>
<p class="employeur">
<?= e(implode(' · ', array_filter([$x['employeur'], $x['client'] ? t('client : %s', $x['client']) : null, $x['lieu']]))) ?>
</p>
<?php if ($x['projet'] || $x['charge']): ?>
<p class="cadre-mission"><?= e(implode(' · ', array_filter([$x['projet'] ? t('Projet : %s', $x['projet']) : null, $x['charge'] ? t('Charge : %s', $x['charge']) : null]))) ?></p>
<?php endif; ?>
<?php if ($x['mission']): ?><p class="mission"><?= nl2br(e($x['mission'])) ?></p><?php endif; ?>
<?php if ($x['description']): ?><p><?= nl2br(e($x['description'])) ?></p><?php endif; ?>
<?php if ($x['technologies']): ?>
<p class="technos"><?php foreach (explode(', ', $x['technologies']) as $t): ?><span><?= e($t) ?></span><?php endforeach; ?></p>
<?php endif; ?>
</article>
<?php };
/** Une ligne du tableau des technologies. */
$technologie = static function (array $t) use ($categories, $fr): void { ?>
<tr><td><?= e($t['nom']) ?></td><td><?= e($categories[$t['categorie']]) ?></td><td class="nombre"><?= e($fr($t['annees'])) ?></td></tr>
<?php };
/** Champs du formulaire d'un entretien, pour l'ajout comme pour la modification. */
$champsEntretien = static function (?array $x) use ($besoinsOuverts): void {
$besoins = $besoinsOuverts;
// Un entretien garde son besoin même s'il n'est plus ouvert
if ($x && $x['besoin_id'] && !in_array((int) $x['besoin_id'], array_map('intval', array_column($besoins, 'id')), true)) {
$besoins[] = ['id' => $x['besoin_id'], 'client' => $x['besoin_client'], 'intitule' => $x['besoin_intitule']];
}
?>
<div class="champs">
<label><?= e(t('Date')) ?> <input type="date" name="date" required value="<?= e($x ? substr($x['date_entretien'], 0, 10) : '') ?>"></label>
<label><?= e(t('Heure, facultative')) ?> <input type="time" name="heure" value="<?= e($x && !str_ends_with($x['date_entretien'], '00:00:00') ? substr($x['date_entretien'], 11, 5) : '') ?>"></label>
<label><?= e(t('Type')) ?>
<select name="type">
<?php foreach (TYPES_ENTRETIEN as $code => $libelle): ?><option value="<?= e($code) ?>"<?= ($x['type'] ?? 'visio') === $code ? ' selected' : '' ?>><?= e(t($libelle)) ?></option><?php endforeach; ?>
</select>
</label>
<label><?= e(t('Mené par')) ?> <input type="text" name="interlocuteur" maxlength="150" value="<?= e($x['interlocuteur'] ?? '') ?>"></label>
<?php if ($besoins): ?>
<label class="large"><?= e(t('Besoin client concerné')) ?>
<select name="besoin_id">
<option value="0"><?= e(t('Aucun')) ?></option>
<?php foreach ($besoins as $b): ?><option value="<?= (int) $b['id'] ?>"<?= (int) ($x['besoin_id'] ?? 0) === (int) $b['id'] ? ' selected' : '' ?>><?= e($b['client'] . ' : ' . $b['intitule']) ?></option><?php endforeach; ?>
</select>
</label>
<?php endif; ?>
<label><?= e(t('Avis')) ?>
<select name="avis">
<option value=""><?= e(t('Pas encore d\'avis')) ?></option>
<?php foreach (AVIS_ENTRETIEN as $code => $libelle): ?><option value="<?= e($code) ?>"<?= ($x['avis'] ?? '') === $code ? ' selected' : '' ?>><?= e(t($libelle)) ?></option><?php endforeach; ?>
</select>
</label>
<label class="large"><?= e(t('Compte rendu')) ?>
<textarea name="compte_rendu" rows="4" maxlength="10000"><?= e($x['compte_rendu'] ?? '') ?></textarea>
</label>
</div>
<?php
};
?>
<p class="fil">
<?php if ($archive): ?>
<a href="<?= e(url('recherche', ['archives' => 'seuls'])) ?>"><?= e(t('Profils archivés')) ?></a> / <?= e(t(STATUTS[$c['statut']])) ?>
<?php else: ?>
<a href="<?= e(url('kanban')) ?>"><?= e(t('Kanban')) ?></a> / <?= e(t(STATUTS[$c['statut']])) ?>
<?php endif; ?>
</p>
<!-- Bandeau : visible quel que soit l'onglet -->
<div class="entete-profil">
<div class="identite-profil">
<?= avatar($c, 'grand') ?>
<?= echelle($c['statut'], 'grande') ?>
<div>
<h1><?= e($c['prenom'] . ' ' . $c['nom']) ?></h1>
<p class="sous-titre">
<?php if ($c['titre']): ?><span><?= e($c['titre']) ?></span><?php endif; ?>
<span class="badge badge-<?= e($c['seniorite']) ?>"><?= e(t(SENIORITES[$c['seniorite']])) ?></span>
<span><?= e(t('%s d\'expérience', annees($c['annees_experience']))) ?></span>
</p>
</div>
</div>
<div class="exports">
<?php if ($c['cv_origine']): ?>
<a class="bouton secondaire" href="<?= e(url('document', ['id' => $c['cv_origine']])) ?>"><?= e(t('CV d\'origine')) ?></a>
<?php endif; ?>
<details class="menu-deroulant">
<summary class="bouton"><?= e(t('CV IT Club')) ?></summary>
<div class="menu-deroulant-liste">
<a href="<?= e(url('cv', ['id' => $c['id']])) ?>" target="_blank" rel="noopener"><?= e(t('Nominatif')) ?></a>
<a href="<?= e(url('cv', ['id' => $c['id'], 'anonyme' => 1])) ?>" target="_blank" rel="noopener"><?= e(t('Anonymisé')) ?></a>
</div>
</details>
<details class="menu-deroulant">
<summary class="bouton secondaire"><?= e(t('CV Europass')) ?></summary>
<div class="menu-deroulant-liste">
<a href="<?= e(url('europass', ['id' => $c['id']])) ?>" target="_blank" rel="noopener"><?= e(t('Nominatif')) ?></a>
<a href="<?= e(url('europass', ['id' => $c['id'], 'anonyme' => 1])) ?>" target="_blank" rel="noopener"><?= e(t('Anonymisé')) ?></a>
</div>
</details>
<?php if (peut_ecrire()): ?>
<a class="bouton secondaire" href="<?= e(url('profil_modifier', ['id' => $c['id']])) ?>"><?= e(t('Modifier')) ?></a>
<?php endif; ?>
</div>
</div>
<?php if ($archive): ?>
<div class="flash flash-info bandeau-archive">
<p><strong><?= e(t('Profil archivé le %s.', date_fr($c['archive_le']))) ?></strong> <?= e(t('Il n\'apparaît plus dans le Kanban ni dans les chiffres. Ses données et ses documents sont conservés.')) ?></p>
<?php if (peut_ecrire()): ?>
<form method="post" action="<?= e(url('archiver')) ?>">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<button type="submit" name="action" value="desarchiver" class="secondaire"><?= e(t('Désarchiver')) ?></button>
</form>
<?php endif; ?>
</div>
<?php endif; ?>
<?php if (!empty($original) && $tr['etat'] === 'a_jour'): ?>
<p class="flash flash-info bandeau-traduction"><?= e(t('Vous lisez le texte d\'origine de ce profil.')) ?> <a href="<?= e(url('profil', ['id' => $c['id']])) ?>"><?= e(t('Voir la traduction %s', $langueNom)) ?></a></p>
<?php elseif ($tr['etat'] === 'absente' || $tr['etat'] === 'perimee'): ?>
<div class="flash flash-info bandeau-traduction">
<p><?= e($tr['etat'] === 'perimee'
? t('La fiche a changé depuis sa traduction : le texte s\'affiche dans sa langue d\'origine.')
: t('Ce profil n\'est pas encore traduit %s : le texte s\'affiche dans sa langue d\'origine.', $langueNom)) ?>
<?php if ($enFile && $enFile['essais'] < TRADUCTION_ESSAIS && Claude::configure()): ?><?= e(t('La traduction se fait en arrière-plan.')) ?><?php endif; ?></p>
<?php if (peut_ecrire() && Claude::configure()): ?>
<form method="post" action="<?= e(url('traduire_profil')) ?>" data-attente="<?= e(t('Traduction en cours…')) ?>" data-attente-bouton="<?= e(t('Traduction en cours…')) ?>">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<input type="hidden" name="langue" value="<?= e(langue_courante()) ?>">
<button type="submit" class="secondaire"><?= e(t('Traduire maintenant')) ?></button>
</form>
<?php endif; ?>
</div>
<?php elseif ($tr['etat'] === 'a_jour'): ?>
<p class="note-traduction"><?= e($tr['origine'] === 'automatique' ? t('Texte traduit automatiquement le %s.', date_fr($tr['cree_le'])) : t('Texte traduit le %s.', date_fr($tr['cree_le']))) ?>
<a href="<?= e(url('profil', ['id' => $c['id'], 'original' => 1])) ?>"><?= e(t('Voir l\'original')) ?></a></p>
<?php endif; ?>
<div class="barre-statut">
<div class="barre-statut-ligne">
<?php if (peut_ecrire() && !$archive): ?>
<form method="post" action="<?= e(url('statut')) ?>" class="statut-form">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<label><?= e(t('Statut')) ?>
<select name="statut" data-motif="champ-motif">
<?php foreach (STATUTS as $code => $libelle): ?>
<option value="<?= e($code) ?>"<?= $code === $c['statut'] ? ' selected' : '' ?>><?= e(t($libelle)) ?></option>
<?php endforeach; ?>
</select>
</label>
<label id="champ-motif"<?= $c['statut'] === 'non_retenu' ? '' : ' hidden' ?>><?= e(t('Motif du refus')) ?>
<input type="text" name="motif" maxlength="500" value="<?= e($c['motif_refus']) ?>">
</label>
<button type="submit"><?= e(t('Mettre à jour')) ?></button>
</form>
<?php else: ?>
<p class="statut-lecture"><span class="etat"><?= e(t(STATUTS[$c['statut']])) ?></span></p>
<?php endif; ?>
<dl class="reperes-profil">
<div><dt><?= e(t('Disponibilité')) ?></dt><dd><?= $disponibilite !== '' ? e($disponibilite) : $nonRenseigne('non renseignée') ?></dd></div>
<div><dt><?= e(t('TJM souhaité')) ?></dt><dd><?= e(euros($c['tjm'])) ?: $nonRenseigne() ?></dd></div>
<?php if ($c['ville'] || $c['pays']): ?>
<div><dt><?= e(t('Lieu')) ?></dt><dd><?= e($c['ville'] ?: $c['pays']) ?></dd></div>
<?php endif; ?>
</dl>
</div>
<?php // Le formulaire montre déjà le motif ; en lecture seule (profil archivé), on l'affiche ici
if ($c['statut'] === 'non_retenu' && $c['motif_refus'] && !(peut_ecrire() && !$archive)): ?>
<p class="motif-profil"><strong><?= e(t('Motif du refus')) ?></strong> : <?= e($c['motif_refus']) ?></p>
<?php endif; ?>
<?php if ($relancesEchues || $prochainEntretien || $avisADonner || $conservationDepassee || $titreExpire || $titreBientot): ?>
<ul class="a-faire" aria-label="<?= e(t('À faire')) ?>">
<?php if ($relancesEchues): ?>
<li class="urgent"><a href="#relances"><?= e(tn(count($relancesEchues), '%d relance en retard', '%d relances en retard')) ?></a></li>
<?php endif; ?>
<?php if ($avisADonner): ?>
<li class="urgent"><a href="#entretiens"><?= e(tn(count($avisADonner), '%d avis d\'entretien à donner', '%d avis d\'entretien à donner')) ?></a></li>
<?php endif; ?>
<?php if ($prochainEntretien): ?>
<li><a href="#entretiens"><?= e(t('Prochain entretien : %s', $dateHeure($prochainEntretien))) ?></a></li>
<?php endif; ?>
<?php if ($conservationDepassee): ?>
<li class="urgent"><a href="#donnees"><?= e(t('Conservation dépassée depuis le %s', date_fr($c['conserver_jusqu_au']))) ?></a></li>
<?php endif; ?>
<?php if ($titreExpire || $titreBientot): ?>
<li class="urgent"><a href="#coordonnees"><?= e($titreExpire ? t('Titre de séjour expiré le %s', date_fr($c['permis_expire_le'])) : t('Titre de séjour : expire le %s', date_fr($c['permis_expire_le']))) ?></a></li>
<?php endif; ?>
</ul>
<?php endif; ?>
</div>
<nav class="onglets" aria-label="<?= e(t('Sections de la fiche')) ?>" data-onglets>
<?php foreach ($onglets as $cle => $o): ?>
<a href="#<?= e($cle) ?>" id="tab-<?= e($cle) ?>" data-onglet="<?= e($cle) ?>">
<?= e($o['libelle']) ?>
<?php if ($o['pastille']): ?>
<span class="pastille pastille-alerte" title="<?= e($o['titre']) ?>"><?= $cle === 'dossier' ? '!' : (int) $o['pastille'] ?></span>
<?php elseif (!empty($compteurs[$cle])): ?>
<small><?= (int) $compteurs[$cle] ?></small>
<?php endif; ?>
</a>
<?php endforeach; ?>
</nav>
<!-- Onglet Profil : qui est le candidat -->
<section class="panneau" id="profil" aria-labelledby="tab-profil">
<h2 class="titre-panneau"><?= e(t('Profil')) ?></h2>
<div class="deux-colonnes">
<div>
<?php if ($c['resume']): ?>
<section class="carte">
<h2><?= e(t('Synthèse')) ?></h2>
<p><?= nl2br(e($c['resume'])) ?></p>
</section>
<?php endif; ?>
<?php if ($c['points_attention']): ?>
<section class="carte attention">
<h2><?= e(t('Points d\'attention')) ?></h2>
<ul><?php foreach ($c['points_attention'] as $p): ?><li><?= e($p) ?></li><?php endforeach; ?></ul>
</section>
<?php endif; ?>
<section class="carte" id="experiences">
<h2><?= e(t('Expériences')) ?> <small><?= count($c['experiences']) ?></small></h2>
<?php array_map($experience, $experiencesVisibles); ?>
<?php if ($experiencesAnciennes): ?>
<details class="suite">
<summary><?= e(tn(count($experiencesAnciennes), 'Voir %d expérience plus ancienne', 'Voir %d expériences plus anciennes')) ?></summary>
<?php array_map($experience, $experiencesAnciennes); ?>
</details>
<?php endif; ?>
<?php if (!$c['experiences']): ?><p class="vide"><?= e(t('Aucune expérience renseignée.')) ?></p><?php endif; ?>
</section>
<section class="carte" id="technologies">
<h2><?= e(t('Technologies')) ?> <small><?= count($c['technologies']) ?></small></h2>
<?php if ($c['technologies']): ?>
<table class="compact">
<thead><tr><th><?= e(t('Technologie')) ?></th><th><?= e(t('Catégorie')) ?></th><th class="nombre"><?= e(t('Années')) ?></th></tr></thead>
<tbody><?php array_map($technologie, $technologiesVisibles); ?></tbody>
</table>
<?php if ($technologiesAutres): ?>
<details class="suite">
<summary><?= e(tn(count($technologiesAutres), 'Voir %d autre technologie', 'Voir %d autres technologies')) ?></summary>
<table class="compact"><tbody><?php array_map($technologie, $technologiesAutres); ?></tbody></table>
</details>
<?php endif; ?>
<?php else: ?><p class="vide"><?= e(t('Aucune technologie renseignée.')) ?></p><?php endif; ?>
</section>
<?php if ($c['formations'] || $c['certifications']): ?>
<section class="carte">
<h2><?= e(t('Formation et certifications')) ?></h2>
<ul class="simple">
<?php foreach ($c['formations'] as $f): ?>
<?php $dates = trim(date_europass($f['date_debut'] ?? null) . (($f['date_debut'] ?? null) && ($f['date_fin'] ?? null) ? ' – ' : '') . date_europass($f['date_fin'] ?? null)) ?: ($f['annee_fin'] ? (string) (int) $f['annee_fin'] : ''); ?>
<li><strong><?= e($f['diplome']) ?></strong><?= $f['etablissement'] ? ', ' . e($f['etablissement']) : '' ?><?= $dates !== '' || ($f['lieu'] ?? '') ? ' <small>' . e(implode(' · ', array_filter([$dates, $f['lieu'] ?? null]))) . '</small>' : '' ?></li>
<?php endforeach; ?>
<?php foreach ($c['certifications'] as $f): ?>
<li><strong><?= e($f['nom']) ?></strong><?= $f['organisme'] ? ', ' . e($f['organisme']) : '' ?><?= $f['annee'] ? ' (' . (int) $f['annee'] . ')' : '' ?></li>
<?php endforeach; ?>
</ul>
</section>
<?php endif; ?>
</div>
<aside>
<section class="carte" id="coordonnees">
<h2><?= e(t('Coordonnées')) ?></h2>
<dl class="grille serre">
<dt><?= e(t('Email')) ?></dt><dd><?= $c['email'] ? '<a href="mailto:' . e($c['email']) . '">' . e($c['email']) . '</a>' : $nonRenseigne() ?></dd>
<dt><?= e(t('Téléphone')) ?></dt><dd><?= e($c['telephone']) ?: $nonRenseigne() ?></dd>
<dt><?= e(t('Adresse')) ?></dt><dd><?= e($adresse) ?: $nonRenseigne('non renseignée') ?></dd>
<dt><?= e(t('Nationalité')) ?></dt><dd><?= $nationalites !== '' ? e($nationalites) : $nonRenseigne('non renseignée') ?></dd>
<dt><?= e(t('Permis de travail')) ?></dt>
<dd><?php if ($permisLibre): ?><?= e(t('Non requis')) ?> <small>(<?= e(t('UE, EEE ou Suisse')) ?>)</small>
<?php elseif ($c['permis_travail'] || $c['permis_expire_le']): ?><?= e((string) $c['permis_travail']) ?><?php if ($c['permis_expire_le']): ?><br><small class="<?= $titreExpire || $titreBientot ? 'retard' : '' ?>"><?= e(t('Titre valable jusqu\'au %s', date_fr($c['permis_expire_le']))) ?></small><?php endif; ?>
<?php else: ?><?= $nonRenseigne($c['hors_ue'] === null ? 'à vérifier' : 'non renseigné') ?><?php endif; ?></dd>
</dl>
<?php if ($c['liens']): ?>
<ul class="simple">
<?php foreach ($c['liens'] as $l): ?>
<li><a href="<?= e($l['url']) ?>" target="_blank" rel="noopener noreferrer"><?= e(ucfirst($l['type'])) ?></a></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</section>
<section class="carte" id="langues">
<h2><?= e(t('Langues')) ?></h2>
<ul class="simple">
<?php foreach ($c['langues'] as $l): $grille = array_filter(array_intersect_key($l, GRILLE_CECRL)); ?>
<li><?= e(t($l['langue'])) ?><?= $l['niveau'] ? ' · ' . e(t($l['niveau'])) : '' ?>
<?php if ($grille): ?><small><?= e(implode(' · ', array_map(static fn ($k, $v) => t(GRILLE_CECRL[$k]) . ' ' . $v, array_keys($grille), $grille))) ?></small><?php endif; ?></li>
<?php endforeach; ?>
</ul>
<?php if (!$c['langues']): ?><p class="vide"><?= e(t('Aucune langue renseignée.')) ?></p><?php endif; ?>
</section>
<?php if ($c['benevolat'] || $c['permis_conduire']): ?>
<section class="carte" id="divers">
<h2><?= e(t('Bénévolat et permis')) ?></h2>
<dl class="grille serre">
<?php if ($c['benevolat']): ?><dt><?= e(t('Bénévolat')) ?></dt><dd><?= nl2br(e($c['benevolat'])) ?></dd><?php endif; ?>
<?php if ($c['permis_conduire']): ?><dt><?= e(t('Permis de conduire')) ?></dt><dd><?= e($c['permis_conduire']) ?></dd><?php endif; ?>
</dl>
</section>
<?php endif; ?>
</aside>
</div>
</section>
<!-- Onglet Suivi : le travail de l'équipe sur ce candidat -->
<section class="panneau" id="suivi" aria-labelledby="tab-suivi">
<h2 class="titre-panneau"><?= e(t('Suivi')) ?></h2>
<div class="deux-colonnes">
<div>
<section class="carte" id="entretiens">
<h2><?= e(t('Entretiens')) ?> <small><?= count($c['entretiens']) ?></small></h2>
<?php foreach ($c['entretiens'] as $x): $futur = substr($x['date_entretien'], 0, 10) >= $aujourdhui; ?>
<article class="entretien">
<p class="periode">
<?= e($dateHeure($x['date_entretien'])) ?> · <?= e(t(TYPES_ENTRETIEN[$x['type']])) ?>
<?php if ($futur): ?><span class="badge"><?= e(t('à venir')) ?></span><?php endif; ?>
<?php if ($x['avis']): ?><span class="badge badge-avis-<?= e($x['avis']) ?>"><?= e(t(AVIS_ENTRETIEN[$x['avis']])) ?></span><?php elseif (!$futur): ?><span class="badge badge-attente"><?= e(t('avis à donner')) ?></span><?php endif; ?>
</p>
<p class="employeur"><?= e(implode(' · ', array_filter([
$x['interlocuteur'] ? t('mené par %s', $x['interlocuteur']) : null,
$x['besoin_intitule'] ? $x['besoin_client'] . ' : ' . $x['besoin_intitule'] : null,
t('saisi par %s', $x['nom_affiche']),
]))) ?></p>
<?php if ($x['compte_rendu']): ?><p><?= nl2br(e($x['compte_rendu'])) ?></p><?php endif; ?>
<?php if (peut_ecrire()): ?>
<details>
<summary><?= e($x['avis'] ? t('Modifier') : t('Donner l\'avis et le compte rendu')) ?></summary>
<form method="post" action="<?= e(url('entretien')) ?>" class="pile">
<?= champ_csrf() ?>
<input type="hidden" name="entretien_id" value="<?= (int) $x['id'] ?>">
<?php $champsEntretien($x); ?>
<div class="actions">
<button type="submit" name="action" value="modifier" class="secondaire"><?= e(t('Enregistrer')) ?></button>
</div>
</form>
<form method="post" action="<?= e(url('entretien')) ?>" class="actions-ligne" data-confirmer="<?= e(t('Supprimer cet entretien ?')) ?>">
<?= champ_csrf() ?>
<input type="hidden" name="entretien_id" value="<?= (int) $x['id'] ?>">
<button type="submit" name="action" value="supprimer" class="lien"><?= e(t('Supprimer cet entretien')) ?></button>
</form>
</details>
<?php endif; ?>
</article>
<?php endforeach; ?>
<?php if (!$c['entretiens']): ?><p class="vide"><?= e(t('Aucun entretien enregistré.')) ?></p><?php endif; ?>
<?php if (peut_ecrire()): ?>
<details class="ajout">
<summary><?= e(t('Ajouter un entretien')) ?></summary>
<form method="post" action="<?= e(url('entretien')) ?>" class="pile">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<?php $champsEntretien(null); ?>
<?php if (!$archive && in_array($c['statut'], ['recu', 'en_cours'], true)): ?>
<label class="case"><input type="checkbox" name="avancer" value="1" checked> <?= e(t('Passer le profil en « Entretiens en cours »')) ?></label>
<?php endif; ?>
<div class="actions">
<button type="submit" name="action" value="ajouter"><?= e(t('Enregistrer l\'entretien')) ?></button>
</div>
</form>
</details>
<?php endif; ?>
</section>
<section class="carte" id="commentaires">
<h2><?= e(t('Commentaires')) ?> <small><?= count($c['commentaires']) ?></small></h2>
<?php if (peut_ecrire()): ?>
<form method="post" action="<?= e(url('commentaire')) ?>" class="pile">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<label><?= e(t('Nouveau commentaire')) ?>
<textarea name="texte" rows="2" required></textarea>
</label>
<div class="actions gauche"><button type="submit" class="secondaire"><?= e(t('Publier')) ?></button></div>
</form>
<?php endif; ?>
<?php foreach ($c['commentaires'] as $m): ?>
<article class="commentaire">
<p class="auteur"><?= e($m['nom_affiche']) ?> · <?= e(date_fr($m['cree_le'], true)) ?></p>
<p><?= nl2br(e($m['texte'])) ?></p>
</article>
<?php endforeach; ?>
<?php if (!$c['commentaires']): ?><p class="vide"><?= e(t('Aucun commentaire.')) ?></p><?php endif; ?>
</section>
</div>
<aside>
<section class="carte" id="relances">
<h2><?= e(t('Relances')) ?> <small><?= count($relancesOuvertes) ?></small></h2>
<ul class="simple relances">
<?php foreach ($c['relances'] as $r): $faite = $r['fait_le'] !== null; ?>
<li class="<?= $faite ? 'faite' : '' ?>">
<span class="<?= !$faite && $r['echeance'] <= $aujourdhui ? 'retard' : '' ?>"><?= e(date_fr($r['echeance'])) ?></span> · <?= e(objet_relance($r)) ?>
<small><?= e($faite ? t('faite le %s par %s', date_fr($r['fait_le']), (string) $r['fait_par_nom']) : t('créée par %s', $r['nom_affiche'])) ?></small>
<?php if (peut_ecrire()): ?>
<form method="post" action="<?= e(url('relance')) ?>" class="actions-ligne">
<?= champ_csrf() ?>
<input type="hidden" name="relance_id" value="<?= (int) $r['id'] ?>">
<?php if (!$faite): ?><button type="submit" name="action" value="faite" class="lien"><?= e(t('Marquer comme faite')) ?></button><?php endif; ?>
<button type="submit" name="action" value="supprimer" class="lien"><?= e(t('Supprimer')) ?></button>
</form>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php if (!$c['relances']): ?><p class="vide"><?= e(t('Aucune relance prévue.')) ?></p><?php endif; ?>
<?php if (peut_ecrire()): ?>
<details class="ajout">
<summary><?= e(t('Prévoir une relance')) ?></summary>
<form method="post" action="<?= e(url('relance')) ?>" class="pile">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<label><?= e(t('À faire')) ?> <input type="text" name="objet" maxlength="200" required placeholder="<?= e(t('Rappeler après sa fin de mission')) ?>"></label>
<label><?= e(t('Échéance')) ?> <input type="date" name="echeance" required value="<?= e(date('Y-m-d', strtotime('+7 days'))) ?>"></label>
<button type="submit" name="action" value="ajouter" class="secondaire"><?= e(t('Prévoir la relance')) ?></button>
</form>
</details>
<?php endif; ?>
</section>
</aside>
</div>
</section>
<!-- Onglet Missions : ce qu'IT Club peut proposer -->
<section class="panneau" id="missions" aria-labelledby="tab-missions">
<h2 class="titre-panneau"><?= e(t('Missions')) ?></h2>
<div class="deux-egales">
<section class="carte" id="besoins">
<h2><?= e(t('Besoins clients')) ?> <small><?= count($c['besoins']) ?></small></h2>
<ul class="simple">
<?php foreach ($c['besoins'] as $b): ?>
<li>
<a href="<?= e(url('besoin', ['id' => $b['id']])) ?>"><?= e($b['client'] . ' : ' . $b['intitule']) ?></a>
<small><?= e(t(ETATS_PROPOSITION[$b['etat']])) ?><?= $b['statut'] !== 'ouvert' ? ' · ' . e(t('besoin %s', mb_strtolower(t(ETATS_BESOIN[$b['statut']])))) : '' ?><?= $b['note'] ? ' · ' . e($b['note']) : '' ?></small>
</li>
<?php endforeach; ?>
</ul>
<?php if (!$c['besoins']): ?><p class="vide"><?= e(t('Ce profil n\'est proposé pour aucun besoin.')) ?></p><?php endif; ?>
<?php $libres = array_filter($besoinsOuverts, static fn ($b) => !in_array((int) $b['id'], array_map('intval', array_column($c['besoins'], 'id')), true)); ?>
<?php if (peut_ecrire() && $libres): ?>
<form method="post" action="<?= e(url('besoin')) ?>" class="pile">
<?= champ_csrf() ?>
<input type="hidden" name="candidat_id" value="<?= (int) $c['id'] ?>">
<input type="hidden" name="retour" value="profil">
<label><?= e(t('Proposer pour un besoin ouvert')) ?>
<select name="besoin_id" required>
<?php foreach ($libres as $b): ?><option value="<?= (int) $b['id'] ?>"><?= e($b['client'] . ' : ' . $b['intitule']) ?></option><?php endforeach; ?>
</select>
</label>
<div class="actions gauche"><button type="submit" name="action" value="proposer" class="secondaire"><?= e(t('Proposer')) ?></button></div>
</form>
<?php endif; ?>
</section>
<section class="carte" id="commercial">
<h2><?= e(t('Données commerciales')) ?></h2>
<dl class="grille serre">
<dt><?= e(t('Disponibilité')) ?></dt><dd><?= e(libelle_disponibilite($c)) ?: $nonRenseigne('non renseignée') ?></dd>
<?php if ($c['disponibilite']): ?><dt><?= e(t('Note')) ?></dt><dd><?= e($c['disponibilite']) ?></dd><?php endif; ?>
<dt><?= e(t('TJM souhaité')) ?></dt><dd><?= e(euros($c['tjm'])) ?: $nonRenseigne() ?></dd>
<dt><?= e(t('Salaire souhaité')) ?></dt><dd><?= $c['salaire_souhaite'] !== null ? e(t('%s brut par an', euros($c['salaire_souhaite']))) : $nonRenseigne() ?></dd>
<dt><?= e(t('Mobilité')) ?></dt><dd><?= e($c['mobilite']) ?: $nonRenseigne('non renseignée') ?></dd>
<dt><?= e(t('Télétravail')) ?></dt><dd><?= $c['teletravail'] ? e(t(TELETRAVAIL[$c['teletravail']])) : $nonRenseigne() ?></dd>
</dl>
<p class="aide"><?= e(t('Réservées à IT Club. Elles ne figurent sur aucun CV exporté.')) ?>
<?php if (peut_ecrire()): ?><a href="<?= e(url('profil_modifier', ['id' => $c['id']])) ?>"><?= e(t('Modifier')) ?></a><?php endif; ?></p>
</section>
</div>
</section>
<!-- Onglet Dossier : pièces, classement, données personnelles, traçabilité, gestion -->
<section class="panneau" id="dossier" aria-labelledby="tab-dossier">
<h2 class="titre-panneau"><?= e(t('Dossier')) ?></h2>
<div class="deux-colonnes">
<div>
<section class="carte" id="documents">
<h2><?= e(t('Documents')) ?> <small><?= count($c['documents']) ?></small></h2>
<ul class="simple">
<?php foreach ($c['documents'] as $d): ?>
<li>
<a href="<?= e(url('document', ['id' => $d['id']])) ?>"><?= e($d['nom_fichier']) ?></a>
<small><?= e(t(TYPES_DOCUMENT[$d['type']])) ?> · <?= e($taille((int) $d['taille_octets'])) ?> · <?= e($d['nom_affiche']) ?>, <?= e(date_fr($d['ajoute_le'])) ?></small>
<span class="actions-ligne">
<?php if (in_array(strtolower(pathinfo($d['nom_fichier'], PATHINFO_EXTENSION)), ['md', 'txt'], true)): ?>
<a href="<?= e(url('rapport', ['id' => $d['id']])) ?>"><?= e(t('Lire')) ?></a>
<?php endif; ?>
<?php if (peut_ecrire()): ?>
<form method="post" action="<?= e(url('document_suppr')) ?>" data-confirmer="<?= e(t('Supprimer ce document ?')) ?>">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $d['id'] ?>">
<button type="submit" class="lien"><?= e(t('Supprimer')) ?></button>
</form>
<?php endif; ?>
</span>
</li>
<?php endforeach; ?>
</ul>
<?php if (!$c['documents']): ?><p class="vide"><?= e(t('Aucun document.')) ?></p><?php endif; ?>
<?php if (peut_ecrire()): ?>
<details class="ajout">
<summary><?= e(t('Ajouter un document')) ?></summary>
<form method="post" action="<?= e(url('document_ajout')) ?>" enctype="multipart/form-data" class="pile">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<label><?= e(t('Fichier')) ?>
<input type="file" name="fichier" required>
</label>
<label><?= e(t('Type')) ?>
<select name="type">
<?php foreach (TYPES_DOCUMENT as $code => $libelle): ?>
<option value="<?= e($code) ?>"<?= $code === 'autre' ? ' selected' : '' ?>><?= e(t($libelle)) ?></option>
<?php endforeach; ?>
</select>
</label>
<div class="actions gauche"><button type="submit" class="secondaire"><?= e(t('Ajouter')) ?></button></div>
</form>
</details>
<?php endif; ?>
</section>
<section class="carte" id="mots-cles">
<h2><?= e(t('Mots-clés et classement')) ?></h2>
<?php if ($c['niveau_etudes'] || $c['encadrement'] !== null): ?>
<dl class="grille serre">
<?php if ($c['niveau_etudes']): ?><dt><?= e(t('Études')) ?></dt><dd><?= e(t(NIVEAUX_ETUDES[$c['niveau_etudes']] ?? $c['niveau_etudes'])) ?></dd><?php endif; ?>
<?php if ($c['encadrement'] !== null): ?><dt><?= e(t('Encadrement')) ?></dt><dd><?= e($c['encadrement'] ? t('Oui') : t('Non')) ?></dd><?php endif; ?>
</dl>
<?php endif; ?>
<?php foreach (TYPES_MOT as $type => $libelle): if (!$c['mots_cles'][$type]) { continue; } ?>
<p class="groupe-mots"><?= e(t($libelle)) ?></p>
<ul class="mots">
<?php foreach ($c['mots_cles'][$type] as $m): ?>
<li<?= $m['manuel'] ? ' class="manuel" title="' . e(t('Ajouté à la main')) . '"' : '' ?>>
<?= e($m['mot']) ?>
<?php if (peut_ecrire()): ?>
<form method="post" action="<?= e(url('mot_cle')) ?>">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<input type="hidden" name="mot_id" value="<?= (int) $m['id'] ?>">
<button type="submit" name="action" value="supprimer" aria-label="<?= e(t('Retirer %s', $m['mot'])) ?>">×</button>
</form>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ul>
<?php endforeach; ?>
<?php if (!array_filter($c['mots_cles'])): ?><p class="vide"><?= e(t('Aucun mot-clé. La recherche s\'appuie sur le reste de la fiche.')) ?></p><?php endif; ?>
<?php if (peut_ecrire()): ?>
<form method="post" action="<?= e(url('mot_cle')) ?>" class="ajout-mot">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<label><?= e(t('Ajouter')) ?>
<input type="text" name="mot" maxlength="80" required>
</label>
<label><?= e(t('Type')) ?>
<select name="type">
<?php foreach (TYPES_MOT as $type => $libelle): ?>
<option value="<?= e($type) ?>"<?= $type === 'mot_cle' ? ' selected' : '' ?>><?= e(t($libelle)) ?></option>
<?php endforeach; ?>
</select>
</label>
<button type="submit" name="action" value="ajouter" class="secondaire"><?= e(t('Ajouter')) ?></button>
</form>
<?php endif; ?>
</section>
<section class="carte" id="historique">
<h2><?= e(t('Historique')) ?> <small><?= count($c['historique']) ?></small></h2>
<?php
$ligneHistorique = static function (array $h): void { ?>
<li>
<span><?= e(date_fr($h['cree_le'], true)) ?> · <?= e($h['nom_affiche']) ?></span>
<?= e(t(ACTIONS_JOURNAL[$h['action']] ?? $h['action'])) ?><?php $detail = detail_journal($h); ?><?= $detail !== '' ? ' : ' . e($detail) : '' ?>
</li>
<?php };
// Les dix dernières actions suffisent le plus souvent : le reste se déplie
$recentes = array_slice($c['historique'], 0, 10);
$anciennes = array_slice($c['historique'], 10);
?>
<ul class="historique"><?php array_map($ligneHistorique, $recentes); ?></ul>
<?php if ($anciennes): ?>
<details class="suite-historique">
<summary><?= e(tn(count($anciennes), '%d action plus ancienne', '%d actions plus anciennes')) ?></summary>
<ul class="historique"><?php array_map($ligneHistorique, $anciennes); ?></ul>
</details>
<?php endif; ?>
</section>
</div>
<aside>
<section class="carte<?= $conservationDepassee ? ' attention' : '' ?>" id="donnees">
<h2><?= e(t('Données personnelles')) ?></h2>
<dl class="grille serre">
<dt><?= e(t('Conservation')) ?></dt><dd class="<?= $conservationDepassee ? 'retard' : '' ?>"><?= e(t('jusqu\'au %s', date_fr($c['conserver_jusqu_au']))) ?></dd>
<dt><?= e(t('Accord')) ?></dt>
<dd><?= $c['consentement_le']
? e(t('donné le %s', date_fr($c['consentement_le']))) . ($c['consentement_note'] ? '<br><small>' . e($c['consentement_note']) . '</small>' : '')
: $nonRenseigne('non enregistré') ?></dd>
</dl>
<?php if (peut_ecrire()): ?>
<details>
<summary><?= e($c['consentement_le'] ? t('Modifier l\'accord') : t('Enregistrer l\'accord du candidat')) ?></summary>
<p class="aide"><?= e(t('Notez la date à laquelle le candidat a accepté que IT Club conserve son CV, et la façon dont il l\'a dit.')) ?></p>
<form method="post" action="<?= e(url('consentement')) ?>" class="pile">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<label><?= e(t('Date de l\'accord')) ?> <input type="date" name="date" required max="<?= e($aujourdhui) ?>" value="<?= e($c['consentement_le'] ?? $aujourdhui) ?>"></label>
<label><?= e(t('Recueilli comment')) ?> <input type="text" name="note" maxlength="200" value="<?= e($c['consentement_note'] ?? '') ?>" placeholder="<?= e(t('Email du candidat, formulaire, entretien')) ?>"></label>
<div class="actions">
<?php if ($c['consentement_le']): ?><button type="submit" name="action" value="retirer" class="secondaire" formnovalidate><?= e(t('Retirer l\'accord')) ?></button><?php endif; ?>
<button type="submit" name="action" value="enregistrer" class="secondaire"><?= e(t('Enregistrer')) ?></button>
</div>
</form>
</details>
<form method="post" action="<?= e(url('profil_export')) ?>">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<button type="submit" class="secondaire"><?= e(t('Exporter les données du candidat')) ?></button>
</form>
<p class="aide"><?= e(t('Un fichier zip avec tout ce que Vivier détient sur cette personne. À lui remettre s\'il demande l\'accès à ses données.')) ?></p>
<?php endif; ?>
</section>
<section class="carte" id="photo">
<h2><?= e(t('Photo')) ?></h2>
<p class="aide"><?= e(t('Sert à reconnaître le candidat dans Vivier. Elle ne figure pas sur les CV exportés.')) ?></p>
<?php if (peut_ecrire()): ?>
<details>
<summary><?= e($c['photo'] ? t('Remplacer la photo') : t('Ajouter une photo')) ?></summary>
<form method="post" action="<?= e(url('photo_maj')) ?>" enctype="multipart/form-data" class="pile">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<label><?= e(t('Fichier')) ?>
<input type="file" name="photo" accept=".jpg,.jpeg,.png,.webp,.gif,image/*" required>
</label>
<div class="actions gauche"><button type="submit" name="action" value="charger" class="secondaire"><?= e(t('Enregistrer la photo')) ?></button></div>
</form>
</details>
<?php if ($c['photo']): ?>
<form method="post" action="<?= e(url('photo_maj')) ?>" class="actions-ligne" data-confirmer="<?= e(t('Retirer la photo de ce profil ?')) ?>">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<button type="submit" name="action" value="retirer" class="lien"><?= e(t('Retirer la photo')) ?></button>
</form>
<?php endif; ?>
<?php endif; ?>
</section>
<?php if (peut_ecrire()): ?>
<section class="carte" id="gestion">
<h2><?= e(t('Gestion')) ?></h2>
<details>
<summary><?= e(t('Mettre à jour depuis une nouvelle analyse')) ?></summary>
<p class="aide"><?= e(t('Remplace les expériences, technologies, langues et mots-clés. Garde le statut, les commentaires, les documents et les mots ajoutés à la main.')) ?></p>
<form method="post" action="<?= e(url('profil_maj')) ?>" enctype="multipart/form-data" class="pile">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<label><?= e(t('Profil structuré (.json)')) ?> <input type="file" name="profil" accept=".json,application/json" required></label>
<label><?= e(t('Nouveau CV, facultatif')) ?> <input type="file" name="cv" accept=".pdf,.docx,.doc,.odt,.rtf,.md,.txt"></label>
<label><?= e(t('Nouveau rapport, facultatif')) ?> <input type="file" name="rapport" accept=".md,.txt,.pdf,.docx"></label>
<button type="submit" class="secondaire"><?= e(t('Mettre à jour')) ?></button>
</form>
</details>
<?php if (!$archive): ?>
<form method="post" action="<?= e(url('archiver')) ?>" class="danger">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<button type="submit" name="action" value="archiver" class="secondaire"><?= e(t('Archiver le profil')) ?></button>
<p class="aide"><?= e(t('Le profil sort du Kanban et des chiffres. Il reste consultable dans Profils, filtre « Archivés ».')) ?></p>
</form>
<?php endif; ?>
<?php if (est_admin()): ?>
<form method="post" action="<?= e(url('profil_suppr')) ?>" class="danger"
data-confirmer="<?= e(t('Supprimer ce profil ? Il part à la corbeille, puis il est effacé avec ses documents au bout de %d jours.', CORBEILLE_JOURS)) ?>">
<?= champ_csrf() ?>
<input type="hidden" name="id" value="<?= (int) $c['id'] ?>">
<button type="submit" class="dangereux"><?= e(t('Supprimer le profil')) ?></button>
<p class="aide"><?= e(t('Le profil part à la corbeille. Vous pouvez le restaurer pendant %d jours.', CORBEILLE_JOURS)) ?></p>
</form>
<?php else: ?>
<p class="aide danger"><?= e(t('Seul le gestionnaire des comptes peut supprimer un profil.')) ?></p>
<?php endif; ?>
</section>
<?php endif; ?>
</aside>
</div>
</section>