Crvi/templates/modules/permanences-admin.php
2026-01-20 07:54:37 +01:00

517 lines
27 KiB
PHP

<?php
/**
* Template Admin - Gestion des Permanences
* Permet à l'admin de créer des permanences pour n'importe quel intervenant
*/
if (!defined('ABSPATH')) {
exit;
}
// Récupérer la liste des intervenants
$intervenants = \ESI_CRVI_AGENDA\models\CRVI_Intervenant_Model::get_intervenants([], true);
// Récupérer toutes les langues disponibles depuis la taxonomie
$langues_terms = get_terms([
'taxonomy' => 'langue',
'hide_empty' => false,
'orderby' => 'name',
'order' => 'ASC',
]);
$langues = [];
if (!is_wp_error($langues_terms) && !empty($langues_terms)) {
foreach ($langues_terms as $term) {
$langues[] = [
'id' => $term->slug,
'nom' => $term->name,
];
}
}
?>
<div class="crvi-admin-permanences" id="admin-permanences-container">
<div class="container-fluid py-4">
<!-- En-tête -->
<div class="row mb-4">
<div class="col-12">
<p class="text-muted">
Créez des permanences pour un intervenant en sélectionnant la période, les jours et la plage horaire, ou importez-les via CSV.
</p>
</div>
</div>
<div class="row">
<div class="col-12">
<!-- Navigation par onglets -->
<ul class="nav nav-tabs mb-4" id="permanences-tabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="creation-manuelle-tab" data-bs-toggle="tab" data-bs-target="#creation-manuelle" type="button" role="tab" aria-controls="creation-manuelle" aria-selected="true">
<i class="fas fa-plus-circle me-2"></i>Création manuelle
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="import-csv-tab" data-bs-toggle="tab" data-bs-target="#import-csv" type="button" role="tab" aria-controls="import-csv" aria-selected="false">
<i class="fas fa-file-csv me-2"></i>Import CSV
</button>
</li>
</ul>
<!-- Contenu des onglets -->
<div class="tab-content" id="permanences-tab-content">
<!-- Onglet 1 : Création manuelle -->
<div class="tab-pane fade show active" id="creation-manuelle" role="tabpanel" aria-labelledby="creation-manuelle-tab">
<form id="admin-permanences-form">
<!-- Sélection de l'intervenant -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-primary text-white">
<h3 class="h5 mb-0">
<i class="fas fa-user me-2"></i>Intervenant
</h3>
</div>
<div class="card-body">
<div class="mb-3">
<label for="intervenant-select" class="form-label fw-bold">Sélectionner un intervenant :</label>
<select class="form-select form-select-lg" id="intervenant-select" name="intervenant_id" required>
<option value="">-- Sélectionner un intervenant --</option>
<?php foreach ($intervenants as $intervenant): ?>
<?php
$days_attr = '';
$times_attr = '';
if (function_exists('get_field')) {
$jours = get_field('jours_de_disponibilite', 'user_' . $intervenant['id']);
$heures = get_field('heures_de_permanences', 'user_' . $intervenant['id']);
if (is_array($jours) && !empty($jours)) {
$days_attr = implode(',', array_map('strval', $jours));
}
if (is_array($heures) && !empty($heures)) {
$times_attr = implode(',', array_map('strval', $heures));
}
}
?>
<option value="<?php echo esc_attr($intervenant['id']); ?>" <?php echo $days_attr !== '' ? 'data-days="' . esc_attr($days_attr) . '"' : ''; ?> <?php echo $times_attr !== '' ? 'data-time-slots="' . esc_attr($times_attr) . '"' : ''; ?>>
<?php echo esc_html($intervenant['nom'] . ' ' . $intervenant['prenom']); ?>
</option>
<?php endforeach; ?>
</select>
</div>
</div>
</div>
<!-- Section 1 : Sélection des permanences -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-primary text-white">
<h3 class="h5 mb-0">
<i class="fas fa-calendar-check me-2"></i>SECTION 1 : Sélection des permanences
</h3>
</div>
<div class="card-body">
<!-- Mois de début -->
<div class="mb-4">
<label for="mois-debut" class="form-label fw-bold">Mois de début :</label>
<input type="month" class="form-control form-control-lg" id="mois-debut" name="mois_debut" required>
<small class="form-text text-muted">
Sélectionnez le mois et l'année à partir desquels les permanences seront créées.
</small>
</div>
<!-- Période -->
<div class="mb-4">
<label class="form-label fw-bold">Période :</label>
<div class="btn-group" role="group" aria-label="Période">
<input type="radio" class="btn-check" name="periode" id="periode-3" value="3" checked>
<label class="btn btn-outline-primary" for="periode-3">3 mois</label>
<input type="radio" class="btn-check" name="periode" id="periode-6" value="6">
<label class="btn btn-outline-primary" for="periode-6">6 mois</label>
</div>
</div>
<!-- Jours de la semaine -->
<div class="mb-4">
<label class="form-label fw-bold">Jours de la semaine :</label>
<div class="row g-2">
<div class="col-md-3 col-sm-4 col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="jours[]" value="lundi" id="jour-lundi">
<label class="form-check-label" for="jour-lundi">Lundi</label>
</div>
</div>
<div class="col-md-3 col-sm-4 col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="jours[]" value="mardi" id="jour-mardi">
<label class="form-check-label" for="jour-mardi">Mardi</label>
</div>
</div>
<div class="col-md-3 col-sm-4 col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="jours[]" value="mercredi" id="jour-mercredi">
<label class="form-check-label" for="jour-mercredi">Mercredi</label>
</div>
</div>
<div class="col-md-3 col-sm-4 col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="jours[]" value="jeudi" id="jour-jeudi">
<label class="form-check-label" for="jour-jeudi">Jeudi</label>
</div>
</div>
<div class="col-md-3 col-sm-4 col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="jours[]" value="vendredi" id="jour-vendredi">
<label class="form-check-label" for="jour-vendredi">Vendredi</label>
</div>
</div>
<div class="col-md-3 col-sm-4 col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="jours[]" value="samedi" id="jour-samedi">
<label class="form-check-label" for="jour-samedi">Samedi</label>
</div>
</div>
<div class="col-md-3 col-sm-4 col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="jours[]" value="dimanche" id="jour-dimanche">
<label class="form-check-label" for="jour-dimanche">Dimanche</label>
</div>
</div>
</div>
</div>
<!-- Durée de permanence -->
<div class="mb-4">
<label class="form-label fw-bold">Durée de permanence :</label>
<div class="btn-group mb-3" role="group" aria-label="Durée">
<input type="radio" class="btn-check" name="duree_permanence" id="duree-1h"
value="1h" checked>
<label class="btn btn-outline-primary" for="duree-1h">1 heure</label>
<input type="radio" class="btn-check" name="duree_permanence" id="duree-15min"
value="15min">
<label class="btn btn-outline-primary" for="duree-15min">1/4 d'heure (15 min)</label>
</div>
<small class="form-text text-muted d-block mb-3">
Choisissez la durée de chaque permanence.
</small>
</div>
<!-- Nombre de tranches (si 1/4 d'heure) -->
<div class="mb-4" id="nb-tranches-container" style="display: none;">
<label for="nb-tranches" class="form-label fw-bold">Nombre de tranches par heure :</label>
<select class="form-select form-select-lg" id="nb-tranches" name="nb_tranches">
<option value="1">1 tranche (ex: 11h00 → 11h15)</option>
<option value="2">2 tranches (ex: 11h00 → 11h15, 11h15 → 11h30)</option>
<option value="3">3 tranches (ex: 11h00 → 11h15, 11h15 → 11h30, 11h30 → 11h45)</option>
<option value="4">4 tranches (ex: 11h00 → 11h15, 11h15 → 11h30, 11h30 → 11h45, 11h45 → 12h00)</option>
</select>
<small class="form-text text-muted">
Si vous choisissez 1/4 d'heure, indiquez combien de tranches de 15 minutes créer pour chaque heure sélectionnée.
</small>
</div>
<!-- Heures de permanence -->
<div class="mb-4">
<label class="form-label fw-bold">Heures de permanence :</label>
<small class="form-text text-muted d-block mb-3" id="heures-description">
Sélectionnez les heures de début. Chaque heure sélectionnée créera une tranche d'1 heure (ex: 09:00 → 10:00).
</small>
<div class="row g-2">
<div class="col-12">
<label class="form-label fw-semibold text-muted">Matin :</label>
</div>
<?php
// Plage matin : 09:00 à 12:00
for ($h = 9; $h <= 12; $h++):
$heure = str_pad($h, 2, '0', STR_PAD_LEFT) . ':00';
$heureFin = str_pad($h + 1, 2, '0', STR_PAD_LEFT) . ':00';
?>
<div class="col-md-3 col-sm-4 col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="heures[]" value="<?php echo esc_attr($heure); ?>" id="heure-<?php echo $h; ?>">
<label class="form-check-label" for="heure-<?php echo $h; ?>">
<?php echo $heure; ?> → <?php echo $heureFin; ?>
</label>
</div>
</div>
<?php endfor; ?>
<div class="col-12 mt-2">
<label class="form-label fw-semibold text-muted">Après-midi :</label>
</div>
<?php
// Plage après-midi : 13:00 à 16:00
for ($h = 13; $h <= 16; $h++):
$heure = str_pad($h, 2, '0', STR_PAD_LEFT) . ':00';
$heureFin = str_pad($h + 1, 2, '0', STR_PAD_LEFT) . ':00';
?>
<div class="col-md-3 col-sm-4 col-6">
<div class="form-check">
<input class="form-check-input" type="checkbox" name="heures[]" value="<?php echo esc_attr($heure); ?>" id="heure-<?php echo $h; ?>">
<label class="form-check-label" for="heure-<?php echo $h; ?>">
<?php echo $heure; ?> → <?php echo $heureFin; ?>
</label>
</div>
</div>
<?php endfor; ?>
</div>
</div>
<!-- Aperçu des tranches générées -->
<div class="mb-3">
<label class="form-label fw-bold">Aperçu des tranches générées :</label>
<div id="tranches-preview" class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
Veuillez sélectionner une plage horaire pour voir l'aperçu.
</div>
</div>
<!-- Estimation -->
<div class="mb-3">
<div id="estimation-container" class="alert alert-warning" style="display: none;">
<i class="fas fa-calculator me-2"></i>
<strong>Estimation :</strong> <span id="estimation-count">0</span> événements seront créés
</div>
</div>
</div>
</div>
<!-- Section 2 : Langues -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-info text-white">
<h3 class="h5 mb-0">
<i class="fas fa-language me-2"></i>SECTION 2 : Langues des permanences
</h3>
</div>
<div class="card-body">
<div class="mb-3">
<label for="langues-permanences" class="form-label fw-bold">Langues disponibles (optionnel) :</label>
<select class="form-select form-select-lg" id="langues-permanences" name="langues[]" multiple>
<?php if (!empty($langues)): ?>
<?php foreach ($langues as $langue): ?>
<option value="<?php echo esc_attr($langue['id']); ?>">
<?php echo esc_html($langue['nom']); ?>
</option>
<?php endforeach; ?>
<?php else: ?>
<option value="">Aucune langue disponible</option>
<?php endif; ?>
</select>
<small class="form-text text-muted">
Sélectionnez une ou plusieurs langues pour ces permanences.
</small>
</div>
</div>
</div>
<!-- Section 3 : Informations complémentaires -->
<div class="card shadow-sm mb-4">
<div class="card-header bg-secondary text-white">
<h3 class="h5 mb-0">
<i class="fas fa-sticky-note me-2"></i>SECTION 3 : Informations complémentaires
</h3>
</div>
<div class="card-body">
<div class="mb-3">
<label for="informations-complementaires" class="form-label">Notes ou commentaires (optionnel)</label>
<textarea class="form-control" id="informations-complementaires" name="informations_complementaires" rows="3" placeholder="Ajoutez des notes ou commentaires sur ces permanences..."></textarea>
<small class="form-text text-muted">
Ces informations seront associées aux permanences créées.
</small>
</div>
</div>
</div>
<!-- Bouton de soumission -->
<div class="card shadow-sm">
<div class="card-body text-center">
<button type="submit" class="btn btn-primary btn-lg" id="submit-permanences-btn">
<i class="fas fa-save me-2"></i>Enregistrer les permanences
</button>
<button type="reset" class="btn btn-outline-secondary btn-lg ms-2" id="reset-permanences-btn">
<i class="fas fa-redo me-2"></i>Réinitialiser
</button>
</div>
</div>
</form>
</div>
<!-- Onglet 2 : Import CSV -->
<div class="tab-pane fade" id="import-csv" role="tabpanel" aria-labelledby="import-csv-tab">
<div class="card shadow-sm">
<div class="card-header bg-info text-white">
<h3 class="h5 mb-0">
<i class="fas fa-file-csv me-2"></i>Import de permanences via CSV
</h3>
</div>
<div class="card-body">
<div class="alert alert-info mb-4">
<i class="fas fa-info-circle me-2"></i>
<strong>Format CSV attendu :</strong> Le fichier CSV doit contenir les colonnes suivantes :
<ul class="mt-2 mb-0">
<li><code>intervenant_id</code> : ID de l'intervenant</li>
<li><code>date_debut</code> : Date de début (format YYYY-MM-DD)</li>
<li><code>date_fin</code> : Date de fin (format YYYY-MM-DD)</li>
<li><code>heure_debut</code> : Heure de début (format HH:MM)</li>
<li><code>heure_fin</code> : Heure de fin (format HH:MM)</li>
<li><code>informations_complementaires</code> : Notes (optionnel)</li>
</ul>
</div>
<form id="import-csv-form" enctype="multipart/form-data">
<div class="mb-3">
<label for="csv-file" class="form-label fw-bold">Sélectionner un fichier CSV :</label>
<input type="file" class="form-control form-control-lg" id="csv-file" name="csv_file" accept=".csv" required>
<small class="form-text text-muted">
Format accepté : CSV (séparateur virgule)
</small>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-info btn-lg" id="submit-csv-import-btn">
<i class="fas fa-upload me-2"></i>Importer le CSV
</button>
<button type="reset" class="btn btn-outline-secondary btn-lg" id="reset-csv-import-btn">
<i class="fas fa-redo me-2"></i>Réinitialiser
</button>
</div>
</form>
<div id="csv-import-result" class="mt-4" style="display: none;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<style>
.crvi-admin-permanences {
min-height: 60vh;
}
/* Augmentation de la largeur de la page */
.crvi-admin-permanences .container-fluid {
max-width: 100%;
padding-left: 20px;
padding-right: 20px;
}
.btn-group .btn-check:checked + .btn {
background-color: #0d6efd;
border-color: #0d6efd;
color: white;
}
.form-check-input:checked {
background-color: #0d6efd;
border-color: #0d6efd;
}
#tranches-preview {
min-height: 60px;
}
#tranches-preview ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
#tranches-preview li {
background-color: #e7f3ff;
padding: 0.5rem 1rem;
border-radius: 4px;
border: 1px solid #b3d9ff;
}
.alert {
border-left: 4px solid;
}
.alert-info {
border-left-color: #0dcaf0;
}
.alert-warning {
border-left-color: #ffc107;
}
/* Styles pour les onglets */
.nav-tabs {
border-bottom: 2px solid #dee2e6;
}
.nav-tabs .nav-link {
color: #495057;
border: none;
border-bottom: 3px solid transparent;
padding: 0.75rem 1.5rem;
transition: all 0.3s ease;
}
.nav-tabs .nav-link:hover {
border-color: #dee2e6;
background-color: #f8f9fa;
}
.nav-tabs .nav-link.active {
color: #0d6efd;
background-color: transparent;
border-color: #0d6efd;
font-weight: 600;
}
.tab-content {
padding-top: 1.5rem;
}
/* Amélioration de l'affichage des résultats d'import */
#csv-import-result {
margin-top: 1.5rem;
}
#csv-import-result .alert {
border-radius: 0.375rem;
}
</style>
<script>
// Gérer l'affichage conditionnel du champ nombre de tranches
document.addEventListener('DOMContentLoaded', function() {
const duree1h = document.getElementById('duree-1h');
const duree15min = document.getElementById('duree-15min');
const nbTranchesContainer = document.getElementById('nb-tranches-container');
const heuresDescription = document.getElementById('heures-description');
function updateDescription() {
if (duree15min && duree15min.checked) {
const nbTranches = document.getElementById('nb-tranches')?.value || '1';
heuresDescription.textContent = `Sélectionnez les heures de début. Pour chaque heure sélectionnée, ${nbTranches} tranche(s) de 15 minutes seront créées (ex: 11h00 → 11h15).`;
} else {
heuresDescription.textContent = `Sélectionnez les heures de début. Chaque heure sélectionnée créera une tranche d'1 heure (ex: 09:00 → 10:00).`;
}
}
if (duree1h && duree15min && nbTranchesContainer) {
duree1h.addEventListener('change', function() {
nbTranchesContainer.style.display = 'none';
updateDescription();
});
duree15min.addEventListener('change', function() {
nbTranchesContainer.style.display = 'block';
updateDescription();
});
const nbTranches = document.getElementById('nb-tranches');
if (nbTranches) {
nbTranches.addEventListener('change', updateDescription);
}
}
});
</script>