Checkpoint: Trois améliorations majeures pour la gestion des séquences :

 **1. Indicateur visuel de remplissage**
- Composant CapacityProgressBar avec barre de progression colorée
- Affichage "X / Y" avec pourcentage
- Couleurs automatiques : vert (<70%), orange (70-90%), rouge (>90%)
- Intégré dans la colonne capacité du tableau des séquences

 **2. Vue calendrier mensuel**
- Nouvelle page AdminCalendrier accessible depuis le menu
- Calendrier mensuel avec navigation (mois précédent/suivant, aujourd'hui)
- Affichage des séquences sur leurs dates respectives
- Dialog de détails au clic sur une séquence
- Vue complète avec toutes les informations (lieu, formateur, capacité, dates)

 **3. Système de rappels automatiques personnalisables**
- Tables rappels et rappelsEnvoyes créées
- Procédures tRPC complètes (list, create, update, delete)
- Page AdminRappels avec interface de gestion
- Configuration de rappels multiples (J-15, J-7, J-1, etc.)
- Templates d'emails personnalisables avec variables dynamiques
- Activation/désactivation des rappels
- Infrastructure prête pour l'envoi automatique (nécessite service de planification externe)

Ces améliorations facilitent grandement la planification et le suivi des formations.
This commit is contained in:
Manus Sandbox
2025-11-19 09:59:37 -05:00
parent 16351ea3d5
commit 4bf589dde3
15 changed files with 1778 additions and 4 deletions

View File

@@ -0,0 +1,43 @@
import { Progress } from "@/components/ui/progress";
import { cn } from "@/lib/utils";
interface CapacityProgressBarProps {
current: number;
max: number;
className?: string;
}
export function CapacityProgressBar({ current, max, className }: CapacityProgressBarProps) {
const percentage = max > 0 ? (current / max) * 100 : 0;
// Définir la couleur en fonction du taux de remplissage
const getColorClass = () => {
if (percentage >= 90) return "bg-red-500";
if (percentage >= 70) return "bg-orange-500";
return "bg-green-500";
};
const getTextColorClass = () => {
if (percentage >= 90) return "text-red-700";
if (percentage >= 70) return "text-orange-700";
return "text-green-700";
};
return (
<div className={cn("space-y-1", className)}>
<div className="flex items-center justify-between text-sm">
<span className={cn("font-medium", getTextColorClass())}>
{current} / {max}
</span>
<span className={cn("text-xs", getTextColorClass())}>
{Math.round(percentage)}%
</span>
</div>
<Progress
value={percentage}
className="h-2"
indicatorClassName={getColorClass()}
/>
</div>
);
}

View File

@@ -21,7 +21,7 @@ import {
} from "@/components/ui/sidebar";
import { APP_LOGO, APP_TITLE, getLoginUrl } from "@/const";
import { useIsMobile } from "@/hooks/useMobile";
import { LayoutDashboard, LogOut, PanelLeft, Users, GraduationCap, Calendar, BarChart3, UserCog, Mail, Settings } from "lucide-react";
import { LayoutDashboard, LogOut, PanelLeft, Users, GraduationCap, Calendar, CalendarDays, BarChart3, UserCog, Mail, Settings, Bell } from "lucide-react";
import { CSSProperties, useEffect, useRef, useState } from "react";
import { useLocation } from "wouter";
import { DashboardLayoutSkeleton } from './DashboardLayoutSkeleton';
@@ -31,10 +31,12 @@ const menuItems = [
{ icon: LayoutDashboard, label: "Tableau de bord", path: "/admin" },
{ icon: GraduationCap, label: "Formations", path: "/admin/formations" },
{ icon: Calendar, label: "Séquences", path: "/admin/sequences" },
{ icon: CalendarDays, label: "Calendrier", path: "/admin/calendrier" },
{ icon: Users, label: "Apprenants", path: "/admin/apprenants" },
{ icon: UserCog, label: "Utilisateurs", path: "/admin/users" },
{ icon: Mail, label: "Templates d'emails", path: "/admin/email-templates" },
{ icon: Settings, label: "Configuration SMTP", path: "/admin/email-config" },
{ icon: Bell, label: "Rappels automatiques", path: "/admin/rappels" },
{ icon: BarChart3, label: "Rapport Public Cible", path: "/admin/rapport-public-cible" },
];

View File

@@ -3,11 +3,16 @@ import * as ProgressPrimitive from "@radix-ui/react-progress";
import { cn } from "@/lib/utils";
interface ProgressProps extends React.ComponentProps<typeof ProgressPrimitive.Root> {
indicatorClassName?: string;
}
function Progress({
className,
value,
indicatorClassName,
...props
}: React.ComponentProps<typeof ProgressPrimitive.Root>) {
}: ProgressProps) {
return (
<ProgressPrimitive.Root
data-slot="progress"
@@ -19,7 +24,7 @@ function Progress({
>
<ProgressPrimitive.Indicator
data-slot="progress-indicator"
className="bg-primary h-full w-full flex-1 transition-all"
className={cn("bg-primary h-full w-full flex-1 transition-all", indicatorClassName)}
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/>
</ProgressPrimitive.Root>