docv/app/formation/devis/page.tsx

554 lines
23 KiB
TypeScript

'use client'
import { useState } from 'react'
import Link from "next/link"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Badge } from "@/components/ui/badge"
import { Textarea } from "@/components/ui/textarea"
import { Checkbox } from "@/components/ui/checkbox"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Shield, ArrowLeft, Users, Calendar, MapPin, Mail, Phone, Building, User, FileText, CheckCircle, Loader2 } from 'lucide-react'
import { submitFormationForm } from '@/app/actions/formation'
export default function DevisFormationPage() {
const [formData, setFormData] = useState({
// Informations entreprise
entreprise: '',
secteur: '',
taille: '',
siret: '',
// Contact
nom: '',
prenom: '',
fonction: '',
email: '',
telephone: '',
// Formations souhaitées
formations: [] as string[],
// Modalités
modalite: '',
participants: '',
dates: '',
lieu: '',
// Besoins spécifiques
objectifs: '',
niveau: '',
contraintes: '',
// Options supplémentaires (initialisées à false)
certification: false,
support: false,
accompagnement: false,
});
const [isSubmitting, setIsSubmitting] = useState(false)
const [submitResult, setSubmitResult] = useState<{ success: boolean; message: string } | null>(null)
const handleFormationChange = (formation: string, checked: boolean) => {
if (checked) {
setFormData(prev => ({
...prev,
formations: [...prev.formations, formation]
}))
} else {
setFormData(prev => ({
...prev,
formations: prev.formations.filter(f => f !== formation)
}))
}
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setIsSubmitting(true)
setSubmitResult(null)
try {
const formDataToSend = new FormData()
// Ajout de tous les champs au FormData
Object.entries(formData).forEach(([key, value]) => {
if (key === 'formations') {
value.forEach((formation: string) => formDataToSend.append('formations', formation))
} else if (typeof value === 'boolean') {
formDataToSend.append(key, value.toString())
} else {
formDataToSend.append(key, value)
}
})
const result = await submitFormationForm(formDataToSend)
setSubmitResult(result)
if (result.success) {
// Reset du formulaire en cas de succès
setFormData({
entreprise: '',
secteur: '',
taille: '',
siret: '',
nom: '',
prenom: '',
fonction: '',
email: '',
telephone: '',
formations: [],
modalite: '',
participants: '',
dates: '',
lieu: '',
objectifs: '',
niveau: '',
contraintes: '',
certification: false,
support: false,
accompagnement: false
})
}
} catch (error) {
setSubmitResult({
success: false,
message: 'Une erreur inattendue est survenue. Veuillez réessayer.'
})
} finally {
setIsSubmitting(false)
}
}
if (submitResult?.success) {
return (
<div className="min-h-screen bg-gray-900 flex items-center justify-center p-4">
<Card className="w-full max-w-2xl border-2 border-green-700 bg-gray-800">
<CardHeader className="text-center">
<CheckCircle className="h-16 w-16 text-green-400 mx-auto mb-4" />
<CardTitle className="text-3xl text-green-300">Demande envoyée !</CardTitle>
<CardDescription className="text-lg text-gray-300">
{submitResult.message}
</CardDescription>
</CardHeader>
<CardContent className="text-center space-y-6">
<div className="bg-gray-700 p-6 rounded-lg border border-green-700">
<h3 className="font-semibold text-green-300 mb-3">Prochaines étapes :</h3>
<ul className="text-left space-y-2 text-gray-300">
<li> Un expert 4NK vous contactera sous 24h</li>
<li> Analyse personnalisée de vos besoins</li>
<li> Proposition de devis détaillé</li>
<li> Planification des sessions de formation</li>
</ul>
</div>
<div className="space-y-4 text-gray-300">
<p>
<strong>Contact direct :</strong>
<a href="mailto:contact@docv.fr" className="text-green-400 hover:text-green-300 ml-1">
contact@docv.fr
</a>
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Link href="/formation">
<Button variant="outline" className="border-green-400 text-green-300 hover:text-green-100 hover:border-green-300">
Retour aux formations
</Button>
</Link>
<Link href="/">
<Button className="bg-green-600 hover:bg-green-500 text-white">
Accueil DocV
</Button>
</Link>
</div>
</div>
</CardContent>
</Card>
</div>
)
}
return (
<div className="min-h-screen bg-gray-900 text-gray-100 flex flex-col">
{/* Header */}
<header className="border-b border-gray-700 bg-gray-800/90 backdrop-blur-sm">
<div className="container mx-auto px-4 py-4 flex justify-between items-center">
<Link href="/formation" className="flex items-center space-x-2">
<Shield className="h-8 w-8 text-blue-400" />
<span className="text-2xl font-bold text-white">DocV</span>
<Badge variant="secondary" className="ml-2 bg-gray-700 text-gray-200">By 4NK</Badge>
</Link>
<Link href="/formation" className="flex items-center text-blue-400 hover:text-blue-500">
<ArrowLeft className="h-4 w-4 mr-2" />
Retour aux formations
</Link>
</div>
</header>
<main className="flex-1 container mx-auto px-4 py-8 space-y-12">
{/* Hero Section */}
<section className="text-center">
<h1 className="text-4xl font-bold mb-4">
Demande de <span className="text-blue-400">Devis Formation</span>
</h1>
<p className="text-lg text-gray-300 max-w-2xl mx-auto">
Obtenez un devis personnalisé pour vos formations en souveraineté numérique.
Nos experts vous accompagnent dans la définition de vos besoins.
</p>
</section>
{/* Error Message */}
{submitResult && !submitResult.success && (
<div className="p-4 bg-red-700 text-red-200 rounded-lg">
{submitResult.message}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-8">
{/* Informations Entreprise */}
<Card className="bg-gray-800 border-gray-700">
<CardHeader>
<CardTitle className="flex items-center text-white">
<Building className="h-5 w-5 mr-2 text-blue-400" />
Informations Entreprise
</CardTitle>
<CardDescription className="text-gray-300">
Renseignez les informations de votre organisation
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="entreprise">Nom de l'entreprise *</Label>
<Input
id="entreprise"
value={formData.entreprise}
onChange={(e) => setFormData(prev => ({ ...prev, entreprise: e.target.value }))}
placeholder="Votre entreprise"
required
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
<div className="space-y-2">
<Label htmlFor="secteur">Secteur d'activité</Label>
<Select onValueChange={(value) => setFormData(prev => ({ ...prev, secteur: value }))}>
<SelectTrigger className="bg-gray-700 text-gray-100 border-gray-600">
<SelectValue placeholder="Sélectionnez votre secteur" />
</SelectTrigger>
<SelectContent className="bg-gray-800 text-gray-100 border-gray-700">
<SelectItem value="finance">Finance / Banque</SelectItem>
<SelectItem value="sante">Santé</SelectItem>
<SelectItem value="notariat">Notariat / Juridique</SelectItem>
<SelectItem value="industrie">Industrie</SelectItem>
<SelectItem value="service-public">Service Public</SelectItem>
<SelectItem value="education">Éducation</SelectItem>
<SelectItem value="tech">Technologies</SelectItem>
<SelectItem value="autre">Autre</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="taille">Taille de l'entreprise</Label>
<Select onValueChange={(value) => setFormData(prev => ({ ...prev, taille: value }))}>
<SelectTrigger className="bg-gray-700 text-gray-100 border-gray-600">
<SelectValue placeholder="Nombre d'employés" />
</SelectTrigger>
<SelectContent className="bg-gray-800 text-gray-100 border-gray-700">
<SelectItem value="1-10">1-10 employés</SelectItem>
<SelectItem value="11-50">11-50 employés</SelectItem>
<SelectItem value="51-200">51-200 employés</SelectItem>
<SelectItem value="201-1000">201-1000 employés</SelectItem>
<SelectItem value="1000+">Plus de 1000 employés</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="siret">SIRET (optionnel)</Label>
<Input
id="siret"
value={formData.siret}
onChange={(e) => setFormData(prev => ({ ...prev, siret: e.target.value }))}
placeholder="Numéro SIRET"
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
</div>
</CardContent>
</Card>
{/* Contact Section */}
<Card className="bg-gray-800 border-gray-700">
<CardHeader>
<CardTitle className="flex items-center text-white">
<User className="h-5 w-5 mr-2 text-blue-400" />
Contact
</CardTitle>
<CardDescription className="text-gray-300">
Vos coordonnées pour le suivi de la demande
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="nom">Nom *</Label>
<Input
id="nom"
value={formData.nom}
onChange={(e) => setFormData(prev => ({ ...prev, nom: e.target.value }))}
placeholder="Votre nom"
required
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
<div className="space-y-2">
<Label htmlFor="prenom">Prénom *</Label>
<Input
id="prenom"
value={formData.prenom}
onChange={(e) => setFormData(prev => ({ ...prev, prenom: e.target.value }))}
placeholder="Votre prénom"
required
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="fonction">Fonction</Label>
<Input
id="fonction"
value={formData.fonction}
onChange={(e) => setFormData(prev => ({ ...prev, fonction: e.target.value }))}
placeholder="Votre fonction"
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="email">Email *</Label>
<Input
id="email"
type="email"
value={formData.email}
onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
placeholder="votre.email@entreprise.com"
required
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
<div className="space-y-2">
<Label htmlFor="telephone">Téléphone</Label>
<Input
id="telephone"
type="tel"
value={formData.telephone}
onChange={(e) => setFormData(prev => ({ ...prev, telephone: e.target.value }))}
placeholder="01 23 45 67 89"
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
</div>
</CardContent>
</Card>
{/* Formations souhaitées */}
<Card className="bg-gray-800 border-gray-700">
<CardHeader>
<CardTitle className="flex items-center text-white">
<FileText className="h-5 w-5 mr-2 text-blue-400" />
Formations souhaitées
</CardTitle>
<CardDescription className="text-gray-300">
Sélectionnez les formations qui vous intéressent
</CardDescription>
</CardHeader>
<CardContent className="space-y-3">
{[
{ id: 'cybersecurite', label: 'Cybersécurité (5 jours)', desc: 'Fondamentaux de la sécurité informatique et spécialisation DocV' },
{ id: 'hygiene', label: 'Hygiène Numérique (3 jours)', desc: 'Bonnes pratiques pour un environnement numérique sain' },
{ id: 'developpement', label: 'Développement Souverain (7 jours)', desc: 'Applications indépendantes et sécurisées' },
{ id: 'parcours-complet', label: 'Parcours Complet (15 jours)', desc: 'Formation intégrée avec certification 4NK' }
].map(f => (
<div key={f.id} className="flex items-start space-x-2">
<Checkbox
id={f.id}
checked={formData.formations.includes(f.id)}
onCheckedChange={(checked) => handleFormationChange(f.id, checked as boolean)}
/>
<Label htmlFor={f.id} className="flex-1 text-gray-100">
<div className="font-medium">{f.label}</div>
<div className="text-sm text-gray-400">{f.desc}</div>
</Label>
</div>
))}
</CardContent>
</Card>
{/* Modalités */}
<Card className="bg-gray-800 border-gray-700">
<CardHeader>
<CardTitle className="flex items-center text-white">
<Calendar className="h-5 w-5 mr-2 text-blue-400" />
Modalités de formation
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<fieldset className="space-y-3">
<legend className="text-gray-200 font-semibold">Mode de formation préféré</legend>
<RadioGroup value={formData.modalite} onValueChange={(value) => setFormData(prev => ({ ...prev, modalite: value }))}>
{['presentiel', 'distanciel', 'hybride'].map(option => (
<div key={option} className="flex items-center space-x-2">
<RadioGroupItem value={option} id={option} />
<Label htmlFor={option} className="text-gray-100 capitalize">{option}</Label>
</div>
))}
</RadioGroup>
</fieldset>
<div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="participants">Nombre de participants</Label>
<Select onValueChange={(value) => setFormData(prev => ({ ...prev, participants: value }))}>
<SelectTrigger className="bg-gray-700 text-gray-100 border-gray-600">
<SelectValue placeholder="Nombre de participants" />
</SelectTrigger>
<SelectContent className="bg-gray-800 text-gray-100 border-gray-700">
<SelectItem value="1-5">1-5 participants</SelectItem>
<SelectItem value="6-10">6-10 participants</SelectItem>
<SelectItem value="11-15">11-15 participants</SelectItem>
<SelectItem value="16-20">16-20 participants</SelectItem>
<SelectItem value="20+">Plus de 20 participants</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="dates">Période souhaitée</Label>
<Input
id="dates"
value={formData.dates}
onChange={(e) => setFormData(prev => ({ ...prev, dates: e.target.value }))}
placeholder="Ex: Mars 2024, Trimestre 2..."
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="lieu">Lieu (si présentiel)</Label>
<Input
id="lieu"
value={formData.lieu}
onChange={(e) => setFormData(prev => ({ ...prev, lieu: e.target.value }))}
placeholder="Ville ou adresse"
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
</CardContent>
</Card>
{/* Besoins spécifiques */}
<Card className="bg-gray-800 border-gray-700">
<CardHeader>
<CardTitle>Besoins spécifiques</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="objectifs">Objectifs de formation</Label>
<Textarea
id="objectifs"
value={formData.objectifs}
onChange={(e) => setFormData(prev => ({ ...prev, objectifs: e.target.value }))}
placeholder="Décrivez vos objectifs et attentes..."
rows={3}
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
<div className="space-y-2">
<Label htmlFor="niveau">Niveau des participants</Label>
<Select onValueChange={(value) => setFormData(prev => ({ ...prev, niveau: value }))}>
<SelectTrigger className="bg-gray-700 text-gray-100 border-gray-600">
<SelectValue placeholder="Niveau technique" />
</SelectTrigger>
<SelectContent className="bg-gray-800 text-gray-100 border-gray-700">
<SelectItem value="debutant">Débutant</SelectItem>
<SelectItem value="intermediaire">Intermédiaire</SelectItem>
<SelectItem value="avance">Avancé</SelectItem>
<SelectItem value="mixte">Mixte</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="contraintes">Contraintes particulières</Label>
<Textarea
id="contraintes"
value={formData.contraintes}
onChange={(e) => setFormData(prev => ({ ...prev, contraintes: e.target.value }))}
placeholder="Contraintes horaires, techniques, organisationnelles..."
rows={2}
className="bg-gray-700 text-gray-100 border-gray-600 placeholder-gray-400"
/>
</div>
</CardContent>
</Card>
{/* Options supplémentaires */}
<Card className="bg-gray-800 border-gray-700">
<CardHeader>
<CardTitle>Options supplémentaires</CardTitle>
</CardHeader>
<CardContent className="space-y-3">
{[
{ id: 'certification', label: 'Certification RNCP "Développeur Blockchain" (niveau 6)' },
{ id: 'support', label: 'Support technique 6 mois post-formation' },
{ id: 'accompagnement', label: 'Accompagnement personnalisé sur projet' }
].map(opt => (
<div key={opt.id} className="flex items-center space-x-2">
<Checkbox
id={opt.id}
checked={formData[opt.id]}
onCheckedChange={(checked) =>
setFormData(prev => ({ ...prev, [opt.id]: checked as boolean }))
}
/>
<Label htmlFor={opt.id}>{opt.label}</Label>
</div>
))}
</CardContent>
</Card>
{/* Submit */}
<div className="text-center">
<Button
type="submit"
size="lg"
className="text-lg px-12 py-3"
disabled={isSubmitting}
>
{isSubmitting ? (
<>
<Loader2 className="h-5 w-5 mr-2 animate-spin" />
Envoi en cours...
</>
) : (
<>
<Mail className="h-5 w-5 mr-2" />
Envoyer la demande de devis
</>
)}
</Button>
<p className="text-sm text-gray-400 mt-4">
Réponse sous 24h Devis gratuit et sans engagement
</p>
</div>
</form>
</main>
</div>
)
}