Refactor controllers and views for improved functionality and styling
This commit is contained in:
parent
dc7d96d826
commit
3aad6d41af
7 changed files with 238 additions and 125 deletions
|
|
@ -1,64 +1,92 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
function planning_afficher_ctrl() {
|
function planning_afficher_ctrl() {
|
||||||
|
require('models/connection.php');
|
||||||
|
require('models/lecture_page_model.php');
|
||||||
|
|
||||||
require_once 'models/connection.php';
|
$c = connection();
|
||||||
require_once 'models/lecture_page_model.php';
|
|
||||||
|
|
||||||
$co = connection();
|
|
||||||
|
|
||||||
|
// Date : aujourd'hui par défaut, modifiable via ?date=YYYY-MM-DD
|
||||||
$date = $_GET['date'] ?? date('Y-m-d');
|
$date = $_GET['date'] ?? date('Y-m-d');
|
||||||
|
$date_precedente = date('Y-m-d', strtotime($date . ' -1 day'));
|
||||||
|
$date_suivante = date('Y-m-d', strtotime($date . ' +1 day'));
|
||||||
|
|
||||||
$sauveteurs = get_all_sauveteurs($co);
|
// Tous les sauveteurs et leurs missions du jour
|
||||||
$missions = get_missions_by_date($co, $date);
|
$sauveteurs = get_all_sauveteurs($c);
|
||||||
|
$missions = get_missions_by_date($c, $date);
|
||||||
|
|
||||||
// Couleurs
|
// Couleurs par spécialité (numéro → couleur)
|
||||||
$couleurs = [
|
$couleurs = [
|
||||||
'Sauveteur disponible' => '#2ecc71',
|
1 => '#e74c3c', // Évacuation
|
||||||
'Sauveteur en approche de la cavité' => '#9b59b6',
|
2 => '#3498db', // ASV
|
||||||
'Sauveteur sous terre' => '#8B4513',
|
3 => '#f39c12', // Transmission
|
||||||
'Sauveteur équipe de gestion' => '#f1c40f',
|
4 => '#9b59b6', // Conseiller technique
|
||||||
"Sauveteur en mission à l'extérieur" => '#e67e22',
|
5 => '#2ecc71', // Gestion
|
||||||
'Sauveteur en repos' => '#3498db',
|
6 => '#8B4513', // Désobstruction
|
||||||
'Sauveteur en brancardage civière' => '#e74c3c',
|
7 => '#e91e63', // Médical
|
||||||
|
8 => '#00bcd4', // Ventilation
|
||||||
|
9 => '#95a5a6', // Pas de spécialité
|
||||||
];
|
];
|
||||||
|
|
||||||
// Créneaux 8h - 20h (30 min)
|
// Créneaux 8h-20h (toutes les 30 min)
|
||||||
$creneaux = [];
|
$creneaux = [];
|
||||||
for ($min = 8 * 60; $min < 20 * 60; $min += 30) {
|
for ($min = 8 * 60; $min < 20 * 60; $min += 30) {
|
||||||
$creneaux[] = sprintf('%02d:%02d', intdiv($min, 60), $min % 60);
|
$creneaux[] = sprintf('%02d:%02d', intdiv($min, 60), $min % 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Index sauveteurs + grille vide
|
// Index des sauveteurs + couleur par spécialité
|
||||||
$sauveteursById = [];
|
$sauveteurs_index = [];
|
||||||
$grille = [];
|
|
||||||
|
|
||||||
foreach ($sauveteurs as $s) {
|
foreach ($sauveteurs as $s) {
|
||||||
$sauveteursById[$s['ID']] = $s;
|
$spe_num = (int) ($s['specialite'] ?? 0);
|
||||||
$grille[$s['ID']] = array_fill_keys($creneaux, '');
|
$s['couleur'] = $couleurs[$spe_num] ?? '#cccccc';
|
||||||
|
$sauveteurs_index[$s['ID']] = $s;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remplissage des missions
|
// Grille : sauveteur_id → créneau → [couleur, en_prepa]
|
||||||
|
$grille = [];
|
||||||
|
foreach ($sauveteurs as $s) {
|
||||||
|
$grille[$s['ID']] = [];
|
||||||
|
foreach ($creneaux as $c) {
|
||||||
|
$grille[$s['ID']][$c] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remplissage de la grille avec les missions
|
||||||
foreach ($missions as $m) {
|
foreach ($missions as $m) {
|
||||||
|
$id_sauv = $m['ID_Sauveteur'];
|
||||||
$id = $m['ID'];
|
if (!isset($grille[$id_sauv])) continue;
|
||||||
|
|
||||||
if (!isset($grille[$id])) continue;
|
|
||||||
|
|
||||||
$specialite = $sauveteursById[$id]['Specialite'] ?? '';
|
|
||||||
$couleur = $couleurs[$specialite] ?? '#cccccc';
|
|
||||||
|
|
||||||
$debut = new DateTime($m['DateHeureDebut']);
|
$debut = new DateTime($m['DateHeureDebut']);
|
||||||
$fin = new DateTime($m['DateHeureFin']);
|
$fin = new DateTime($m['DateHeureFin']);
|
||||||
|
$en_prepa = (bool) $m['EnPrepa'];
|
||||||
|
|
||||||
foreach ($creneaux as $c) {
|
foreach ($creneaux as $c) {
|
||||||
|
$debut_creneau = new DateTime($date . ' ' . $c . ':00');
|
||||||
|
$fin_creneau = (clone $debut_creneau)->modify('+30 minutes');
|
||||||
|
|
||||||
$start = new DateTime($date . ' ' . $c . ':00');
|
if ($debut < $fin_creneau && $fin > $debut_creneau) {
|
||||||
$end = (clone $start)->modify('+30 minutes');
|
$grille[$id_sauv][$c] = [
|
||||||
|
'couleur' => $sauveteurs_index[$id_sauv]['couleur'],
|
||||||
|
'en_prepa' => $en_prepa,
|
||||||
|
'mission_id' => $m['ID'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($debut < $end && $fin > $start) {
|
// Légende des spécialités
|
||||||
$grille[$id][$c] = $couleur;
|
$legendes = [
|
||||||
}
|
1 => 'Évacuation',
|
||||||
}
|
2 => 'ASV',
|
||||||
}
|
3 => 'Transmission',
|
||||||
|
4 => 'Conseiller technique',
|
||||||
|
5 => 'Gestion',
|
||||||
|
6 => 'Désobstruction',
|
||||||
|
7 => 'Médical',
|
||||||
|
8 => 'Ventilation',
|
||||||
|
9 => 'Pas de spécialité',
|
||||||
|
];
|
||||||
|
|
||||||
|
require('views/lecture_page.php');
|
||||||
|
planning_view($sauveteurs, $sauveteurs_index, $creneaux, $grille, $date, $date_precedente, $date_suivante, $couleurs, $legendes);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,37 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
|
|
||||||
require_once('models/connection.php');
|
|
||||||
require_once('models/operation_crud.php');
|
|
||||||
|
|
||||||
function operations_form_ctrl() {
|
function operations_form_ctrl() {
|
||||||
// Appelle TA vue exacte
|
|
||||||
require('views/operations_view.php');
|
require('views/operations_view.php');
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_operation_write_ctrl() {
|
function add_operation_write_ctrl() {
|
||||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
header('Location: index.php?route=operations');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
// 1. On récupère les 3 champs de ton formulaire
|
|
||||||
$date_debut = $_POST['date_debut'];
|
$date_debut = $_POST['date_debut'];
|
||||||
$date_fin = $_POST['date_fin'];
|
$date_fin = $_POST['date_fin'];
|
||||||
$lieu = $_POST['lieu'];
|
$lieu = $_POST['lieu'];
|
||||||
|
|
||||||
// 2. On force les champs obligatoires de la BDD en arrière-plan
|
// Valeurs par défaut pour les clés étrangères (à adapter quand l'auth sera active)
|
||||||
$en_prepa = 0;
|
$en_prepa = 0;
|
||||||
$id_sauveteur = 1; // Par défaut
|
$id_sauveteur = 1;
|
||||||
$id_statut = 1; // Par défaut
|
$id_statut = 1;
|
||||||
$id_utilisateur = 1; // Par défaut
|
$id_utilisateur = 1;
|
||||||
|
|
||||||
$connex = connection();
|
require('models/connection.php');
|
||||||
|
$c = connection();
|
||||||
|
require('models/operation_crud.php');
|
||||||
|
|
||||||
// On envoie tout au modèle
|
$resultat = create_operation_crud($c, $date_debut, $date_fin, $lieu, $en_prepa, $id_sauveteur, $id_statut, $id_utilisateur);
|
||||||
$resultat = create_operation_crud($connex, $date_debut, $date_fin, $lieu, $en_prepa, $id_sauveteur, $id_statut, $id_utilisateur);
|
|
||||||
|
|
||||||
require('models/close_connection.php');
|
|
||||||
|
|
||||||
if ($resultat) {
|
if ($resultat) {
|
||||||
$_SESSION['notification'] = "Opération enregistrée avec succès.";
|
$_SESSION['notification'] = 'Opération enregistrée avec succès.';
|
||||||
} else {
|
} else {
|
||||||
$_SESSION['notification'] = "<span style='color:red;'>Erreur lors de l'enregistrement.</span>";
|
$_SESSION['notification'] = 'Erreur lors de l\'enregistrement.';
|
||||||
}
|
}
|
||||||
|
|
||||||
header('Location: index.php?route=operations');
|
header('Location: index.php?route=operations');
|
||||||
exit();
|
exit;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
?>
|
|
||||||
|
|
@ -70,7 +70,7 @@ nav a.nav-right { margin-left: auto; }
|
||||||
|
|
||||||
/* CONTENU */
|
/* CONTENU */
|
||||||
article {
|
article {
|
||||||
max-width: 1000px;
|
max-width: 1100px;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
padding: 20px 30px;
|
padding: 20px 30px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
|
@ -101,6 +101,79 @@ table { width: 100%; border-collapse: collapse; margin: 10px 0; }
|
||||||
table th { background: #f8f6f0; color: #3b4a2e; padding: 10px; text-align: left; border-bottom: 2px solid #c49a3c; }
|
table th { background: #f8f6f0; color: #3b4a2e; padding: 10px; text-align: left; border-bottom: 2px solid #c49a3c; }
|
||||||
table td { padding: 8px 10px; border-bottom: 1px solid #e8e2d2; }
|
table td { padding: 8px 10px; border-bottom: 1px solid #e8e2d2; }
|
||||||
|
|
||||||
|
/* PLANNING */
|
||||||
|
.planning-nav {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planning-nav a {
|
||||||
|
color: #c49a3c;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planning-nav a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
.planning-tableau {
|
||||||
|
overflow-x: auto;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planning-tableau table { margin: 0; }
|
||||||
|
|
||||||
|
.planning-tableau th {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
padding: 5px 3px;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 35px;
|
||||||
|
writing-mode: horizontal-tb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planning-tableau td {
|
||||||
|
padding: 0;
|
||||||
|
height: 28px;
|
||||||
|
min-width: 35px;
|
||||||
|
border: 1px solid #e0dbce;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 0.65rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sauveteur-nom {
|
||||||
|
min-width: 150px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
border-right: 2px solid #c49a3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sauveteur-nom small { color: #8b7a5c; font-size: 0.7rem; }
|
||||||
|
|
||||||
|
.cell-actif { opacity: 0.85; }
|
||||||
|
|
||||||
|
.cell-prepa { opacity: 0.4; }
|
||||||
|
|
||||||
|
.planning-legende {
|
||||||
|
margin-top: 15px;
|
||||||
|
padding-top: 10px;
|
||||||
|
border-top: 1px solid #e8e2d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.planning-legende h3 { font-size: 0.9rem; margin-bottom: 8px; }
|
||||||
|
|
||||||
|
.legende-item { display: inline-block; margin-right: 15px; font-size: 0.8rem; }
|
||||||
|
|
||||||
|
.legende-couleur {
|
||||||
|
display: inline-block;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
border-radius: 2px;
|
||||||
|
margin-right: 4px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
/* FORMULAIRES */
|
/* FORMULAIRES */
|
||||||
form label { display: inline-block; min-width: 140px; }
|
form label { display: inline-block; min-width: 140px; }
|
||||||
form input[type="text"],
|
form input[type="text"],
|
||||||
|
|
|
||||||
|
|
@ -83,12 +83,8 @@
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'lecture':
|
case 'lecture':
|
||||||
require('views/lecture_page.php');
|
|
||||||
planning_afficher_ctrl();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'lecture_ctrl':
|
|
||||||
require('controllers/lecture_page_ctrl.php');
|
require('controllers/lecture_page_ctrl.php');
|
||||||
|
planning_afficher_ctrl();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,21 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
require('config/config.php');
|
|
||||||
|
|
||||||
// Récupère tous les sauveteurs
|
// Récupère tous les sauveteurs
|
||||||
function get_all_sauveteurs(PDO $c): array {
|
function get_all_sauveteurs(PDO $c): array {
|
||||||
$req = "SELECT ID, nom, prenom, specialite FROM Sauveteur ORDER BY Nom, Prenom";
|
$req = "SELECT ID, nom, prenom, specialite FROM Sauveteur ORDER BY nom, prenom";
|
||||||
return $c->query($req)->fetchAll(PDO::FETCH_ASSOC);
|
return $c->query($req)->fetchAll(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Récupère les missions d'une date
|
// Récupère les missions d'une date donnée
|
||||||
function get_missions_by_date(PDO $c, string $date): array {
|
function get_missions_by_date(PDO $c, string $date): array {
|
||||||
$req = "
|
$req = "SELECT ID, DateHeureDebut, DateHeureFin, ID_Sauveteur, EnPrepa
|
||||||
SELECT ID, DateHeureDebut, DateHeureFin, ID_Sauveteur
|
|
||||||
FROM Mission
|
FROM Mission
|
||||||
WHERE DATE(DateHeureDebut) = :date
|
WHERE DATE(DateHeureDebut) = :date
|
||||||
OR DATE(DateHeureFin) = :date
|
OR DATE(DateHeureFin) = :date
|
||||||
";
|
ORDER BY DateHeureDebut";
|
||||||
|
|
||||||
$stmt = $c->prepare($req);
|
$stmt = $c->prepare($req);
|
||||||
$stmt->bindValue(':date', $date);
|
$stmt->bindValue(':date', $date);
|
||||||
$stmt->execute();
|
$stmt->execute();
|
||||||
|
|
||||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,68 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
|
function planning_view(array $sauveteurs, array $sauveteurs_index, array $creneaux, array $grille, string $date, string $date_prec, string $date_suiv, array $couleurs, array $legendes) {
|
||||||
ini_set('display_errors', 1);
|
require('views/header.php');
|
||||||
|
|
||||||
function planning_view(array $sauveteurs, array $creneaux, array $grille, string $date) {
|
|
||||||
?>
|
?>
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head><meta charset="UTF-8"><title>Planning</title></head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<h2>Planning du <?= $date ?></h2>
|
<h2>Planning du <?= date('d/m/Y', strtotime($date)) ?></h2>
|
||||||
|
|
||||||
<table border="1">
|
<!-- Navigation des dates -->
|
||||||
|
<nav class="planning-nav">
|
||||||
|
<a href="index.php?date=<?= $date_prec ?>">← Jour précédent</a>
|
||||||
|
<strong><?= date('d/m/Y', strtotime($date)) ?></strong>
|
||||||
|
<a href="index.php?date=<?= $date_suiv ?>">Jour suivant →</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Tableau du planning -->
|
||||||
|
<div class="planning-tableau">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Nom / Prénom</th>
|
<th>Sauveteur</th>
|
||||||
<?php foreach ($creneaux as $c): ?>
|
<?php foreach ($creneaux as $c): ?>
|
||||||
<th><?= $c ?></th>
|
<th><?= substr($c, 0, 5) ?></th>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</tr>
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
<?php foreach ($sauveteurs as $s): ?>
|
<?php foreach ($sauveteurs as $s): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?= $s['Nom'] ?> <?= $s['Prenom'] ?></td>
|
<td class="sauveteur-nom">
|
||||||
|
<?= htmlentities($s['nom'] . ' ' . $s['prenom']) ?>
|
||||||
|
<br><small><?= $legendes[(int) $s['specialite']] ?? 'Inconnu' ?></small>
|
||||||
|
</td>
|
||||||
<?php foreach ($creneaux as $c):
|
<?php foreach ($creneaux as $c):
|
||||||
$couleur = $grille[$s['ID_Sauveteur']][$c];
|
$cell = $grille[$s['ID']][$c] ?? null;
|
||||||
|
$bg = $cell ? $cell['couleur'] : '';
|
||||||
|
$class = '';
|
||||||
|
if ($cell) {
|
||||||
|
$class = $cell['en_prepa'] ? 'cell-prepa' : 'cell-actif';
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
<td <?= $couleur ? 'bgcolor="' . $couleur . '"' : '' ?>></td>
|
<td class="<?= $class ?>" style="<?= $bg ? 'background:' . $bg : '' ?>">
|
||||||
|
<?= $cell && $cell['en_prepa'] ? 'P' : '' ?>
|
||||||
|
</td>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
<!-- Légende -->
|
||||||
</html>
|
<div class="planning-legende">
|
||||||
<?php
|
<h3>Légende : Spécialités</h3>
|
||||||
|
<?php foreach ($legendes as $num => $nom): ?>
|
||||||
|
<span class="legende-item">
|
||||||
|
<span class="legende-couleur" style="background:<?= $couleurs[$num] ?>"></span>
|
||||||
|
<?= $nom ?>
|
||||||
|
</span>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<span class="legende-item">
|
||||||
|
<span class="legende-couleur" style="background:#ccc; opacity:0.5;"></span>
|
||||||
|
En préparation (P)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php require('views/footer.php');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
#ceci est la partie "view" de la page de login, le header et le footer ne sont pour l'instant pas actif
|
|
||||||
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED);
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
|
|
||||||
function login_form_view(?string $route) {
|
function login_form_view(?string $route) {
|
||||||
#require('header.php');
|
require('views/header.php');
|
||||||
|
|
||||||
echo '<h2>Page d\'authentification</h2>';
|
echo '<h2>Page d\'authentification</h2>';
|
||||||
|
echo '<p>Merci de vous authentifier pour accéder à cette fonctionnalité.</p>';
|
||||||
echo '<form action="index.php?route=auth&ask=' . $route . '" method="post">';
|
echo '<form action="index.php?route=auth&ask=' . $route . '" method="post">';
|
||||||
echo '<p>Login<input type="text" name="login" /></p>';
|
echo '<p><label>Login :</label> <input type="text" name="login"></p>';
|
||||||
echo '<p>Mot de passe<input type="passwd" name="password" /></p>';
|
echo '<p><label>Mot de passe :</label> <input type="password" name="password"></p>';
|
||||||
echo '<p><input type="submit" value="Valider" /></form>';
|
echo '<p><input type="submit" value="Valider"></p>';
|
||||||
|
echo '</form>';
|
||||||
|
|
||||||
#require('footer.php');
|
require('views/footer.php');
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue