Checkpoint: Ajout de deux vues (complète et réduite) pour la gestion des séquences avec un bouton de basculement permettant d'alterner entre les deux modes d'affichage. Vue complète : affiche toutes les colonnes (Formation, Nom, Dates, Rappels configurés, Lieu, Formateur, Public cible, Capacité, Statut, Actions). Vue réduite : masque les colonnes Lieu, Formateur et Public cible pour un affichage plus compact et focalisé sur les informations essentielles. Simplification de l'affichage des rappels configurés : suppression des titres "Date 1:", "Date 2:" etc., les badges de rappels sont maintenant affichés directement sur une seule ligne par date, rendant la colonne plus compacte et lisible. Le bouton de basculement utilise les icônes Maximize2 (pour passer en vue complète) et Minimize2 (pour passer en vue réduite) avec un état géré par isCompactView. Les colonnes conditionnelles utilisent {!isCompactView && (<>...</>)} pour masquer/afficher dynamiquement Lieu, Formateur et Public cible. Cette double vue améliore l'expérience utilisateur en permettant d'adapter l'affichage selon le contexte d'utilisation : vue réduite pour un aperçu rapide, vue complète pour des informations détaillées.

This commit is contained in:
Manus
2026-01-08 10:54:11 -05:00
parent b0fcb4d573
commit 8965dd0ea6
2 changed files with 66 additions and 36 deletions

View File

@@ -9,7 +9,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { trpc } from "@/lib/trpc";
import { Calendar, Edit, Eye, Plus, Trash2, X, Bell } from "lucide-react";
import { Calendar, Edit, Eye, Plus, Trash2, X, Bell, Maximize2, Minimize2 } from "lucide-react";
import FormateurCombobox from "@/components/FormateurCombobox";
import CapacityProgressBar from "@/components/CapacityProgressBar";
import { toast } from "sonner";
@@ -32,6 +32,7 @@ export default function AdminSequences() {
const [filterStatut, setFilterStatut] = useState<string>("all");
const [filterPublicCible, setFilterPublicCible] = useState<string>("all");
const [sortBy, setSortBy] = useState<"date" | "lieu" | "capacite">("date");
const [isCompactView, setIsCompactView] = useState(false);
const [formData, setFormData] = useState({
formationId: "",
@@ -366,14 +367,32 @@ export default function AdminSequences() {
Créez et gérez les séquences de formation avec leurs dates
</p>
</div>
<Dialog open={isCreateOpen} onOpenChange={setIsCreateOpen}>
<DialogTrigger asChild>
<Button onClick={resetForm}>
<Plus className="h-4 w-4 mr-2" />
Nouvelle Séquence
</Button>
</DialogTrigger>
<DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
<div className="flex gap-2">
<Button
variant="outline"
size="sm"
onClick={() => setIsCompactView(!isCompactView)}
>
{isCompactView ? (
<>
<Maximize2 className="h-4 w-4 mr-2" />
Vue complète
</>
) : (
<>
<Minimize2 className="h-4 w-4 mr-2" />
Vue réduite
</>
)}
</Button>
<Dialog open={isCreateOpen} onOpenChange={setIsCreateOpen}>
<DialogTrigger asChild>
<Button onClick={resetForm}>
<Plus className="h-4 w-4 mr-2" />
Nouvelle Séquence
</Button>
</DialogTrigger>
<DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>Créer une nouvelle séquence</DialogTitle>
<DialogDescription>
@@ -564,7 +583,8 @@ export default function AdminSequences() {
</div>
</form>
</DialogContent>
</Dialog>
</Dialog>
</div>
</div>
{/* Filtres */}
@@ -677,9 +697,13 @@ export default function AdminSequences() {
<TableHead>Nom</TableHead>
<TableHead>Dates</TableHead>
<TableHead>Rappels configurés</TableHead>
<TableHead>Lieu</TableHead>
<TableHead>Formateur</TableHead>
<TableHead>Public cible</TableHead>
{!isCompactView && (
<>
<TableHead>Lieu</TableHead>
<TableHead>Formateur</TableHead>
<TableHead>Public cible</TableHead>
</>
)}
<TableHead>Capacité</TableHead>
<TableHead>Statut</TableHead>
<TableHead className="text-right">Actions</TableHead>
@@ -701,37 +725,38 @@ export default function AdminSequences() {
</div>
</TableCell>
<TableCell>
<div className="space-y-2">
<div className="space-y-1">
{sequence.dates.map((date: any) => (
<div key={date.id} className="space-y-1">
<div className="text-xs font-medium text-muted-foreground">Date {date.ordre}:</div>
<div className="flex flex-wrap gap-1">
{date.rappels && date.rappels.length > 0 ? (
date.rappels.map((rappel: any) => (
<Badge
key={rappel.id}
variant="outline"
className="bg-purple-50 text-purple-700 border-purple-300 text-xs"
>
<Bell className="w-3 h-3 mr-1" />
{rappel.nom}
</Badge>
))
) : (
<span className="text-xs text-muted-foreground italic">Aucun rappel</span>
)}
</div>
<div key={date.id} className="flex flex-wrap gap-1">
{date.rappels && date.rappels.length > 0 ? (
date.rappels.map((rappel: any) => (
<Badge
key={rappel.id}
variant="outline"
className="bg-purple-50 text-purple-700 border-purple-300 text-xs"
>
<Bell className="w-3 h-3 mr-1" />
{rappel.nom}
</Badge>
))
) : (
<span className="text-xs text-muted-foreground italic">Aucun rappel</span>
)}
</div>
))}
</div>
</TableCell>
<TableCell className="max-w-xs truncate">{sequence.lieu}</TableCell>
<TableCell className="text-sm">{sequence.formateur?.nom || "-"}</TableCell>
<TableCell>
{!isCompactView && (
<>
<TableCell className="max-w-xs truncate">{sequence.lieu}</TableCell>
<TableCell className="text-sm">{sequence.formateur?.nom || "-"}</TableCell>
<TableCell>
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${getPublicCibleBadge(sequence.publicCible)}`}>
{getPublicCibleLabel(sequence.publicCible)}
</span>
</TableCell>
</TableCell>
</>
)}
<TableCell>
<CapacityProgressBar
nbInscrits={sequence.nbInscrits || 0}