refactor(ui): unify frontend around compact, desktop-first design
All checks were successful
Build and Publish Docker Images / Build Frontend Image (push) Successful in 3m3s
Build and Publish Docker Images / Build Backend Image (push) Successful in 3m14s
Build and Publish Docker Images / Build Summary (push) Successful in 3s

Extract shared utilities (color functions, icon registry), replace hero
banners with compact PageHeader, add TrimesterSelector/ConfirmDialog/
Breadcrumb components, consolidate off-palette colors to design tokens,
convert AssessmentListView to table layout, compress ResultsView stats
into horizontal bar, and inline ClassFormView as a modal in ClassListView.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-24 09:37:46 +01:00
parent bb15933e69
commit 6cca179346
31 changed files with 754 additions and 843 deletions

View File

@@ -1,59 +1,26 @@
<template>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<div class="px-4 sm:px-6 lg:px-8 py-8">
<LoadingSpinner v-if="loading" text="Chargement..." fullPage />
<template v-else-if="classData">
<!-- Hero amélioré -->
<div class="bg-gradient-to-br from-blue-50 to-indigo-100 rounded-xl p-6 md:p-8 mb-8">
<div class="flex justify-between items-start">
<div>
<h1 class="text-3xl font-bold text-gray-900 mb-2">{{ classData.name }}</h1>
<p class="text-gray-600">{{ classData.year }} - {{ classData.students_count }} élèves</p>
</div>
<div class="flex gap-2">
<router-link :to="`/classes/${classData.id}/students`" class="btn btn-secondary">
Élèves
</router-link>
<router-link :to="`/classes/${classData.id}/council`" class="btn btn-secondary">
Conseil
</router-link>
</div>
</div>
</div>
<PageHeader
:title="classData.name"
:subtitle="`${classData.year} \u00b7 ${classData.students_count} élèves`"
:breadcrumbs="[{ label: 'Classes', to: '/classes' }, { label: classData.name }]"
>
<template #actions>
<router-link :to="`/classes/${classData.id}/students`" class="btn btn-secondary">
Élèves
</router-link>
<router-link :to="`/classes/${classData.id}/council`" class="btn btn-secondary">
Conseil
</router-link>
</template>
</PageHeader>
<!-- Trimester selector -->
<div class="mb-6">
<div class="flex flex-wrap gap-2 items-center">
<!-- Vision annuelle -->
<button
@click="selectTrimester(null)"
class="btn"
:class="trimester === null ? 'btn-primary' : 'btn-secondary'"
>
📊 Vision annuelle
</button>
<!-- Séparateur visuel -->
<div class="border-l border-gray-300 h-8 mx-1"></div>
<!-- Trimestres individuels -->
<button
v-for="t in [1, 2, 3]"
:key="t"
@click="selectTrimester(t)"
class="btn"
:class="trimester === t ? 'btn-primary' : 'btn-secondary'"
>
Trimestre {{ t }}
</button>
</div>
<!-- Indicateur de période affichée -->
<div class="mt-3 text-center">
<p class="text-sm font-medium text-gray-600">
{{ trimester === null ? '📊 Toutes les évaluations de l\'année' : `📅 Évaluations du trimestre ${trimester}` }}
</p>
</div>
<TrimesterSelector v-model="trimester" showAll allLabel="Annuel" size="md" @update:modelValue="selectTrimester" />
</div>
<!-- Stats principales - Grid 4 colonnes -->
@@ -238,6 +205,8 @@ import { ref, computed, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { useClassesStore } from '@/stores/classes'
import LoadingSpinner from '@/components/common/LoadingSpinner.vue'
import PageHeader from '@/components/common/PageHeader.vue'
import TrimesterSelector from '@/components/common/TrimesterSelector.vue'
const route = useRoute()
const classesStore = useClassesStore()