779 lines
27 KiB
PHP
779 lines
27 KiB
PHP
<?php
|
||
/**
|
||
* Tableau de bord enseignant
|
||
* Fichier : dashboard_enseignant.php
|
||
*/
|
||
|
||
require_once __DIR__ . '/../config/database.php';
|
||
require_once __DIR__ . '/../config/session.php';
|
||
|
||
// Vérifier que l'utilisateur est connecté et est un enseignant
|
||
// if (!SessionManager::isEnseignant()) {
|
||
// header('Location: ../login.php?error=session');
|
||
// exit();
|
||
// }
|
||
|
||
$user = SessionManager::getUser();
|
||
|
||
try {
|
||
$db = Database::getInstance()->getConnection();
|
||
|
||
// Récupérer les statistiques globales
|
||
$stmt = $db->query("
|
||
SELECT
|
||
(SELECT COUNT(*) FROM utilisateurs WHERE id_type IN (2,3)) as nb_eleves,
|
||
(SELECT COUNT(*) FROM classes WHERE actif = 1) as nb_classes,
|
||
(SELECT COUNT(*) FROM utilisateurs WHERE id_type = 1) as nb_enseignants,
|
||
(SELECT COUNT(*) FROM evaluations WHERE actif = 1) as nb_evaluations_actives,
|
||
(SELECT COUNT(*) FROM evaluations) as nb_evaluations_total
|
||
");
|
||
$stats = $stmt->fetch();
|
||
|
||
// Récupérer les évaluations récentes
|
||
$stmt = $db->query("
|
||
SELECT
|
||
e.id_evaluation,
|
||
e.titre,
|
||
e.type,
|
||
e.actif,
|
||
e.duree_minutes,
|
||
e.note_totale,
|
||
COUNT(DISTINCT q.id_question) as nb_questions,
|
||
COUNT(DISTINCT t.id_eleve) as nb_participants
|
||
FROM evaluations e
|
||
LEFT JOIN questions q ON e.id_evaluation = q.id_evaluation
|
||
LEFT JOIN tentatives_eleves t ON e.id_evaluation = t.id_evaluation
|
||
GROUP BY e.id_evaluation
|
||
ORDER BY e.id_evaluation DESC
|
||
LIMIT 5
|
||
");
|
||
$evaluations_recentes = $stmt->fetchAll();
|
||
|
||
// Récupérer la liste des classes avec le nombre d'élèves
|
||
$stmt = $db->query("
|
||
SELECT
|
||
c.id_classe,
|
||
c.nom_classe,
|
||
c.niveau,
|
||
c.type_classe,
|
||
COUNT(u.id_utilisateur) as nb_eleves
|
||
FROM classes c
|
||
LEFT JOIN utilisateurs u ON c.id_classe = u.id_classe AND u.actif = 1
|
||
WHERE c.actif = 1
|
||
GROUP BY c.id_classe
|
||
ORDER BY c.niveau, c.nom_classe
|
||
");
|
||
$classes = $stmt->fetchAll();
|
||
|
||
// Récupérer les dernières connexions
|
||
$stmt = $db->query("
|
||
SELECT
|
||
u.login,
|
||
u.nom,
|
||
u.prenom,
|
||
c.nom_classe,
|
||
u.date_derniere_connexion
|
||
FROM utilisateurs u
|
||
LEFT JOIN classes c ON u.id_classe = c.id_classe
|
||
WHERE u.id_type IN (2,3) AND u.date_derniere_connexion IS NOT NULL
|
||
ORDER BY u.date_derniere_connexion DESC
|
||
LIMIT 10
|
||
");
|
||
$dernieres_connexions = $stmt->fetchAll();
|
||
|
||
} catch (PDOException $e) {
|
||
error_log("Erreur dashboard enseignant : " . $e->getMessage());
|
||
$stats = ['nb_eleves' => 0, 'nb_classes' => 0, 'nb_enseignants' => 0, 'nb_evaluations_actives' => 0, 'nb_evaluations_total' => 0];
|
||
$classes = [];
|
||
$evaluations_recentes = [];
|
||
$dernieres_connexions = [];
|
||
}
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="fr">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||
<meta name="theme-color" content="#1976d2">
|
||
<title>Dashboard Enseignant - <?= htmlspecialchars($user['prenom']) ?></title>
|
||
<style>
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
|
||
background: #f5f5f5;
|
||
padding-bottom: 20px;
|
||
}
|
||
|
||
/* Header */
|
||
.header {
|
||
background: linear-gradient(135deg, #1976d2 0%, #1565c0 100%);
|
||
color: white;
|
||
padding: 20px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
}
|
||
|
||
.header-top {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.header h1 {
|
||
font-size: 22px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.btn-logout {
|
||
background: rgba(255, 255, 255, 0.2);
|
||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||
color: white;
|
||
padding: 8px 15px;
|
||
border-radius: 8px;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
text-decoration: none;
|
||
display: inline-block;
|
||
}
|
||
|
||
.user-info {
|
||
background: rgba(255, 255, 255, 0.15);
|
||
padding: 15px;
|
||
border-radius: 10px;
|
||
backdrop-filter: blur(10px);
|
||
}
|
||
|
||
.user-info p {
|
||
margin: 5px 0;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.user-info strong {
|
||
font-weight: 600;
|
||
}
|
||
|
||
/* Container */
|
||
.container {
|
||
padding: 20px;
|
||
max-width: 1200px;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
/* Cartes de statistiques */
|
||
.stats-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||
gap: 15px;
|
||
margin-bottom: 30px;
|
||
}
|
||
|
||
.stat-card {
|
||
background: white;
|
||
padding: 25px;
|
||
border-radius: 15px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
|
||
text-align: center;
|
||
transition: transform 0.2s;
|
||
}
|
||
|
||
.stat-card:hover {
|
||
transform: translateY(-5px);
|
||
}
|
||
|
||
.stat-card .icon {
|
||
font-size: 36px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.stat-card .value {
|
||
font-size: 32px;
|
||
font-weight: 700;
|
||
color: #1976d2;
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
.stat-card .label {
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
/* Section */
|
||
.section {
|
||
background: white;
|
||
border-radius: 15px;
|
||
padding: 25px;
|
||
margin-bottom: 20px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.08);
|
||
}
|
||
|
||
.section h2 {
|
||
font-size: 20px;
|
||
margin-bottom: 20px;
|
||
color: #333;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
}
|
||
|
||
/* Table */
|
||
.table-responsive {
|
||
overflow-x: auto;
|
||
}
|
||
|
||
table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
}
|
||
|
||
th, td {
|
||
padding: 12px;
|
||
text-align: left;
|
||
border-bottom: 1px solid #eee;
|
||
}
|
||
|
||
th {
|
||
background: #f8f9fa;
|
||
font-weight: 600;
|
||
color: #333;
|
||
font-size: 14px;
|
||
}
|
||
|
||
td {
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
|
||
tr:hover {
|
||
background: #f8f9fa;
|
||
}
|
||
|
||
.badge {
|
||
display: inline-block;
|
||
padding: 4px 12px;
|
||
border-radius: 12px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.badge-primary {
|
||
background: #e3f2fd;
|
||
color: #1976d2;
|
||
}
|
||
|
||
.badge-success {
|
||
background: #e8f5e9;
|
||
color: #2e7d32;
|
||
}
|
||
|
||
.badge-warning {
|
||
background: #fff3e0;
|
||
color: #f57c00;
|
||
}
|
||
|
||
.badge-secondary {
|
||
background: #f5f5f5;
|
||
color: #666;
|
||
}
|
||
|
||
/* Boutons d'action */
|
||
.action-buttons {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||
gap: 15px;
|
||
}
|
||
|
||
.btn {
|
||
padding: 15px 20px;
|
||
border-radius: 12px;
|
||
text-decoration: none;
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
transition: all 0.2s;
|
||
border: none;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8px;
|
||
text-align: center;
|
||
}
|
||
|
||
.btn:hover {
|
||
transform: translateY(-3px);
|
||
box-shadow: 0 5px 15px rgba(0,0,0,0.15);
|
||
}
|
||
|
||
.btn-primary {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
color: white;
|
||
}
|
||
|
||
.btn-success {
|
||
background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
|
||
color: white;
|
||
}
|
||
|
||
.btn-info {
|
||
background: linear-gradient(135deg, #2196F3 0%, #1976D2 100%);
|
||
color: white;
|
||
}
|
||
|
||
.btn-secondary {
|
||
background: #f5f5f5;
|
||
color: #333;
|
||
border: 2px solid #e0e0e0;
|
||
}
|
||
|
||
.btn-sm {
|
||
padding: 6px 12px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
/* Temps relatif */
|
||
.time-relative {
|
||
color: #999;
|
||
font-size: 12px;
|
||
}
|
||
|
||
/* Empty state */
|
||
.empty-state {
|
||
text-align: center;
|
||
padding: 40px;
|
||
color: #999;
|
||
}
|
||
|
||
.empty-state .icon {
|
||
font-size: 48px;
|
||
margin-bottom: 15px;
|
||
opacity: 0.5;
|
||
}
|
||
|
||
/* Evaluation card */
|
||
.eval-card {
|
||
border: 2px solid #e0e0e0;
|
||
border-radius: 10px;
|
||
padding: 15px;
|
||
margin-bottom: 15px;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.eval-card:hover {
|
||
border-color: #667eea;
|
||
box-shadow: 0 3px 10px rgba(102, 126, 234, 0.2);
|
||
}
|
||
|
||
.eval-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: start;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.eval-title {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: #333;
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
.eval-meta {
|
||
display: flex;
|
||
gap: 15px;
|
||
flex-wrap: wrap;
|
||
font-size: 13px;
|
||
color: #666;
|
||
}
|
||
|
||
.eval-actions {
|
||
display: flex;
|
||
gap: 8px;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
/* Responsive */
|
||
@media (max-width: 768px) {
|
||
.container {
|
||
padding: 10px;
|
||
}
|
||
|
||
.stats-grid {
|
||
grid-template-columns: repeat(2, 1fr);
|
||
}
|
||
|
||
.action-buttons {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
table {
|
||
font-size: 12px;
|
||
}
|
||
|
||
th, td {
|
||
padding: 8px;
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<!-- Header -->
|
||
<div class="header">
|
||
<div class="header-top">
|
||
<h1>👨🏫 Dashboard Enseignant</h1>
|
||
<a href="../logout.php" class="btn-logout">Déconnexion</a>
|
||
</div>
|
||
<div class="user-info">
|
||
<p><strong><?= htmlspecialchars($user['prenom'] . ' ' . $user['nom']) ?></strong></p>
|
||
<p>🎓 Enseignant de Mathématiques</p>
|
||
<p>Login : <?= htmlspecialchars($user['login']) ?></p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Container principal -->
|
||
<div class="container">
|
||
<!-- Statistiques globales -->
|
||
<div class="stats-grid">
|
||
<div class="stat-card">
|
||
<div class="icon">👥</div>
|
||
<div class="value"><?= $stats['nb_eleves'] ?></div>
|
||
<div class="label">Élèves</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="icon">🏫</div>
|
||
<div class="value"><?= $stats['nb_classes'] ?></div>
|
||
<div class="label">Classes</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="icon">📝</div>
|
||
<div class="value"><?= $stats['nb_evaluations_actives'] ?></div>
|
||
<div class="label">Évaluations actives</div>
|
||
</div>
|
||
<div class="stat-card">
|
||
<div class="icon">📚</div>
|
||
<div class="value"><?= $stats['nb_evaluations_total'] ?></div>
|
||
<div class="label">Total évaluations</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Actions rapides -->
|
||
<div class="section">
|
||
<h2>⚡ Gestion des évaluations</h2>
|
||
<div class="action-buttons">
|
||
<a href="../importer_evaluation.php" class="btn btn-primary">
|
||
📥 Importer une évaluation
|
||
</a>
|
||
<a href="#liste-evaluations" class="btn btn-info">
|
||
📋 Voir toutes les évaluations
|
||
</a>
|
||
<a href="statistiques/index.php" class="btn btn-secondary">
|
||
📊 Statistiques détaillées
|
||
</a>
|
||
<a href="chatbot_api_settings.php" class="btn btn-secondary">
|
||
🤖 Configuration IA Chatbot
|
||
</a>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Évaluations récentes -->
|
||
<div class="section" id="liste-evaluations">
|
||
<h2>📝 Évaluations récentes</h2>
|
||
<?php if (count($evaluations_recentes) > 0): ?>
|
||
<?php foreach ($evaluations_recentes as $eval): ?>
|
||
<div class="eval-card">
|
||
<div class="eval-header">
|
||
<div>
|
||
<div class="eval-title"><?= htmlspecialchars($eval['titre']) ?></div>
|
||
<div class="eval-meta">
|
||
<span>📋 <?= $eval['nb_questions'] ?> question(s)</span>
|
||
<span>⏱️ <?= $eval['duree_minutes'] ?> min</span>
|
||
<span>📊 <?= $eval['note_totale'] ?> pts</span>
|
||
<span>👥 <?= $eval['nb_participants'] ?> participant(s)</span>
|
||
</div>
|
||
</div>
|
||
<span class="badge <?= $eval['actif'] ? 'badge-success' : 'badge-secondary' ?>">
|
||
<?= $eval['actif'] ? '✓ Active' : '✕ Inactive' ?>
|
||
</span>
|
||
</div>
|
||
<div class="eval-actions">
|
||
<a href="../gerer_evaluation.php?id=<?= $eval['id_evaluation'] ?>" class="btn btn-primary btn-sm">
|
||
⚙️ Gérer
|
||
</a>
|
||
<a href="../resultat_evaluation.php?id=<?= $eval['id_evaluation'] ?>" class="btn btn-info btn-sm">
|
||
📊 Résultats
|
||
</a>
|
||
<a href="monitoring.php?id_evaluation=<?= $eval['id_evaluation'] ?>"
|
||
class="btn btn-primary btn-sm"
|
||
title="Monitoring temps réel">
|
||
📊 Monitoring
|
||
</a>
|
||
<a href="../passer_evaluation.php?id_evaluation=<?= $eval['id_evaluation'] ?>&apercu=1" target="_blank" class="btn btn-secondary btn-sm">
|
||
👁️ Aperçu
|
||
</a>
|
||
<a href="export.php?id_evaluation=<?= $eval['id_evaluation'] ?>&format=csv"
|
||
class="btn btn-success btn-sm"
|
||
title="Télécharger CSV (Excel)">
|
||
📥 CSV
|
||
</a>
|
||
<a href="export.php?id_evaluation=<?= $eval['id_evaluation'] ?>&format=json"
|
||
class="btn btn-warning btn-sm"
|
||
title="Télécharger JSON (Archive)">
|
||
📥 JSON
|
||
</a>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
<?php else: ?>
|
||
<div class="empty-state">
|
||
<div class="icon">📝</div>
|
||
<p>Aucune évaluation créée</p>
|
||
<p style="margin-top: 10px;">
|
||
<a href="../importer_evaluation.php" class="btn btn-primary">
|
||
📥 Importer votre première évaluation
|
||
</a>
|
||
</p>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<!-- Actions secondaires -->
|
||
<div class="section">
|
||
<h2>⚡ Autres actions</h2>
|
||
<div class="action-buttons">
|
||
<button class="btn btn-secondary" disabled title="Fonctionnalité en développement">➕ Ajouter un élève</button>
|
||
<button class="btn btn-secondary" disabled title="Fonctionnalité en développement">📝 Créer un exercice</button>
|
||
<button class="btn btn-secondary" disabled title="Fonctionnalité en développement">⚙️ Paramètres</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Liste des classes -->
|
||
<div class="section">
|
||
<h2>🏫 Mes classes</h2>
|
||
<div class="table-responsive">
|
||
<?php if (count($classes) > 0): ?>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Classe</th>
|
||
<th>Niveau</th>
|
||
<th>Type</th>
|
||
<th>Élèves</th>
|
||
<th>Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($classes as $classe): ?>
|
||
<tr>
|
||
<td><strong><?= htmlspecialchars($classe['nom_classe']) ?></strong></td>
|
||
<td><?= htmlspecialchars($classe['niveau']) ?></td>
|
||
<td>
|
||
<span class="badge <?= $classe['type_classe'] == 'reguliere' ? 'badge-primary' : 'badge-secondary' ?>">
|
||
<?= ucfirst($classe['type_classe']) ?>
|
||
</span>
|
||
</td>
|
||
<td><?= $classe['nb_eleves'] ?> élève(s)</td>
|
||
<td>
|
||
<button class="btn btn-primary btn-sm" onclick="voirEleves(<?php echo $classe['id_classe']; ?>, '<?php echo htmlspecialchars($classe['nom_classe'], ENT_QUOTES); ?>')">👥 Voir</button>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
<?php else: ?>
|
||
<div class="empty-state">
|
||
<div class="icon">📚</div>
|
||
<p>Aucune classe active</p>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Dernières connexions -->
|
||
<div class="section">
|
||
<h2>🕒 Dernières connexions</h2>
|
||
<div class="table-responsive">
|
||
<?php if (count($dernieres_connexions) > 0): ?>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Élève</th>
|
||
<th>Classe</th>
|
||
<th>Dernière connexion</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($dernieres_connexions as $connexion): ?>
|
||
<tr>
|
||
<td>
|
||
<strong><?= htmlspecialchars($connexion['prenom'] . ' ' . $connexion['nom']) ?></strong>
|
||
<div class="time-relative"><?= htmlspecialchars($connexion['login']) ?></div>
|
||
</td>
|
||
<td><?= htmlspecialchars($connexion['nom_classe'] ?? '-') ?></td>
|
||
<td>
|
||
<?php
|
||
$date = new DateTime($connexion['date_derniere_connexion']);
|
||
echo $date->format('d/m/Y à H:i');
|
||
?>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
<?php else: ?>
|
||
<div class="empty-state">
|
||
<div class="icon">👤</div>
|
||
<p>Aucune connexion récente</p>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// Renouvellement automatique de la session
|
||
setInterval(() => {
|
||
fetch('api/renew_session.php', { method: 'POST' })
|
||
.catch(err => console.error('Erreur renouvellement:', err));
|
||
}, 600000); // Toutes les 10 minutes
|
||
</script>
|
||
|
||
<!-- Modal pour voir les élèves -->
|
||
<div id="modalEleves" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1000;">
|
||
<div style="background: white; margin: 50px auto; max-width: 800px; border-radius: 10px; padding: 30px; max-height: 80vh; overflow-y: auto;">
|
||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
|
||
<h2 id="modalTitre" style="margin: 0;">Liste des élèves</h2>
|
||
<button onclick="fermerModal()" style="background: #e74c3c; color: white; border: none; padding: 10px 15px; border-radius: 5px; cursor: pointer;">✕ Fermer</button>
|
||
</div>
|
||
<div id="modalContenu">
|
||
<div style="text-align: center; padding: 40px;">
|
||
<p>Chargement des élèves...</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
function voirEleves(idClasse, nomClasse) {
|
||
document.getElementById('modalEleves').style.display = 'block';
|
||
document.getElementById('modalTitre').textContent = 'Élèves de ' + nomClasse;
|
||
|
||
fetch('get_eleves_classe.php?id_classe=' + idClasse)
|
||
.then(response => {
|
||
console.log('Réponse get_eleves_classe:', response);
|
||
if (!response.ok) {
|
||
console.error('Erreur HTTP:', response.status);
|
||
}
|
||
return response.text();
|
||
})
|
||
.then(text => {
|
||
console.log('Contenu brut:', text.substring(0, 200));
|
||
return JSON.parse(text);
|
||
})
|
||
.then(data => {
|
||
if (data.success) {
|
||
afficherEleves(data.eleves);
|
||
} else {
|
||
document.getElementById('modalContenu').innerHTML = '<div class="alert alert-danger">Erreur : ' + data.message + '</div>';
|
||
}
|
||
})
|
||
.catch(error => {
|
||
document.getElementById('modalContenu').innerHTML = '<div class="alert alert-danger">Erreur : ' + error.message + '</div>';
|
||
});
|
||
}
|
||
|
||
function afficherEleves(eleves) {
|
||
if (eleves.length === 0) {
|
||
document.getElementById('modalContenu').innerHTML = '<div class="alert alert-info">Aucun élève dans cette classe</div>';
|
||
return;
|
||
}
|
||
|
||
// Message mot de passe en haut
|
||
let html = '<div class="alert alert-info mb-3">';
|
||
html += '<strong>🔑 Mot de passe par défaut :</strong> <code class="bg-white text-dark px-2 py-1" style="font-size: 1.1em;">eleve2025</code>';
|
||
html += '<p class="mb-0 mt-2"><small>Ce mot de passe est utilisé pour tous les élèves lors de l\'import.</small></p>';
|
||
html += '</div>';
|
||
|
||
// Tableau avec colonne mot de passe
|
||
html += '<table class="table table-striped"><thead><tr><th>Login</th><th>Nom</th><th>Prénom</th><th>Mot de passe</th><th>Statut</th><th>Actions</th></tr></thead><tbody>';
|
||
|
||
eleves.forEach(eleve => {
|
||
let statut = eleve.actif == 1 ? '<span class="badge badge-success">Actif</span>' : '<span class="badge badge-secondary">Inactif</span>';
|
||
html += '<tr>';
|
||
html += '<td><code>' + eleve.login + '</code></td>';
|
||
html += '<td>' + eleve.nom + '</td>';
|
||
html += '<td>' + eleve.prenom + '</td>';
|
||
html += '<td><code class="text-primary">eleve2025</code></td>';
|
||
html += '<td>' + statut + '</td>';
|
||
html += '<td><button class="btn btn-sm btn-warning" onclick="resetMotDePasse(' + eleve.id_utilisateur + ', \'' + eleve.login + '\', \'' + eleve.prenom + ' ' + eleve.nom + '\')">🔄 Reset</button></td>';
|
||
html += '</tr>';
|
||
});
|
||
|
||
html += '</tbody></table><p class="text-muted"><strong>Total :</strong> ' + eleves.length + ' élève(s)</p>';
|
||
document.getElementById('modalContenu').innerHTML = html;
|
||
}
|
||
|
||
function fermerModal() {
|
||
document.getElementById('modalEleves').style.display = 'none';
|
||
}
|
||
|
||
function resetMotDePasse(idEleve, login, nomComplet) {
|
||
if (!confirm('Réinitialiser le mot de passe de ' + nomComplet + ' (login: ' + login + ') ?\n\nLe mot de passe sera remis à la valeur par défaut.')) {
|
||
return;
|
||
}
|
||
|
||
// Afficher loader
|
||
const btn = event.target;
|
||
const textOriginal = btn.innerHTML;
|
||
btn.innerHTML = '⏳';
|
||
btn.disabled = true;
|
||
|
||
// Appel AJAX
|
||
fetch('../api/reset_password_eleve.php', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/x-www-form-urlencoded',
|
||
},
|
||
credentials: 'include',
|
||
body: 'id_eleve=' + idEleve
|
||
})
|
||
.then(response => {
|
||
console.log('Réponse reset_password:', response);
|
||
if (!response.ok) {
|
||
console.error('Erreur HTTP:', response.status);
|
||
}
|
||
return response.text();
|
||
})
|
||
.then(text => {
|
||
console.log('Contenu brut reset:', text.substring(0, 200));
|
||
return JSON.parse(text);
|
||
})
|
||
.then(data => {
|
||
btn.innerHTML = textOriginal;
|
||
btn.disabled = false;
|
||
|
||
if (data.success) {
|
||
alert('✅ Mot de passe réinitialisé avec succès !\n\nLogin: ' + data.data.login + '\nNouveau mot de passe: ' + data.data.nouveau_mdp);
|
||
// Rafraîchir la liste si besoin
|
||
} else {
|
||
alert('❌ Erreur: ' + data.message);
|
||
}
|
||
})
|
||
.catch(error => {
|
||
btn.innerHTML = textOriginal;
|
||
btn.disabled = false;
|
||
alert('❌ Erreur de communication avec le serveur');
|
||
console.error('Erreur:', error);
|
||
});
|
||
}
|
||
|
||
document.addEventListener('click', function(event) {
|
||
const modal = document.getElementById('modalEleves');
|
||
if (event.target === modal) fermerModal();
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|