Файловый менеджер - Редактировать - /home/gqdcvggs/go.imators.com/Passage.tar
Назад
upload.php 0000644 00000015127 15114743032 0006547 0 ustar 00 <?php // Inclure la connexion à la base de données require_once 'db.php'; // Démarrer la session session_start(); // Vérifier si l'utilisateur est connecté if (!isset($_SESSION['user_id'])) { header('Location: index.php'); exit; } // Créer le dossier uploads s'il n'existe pas $uploadDir = 'assets/uploads/'; if (!file_exists($uploadDir)) { mkdir($uploadDir, 0777, true); } // Traitement pour l'ajout d'une note if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_note'])) { $titre = $_POST['titre']; $matiere_id = $_POST['matiere_id']; $description = $_POST['description']; $user_id = $_SESSION['user_id']; $image_url = null; // Traitement de l'image si elle est fournie if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) { $tmpName = $_FILES['image']['tmp_name']; $fileName = uniqid() . '_' . $_FILES['image']['name']; $destination = $uploadDir . $fileName; // Déplacer l'image téléchargée if (move_uploaded_file($tmpName, $destination)) { $image_url = $destination; } } // Insérer la note dans la base de données $stmt = $pdo->prepare('INSERT INTO notes (user_id, matiere_id, titre, description, image_url) VALUES (?, ?, ?, ?, ?)'); if ($stmt->execute([$user_id, $matiere_id, $titre, $description, $image_url])) { header('Location: index.php?success=note_added'); exit; } else { header('Location: index.php?error=note_failed'); exit; } } // Traitement pour l'ajout d'un commentaire if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_comment'])) { $note_id = $_POST['note_id']; $contenu = $_POST['contenu']; $user_id = $_SESSION['user_id']; // Vérifier que l'utilisateur est un professeur s'il tente d'ajouter un commentaire if ($_SESSION['role'] !== 'prof') { header('Location: index.php?error=not_authorized'); exit; } // Insérer le commentaire $stmt = $pdo->prepare('INSERT INTO commentaires (note_id, user_id, contenu) VALUES (?, ?, ?)'); if ($stmt->execute([$note_id, $user_id, $contenu])) { header('Location: index.php?success=comment_added'); exit; } else { header('Location: index.php?error=comment_failed'); exit; } } // Traitement pour l'ajout d'un examen if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_examen'])) { $titre = $_POST['titre_examen']; $date_debut = $_POST['date_debut']; $date_fin = $_POST['date_fin']; $debut_preparation = $_POST['debut_preparation']; $examens_blancs = $_POST['examens_blancs']; $user_id = $_SESSION['user_id']; $matieres = isset($_POST['matieres']) ? $_POST['matieres'] : []; // Vérifier que la date de fin est après la date de début if (strtotime($date_fin) < strtotime($date_debut)) { header('Location: index.php?error=invalid_dates'); exit; } // Vérifier que la date de début de préparation est avant la date de début d'examen if (strtotime($debut_preparation) > strtotime($date_debut)) { header('Location: index.php?error=invalid_preparation'); exit; } // Insérer l'examen try { $pdo->beginTransaction(); // Insérer l'examen dans la table examens $stmt = $pdo->prepare('INSERT INTO examens (user_id, titre, date_debut, date_fin, debut_preparation, fin_preparation, nombre_examens_blancs) VALUES (?, ?, ?, ?, ?, ?, ?)'); $stmt->execute([ $user_id, $titre, $date_debut, $date_fin, $debut_preparation, $date_debut, // Fin de préparation = début de l'examen $examens_blancs ]); $examen_id = $pdo->lastInsertId(); // Insérer les matières associées à l'examen if (!empty($matieres)) { $stmt = $pdo->prepare('INSERT INTO examen_matieres (examen_id, matiere_id) VALUES (?, ?)'); foreach ($matieres as $matiere_id) { $stmt->execute([$examen_id, $matiere_id]); } } $pdo->commit(); header('Location: index.php?success=examen_added'); exit; } catch (Exception $e) { $pdo->rollBack(); header('Location: index.php?error=examen_failed'); exit; } } // Traitement pour l'ajout d'un examen blanc if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_examen_blanc'])) { $examen_id = $_POST['examen_id']; $titre_blanc = $_POST['titre_blanc']; $date_blanc = $_POST['date_blanc']; $notes = isset($_POST['notes']) ? $_POST['notes'] : []; // Vérifier que l'utilisateur est un élève (admin) s'il tente d'ajouter un examen blanc if ($_SESSION['role'] !== 'eleve') { header('Location: index.php?error=not_authorized'); exit; } // Vérifier que l'examen existe et appartient à l'utilisateur $stmt = $pdo->prepare('SELECT * FROM examens WHERE id = ? AND user_id = ?'); $stmt->execute([$examen_id, $_SESSION['user_id']]); $examen = $stmt->fetch(); if (!$examen) { header('Location: index.php?error=not_found'); exit; } try { $pdo->beginTransaction(); // Insérer l'examen blanc $stmt = $pdo->prepare('INSERT INTO examens_blancs (examen_id, titre, date) VALUES (?, ?, ?)'); $stmt->execute([$examen_id, $titre_blanc, $date_blanc]); $examen_blanc_id = $pdo->lastInsertId(); // Insérer les notes par matière if (!empty($notes)) { $stmt = $pdo->prepare('INSERT INTO examen_blanc_notes (examen_blanc_id, matiere_id, note, max_note) VALUES (?, ?, ?, ?)'); foreach ($notes as $matiere_id => $note_data) { $note = $note_data['note']; $max_note = $note_data['max_note']; // Vérifier que la note ne dépasse pas la note maximale if ($note > $max_note) { $note = $max_note; } $stmt->execute([$examen_blanc_id, $matiere_id, $note, $max_note]); } } $pdo->commit(); header('Location: index.php?success=examen_blanc_added'); exit; } catch (Exception $e) { $pdo->rollBack(); header('Location: index.php?error=examen_blanc_failed'); exit; } } // Si aucune action n'est effectuée, rediriger vers la page d'accueil header('Location: index.php'); exit; db.php 0000644 00000007617 15114743032 0005655 0 ustar 00 <?php $host = 'localhost:3306'; $dbname = 'gqdcvggs_izhak'; $username = 'gqdcvggs'; $password = 'imaors_management.346980*#@-onlyforcpanel;forchange'; $charset = 'utf8mb4'; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; // Connexion PDO try { $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=$charset", $username, $password, $options); } catch (PDOException $e) { die("Erreur de connexion à la base de données : " . $e->getMessage()); } // Création des tables si elles n'existent pas function createTables($pdo) { // Table utilisateurs $pdo->exec("CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(255) NOT NULL, role ENUM('eleve', 'prof') NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )"); // Table matières $pdo->exec("CREATE TABLE IF NOT EXISTS matieres ( id INT AUTO_INCREMENT PRIMARY KEY, nom VARCHAR(100) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )"); // Table notes $pdo->exec("CREATE TABLE IF NOT EXISTS notes ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, matiere_id INT NOT NULL, titre VARCHAR(255) NOT NULL, description TEXT, image_url VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, FOREIGN KEY (matiere_id) REFERENCES matieres(id) ON DELETE CASCADE )"); // Table commentaires $pdo->exec("CREATE TABLE IF NOT EXISTS commentaires ( id INT AUTO_INCREMENT PRIMARY KEY, note_id INT NOT NULL, user_id INT NOT NULL, contenu TEXT NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE )"); // Table examens $pdo->exec("CREATE TABLE IF NOT EXISTS examens ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT NOT NULL, titre VARCHAR(255) NOT NULL, date_debut DATETIME NOT NULL, date_fin DATETIME NOT NULL, debut_preparation DATETIME NOT NULL, fin_preparation DATETIME, nombre_examens_blancs INT DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE )"); // Table matières d'examen $pdo->exec("CREATE TABLE IF NOT EXISTS examen_matieres ( id INT AUTO_INCREMENT PRIMARY KEY, examen_id INT NOT NULL, matiere_id INT NOT NULL, FOREIGN KEY (examen_id) REFERENCES examens(id) ON DELETE CASCADE, FOREIGN KEY (matiere_id) REFERENCES matieres(id) ON DELETE CASCADE )"); // Table examens blancs $pdo->exec("CREATE TABLE IF NOT EXISTS examens_blancs ( id INT AUTO_INCREMENT PRIMARY KEY, examen_id INT NOT NULL, titre VARCHAR(255) NOT NULL, date DATETIME NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (examen_id) REFERENCES examens(id) ON DELETE CASCADE )"); // Table notes des examens blancs $pdo->exec("CREATE TABLE IF NOT EXISTS examen_blanc_notes ( id INT AUTO_INCREMENT PRIMARY KEY, examen_blanc_id INT NOT NULL, matiere_id INT NOT NULL, note DECIMAL(5,2) NOT NULL, max_note DECIMAL(5,2) NOT NULL DEFAULT 100.00, pourcentage DECIMAL(5,2) AS (note * 100 / max_note), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (examen_blanc_id) REFERENCES examens_blancs(id) ON DELETE CASCADE, FOREIGN KEY (matiere_id) REFERENCES matieres(id) ON DELETE CASCADE )"); } // Créer les tables createTables($pdo); index.php 0000644 00000127342 15114743032 0006375 0 ustar 00 <?php require_once 'db.php'; session_start(); $isLoggedIn = isset($_SESSION['user_id']); $userRole = $isLoggedIn ? $_SESSION['role'] : ''; $loginError = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login'])) { $username = $_POST['username']; $password = $_POST['password']; $stmt = $pdo->prepare('SELECT * FROM users WHERE username = ?'); $stmt->execute([$username]); $user = $stmt->fetch(); if ($user && password_verify($password, $user['password'])) { $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; $_SESSION['role'] = $user['role']; header('Location: index.php'); exit; } else { $loginError = 'Identifiants incorrects'; } } $matieres = $pdo->query('SELECT * FROM matieres ORDER BY nom')->fetchAll(); $notes = []; if ($isLoggedIn) { $query = 'SELECT n.*, m.nom as matiere, u.username FROM notes n JOIN matieres m ON n.matiere_id = m.id JOIN users u ON n.user_id = u.id ORDER BY n.created_at DESC'; $notes = $pdo->query($query)->fetchAll(); } $examens = []; if ($isLoggedIn) { $query = 'SELECT * FROM examens WHERE user_id = ? ORDER BY date_debut'; $stmt = $pdo->prepare($query); $stmt->execute([$_SESSION['user_id']]); $examens = $stmt->fetchAll(); foreach ($examens as &$examen) { $query = 'SELECT eb.* FROM examens_blancs eb WHERE eb.examen_id = ?'; $stmt = $pdo->prepare($query); $stmt->execute([$examen['id']]); $examen['examens_blancs'] = $stmt->fetchAll(); $examen['stats'] = [ 'total_blancs' => 0, 'somme_pourcentages' => 0, 'moyenne_pourcentage' => 0, 'statut' => 'Non commencé' ]; foreach ($examen['examens_blancs'] as &$examen_blanc) { $query = 'SELECT ebn.*, m.nom as matiere_nom FROM examen_blanc_notes ebn JOIN matieres m ON ebn.matiere_id = m.id WHERE ebn.examen_blanc_id = ?'; $stmt = $pdo->prepare($query); $stmt->execute([$examen_blanc['id']]); $examen_blanc['notes'] = $stmt->fetchAll(); $total_pourcentage = 0; $nb_notes = count($examen_blanc['notes']); if ($nb_notes > 0) { foreach ($examen_blanc['notes'] as $note) { $total_pourcentage += $note['pourcentage']; } $examen_blanc['pourcentage_moyen'] = $total_pourcentage / $nb_notes; $examen['stats']['total_blancs']++; $examen['stats']['somme_pourcentages'] += $examen_blanc['pourcentage_moyen']; } else { $examen_blanc['pourcentage_moyen'] = 0; } } if ($examen['stats']['total_blancs'] > 0) { $examen['stats']['moyenne_pourcentage'] = $examen['stats']['somme_pourcentages'] / $examen['stats']['total_blancs']; if ($examen['stats']['moyenne_pourcentage'] < 60) { $examen['stats']['statut'] = 'Passation possible mais risquée'; $examen['stats']['couleur'] = 'text-yellow-600 dark:text-yellow-400'; } elseif ($examen['stats']['moyenne_pourcentage'] >= 70) { $examen['stats']['statut'] = 'Super réussite !'; $examen['stats']['couleur'] = 'text-green-600 dark:text-green-400'; } else { $examen['stats']['statut'] = 'En progression'; $examen['stats']['couleur'] = 'text-blue-600 dark:text-blue-400'; } } } } function calculerExamensBlancs($dateDebut, $dateFin) { $debut = new DateTime($dateDebut); $fin = new DateTime($dateFin); $interval = $debut->diff($fin); $jours = 0; for ($i = 0; $i <= $interval->days; $i++) { $jour = (clone $debut)->modify("+$i days"); $jourSemaine = $jour->format('N'); if ($jourSemaine < 6) { $jours++; } } return $jours; } $userCount = $pdo->query('SELECT COUNT(*) FROM users')->fetchColumn(); if ($userCount == 0) { $pdo->exec("INSERT INTO users (username, password, role) VALUES ('eleve', '".password_hash('eleve123', PASSWORD_DEFAULT)."', 'eleve'), ('prof', '".password_hash('prof123', PASSWORD_DEFAULT)."', 'prof')"); $pdo->exec("INSERT INTO matieres (nom) VALUES ('Mathématiques'), ('Français'), ('Histoire'), ('Sciences'), ('Anglais')"); } if (isset($_GET['logout'])) { session_unset(); session_destroy(); header('Location: index.php'); exit; } ?> <!DOCTYPE html> <html lang="fr"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Passage - Gestion de notes et examens</title> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet"> <script src="https://cdn.tailwindcss.com"></script> <script> tailwind.config = { darkMode: 'media', theme: { extend: { fontFamily: { sans: ['Poppins', 'sans-serif'], }, colors: { primary: { 50: '#f5f3ff', 100: '#ede9fe', 200: '#ddd6fe', 300: '#c4b5fd', 400: '#a78bfa', 500: '#8b5cf6', 600: '#7c3aed', 700: '#6d28d9', 800: '#5b21b6', 900: '#4c1d95', }, }, animation: { 'fade-in': 'fadeIn 0.5s ease-out', 'slide-up': 'slideUp 0.5s ease-out', }, keyframes: { fadeIn: { '0%': { opacity: '0' }, '100%': { opacity: '1' }, }, slideUp: { '0%': { transform: 'translateY(20px)', opacity: '0' }, '100%': { transform: 'translateY(0)', opacity: '1' }, }, }, }, }, } </script> <style> .transition-all { transition-property: all; transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); transition-duration: 150ms; } </style> </head> <body class="bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 min-h-screen font-sans"> <div class="container mx-auto px-4 py-8 max-w-6xl"> <header class="flex flex-col md:flex-row justify-between items-center mb-12 animate-fade-in"> <h1 class="text-3xl md:text-4xl font-bold text-primary-600 dark:text-primary-400 mb-4 md:mb-0"> Passage </h1> <?php if ($isLoggedIn): ?> <div class="flex items-center space-x-4"> <span class="text-sm font-medium"> Connecté en tant que <span class="text-primary-600 dark:text-primary-400"><?= htmlspecialchars($_SESSION['username']) ?></span> (<?= $_SESSION['role'] === 'eleve' ? 'Élève' : 'Professeur' ?>) </span> <a href="index.php?logout=1" class="px-4 py-2 bg-red-500 hover:bg-red-600 text-white rounded-lg transition-all"> Déconnexion </a> </div> <?php endif; ?> </header> <main class="animate-slide-up"> <?php if (!$isLoggedIn): ?> <div class="max-w-md mx-auto bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden p-6"> <h2 class="text-xl font-semibold mb-6 text-center">Connexion</h2> <?php if ($loginError): ?> <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"> <?= $loginError ?> </div> <?php endif; ?> <form method="POST" action="index.php"> <div class="mb-4"> <label for="username" class="block text-sm font-medium mb-1">Nom d'utilisateur</label> <input type="text" id="username" name="username" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> <div class="mb-6"> <label for="password" class="block text-sm font-medium mb-1">Mot de passe</label> <input type="password" id="password" name="password" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> <div class="flex justify-between items-center mb-4"> <div class="flex items-center"> <input type="radio" id="role_eleve" name="role" value="eleve" checked class="h-4 w-4 text-primary-600 focus:ring-primary-500"> <label for="role_eleve" class="ml-2 text-sm">Élève (Admin)</label> </div> <div class="flex items-center"> <input type="radio" id="role_prof" name="role" value="prof" class="h-4 w-4 text-primary-600 focus:ring-primary-500"> <label for="role_prof" class="ml-2 text-sm">Professeur</label> </div> </div> <button type="submit" name="login" class="w-full bg-primary-600 hover:bg-primary-700 text-white font-medium py-2 px-4 rounded-lg transition-all"> Se connecter </button> </form> <div class="mt-4 text-sm text-center text-gray-600 dark:text-gray-400"> Utilisateurs par défaut : <div class="grid grid-cols-2 gap-2 mt-2"> <div class="bg-gray-100 dark:bg-gray-700 p-2 rounded"> <p>Élève: eleve</p> <p>Password: eleve123</p> </div> <div class="bg-gray-100 dark:bg-gray-700 p-2 rounded"> <p>Prof: prof</p> <p>Password: prof123</p> </div> </div> </div> </div> <?php else: ?> <div class="grid grid-cols-1 md:grid-cols-3 gap-6"> <div class="md:col-span-2 bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden"> <div class="p-6"> <div class="flex justify-between items-center mb-6"> <h2 class="text-xl font-semibold">Notes de cours</h2> <a href="#" onclick="document.getElementById('modal-note').classList.remove('hidden')" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-all text-sm"> Ajouter une note </a> </div> <?php if (empty($notes)): ?> <p class="text-gray-500 dark:text-gray-400 text-center py-8"> Aucune note disponible. Commencez par en ajouter une ! </p> <?php else: ?> <div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <?php foreach ($notes as $note): ?> <div class="border border-gray-200 dark:border-gray-700 rounded-lg p-4 hover:shadow-md transition-all"> <div class="flex justify-between items-start mb-2"> <h3 class="font-medium"><?= htmlspecialchars($note['titre']) ?></h3> <span class="text-xs bg-primary-100 dark:bg-primary-900 text-primary-800 dark:text-primary-200 px-2 py-1 rounded"> <?= htmlspecialchars($note['matiere']) ?> </span> </div> <?php if ($note['image_url']): ?> <div class="my-2"> <img src="<?= htmlspecialchars($note['image_url']) ?>" alt="Note image" class="w-full h-32 object-cover rounded"> </div> <?php endif; ?> <p class="text-sm text-gray-600 dark:text-gray-400 mb-2"> <?= htmlspecialchars($note['description']) ?> </p> <div class="flex justify-between items-center text-xs text-gray-500 dark:text-gray-400"> <span>Par <?= htmlspecialchars($note['username']) ?></span> <span> <?= date('d/m/Y H:i', strtotime($note['created_at'])) ?> </span> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> </div> </div> <div class="bg-white dark:bg-gray-800 rounded-xl shadow-md overflow-hidden"> <div class="p-6"> <div class="flex justify-between items-center mb-6"> <h2 class="text-xl font-semibold">Examens</h2> <a href="#" onclick="document.getElementById('modal-examen').classList.remove('hidden')" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-all text-sm"> Planifier </a> </div> <?php if (empty($examens)): ?> <p class="text-gray-500 dark:text-gray-400 text-center py-8"> Aucun examen planifié. </p> <?php else: ?> <div class="space-y-4"> <?php foreach ($examens as $examen): ?> <?php $dateDebut = new DateTime($examen['date_debut']); $dateFin = new DateTime($examen['date_fin']); $maintenant = new DateTime(); $status = 'À venir'; $statusClass = 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200'; if ($maintenant > $dateFin) { $status = 'Terminé'; $statusClass = 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-200'; } elseif ($maintenant >= $dateDebut) { $status = 'En cours'; $statusClass = 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'; } ?> <div class="border border-gray-200 dark:border-gray-700 rounded-lg p-4 hover:shadow-md transition-all"> <div class="flex justify-between items-start mb-2"> <h3 class="font-medium"><?= htmlspecialchars($examen['titre']) ?></h3> <span class="text-xs <?= $statusClass ?> px-2 py-1 rounded"> <?= $status ?> </span> </div> <div class="space-y-1 text-sm"> <p> <span class="text-gray-500 dark:text-gray-400">Période:</span> <?= $dateDebut->format('d/m/Y') ?> - <?= $dateFin->format('d/m/Y') ?> </p> <p> <span class="text-gray-500 dark:text-gray-400">Préparation:</span> <?= (new DateTime($examen['debut_preparation']))->format('d/m/Y') ?> - <?= $dateDebut->format('d/m/Y') ?> </p> <p> <span class="text-gray-500 dark:text-gray-400">Examens blancs:</span> <?= count($examen['examens_blancs']) ?> / <?= $examen['nombre_examens_blancs'] ?> </p> <?php if ($examen['stats']['total_blancs'] > 0): ?> <p> <span class="text-gray-500 dark:text-gray-400">Moyenne:</span> <span class="font-medium"><?= number_format($examen['stats']['moyenne_pourcentage'], 1) ?>%</span> </p> <p> <span class="text-gray-500 dark:text-gray-400">Statut:</span> <span class="font-medium <?= $examen['stats']['couleur'] ?>"><?= $examen['stats']['statut'] ?></span> </p> <?php endif; ?> <div class="mt-2"> <a href="#" onclick="document.getElementById('modal-examen-blanc-<?= $examen['id'] ?>').classList.remove('hidden')" class="text-xs px-3 py-1 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-all inline-block"> <?php if (count($examen['examens_blancs']) > 0): ?> Voir détails / Ajouter <?php else: ?> Ajouter un examen blanc <?php endif; ?> </a> </div> </div> </div> <?php endforeach; ?> </div> <?php endif; ?> </div> </div> </div> <div id="modal-note" class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center hidden"> <div class="bg-white dark:bg-gray-800 rounded-xl shadow-xl max-w-md w-full p-6 mx-4"> <h2 class="text-xl font-semibold mb-4">Ajouter une note</h2> <form action="upload.php" method="POST" enctype="multipart/form-data"> <div class="mb-4"> <label for="titre" class="block text-sm font-medium mb-1">Titre</label> <input type="text" id="titre" name="titre" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> <div class="mb-4"> <label for="matiere_id" class="block text-sm font-medium mb-1">Matière</label> <select id="matiere_id" name="matiere_id" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> <?php foreach ($matieres as $matiere): ?> <option value="<?= $matiere['id'] ?>"><?= htmlspecialchars($matiere['nom']) ?></option> <?php endforeach; ?> </select> </div> <div class="mb-4"> <label for="description" class="block text-sm font-medium mb-1">Description</label> <textarea id="description" name="description" rows="3" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"></textarea> </div> <div class="mb-6"> <label for="image" class="block text-sm font-medium mb-1">Image</label> <input type="file" id="image" name="image" accept="image/*" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> <div class="flex justify-end space-x-3"> <button type="button" onclick="document.getElementById('modal-note').classList.add('hidden')" class="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg transition-all"> Annuler </button> <button type="submit" name="add_note" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-all"> Enregistrer </button> </div> </form> </div> </div> <div id="modal-examen" class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center hidden"> <div class="bg-white dark:bg-gray-800 rounded-xl shadow-xl max-w-md w-full p-6 mx-4"> <h2 class="text-xl font-semibold mb-4">Planifier un examen</h2> <form action="upload.php" method="POST"> <div class="mb-4"> <label for="titre_examen" class="block text-sm font-medium mb-1">Intitulé de l'examen</label> <input type="text" id="titre_examen" name="titre_examen" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> <div class="grid grid-cols-2 gap-4 mb-4"> <div> <label for="date_debut" class="block text-sm font-medium mb-1">Date de début</label> <input type="date" id="date_debut" name="date_debut" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> <div> <label for="date_fin" class="block text-sm font-medium mb-1">Date de fin</label> <input type="date" id="date_fin" name="date_fin" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> </div> <div class="mb-4"> <label for="debut_preparation" class="block text-sm font-medium mb-1">Début de la préparation</label> <input type="date" id="debut_preparation" name="debut_preparation" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> <div class="mb-4"> <label class="block text-sm font-medium mb-1">Matières concernées</label> <div class="grid grid-cols-2 gap-2"> <?php foreach ($matieres as $matiere): ?> <div class="flex items-center"> <input type="checkbox" id="matiere_<?= $matiere['id'] ?>" name="matieres[]" value="<?= $matiere['id'] ?>" class="h-4 w-4 text-primary-600 focus:ring-primary-500"> <label for="matiere_<?= $matiere['id'] ?>" class="ml-2 text-sm"> <?= htmlspecialchars($matiere['nom']) ?> </label> </div> <?php endforeach; ?> </div> </div> <div class="mb-6"> <label for="examens_blancs" class="block text-sm font-medium mb-1">Nombre d'examens blancs</label> <input type="number" id="examens_blancs" name="examens_blancs" min="0" value="0" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> <p class="text-xs text-gray-500 mt-1"> Le système suggère <span id="examens_suggeres">0</span> examens blancs selon la durée de préparation. </p> </div> <div class="flex justify-end space-x-3"> <button type="button" onclick="document.getElementById('modal-examen').classList.add('hidden')" class="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg transition-all"> Annuler </button> <button type="submit" name="add_examen" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-all"> Planifier </button> </div> </form> </div> </div> <?php foreach ($examens as $examen): ?> <div id="modal-examen-blanc-<?= $examen['id'] ?>" class="fixed inset-0 bg-black bg-opacity-50 z-50 flex items-center justify-center hidden"> <div class="bg-white dark:bg-gray-800 rounded-xl shadow-xl max-w-3xl w-full p-6 mx-4 max-h-[90vh] overflow-y-auto"> <div class="flex justify-between items-center mb-4"> <h2 class="text-xl font-semibold">Examens blancs - <?= htmlspecialchars($examen['titre']) ?></h2> <button type="button" onclick="document.getElementById('modal-examen-blanc-<?= $examen['id'] ?>').classList.add('hidden')" class="p-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"> <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> <?php if ($examen['stats']['total_blancs'] > 0): ?> <div class="bg-gray-100 dark:bg-gray-700 p-4 rounded-lg mb-4"> <h3 class="font-medium mb-2">Statistiques globales</h3> <div class="grid grid-cols-3 gap-4"> <div> <p class="text-sm text-gray-500 dark:text-gray-400">Examens passés</p> <p class="font-medium text-lg"><?= $examen['stats']['total_blancs'] ?> / <?= $examen['nombre_examens_blancs'] ?></p> </div> <div> <p class="text-sm text-gray-500 dark:text-gray-400">Moyenne</p> <p class="font-medium text-lg"><?= number_format($examen['stats']['moyenne_pourcentage'], 1) ?>%</p> </div> <div> <p class="text-sm text-gray-500 dark:text-gray-400">Statut</p> <p class="font-medium <?= $examen['stats']['couleur'] ?>"><?= $examen['stats']['statut'] ?></p> </div> </div> </div> <?php endif; ?> <?php if (count($examen['examens_blancs']) > 0): ?> <div class="mb-6"> <h3 class="font-medium mb-3">Examens blancs passés</h3> <div class="space-y-4"> <?php foreach ($examen['examens_blancs'] as $index => $examen_blanc): ?> <div class="border border-gray-200 dark:border-gray-700 p-4 rounded-lg"> <div class="flex justify-between items-center mb-3"> <h4 class="font-medium"><?= htmlspecialchars($examen_blanc['titre']) ?></h4> <div class="flex items-center"> <span class="text-sm mr-2"> <?= date('d/m/Y', strtotime($examen_blanc['date'])) ?> </span> <span class="text-sm font-medium px-2 py-1 rounded-full <?php if ($examen_blanc['pourcentage_moyen'] >= 70) echo 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'; elseif ($examen_blanc['pourcentage_moyen'] >= 60) echo 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200'; else echo 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200'; ?>"> <?= number_format($examen_blanc['pourcentage_moyen'], 1) ?>% </span> </div> </div> <div class="grid grid-cols-1 md:grid-cols-2 gap-2"> <?php foreach ($examen_blanc['notes'] as $note): ?> <div class="flex justify-between items-center text-sm bg-gray-50 dark:bg-gray-700 p-2 rounded"> <span><?= htmlspecialchars($note['matiere_nom']) ?></span> <div> <span class="font-medium"><?= $note['note'] ?>/<?= $note['max_note'] ?></span> <span class="ml-1 px-1.5 py-0.5 rounded-full text-xs <?php if ($note['pourcentage'] >= 70) echo 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200'; elseif ($note['pourcentage'] >= 60) echo 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200'; else echo 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200'; ?>"> <?= number_format($note['pourcentage'], 1) ?>% </span> </div> </div> <?php endforeach; ?> </div> </div> <?php endforeach; ?> </div> </div> <?php endif; ?> <div> <h3 class="font-medium mb-3">Ajouter un nouvel examen blanc</h3> <form action="upload.php" method="POST"> <input type="hidden" name="examen_id" value="<?= $examen['id'] ?>"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4"> <div> <label for="titre_blanc_<?= $examen['id'] ?>" class="block text-sm font-medium mb-1">Titre</label> <input type="text" id="titre_blanc_<?= $examen['id'] ?>" name="titre_blanc" required value="Examen Blanc #<?= count($examen['examens_blancs']) + 1 ?>" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> <div> <label for="date_blanc_<?= $examen['id'] ?>" class="block text-sm font-medium mb-1">Date</label> <input type="date" id="date_blanc_<?= $examen['id'] ?>" name="date_blanc" required value="<?= date('Y-m-d') ?>" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> </div> <div class="mb-4"> <h4 class="text-sm font-medium mb-2">Notes par matière</h4> <?php $query = 'SELECT m.* FROM examen_matieres em JOIN matieres m ON em.matiere_id = m.id WHERE em.examen_id = ?'; $stmt = $pdo->prepare($query); $stmt->execute([$examen['id']]); $examen_matieres = $stmt->fetchAll(); if (empty($examen_matieres)) { $examen_matieres = $matieres; } ?> <div class="space-y-2"> <?php foreach ($examen_matieres as $matiere): ?> <div class="grid grid-cols-2 gap-2 items-center"> <label for="note_<?= $examen['id'] ?>_<?= $matiere['id'] ?>" class="text-sm"> <?= htmlspecialchars($matiere['nom']) ?> </label> <div class="flex"> <input type="number" id="note_<?= $examen['id'] ?>_<?= $matiere['id'] ?>" name="notes[<?= $matiere['id'] ?>][note]" step="0.01" min="0" max="100" required placeholder="Note" class="w-1/2 px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-l-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> <input type="number" id="max_note_<?= $examen['id'] ?>_<?= $matiere['id'] ?>" name="notes[<?= $matiere['id'] ?>][max_note]" step="0.01" min="1" value="100" required placeholder="Max" class="w-1/2 px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-r-lg focus:outline-none focus:ring-2 focus:ring-primary-500 dark:bg-gray-700"> </div> </div> <?php endforeach; ?> </div> </div> <div class="flex justify-end"> <button type="submit" name="add_examen_blanc" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-lg transition-all"> Enregistrer les résultats </button> </div> </form> </div> </div> </div> <?php endforeach; ?> <?php endif; ?> </main> </div> <script> document.addEventListener('DOMContentLoaded', function() { const dateDebutInput = document.getElementById('date_debut'); const debutPreparationInput = document.getElementById('debut_preparation'); const examensBlancsSuggeres = document.getElementById('examens_suggeres'); const examensBlancsInput = document.getElementById('examens_blancs'); function updateExamensBlancs() { if (dateDebutInput && debutPreparationInput && dateDebutInput.value && debutPreparationInput.value) { const dateDebut = new Date(dateDebutInput.value); const debutPreparation = new Date(debutPreparationInput.value); let jours = 0; const currentDate = new Date(debutPreparation); while (currentDate < dateDebut) { const jourSemaine = currentDate.getDay(); if (jourSemaine !== 0 && jourSemaine !== 6) { jours++; } currentDate.setDate(currentDate.getDate() + 1); } const nbMatieresSelectionnees = document.querySelectorAll('input[name="matieres[]"]:checked').length; const suggestion = Math.max(Math.floor(jours / 5), nbMatieresSelectionnees || 1); if (examensBlancsSuggeres) examensBlancsSuggeres.textContent = suggestion; if (examensBlancsInput) examensBlancsInput.value = suggestion; } } if (dateDebutInput && debutPreparationInput) { dateDebutInput.addEventListener('change', updateExamensBlancs); debutPreparationInput.addEventListener('change', updateExamensBlancs); const matiereCheckboxes = document.querySelectorAll('input[name="matieres[]"]'); matiereCheckboxes.forEach(checkbox => { checkbox.addEventListener('change', updateExamensBlancs); }); } }); </script> </body> </html>