Initial commit (code), runtime ignoré, secrets exclus
This commit is contained in:
450
eleve/dashboard.php
Normal file
450
eleve/dashboard.php
Normal file
@ -0,0 +1,450 @@
|
||||
<?php
|
||||
/**
|
||||
* Dashboard élève (classe fixe + libre)
|
||||
* Fichier : eleve/dashboard.php
|
||||
*/
|
||||
|
||||
require_once __DIR__ . '/../config/config.php';
|
||||
require_once __DIR__ . '/../config/database.php';
|
||||
|
||||
// Vérifier l'authentification
|
||||
if (!isLoggedIn()) {
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$user = currentUser();
|
||||
|
||||
// Vérifier que c'est bien un élève
|
||||
if (!isEleve()) {
|
||||
header('Location: ../login.php');
|
||||
exit;
|
||||
}
|
||||
|
||||
$db = Database::getInstance();
|
||||
|
||||
// Déterminer le type d'élève
|
||||
$isEleveLibre = ($user['id_type'] == 3);
|
||||
$isEleveClasse = ($user['id_type'] == 2);
|
||||
|
||||
// Récupérer les évaluations disponibles
|
||||
if ($isEleveLibre) {
|
||||
// Élève libre : évaluations de type soutien uniquement
|
||||
$queryEvals = "SELECT DISTINCT e.*,
|
||||
COALESCE(t.statut, 'non_commence') as statut_tentative,
|
||||
t.note as note_obtenue,
|
||||
t.date_debut as date_tentative
|
||||
FROM evaluations e
|
||||
INNER JOIN acces_evaluations ae ON e.id_evaluation = ae.id_evaluation
|
||||
INNER JOIN classes c ON ae.id_classe = c.id_classe
|
||||
LEFT JOIN tentatives_eleves t ON e.id_evaluation = t.id_evaluation
|
||||
AND t.id_eleve = ?
|
||||
WHERE c.type_classe = 'soutien'
|
||||
AND ae.actif = 1
|
||||
AND NOW() BETWEEN ae.date_debut AND ae.date_fin
|
||||
AND e.actif = 1
|
||||
ORDER BY ae.date_fin ASC, e.titre ASC";
|
||||
|
||||
$evaluations = $db->fetchAll($queryEvals, [$user['id_utilisateur']]);
|
||||
|
||||
} else {
|
||||
// Élève classe fixe : évaluations de sa classe
|
||||
if ($user['id_classe']) {
|
||||
$queryEvals = "SELECT DISTINCT e.*,
|
||||
ae.date_debut as debut_acces,
|
||||
ae.date_fin as fin_acces,
|
||||
COALESCE(t.statut, 'non_commence') as statut_tentative,
|
||||
t.note as note_obtenue,
|
||||
t.date_debut as date_tentative
|
||||
FROM evaluations e
|
||||
INNER JOIN acces_evaluations ae ON e.id_evaluation = ae.id_evaluation
|
||||
LEFT JOIN tentatives_eleves t ON e.id_evaluation = t.id_evaluation
|
||||
AND t.id_eleve = ?
|
||||
WHERE ae.id_classe = ?
|
||||
AND ae.actif = 1
|
||||
AND NOW() BETWEEN ae.date_debut AND ae.date_fin
|
||||
AND e.actif = 1
|
||||
ORDER BY ae.date_fin ASC, e.titre ASC";
|
||||
|
||||
$evaluations = $db->fetchAll($queryEvals, [$user['id_utilisateur'], $user['id_classe']]);
|
||||
} else {
|
||||
$evaluations = [];
|
||||
}
|
||||
}
|
||||
|
||||
// Récupérer les statistiques de l'élève
|
||||
$queryStats = "SELECT
|
||||
COUNT(DISTINCT t.id_evaluation) as nb_evaluations_passees,
|
||||
COUNT(CASE WHEN t.statut = 'terminee' THEN 1 END) as nb_evaluations_terminees,
|
||||
AVG(
|
||||
CASE WHEN t.statut = 'terminee'
|
||||
THEN CEILING((t.note / e.note_totale * 20) * 2) / 2
|
||||
ELSE NULL END
|
||||
) as moyenne_generale
|
||||
FROM tentatives_eleves t
|
||||
INNER JOIN evaluations e ON t.id_evaluation = e.id_evaluation
|
||||
WHERE t.id_eleve = ?";
|
||||
|
||||
$stats = $db->fetchOne($queryStats, [$user['id_utilisateur']]) ?? [
|
||||
'nb_evaluations_passees' => 0,
|
||||
'nb_evaluations_terminees' => 0,
|
||||
'moyenne_generale' => null
|
||||
];
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Dashboard Élève - <?= htmlspecialchars($user['prenom'] . ' ' . $user['nom']) ?></title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: #f5f7fa;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 20px 40px;
|
||||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.header-content {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.user-info h1 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.user-info p {
|
||||
opacity: 0.9;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
background: rgba(255,255,255,0.2);
|
||||
padding: 5px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.logout-btn {
|
||||
background: rgba(255,255,255,0.2);
|
||||
border: 2px solid white;
|
||||
color: white;
|
||||
padding: 10px 20px;
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.logout-btn:hover {
|
||||
background: white;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 30px auto;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.stats-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||
gap: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: white;
|
||||
padding: 25px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
border-left: 4px solid #667eea;
|
||||
}
|
||||
|
||||
.stat-card h3 {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.stat-card .value {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.section {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 22px;
|
||||
color: #333;
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.eval-grid {
|
||||
display: grid;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.eval-card {
|
||||
border: 2px solid #e0e0e0;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
transition: all 0.3s;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.eval-card:hover {
|
||||
border-color: #667eea;
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.eval-info h3 {
|
||||
color: #333;
|
||||
margin-bottom: 8px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.eval-info p {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.eval-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
padding: 10px 20px;
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
transition: all 0.3s;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: #f0f0f0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
padding: 5px 12px;
|
||||
border-radius: 20px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.status-non-commence {
|
||||
background: #e3f2fd;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
.status-en-cours {
|
||||
background: #fff3e0;
|
||||
color: #f57c00;
|
||||
}
|
||||
|
||||
.status-termine {
|
||||
background: #e8f5e9;
|
||||
color: #388e3c;
|
||||
}
|
||||
|
||||
.note-display {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 15px 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
border-left: 4px solid;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: #e3f2fd;
|
||||
border-color: #2196f3;
|
||||
color: #1565c0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="header-content">
|
||||
<div class="user-info">
|
||||
<h1>👋 Bonjour, <?= htmlspecialchars($user['prenom']) ?> !</h1>
|
||||
<p>
|
||||
<?php if ($isEleveLibre): ?>
|
||||
<span class="badge">🎯 Groupe de Soutien</span>
|
||||
<?php else: ?>
|
||||
Classe : <?= htmlspecialchars($user['nom_classe'] ?? 'Non assigné') ?>
|
||||
(<?= htmlspecialchars($user['niveau'] ?? '') ?>)
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<a href="../logout.php" class="logout-btn">Déconnexion</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<!-- STATISTIQUES -->
|
||||
<div class="stats-grid">
|
||||
<div class="stat-card">
|
||||
<h3>📚 Évaluations passées</h3>
|
||||
<div class="value"><?= $stats['nb_evaluations_passees'] ?></div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>✅ Évaluations terminées</h3>
|
||||
<div class="value"><?= $stats['nb_evaluations_terminees'] ?></div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<h3>📊 Moyenne générale</h3>
|
||||
<div class="value">
|
||||
<?= $stats['moyenne_generale'] !== null
|
||||
? number_format($stats['moyenne_generale'], 2) . '/20'
|
||||
: '-' ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- INFO ÉLÈVE LIBRE -->
|
||||
<?php if ($isEleveLibre): ?>
|
||||
<div class="alert alert-info">
|
||||
<strong>ℹ️ Mode Soutien :</strong>
|
||||
Vous êtes inscrit dans le groupe de soutien. Les évaluations que vous passez ne comptent
|
||||
pas dans votre bulletin scolaire, elles sont là pour vous entraîner et progresser.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- ÉVALUATIONS DISPONIBLES -->
|
||||
<div class="section">
|
||||
<h2 class="section-title">📝 Évaluations disponibles</h2>
|
||||
|
||||
<?php if (empty($evaluations)): ?>
|
||||
<div class="empty-state">
|
||||
<p style="font-size: 18px; margin-bottom: 10px;">
|
||||
Aucune évaluation disponible pour le moment
|
||||
</p>
|
||||
<p>Les nouvelles évaluations apparaîtront ici lorsque votre enseignant les publiera.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="eval-grid">
|
||||
<?php foreach ($evaluations as $eval): ?>
|
||||
<div class="eval-card">
|
||||
<div class="eval-info">
|
||||
<h3><?= htmlspecialchars($eval['titre']) ?></h3>
|
||||
<?php if (!empty($eval['description'])): ?>
|
||||
<p><?= htmlspecialchars($eval['description']) ?></p>
|
||||
<?php endif; ?>
|
||||
<p>
|
||||
<strong>Chapitre :</strong> <?= htmlspecialchars($eval['chapitre'] ?? 'Non spécifié') ?>
|
||||
| <strong>Durée :</strong> <?= $eval['duree_minutes'] ?? 'Libre' ?> min
|
||||
| <strong>Note :</strong> /<?= $eval['note_totale'] ?? 20 ?>
|
||||
</p>
|
||||
<?php if (isset($eval['fin_acces'])): ?>
|
||||
<p style="color: #f57c00;">
|
||||
⏰ Disponible jusqu'au <?= date('d/m/Y H:i', strtotime($eval['fin_acces'])) ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="eval-actions">
|
||||
<?php
|
||||
$statut = $eval['statut_tentative'] ?? 'non_commence';
|
||||
?>
|
||||
|
||||
<?php if ($statut === 'terminee'): ?>
|
||||
<span class="note-display">
|
||||
<?= number_format($eval['note_obtenue'], 2) ?>/<?= $eval['note_totale'] ?? 20 ?>
|
||||
</span>
|
||||
<span class="status-badge status-termine">✅ Terminé</span>
|
||||
<a href="../resultats.php?id_evaluation=<?= $eval['id_evaluation'] ?>"
|
||||
class="btn btn-secondary">
|
||||
Voir le résultat
|
||||
</a>
|
||||
|
||||
<?php elseif ($statut === 'en_cours'): ?>
|
||||
<span class="status-badge status-en-cours">⏳ En cours</span>
|
||||
<a href="../passer_evaluation.php?id_evaluation=<?= $eval['id_evaluation'] ?>"
|
||||
class="btn btn-primary">
|
||||
Reprendre
|
||||
</a>
|
||||
|
||||
<?php else: ?>
|
||||
<span class="status-badge status-non-commence">🆕 Nouveau</span>
|
||||
<a href="../passer_evaluation.php?id_evaluation=<?= $eval['id_evaluation'] ?>"
|
||||
class="btn btn-primary">
|
||||
Commencer
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user