Files
Classeo/frontend/src/lib/components/organisms/Dashboard/DashboardAdmin.svelte
Mathias STRASSER 5f3c5c2d71
Some checks failed
CI / Backend Tests (push) Has been cancelled
CI / Frontend Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Naming Conventions (push) Has been cancelled
CI / Build Check (push) Has been cancelled
feat: Permettre aux administrateurs de configurer les règles de devoirs
Les établissements ont besoin de protéger les élèves et familles des
devoirs de dernière minute. Cette configuration au niveau tenant permet
de définir des règles de timing (délai minimum, pas de devoir pour
lundi après une heure limite) et un mode d'application (avertissement,
blocage ou désactivé).

Le service de validation est prêt pour être branché dans le flux de
création de devoirs (Stories 5.4/5.5). L'historique des changements
assure la traçabilité des modifications de configuration.
2026-03-17 21:28:10 +01:00

289 lines
7.4 KiB
Svelte

<script lang="ts">
import DashboardSection from '$lib/components/molecules/DashboardSection.svelte';
import SkeletonList from '$lib/components/atoms/Skeleton/SkeletonList.svelte';
let {
isLoading = false,
hasRealData = false,
establishmentName = ''
}: {
isLoading?: boolean;
hasRealData?: boolean;
establishmentName?: string;
} = $props();
</script>
<div class="dashboard-admin">
<header class="dashboard-header">
<h1>Administration</h1>
{#if establishmentName}
<p class="dashboard-subtitle">{establishmentName}</p>
{:else}
<p class="dashboard-subtitle">Bienvenue dans votre espace d'administration</p>
{/if}
</header>
<div class="quick-actions">
<h2 class="sr-only">Actions de configuration</h2>
<div class="action-cards">
<a class="action-card" href="/admin/users">
<span class="action-icon">👥</span>
<span class="action-label">Gérer les utilisateurs</span>
<span class="action-hint">Inviter et gérer</span>
</a>
<a class="action-card" href="/admin/parent-invitations">
<span class="action-icon">✉️</span>
<span class="action-label">Invitations parents</span>
<span class="action-hint">Codes d'invitation</span>
</a>
<a class="action-card" href="/admin/classes">
<span class="action-icon">🏫</span>
<span class="action-label">Configurer les classes</span>
<span class="action-hint">Créer et gérer</span>
</a>
<a class="action-card" href="/admin/students">
<span class="action-icon">🎒</span>
<span class="action-label">Gérer les élèves</span>
<span class="action-hint">Inscrire et affecter</span>
</a>
<a class="action-card" href="/admin/subjects">
<span class="action-icon">📚</span>
<span class="action-label">Gérer les matières</span>
<span class="action-hint">Créer et gérer</span>
</a>
<a class="action-card" href="/admin/assignments">
<span class="action-icon">📋</span>
<span class="action-label">Affectations</span>
<span class="action-hint">Enseignants et classes</span>
</a>
<a class="action-card" href="/admin/replacements">
<span class="action-icon">🔄</span>
<span class="action-label">Remplacements</span>
<span class="action-hint">Enseignants absents</span>
</a>
<a class="action-card" href="/admin/schedule">
<span class="action-icon">🕐</span>
<span class="action-label">Emploi du temps</span>
<span class="action-hint">Cours et créneaux</span>
</a>
<a class="action-card" href="/admin/academic-year/periods">
<span class="action-icon">📅</span>
<span class="action-label">Périodes scolaires</span>
<span class="action-hint">Trimestres et semestres</span>
</a>
<a class="action-card" href="/admin/calendar">
<span class="action-icon">🗓️</span>
<span class="action-label">Calendrier scolaire</span>
<span class="action-hint">Fériés et vacances</span>
</a>
<a class="action-card" href="/admin/image-rights">
<span class="action-icon">📷</span>
<span class="action-label">Droit à l'image</span>
<span class="action-hint">Autorisations élèves</span>
</a>
<a class="action-card" href="/admin/pedagogy">
<span class="action-icon">🎓</span>
<span class="action-label">Pédagogie</span>
<span class="action-hint">Mode de notation</span>
</a>
<a class="action-card" href="/admin/branding">
<span class="action-icon">🎨</span>
<span class="action-label">Identité visuelle</span>
<span class="action-hint">Logo et couleurs</span>
</a>
<a class="action-card" href="/admin/homework-rules">
<span class="action-icon">📏</span>
<span class="action-label">Règles de devoirs</span>
<span class="action-hint">Timing et contraintes</span>
</a>
<a class="action-card" href="/admin/import/students">
<span class="action-icon">📤</span>
<span class="action-label">Importer des élèves</span>
<span class="action-hint">CSV ou XLSX</span>
</a>
<a class="action-card" href="/admin/import/teachers">
<span class="action-icon">📤</span>
<span class="action-label">Importer des enseignants</span>
<span class="action-hint">CSV ou XLSX</span>
</a>
</div>
</div>
<div class="dashboard-grid">
<DashboardSection
title="Utilisateurs"
isPlaceholder={!hasRealData}
placeholderMessage="Les statistiques utilisateurs s'afficheront une fois les comptes créés"
>
{#if hasRealData}
{#if isLoading}
<SkeletonList items={3} message="Chargement des statistiques..." />
{:else}
<div class="stats-grid">
<div class="stat-card">
<span class="stat-value">--</span>
<span class="stat-label">Élèves</span>
</div>
<div class="stat-card">
<span class="stat-value">--</span>
<span class="stat-label">Enseignants</span>
</div>
<div class="stat-card">
<span class="stat-value">--</span>
<span class="stat-label">Parents</span>
</div>
</div>
{/if}
{/if}
</DashboardSection>
<DashboardSection
title="Configuration"
isPlaceholder={!hasRealData}
placeholderMessage="L'état de la configuration sera affiché ici"
>
{#if hasRealData && isLoading}
<SkeletonList items={4} message="Vérification de la configuration..." />
{/if}
</DashboardSection>
<DashboardSection
title="Activité récente"
isPlaceholder={!hasRealData}
placeholderMessage="L'historique des actions s'affichera ici"
>
{#if hasRealData && isLoading}
<SkeletonList items={5} message="Chargement de l'activité..." />
{/if}
</DashboardSection>
</div>
</div>
<style>
.dashboard-admin {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.dashboard-header {
margin-bottom: 0.5rem;
}
.dashboard-header h1 {
margin: 0;
font-size: 1.5rem;
font-weight: 700;
color: #1f2937;
}
.dashboard-subtitle {
margin: 0.25rem 0 0;
color: #6b7280;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.quick-actions {
margin-bottom: 0.5rem;
}
.action-cards {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 1rem;
}
.action-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
padding: 1.25rem 1rem;
background: white;
border: 2px solid #e5e7eb;
border-radius: 0.75rem;
text-decoration: none;
color: inherit;
transition: all 0.2s;
}
.action-card:hover {
border-color: #3b82f6;
background: #eff6ff;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.action-icon {
font-size: 2rem;
}
.action-label {
font-weight: 600;
color: #374151;
text-align: center;
}
.action-hint {
font-size: 0.75rem;
color: #6b7280;
text-align: center;
}
.dashboard-grid {
display: grid;
gap: 1.5rem;
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.dashboard-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.dashboard-grid {
grid-template-columns: repeat(3, 1fr);
}
}
.stats-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.stat-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.25rem;
padding: 1rem;
background: #f9fafb;
border-radius: 0.5rem;
}
.stat-value {
font-size: 1.5rem;
font-weight: 700;
color: #1f2937;
}
.stat-label {
font-size: 0.75rem;
color: #6b7280;
}
</style>