feat: Dashboard placeholder avec preview Score Sérénité
Permet aux parents de visualiser une démo du Score Sérénité dès leur première connexion, avant même que les données réelles soient disponibles. Les autres rôles (enseignant, élève, admin) ont également leur dashboard adapté avec des sections placeholder. La landing page redirige automatiquement vers /dashboard si l'utilisateur est déjà authentifié, offrant un accès direct au tableau de bord.
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
<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">
|
||||
<div class="action-card disabled" aria-disabled="true">
|
||||
<span class="action-icon">👥</span>
|
||||
<span class="action-label">Gérer les utilisateurs</span>
|
||||
<span class="action-hint">Bientôt disponible</span>
|
||||
</div>
|
||||
<div class="action-card disabled" aria-disabled="true">
|
||||
<span class="action-icon">🏫</span>
|
||||
<span class="action-label">Configurer les classes</span>
|
||||
<span class="action-hint">Bientôt disponible</span>
|
||||
</div>
|
||||
<div class="action-card disabled" aria-disabled="true">
|
||||
<span class="action-icon">📅</span>
|
||||
<span class="action-label">Calendrier scolaire</span>
|
||||
<span class="action-hint">Bientôt disponible</span>
|
||||
</div>
|
||||
<div class="action-card disabled" aria-disabled="true">
|
||||
<span class="action-icon">📤</span>
|
||||
<span class="action-label">Importer des données</span>
|
||||
<span class="action-hint">Bientôt disponible</span>
|
||||
</div>
|
||||
</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:not(.disabled):hover {
|
||||
border-color: #3b82f6;
|
||||
background: #eff6ff;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.action-card.disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.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>
|
||||
Reference in New Issue
Block a user