diff --git a/project/.gitignore b/project/.gitignore
new file mode 100644
index 0000000..7ceb59f
--- /dev/null
+++ b/project/.gitignore
@@ -0,0 +1,25 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+.env
diff --git a/project/index.html b/project/index.html
new file mode 100644
index 0000000..23ca1ce
--- /dev/null
+++ b/project/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
🔄 Réinitialisation des Compteurs de Congés
+
+
+
⚠️ ATTENTION
+
Cette opération va réinitialiser TOUS les compteurs de congés selon les règles suivantes :
+
+ - Congés Payés : 25 jours (exercice du 01/06 au 31/05)
+ - RTT : 10 jours pour 2025 (exercice du 01/01 au 31/12)
+ - Congés Maladie : 0 jours (remise à zéro)
+
+
Cette action est irréversible !
+
+
+ [
+ 'method' => 'POST',
+ 'header' => 'Content-Type: application/json',
+ 'content' => json_encode(['manual_reset' => true])
+ ]
+ ]);
+
+ $result = file_get_contents($resetUrl, false, $context);
+ $data = json_decode($result, true);
+
+ if ($data && $data['success']) {
+ echo '
';
+ echo '
✅ Réinitialisation réussie !
';
+ echo '
Employés mis à jour : ' . $data['details']['employees_updated'] . '
';
+ echo '
Exercice CP : ' . $data['details']['leave_year'] . '
';
+ echo '
Année RTT : ' . $data['details']['rtt_year'] . '
';
+ echo '
Date de réinitialisation : ' . $data['details']['reset_date'] . '
';
+
+ if (!empty($data['log'])) {
+ echo '
Voir le détail
';
+ foreach ($data['log'] as $logLine) {
+ echo htmlspecialchars($logLine) . "\n";
+ }
+ echo '';
+ }
+ echo '
';
+ } else {
+ echo '
';
+ echo '
❌ Erreur lors de la réinitialisation
';
+ echo '
' . ($data['message'] ?? 'Erreur inconnue') . '
';
+ echo '
';
+ }
+ }
+ ?>
+
+
+
+
+
+
📋 Informations sur les exercices
+ format('Y');
+ $currentMonth = (int)$currentDate->format('m');
+
+ // Calcul exercice CP
+ $leaveYear = ($currentMonth < 6) ? $currentYear - 1 : $currentYear;
+ $leaveYearEnd = $leaveYear + 1;
+
+ echo "
Exercice Congés Payés actuel : du 01/06/$leaveYear au 31/05/$leaveYearEnd
";
+ echo "
Exercice RTT actuel : du 01/01/$currentYear au 31/12/$currentYear
";
+ echo "
Date actuelle : " . $currentDate->format('d/m/Y H:i:s') . "
";
+ ?>
+
+
🔗 Actions rapides
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/project/public/resetLeaveCounters.php b/project/public/resetLeaveCounters.php
new file mode 100644
index 0000000..60e4cd9
--- /dev/null
+++ b/project/public/resetLeaveCounters.php
@@ -0,0 +1,228 @@
+connect_error) {
+ error_log("Erreur connexion DB reset: " . $conn->connect_error);
+ echo json_encode([
+ "success" => false,
+ "message" => "Erreur de connexion à la base de données : " . $conn->connect_error
+ ]);
+ exit();
+}
+
+// Log de debug
+error_log("Reset counters - Début du script");
+
+// Fonction pour déterminer l'exercice des congés payés (01/06 au 31/05)
+function getLeaveYear($date = null) {
+ if ($date === null) {
+ $date = new DateTime();
+ } else {
+ $date = new DateTime($date);
+ }
+
+ $currentYear = (int)$date->format('Y');
+ $currentMonth = (int)$date->format('m');
+
+ // Si on est avant le 1er juin, l'exercice a commencé l'année précédente
+ if ($currentMonth < 6) {
+ return $currentYear - 1;
+ }
+ // Si on est le 1er juin ou après, l'exercice a commencé cette année
+ return $currentYear;
+}
+
+// Fonction pour déterminer l'année RTT (01/01 au 31/12)
+function getRTTYear($date = null) {
+ if ($date === null) {
+ $date = new DateTime();
+ } else {
+ $date = new DateTime($date);
+ }
+
+ return (int)$date->format('Y');
+}
+
+try {
+ $conn->begin_transaction();
+
+ $currentDate = new DateTime();
+ $leaveYear = getLeaveYear();
+ $rttYear = getRTTYear();
+
+ error_log("Reset counters - Exercice CP: $leaveYear, RTT: $rttYear");
+
+ $resetLog = [];
+
+ // 1. Récupérer tous les employés depuis la table Users
+ $queryEmployees = "SELECT ID FROM Users";
+ $resultEmployees = $conn->query($queryEmployees);
+
+ if (!$resultEmployees) {
+ throw new Exception("Erreur lors de la récupération des employés : " . $conn->error);
+ }
+
+ error_log("Reset counters - Nombre d'employés trouvés: " . $resultEmployees->num_rows);
+
+ // 2. Récupérer les IDs des types de congés
+ $queryTypes = "SELECT Id, Nom FROM TypeConge WHERE Nom IN ('Congé payé', 'RTT', 'Congé maladie')";
+ $resultTypes = $conn->query($queryTypes);
+
+ $typeIds = [];
+ while ($row = $resultTypes->fetch_assoc()) {
+ $typeIds[$row['Nom']] = $row['Id'];
+ }
+
+ error_log("Reset counters - Types trouvés: " . print_r($typeIds, true));
+
+ if (count($typeIds) < 3) {
+ throw new Exception("Types de congés manquants dans la base de données");
+ }
+
+ // 3. Pour chaque employé, réinitialiser les compteurs
+ $employeesUpdated = 0;
+ while ($employee = $resultEmployees->fetch_assoc()) {
+ $employeeId = $employee['ID'];
+
+ error_log("Reset counters - Traitement employé: $employeeId");
+
+ // CONGÉS PAYÉS - Exercice du 01/06 au 31/05 (25 jours)
+ $queryUpdateCP = "
+ INSERT INTO CompteurConges (EmployeeId, TypeCongeId, Annee, Solde, Total)
+ VALUES (?, ?, ?, 25, 25)
+ ON DUPLICATE KEY UPDATE
+ Solde = 25,
+ Total = 25
+ ";
+ $stmtCP = $conn->prepare($queryUpdateCP);
+ if (!$stmtCP) {
+ throw new Exception("Erreur préparation CP: " . $conn->error);
+ }
+ $stmtCP->bind_param("iii", $employeeId, $typeIds['Congé payé'], $leaveYear);
+
+ if (!$stmtCP->execute()) {
+ throw new Exception("Erreur lors de la mise à jour des CP pour l'employé $employeeId : " . $stmtCP->error);
+ }
+ $stmtCP->close();
+
+ // RTT - Année civile du 01/01 au 31/12
+ // Calcul du nombre de RTT selon l'année
+ $rttCount = 10; // Par défaut 10 pour 2025
+ if ($rttYear == 2024) {
+ $rttCount = 8; // Exemple pour 2024
+ } elseif ($rttYear >= 2025) {
+ $rttCount = 10; // 10 pour 2025 et après
+ }
+
+ $queryUpdateRTT = "
+ INSERT INTO CompteurConges (EmployeeId, TypeCongeId, Annee, Solde, Total)
+ VALUES (?, ?, ?, ?, ?)
+ ON DUPLICATE KEY UPDATE
+ Solde = ?,
+ Total = ?
+ ";
+ $stmtRTT = $conn->prepare($queryUpdateRTT);
+ if (!$stmtRTT) {
+ throw new Exception("Erreur préparation RTT: " . $conn->error);
+ }
+ $stmtRTT->bind_param("iiiiiii", $employeeId, $typeIds['RTT'], $rttYear, $rttCount, $rttCount, $rttCount, $rttCount);
+
+ if (!$stmtRTT->execute()) {
+ throw new Exception("Erreur lors de la mise à jour des RTT pour l'employé $employeeId : " . $stmtRTT->error);
+ }
+ $stmtRTT->close();
+
+ // CONGÉ MALADIE - Réinitialiser à 0 (pas de limite)
+ $queryUpdateABS = "
+ INSERT INTO CompteurConges (EmployeeId, TypeCongeId, Annee, Solde, Total)
+ VALUES (?, ?, ?, 0, 0)
+ ON DUPLICATE KEY UPDATE
+ Solde = 0,
+ Total = 0
+ ";
+ $stmtABS = $conn->prepare($queryUpdateABS);
+ if (!$stmtABS) {
+ throw new Exception("Erreur préparation ABS: " . $conn->error);
+ }
+ $stmtABS->bind_param("iii", $employeeId, $typeIds['Congé maladie'], $rttYear);
+
+ if (!$stmtABS->execute()) {
+ throw new Exception("Erreur lors de la mise à jour des ABS pour l'employé $employeeId : " . $stmtABS->error);
+ }
+ $stmtABS->close();
+
+ $resetLog[] = "Employé $employeeId : CP=$leaveYear (25j), RTT=$rttYear ({$rttCount}j), ABS=$rttYear (0j)";
+ $employeesUpdated++;
+ }
+
+ error_log("Reset counters - Employés mis à jour: $employeesUpdated");
+
+ // 4. Log de la réinitialisation
+ $logEntry = "
+ === RÉINITIALISATION DES COMPTEURS ===
+ Date: " . $currentDate->format('Y-m-d H:i:s') . "
+ Exercice CP: $leaveYear (01/06/$leaveYear au 31/05/" . ($leaveYear + 1) . ")
+ Année RTT: $rttYear (01/01/$rttYear au 31/12/$rttYear)
+ Employés traités: $employeesUpdated
+
+ Détails:
+ " . implode("\n ", $resetLog) . "
+ ";
+
+ // Sauvegarder le log (optionnel - créer une table de logs si nécessaire)
+ error_log($logEntry, 3, "reset_counters.log");
+
+ $conn->commit();
+ error_log("Reset counters - Transaction commitée avec succès");
+
+ echo json_encode([
+ "success" => true,
+ "message" => "Compteurs réinitialisés avec succès",
+ "details" => [
+ "employees_updated" => $employeesUpdated,
+ "leave_year" => $leaveYear,
+ "rtt_year" => $rttYear,
+ "cp_days" => 25,
+ "rtt_days" => $rttCount,
+ "reset_date" => $currentDate->format('Y-m-d H:i:s')
+ ],
+ "log" => $resetLog
+ ]);
+
+} catch (Exception $e) {
+ $conn->rollback();
+ error_log("Erreur réinitialisation compteurs : " . $e->getMessage());
+
+ echo json_encode([
+ "success" => false,
+ "message" => "Erreur lors de la réinitialisation : " . $e->getMessage()
+ ]);
+}
+
+$conn->close();
+?>
\ No newline at end of file
diff --git a/project/public/submitLeaveRequest.php b/project/public/submitLeaveRequest.php
new file mode 100644
index 0000000..bcb819c
--- /dev/null
+++ b/project/public/submitLeaveRequest.php
@@ -0,0 +1,181 @@
+connect_error) {
+ error_log("Erreur connexion DB submitLeaveRequest: " . $conn->connect_error);
+ echo json_encode([
+ "success" => false,
+ "message" => "Erreur de connexion DB : " . $conn->connect_error
+ ]);
+ exit();
+}
+
+// Lecture du JSON envoyé
+$input = file_get_contents('php://input');
+error_log("submitLeaveRequest - Input reçu: " . $input);
+
+$data = json_decode($input, true);
+
+if (!isset(
+ $data['EmployeeId'],
+ $data['TypeConge'],
+ $data['DateDebut'],
+ $data['DateFin'],
+ $data['NumDays']
+)) {
+ error_log("submitLeaveRequest - Données manquantes: " . print_r($data, true));
+ echo json_encode([
+ "success" => false,
+ "message" => "Données manquantes pour la demande de congé."
+ ]);
+ exit();
+}
+
+// Récupération des champs
+$employeeId = (int) $data['EmployeeId'];
+$typeCongeNom= $data['TypeConge'];
+$dateDebut = $data['DateDebut'];
+$dateFin = $data['DateFin'];
+$commentaire = $data['Commentaire'] ?? '';
+$numDays = (int) $data['NumDays'];
+
+error_log("submitLeaveRequest - Données parsées: EmployeeId=$employeeId, Type=$typeCongeNom, Début=$dateDebut, Fin=$dateFin");
+
+$statut = 'En attente';
+$validateur = null;
+$currentDate= date('Y-m-d H:i:s'); // date complète pour DateDemande
+
+// Mapping frontend → DB
+switch ($typeCongeNom) {
+ case 'CP': $dbTypeCongeName = 'Congé payé'; break;
+ case 'RTT': $dbTypeCongeName = 'RTT'; break;
+ case 'ABS': $dbTypeCongeName = 'Congé maladie'; break;
+ default:
+ error_log("submitLeaveRequest - Type de congé inconnu: $typeCongeNom");
+ echo json_encode([
+ "success" => false,
+ "message" => "Type de congé inconnu."
+ ]);
+ $conn->close();
+ exit();
+}
+
+error_log("submitLeaveRequest - Type DB mappé: $dbTypeCongeName");
+
+// Récupération de l'ID du type de congé
+$stmt = $conn->prepare("SELECT Id FROM TypeConge WHERE Nom = ?");
+if (!$stmt) {
+ error_log("submitLeaveRequest - Erreur préparation requête TypeConge: " . $conn->error);
+ echo json_encode([
+ "success" => false,
+ "message" => "Erreur préparation requête TypeConge"
+ ]);
+ $conn->close();
+ exit();
+}
+
+$stmt->bind_param("s", $dbTypeCongeName);
+$stmt->execute();
+$res = $stmt->get_result();
+if ($row = $res->fetch_assoc()) {
+ $typeCongeId = (int) $row['Id'];
+ error_log("submitLeaveRequest - TypeCongeId trouvé: $typeCongeId");
+} else {
+ error_log("submitLeaveRequest - Type de congé non trouvé en DB: $dbTypeCongeName");
+ echo json_encode([
+ "success" => false,
+ "message" => "Type de congé non trouvé en DB : $dbTypeCongeName"
+ ]);
+ $stmt->close();
+ $conn->close();
+ exit();
+}
+$stmt->close();
+
+// Requête d'insertion dans DemandeConge
+$query = "
+ INSERT INTO DemandeConge
+ (EmployeeId, DateDebut, DateFin, TypeCongeId, Statut, DateDemande, Commentaire, Validateur, NombreJours)
+ VALUES
+ (?, ?, ?, ?, ?, ?, ?, ?, ?)
+";
+
+error_log("submitLeaveRequest - Requête d'insertion: $query");
+
+// Préparation de la requête
+$stmt = $conn->prepare($query);
+if (!$stmt) {
+ error_log("Erreur prepare insert : " . $conn->error);
+ echo json_encode([
+ "success" => false,
+ "message" => "Erreur interne lors de la préparation de la requête."
+ ]);
+ $conn->close();
+ exit();
+}
+
+// Pour la colonne Validateur, on passe '' si null
+$validParam = $validateur ?? '';
+
+error_log("submitLeaveRequest - Paramètres bind: $employeeId, $dateDebut, $dateFin, $typeCongeId, $statut, $currentDate, $commentaire, $validParam, $numDays");
+
+// Bind des paramètres (types : i=integer, s=string, d=decimal)
+$stmt->bind_param(
+ "ississssi",
+ $employeeId, // i
+ $dateDebut, // s
+ $dateFin, // s
+ $typeCongeId, // i
+ $statut, // s
+ $currentDate, // s - DateDemande
+ $commentaire, // s
+ $validParam, // s
+ $numDays // i - NombreJours
+);
+
+// Exécution
+if ($stmt->execute()) {
+ $insertId = $conn->insert_id;
+ error_log("submitLeaveRequest - Insertion réussie, ID: $insertId");
+ echo json_encode([
+ "success" => true,
+ "message" => "Demande de congé soumise avec succès.",
+ "request_id" => $insertId
+ ]);
+} else {
+ error_log("Erreur execute insert : " . $stmt->error);
+ echo json_encode([
+ "success" => false,
+ "message" => "Erreur lors de l'enregistrement : " . $stmt->error
+ ]);
+}
+
+$stmt->close();
+$conn->close();
+
+error_log("submitLeaveRequest - Script terminé");
+
+?>
diff --git a/project/public/test_db.php b/project/public/test_db.php
new file mode 100644
index 0000000..a599817
--- /dev/null
+++ b/project/public/test_db.php
@@ -0,0 +1,14 @@
+connect_error) {
+ die("❌ Connexion échouée : " . $conn->connect_error);
+}
+echo "✅ Connexion réussie à la base de données !";
+
+?>
diff --git a/project/public/validateRequest.php b/project/public/validateRequest.php
new file mode 100644
index 0000000..5792465
--- /dev/null
+++ b/project/public/validateRequest.php
@@ -0,0 +1,197 @@
+connect_error) {
+ error_log("Erreur connexion DB validateRequest: " . $conn->connect_error);
+ echo json_encode(["success" => false, "message" => "Erreur de connexion à la base de données"]);
+ exit();
+}
+
+// Lecture du JSON envoyé
+$input = file_get_contents('php://input');
+error_log("validateRequest - Input reçu: " . $input);
+
+$data = json_decode($input, true);
+
+if (!isset($data['request_id'], $data['action'], $data['validator_id'])) {
+ error_log("validateRequest - Données manquantes: " . print_r($data, true));
+ echo json_encode([
+ "success" => false,
+ "message" => "Données manquantes pour la validation"
+ ]);
+ exit();
+}
+
+$requestId = (int)$data['request_id'];
+$action = $data['action']; // 'approve' ou 'reject'
+$validatorId = (int)$data['validator_id'];
+$comment = $data['comment'] ?? '';
+
+error_log("validateRequest - Request ID: $requestId, Action: $action, Validator: $validatorId");
+
+try {
+ $conn->begin_transaction();
+
+ // Vérifier que la demande existe et est en attente
+ $queryCheck = "
+ SELECT dc.Id, dc.EmployeeId, dc.TypeCongeId, dc.DateDebut, dc.DateFin, dc.NombreJours,
+ u.Nom, u.Prenom, tc.Nom as TypeNom
+ FROM DemandeConge dc
+ JOIN Users u ON dc.EmployeeId = u.ID
+ JOIN TypeConge tc ON dc.TypeCongeId = tc.Id
+ WHERE dc.Id = ? AND dc.Statut = 'En attente'
+ ";
+
+ $stmtCheck = $conn->prepare($queryCheck);
+ $stmtCheck->bind_param("i", $requestId);
+ $stmtCheck->execute();
+ $resultCheck = $stmtCheck->get_result();
+
+ if ($requestRow = $resultCheck->fetch_assoc()) {
+ $employeeId = $requestRow['EmployeeId'];
+ $typeCongeId = $requestRow['TypeCongeId'];
+ $nombreJours = $requestRow['NombreJours'];
+ $employeeName = $requestRow['Prenom'] . ' ' . $requestRow['Nom'];
+ $typeNom = $requestRow['TypeNom'];
+
+ error_log("validateRequest - Demande trouvée: $employeeName, Type: $typeNom, Jours: $nombreJours");
+
+ // Déterminer le nouveau statut
+ $newStatus = ($action === 'approve') ? 'Validée' : 'Refusée';
+
+ // Mettre à jour la demande
+ $queryUpdate = "
+ UPDATE DemandeConge
+ SET Statut = ?,
+ ValidateurId = ?,
+ DateValidation = NOW(),
+ CommentaireValidation = ?
+ WHERE Id = ?
+ ";
+
+ $stmtUpdate = $conn->prepare($queryUpdate);
+ $stmtUpdate->bind_param("sisi", $newStatus, $validatorId, $comment, $requestId);
+
+ if ($stmtUpdate->execute()) {
+ error_log("validateRequest - Demande mise à jour avec succès");
+
+ // Si approuvée, déduire du solde (sauf pour congé maladie)
+ if ($action === 'approve' && $typeNom !== 'Congé maladie') {
+ // Déterminer l'année selon le type de congé
+ $currentDate = new DateTime();
+ if ($typeNom === 'Congé payé') {
+ // Exercice CP: 01/06 au 31/05
+ $year = ($currentDate->format('m') < 6) ? $currentDate->format('Y') - 1 : $currentDate->format('Y');
+ } else {
+ // RTT: année civile
+ $year = $currentDate->format('Y');
+ }
+
+ error_log("validateRequest - Déduction solde: Type=$typeNom, Année=$year, Jours=$nombreJours");
+
+ // Déduire du solde
+ $queryDeduct = "
+ UPDATE CompteurConges
+ SET Solde = GREATEST(0, Solde - ?)
+ WHERE EmployeeId = ? AND TypeCongeId = ? AND Annee = ?
+ ";
+
+ $stmtDeduct = $conn->prepare($queryDeduct);
+ $stmtDeduct->bind_param("diii", $nombreJours, $employeeId, $typeCongeId, $year);
+
+ if ($stmtDeduct->execute()) {
+ error_log("validateRequest - Solde déduit avec succès");
+ } else {
+ error_log("validateRequest - Erreur déduction solde: " . $stmtDeduct->error);
+ }
+
+ $stmtDeduct->close();
+ }
+
+ // Créer une notification pour l'employé
+ $notificationTitle = ($action === 'approve') ? 'Demande approuvée' : 'Demande refusée';
+ $notificationMessage = "Votre demande de $typeNom a été " . (($action === 'approve') ? 'approuvée' : 'refusée');
+ if ($comment) {
+ $notificationMessage .= ". Commentaire: $comment";
+ }
+
+ $queryNotif = "
+ INSERT INTO Notifications (UserId, Titre, Message, Type, DemandeCongeId)
+ VALUES (?, ?, ?, ?, ?)
+ ";
+
+ $notifType = ($action === 'approve') ? 'Success' : 'Error';
+ $stmtNotif = $conn->prepare($queryNotif);
+ $stmtNotif->bind_param("isssi", $employeeId, $notificationTitle, $notificationMessage, $notifType, $requestId);
+ $stmtNotif->execute();
+ $stmtNotif->close();
+
+ // Log dans l'historique
+ $actionText = ($action === 'approve') ? 'Validation congé' : 'Refus congé';
+ $actionDetails = "$actionText $employeeName ($typeNom)";
+ if ($comment) {
+ $actionDetails .= " - $comment";
+ }
+
+ $queryHistory = "
+ INSERT INTO HistoriqueActions (UserId, Action, Details, DemandeCongeId)
+ VALUES (?, ?, ?, ?)
+ ";
+
+ $stmtHistory = $conn->prepare($queryHistory);
+ $stmtHistory->bind_param("issi", $validatorId, $actionText, $actionDetails, $requestId);
+ $stmtHistory->execute();
+ $stmtHistory->close();
+
+ $conn->commit();
+
+ echo json_encode([
+ "success" => true,
+ "message" => "Demande " . (($action === 'approve') ? 'approuvée' : 'refusée') . " avec succès",
+ "new_status" => $newStatus
+ ]);
+
+ } else {
+ throw new Exception("Erreur lors de la mise à jour: " . $stmtUpdate->error);
+ }
+
+ $stmtUpdate->close();
+ } else {
+ throw new Exception("Demande non trouvée ou déjà traitée");
+ }
+
+ $stmtCheck->close();
+
+} catch (Exception $e) {
+ $conn->rollback();
+ error_log("Erreur validateRequest: " . $e->getMessage());
+ echo json_encode([
+ "success" => false,
+ "message" => "Erreur lors de la validation: " . $e->getMessage()
+ ]);
+}
+
+$conn->close();
+?>
\ No newline at end of file
diff --git a/project/src/App.jsx b/project/src/App.jsx
new file mode 100644
index 0000000..8dab5db
--- /dev/null
+++ b/project/src/App.jsx
@@ -0,0 +1,44 @@
+import React from 'react';
+import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom';
+import { AuthProvider } from './context/AuthContext';
+import Dashboard from './pages/Dashboard';
+import Login from './pages/Login';
+import Requests from './pages/Requests';
+import Calendar from './pages/Calendar';
+import Manager from './pages/Manager';
+import ProtectedRoute from './components/ProtectedRoute';
+
+function App() {
+ return (
+
+ {/* Mobile close button */}
+
+
+
+
+ {/* Logo Section */}
+
+
+
+
+
+
+
GTA
+
Gestion de congés
+
+
+
+
+ {/* User Info */}
+
+
+

+
+
{user?.name || "Utilisateur"}
+
{user?.department || "Service"}
+
+ Employé
+
+
+
+
+
+ {/* Navigation */}
+
+
+ {/* Logout Button */}
+
+
+
+
+ >
+ );
+};
+
+export default Sidebar;
\ No newline at end of file
diff --git a/project/src/context/AuthContext.jsx b/project/src/context/AuthContext.jsx
new file mode 100644
index 0000000..fc1750d
--- /dev/null
+++ b/project/src/context/AuthContext.jsx
@@ -0,0 +1,126 @@
+import React, { createContext, useContext, useState, useEffect } from 'react';
+
+const AuthContext = createContext();
+
+export const useAuth = () => {
+ const context = useContext(AuthContext);
+ if (!context) {
+ throw new Error('useAuth must be used within an AuthProvider');
+ }
+ return context;
+};
+
+export const AuthProvider = ({ children }) => {
+ const [user, setUser] = useState(null);
+ const [isLoading, setIsLoading] = useState(true);
+
+ useEffect(() => {
+ // Vérifier si l'utilisateur est déjà connecté
+ const savedUser = localStorage.getItem('user');
+ if (savedUser) {
+ try {
+ setUser(JSON.parse(savedUser));
+ } catch (error) {
+ console.error('Erreur lors du parsing de l\'utilisateur sauvegardé:', error);
+ localStorage.removeItem('user');
+ }
+ }
+ setIsLoading(false);
+ }, []);
+
+ const login = async (email, password) => {
+ try {
+ // Tester plusieurs URLs possibles selon la configuration locale
+ const possibleUrls = [
+ 'http://localhost/GTA/project/public/login.php',
+ 'http://localhost:80/GTA/project/public/login.php',
+ 'http://localhost/GTA/public/login.php',
+ 'http://localhost/public/login.php'
+ ];
+
+ let response = null;
+ let lastError = null;
+
+ for (const url of possibleUrls) {
+ try {
+ console.log(' Test URL:', url);
+ response = await fetch(url, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({
+ email: email,
+ mot_de_passe: password
+ }),
+ });
+
+ if (response.ok) {
+ console.log(' URL qui fonctionne:', url);
+ break;
+ }
+ } catch (error) {
+ lastError = error;
+ console.log(' URL échouée:', url, error.message);
+ continue;
+ }
+ }
+
+ if (!response || !response.ok) {
+ throw new Error('Aucune URL de connexion accessible');
+ }
+
+ const text = await response.text();
+ console.log(' Réponse brute:', text);
+
+ // Vérifier si la réponse est du JSON valide
+ let data;
+ try {
+ data = JSON.parse(text);
+ } catch (parseError) {
+ console.error(' Réponse non-JSON:', text.substring(0, 200));
+ throw new Error('Le serveur PHP ne répond pas correctement. Vérifiez que PHP est démarré.');
+ }
+
+ if (data.success) {
+ const userData = {
+ id: data.user.id,
+ name: data.user.prenom + ' ' + data.user.nom,
+ prenom: data.user.prenom,
+ nom: data.user.nom,
+ email: data.user.email,
+ role: data.user.role || 'Employe'
+ };
+ setUser(userData);
+ localStorage.setItem('user', JSON.stringify(userData));
+ return true;
+ } else {
+ console.error(' Échec connexion:', data.message);
+ return false;
+ }
+ } catch (error) {
+ console.error('Erreur de connexion:', error);
+ return false;
+ }
+ };
+
+ const logout = () => {
+ setUser(null);
+ localStorage.removeItem('user');
+ };
+
+ const value = {
+ user,
+ login,
+ logout,
+ isLoading
+ };
+
+ return (
+