200 lines
8.6 KiB
TypeScript
200 lines
8.6 KiB
TypeScript
import { useAuth } from "@/_core/hooks/useAuth";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { APP_LOGO, APP_TITLE, getLoginUrl } from "@/const";
|
|
import { GraduationCap, Calendar, Users, CheckCircle, Mail, Download } from "lucide-react";
|
|
import { useLocation, Link } from "wouter";
|
|
import { useEffect } from "react";
|
|
|
|
export default function Home() {
|
|
const { user, loading, isAuthenticated } = useAuth();
|
|
const [, setLocation] = useLocation();
|
|
|
|
useEffect(() => {
|
|
if (!loading && isAuthenticated) {
|
|
if (user?.role === 'admin' || user?.role === 'super_formateur') {
|
|
setLocation('/admin');
|
|
} else if (user?.role === 'formateur') {
|
|
setLocation('/formateur');
|
|
}
|
|
}
|
|
}, [loading, isAuthenticated, user?.role, setLocation]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center">
|
|
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (isAuthenticated && (user?.role === 'admin' || user?.role === 'formateur' || user?.role === 'super_formateur')) {
|
|
return null;
|
|
}
|
|
|
|
const features = [
|
|
{
|
|
icon: <GraduationCap className="w-8 h-8 text-blue-600" />,
|
|
title: "Gestion des formations",
|
|
description: "Créez et gérez plusieurs formations en parallèle avec des liens d'inscription uniques pour chaque formation.",
|
|
},
|
|
{
|
|
icon: <Calendar className="w-8 h-8 text-green-600" />,
|
|
title: "Sessions planifiées",
|
|
description: "Organisez des sequences avec dates, lieux et capacité maximale de 12 participants. Blocage automatique à J-15.",
|
|
},
|
|
{
|
|
icon: <Users className="w-8 h-8 text-purple-600" />,
|
|
title: "Inscriptions simplifiées",
|
|
description: "Les apprenants s'inscrivent facilement via un lien unique. Validation automatique de la capacité et anti-doublons.",
|
|
},
|
|
{
|
|
icon: <Mail className="w-8 h-8 text-orange-600" />,
|
|
title: "Communications automatiques",
|
|
description: "Emails de confirmation, invitations Outlook avec statut 'occupé', teasers et rappels J-7 automatisés.",
|
|
},
|
|
{
|
|
icon: <Download className="w-8 h-8 text-red-600" />,
|
|
title: "Exports facilitées",
|
|
description: "Exportez les listes d'inscrits en Excel ou PDF. Générez des feuilles de présence prêtes à imprimer.",
|
|
},
|
|
{
|
|
icon: <CheckCircle className="w-8 h-8 text-teal-600" />,
|
|
title: "Gestion des contraintes",
|
|
description: "Respect automatique des règles : capacité maximale, blocage J-15, liste d'attente et prévention des doubles inscriptions.",
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gradient-to-br from-blue-50 via-white to-indigo-50">
|
|
{/* Header */}
|
|
<header className="bg-white shadow-sm border-b">
|
|
<div className="container mx-auto px-4 py-4 flex items-center justify-between">
|
|
<div className="flex items-center gap-3">
|
|
<img src={APP_LOGO} alt={APP_TITLE} className="h-10 w-10" />
|
|
<h1 className="text-xl font-bold text-gray-900">{APP_TITLE}</h1>
|
|
</div>
|
|
{!isAuthenticated && (
|
|
<div className="flex gap-2">
|
|
<Link href="/login">
|
|
<Button variant="outline">
|
|
Connexion locale
|
|
</Button>
|
|
</Link>
|
|
<Button onClick={() => window.location.href = getLoginUrl()}>
|
|
Connexion OAuth
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</header>
|
|
|
|
{/* Hero Section */}
|
|
<section className="py-20 px-4">
|
|
<div className="container mx-auto text-center max-w-4xl">
|
|
<h2 className="text-5xl font-bold text-gray-900 mb-6">
|
|
Gestion des Formations Manager Itinova
|
|
</h2>
|
|
<p className="text-xl text-gray-600 mb-8">
|
|
Solution complète pour gérer l'organisation interne des formations destinées à environ 150 apprenants.
|
|
Inscriptions, sequences, communications automatisées et exports simplifiés.
|
|
</p>
|
|
<div className="flex gap-4 justify-center">
|
|
{isAuthenticated && user?.role === 'admin' && (
|
|
<Button size="lg" onClick={() => setLocation('/admin')}>
|
|
Accéder au tableau de bord
|
|
</Button>
|
|
)}
|
|
{!isAuthenticated && (
|
|
<Button size="lg" onClick={() => window.location.href = getLoginUrl()}>
|
|
Connexion Administrateur
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Features Grid */}
|
|
<section className="py-16 px-4 bg-white">
|
|
<div className="container mx-auto max-w-6xl">
|
|
<h3 className="page-title">Fonctionnalités principales</h3>
|
|
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
{features.map((feature, index) => (
|
|
<Card key={index} className="hover:shadow-lg transition-shadow">
|
|
<CardHeader>
|
|
<div className="mb-4">{feature.icon}</div>
|
|
<CardTitle className="text-xl">{feature.title}</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<CardDescription className="text-base">
|
|
{feature.description}
|
|
</CardDescription>
|
|
</CardContent>
|
|
</Card>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* How it works */}
|
|
<section className="py-16 px-4">
|
|
<div className="container mx-auto max-w-4xl">
|
|
<h3 className="page-title">Comment ça fonctionne ?</h3>
|
|
<div className="space-y-8">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<span className="bg-blue-600 text-white rounded-full w-8 h-8 flex items-center justify-center font-bold">1</span>
|
|
Pour les administrateurs
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-2">
|
|
<p>Créez des formations et des sequences avec toutes les informations nécessaires (dates, lieu, capacité). Chaque formation dispose d'un lien unique d'inscription à partager avec les apprenants.</p>
|
|
<p>Gérez les inscriptions, envoyez des emails groupés (teaser, rappels), et exportez les listes d'inscrits en Excel ou PDF pour vos besoins administratifs.</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<span className="bg-green-600 text-white rounded-full w-8 h-8 flex items-center justify-center font-bold">2</span>
|
|
Pour les apprenants
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-2">
|
|
<p>Cliquez sur le lien d'inscription fourni par la DRH, consultez les sequences disponibles avec les dates et lieux, puis inscrivez-vous en quelques clics.</p>
|
|
<p>Recevez immédiatement un email de confirmation avec une invitation Outlook (.ics) qui bloque automatiquement votre agenda. Un rappel vous sera envoyé 7 jours avant la formation.</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<span className="bg-purple-600 text-white rounded-full w-8 h-8 flex items-center justify-center font-bold">3</span>
|
|
Règles automatiques
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-2">
|
|
<p>Le système applique automatiquement toutes les contraintes : capacité maximale de 12 participants par sequence, prévention des doubles inscriptions, et gestion de la liste d'attente.</p>
|
|
<p>Les inscriptions et désinscriptions sont bloquées automatiquement 15 jours avant le début de la sequence pour garantir la stabilité des groupes.</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Footer */}
|
|
<footer className="bg-gray-900 text-white py-8 px-4">
|
|
<div className="container mx-auto text-center">
|
|
<p className="text-gray-400">
|
|
© 2026 Itinova - Gestion des Formations Manager Itinova
|
|
</p>
|
|
<p className="text-gray-500 text-sm mt-2">
|
|
Pour toute question, veuillez contacter le service RH.
|
|
</p>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
);
|
|
}
|