'use client'; import React, { useState, useEffect } from 'react'; import { Card } from 'primereact/card'; import { InputText } from 'primereact/inputtext'; import { InputTextarea } from 'primereact/inputtextarea'; import { Dropdown } from 'primereact/dropdown'; import { Button } from 'primereact/button'; import { Toolbar } from 'primereact/toolbar'; import { Message } from 'primereact/message'; import { FileUpload } from 'primereact/fileupload'; import { Tag } from 'primereact/tag'; import { Steps } from 'primereact/steps'; import { useRouter } from 'next/navigation'; import { apiClient } from '../../../../services/api-client'; interface SignalementPanne { materielId: number; chantierImpacte?: number; gravite: 'MINEURE' | 'MODEREE' | 'MAJEURE' | 'CRITIQUE'; impactProduction: 'AUCUN' | 'FAIBLE' | 'MOYEN' | 'ELEVE' | 'ARRET_TOTAL'; problemeSignale: string; symptomesObserves: string; circonstancesApparition: string; mesuresTemporaires?: string; personneSignalement: string; contactUrgence: string; photos: File[]; prioriteUrgence: boolean; interventionImmediate: boolean; } interface Materiel { id: number; nom: string; type: string; marque: string; modele: string; localisation: string; statut: string; } interface Chantier { id: number; nom: string; localisation: string; statut: string; } const SignalerPannePage = () => { const [signalement, setSignalement] = useState({ materielId: 0, gravite: 'MODEREE', impactProduction: 'MOYEN', problemeSignale: '', symptomesObserves: '', circonstancesApparition: '', personneSignalement: '', contactUrgence: '', photos: [], prioriteUrgence: false, interventionImmediate: false }); const [materiels, setMateriels] = useState([]); const [chantiers, setChantiers] = useState([]); const [loading, setLoading] = useState(false); const [errors, setErrors] = useState<{ [key: string]: string }>({}); const [etapeActuelle, setEtapeActuelle] = useState(0); const [signalementEnvoye, setSignalementEnvoye] = useState(false); const router = useRouter(); const graviteOptions = [ { label: 'Mineure - Fonctionnement dégradé', value: 'MINEURE' }, { label: 'Modérée - Dysfonctionnement notable', value: 'MODEREE' }, { label: 'Majeure - Panne importante', value: 'MAJEURE' }, { label: 'Critique - Arrêt complet', value: 'CRITIQUE' } ]; const impactOptions = [ { label: 'Aucun impact', value: 'AUCUN' }, { label: 'Impact faible', value: 'FAIBLE' }, { label: 'Impact moyen', value: 'MOYEN' }, { label: 'Impact élevé', value: 'ELEVE' }, { label: 'Arrêt total de production', value: 'ARRET_TOTAL' } ]; const etapes = [ { label: 'Matériel' }, { label: 'Problème' }, { label: 'Impact' }, { label: 'Contact' }, { label: 'Confirmation' } ]; useEffect(() => { loadMateriels(); loadChantiers(); }, []); const loadMateriels = async () => { try { console.log('🔄 Chargement des matériels...'); const response = await apiClient.get('/api/materiels'); console.log('✅ Matériels chargés:', response.data); setMateriels(response.data || []); } catch (error) { console.error('❌ Erreur lors du chargement des matériels:', error); } }; const loadChantiers = async () => { try { const response = await apiClient.get('/api/chantiers'); setChantiers(response.data || []); } catch (error) { console.error('❌ Erreur lors du chargement des chantiers:', error); } }; const validateEtape = (etape: number) => { const newErrors: { [key: string]: string } = {}; switch (etape) { case 0: // Matériel if (!signalement.materielId) { newErrors.materielId = 'Le matériel est requis'; } break; case 1: // Problème if (!signalement.problemeSignale.trim()) { newErrors.problemeSignale = 'La description du problème est requise'; } if (!signalement.symptomesObserves.trim()) { newErrors.symptomesObserves = 'Les symptômes observés sont requis'; } break; case 2: // Impact if (!signalement.circonstancesApparition.trim()) { newErrors.circonstancesApparition = 'Les circonstances d\'apparition sont requises'; } break; case 3: // Contact if (!signalement.personneSignalement.trim()) { newErrors.personneSignalement = 'Le nom de la personne est requis'; } if (!signalement.contactUrgence.trim()) { newErrors.contactUrgence = 'Le contact d\'urgence est requis'; } break; } setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const etapeSuivante = () => { if (validateEtape(etapeActuelle)) { setEtapeActuelle(etapeActuelle + 1); } }; const etapePrecedente = () => { setEtapeActuelle(etapeActuelle - 1); }; const handleSubmit = async () => { if (!validateEtape(3)) { return; } try { setLoading(true); console.log('🔄 Envoi du signalement de panne...', signalement); // Créer FormData pour inclure les photos const formData = new FormData(); Object.entries(signalement).forEach(([key, value]) => { if (key === 'photos') { signalement.photos.forEach((photo, index) => { formData.append(`photo_${index}`, photo); }); } else { formData.append(key, value.toString()); } }); const response = await apiClient.post('/api/maintenances/signaler-panne', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); console.log('✅ Signalement envoyé avec succès:', response.data); setSignalementEnvoye(true); setEtapeActuelle(4); } catch (error) { console.error('❌ Erreur lors de l\'envoi du signalement:', error); } finally { setLoading(false); } }; const materielOptionTemplate = (option: Materiel) => { return (
{option.nom}
{option.type} - {option.marque} {option.modele}
📍 {option.localisation}
); }; const chantierOptionTemplate = (option: Chantier) => { return (
{option.nom}
📍 {option.localisation}
); }; const onPhotoUpload = (event: any) => { const files = Array.from(event.files) as File[]; setSignalement({ ...signalement, photos: [...signalement.photos, ...files] }); }; const supprimerPhoto = (index: number) => { const nouvellesPhotos = signalement.photos.filter((_, i) => i !== index); setSignalement({ ...signalement, photos: nouvellesPhotos }); }; const getGraviteSeverity = (gravite: string) => { switch (gravite) { case 'MINEURE': return 'info'; case 'MODEREE': return 'warning'; case 'MAJEURE': return 'danger'; case 'CRITIQUE': return 'danger'; default: return 'secondary'; } }; const getImpactSeverity = (impact: string) => { switch (impact) { case 'AUCUN': return 'success'; case 'FAIBLE': return 'info'; case 'MOYEN': return 'warning'; case 'ELEVE': return 'danger'; case 'ARRET_TOTAL': return 'danger'; default: return 'secondary'; } }; const leftToolbarTemplate = () => { return (
); }; const rightToolbarTemplate = () => { return (
); }; if (signalementEnvoye) { return (

Signalement envoyé avec succès !

Votre signalement de panne a été transmis à l'équipe de maintenance.

Un technicien sera assigné dans les plus brefs délais selon la priorité définie.

); } return (
{etapeActuelle === 0 && (

Sélection du matériel

setSignalement({ ...signalement, materielId: e.value })} optionLabel="nom" optionValue="id" placeholder="Sélectionner le matériel en panne" itemTemplate={materielOptionTemplate} className={errors.materielId ? 'p-invalid' : ''} filter /> {errors.materielId && {errors.materielId}}
setSignalement({ ...signalement, chantierImpacte: e.value })} optionLabel="nom" optionValue="id" placeholder="Sélectionner le chantier impacté" itemTemplate={chantierOptionTemplate} filter showClear />
)} {etapeActuelle === 1 && (

Description du problème

setSignalement({ ...signalement, problemeSignale: e.target.value })} rows={4} placeholder="Décrivez précisément le problème rencontré..." className={errors.problemeSignale ? 'p-invalid' : ''} /> {errors.problemeSignale && {errors.problemeSignale}}
setSignalement({ ...signalement, symptomesObserves: e.target.value })} rows={3} placeholder="Bruits anormaux, fumée, vibrations, arrêt soudain..." className={errors.symptomesObserves ? 'p-invalid' : ''} /> {errors.symptomesObserves && {errors.symptomesObserves}}
{signalement.photos.length > 0 && (
{signalement.photos.map((photo, index) => (
{`Photo
))}
)}
)} {etapeActuelle === 2 && (

Évaluation de l'impact

setSignalement({ ...signalement, gravite: e.value })} placeholder="Évaluer la gravité" />
setSignalement({ ...signalement, impactProduction: e.value })} placeholder="Évaluer l'impact" />
setSignalement({ ...signalement, circonstancesApparition: e.target.value })} rows={3} placeholder="Quand et comment le problème est-il apparu ? Conditions météo, charge de travail..." className={errors.circonstancesApparition ? 'p-invalid' : ''} /> {errors.circonstancesApparition && {errors.circonstancesApparition}}
setSignalement({ ...signalement, mesuresTemporaires: e.target.value })} rows={2} placeholder="Actions déjà entreprises pour limiter l'impact..." />
)} {etapeActuelle === 3 && (

Informations de contact

setSignalement({ ...signalement, personneSignalement: e.target.value })} placeholder="Nom et prénom" className={errors.personneSignalement ? 'p-invalid' : ''} /> {errors.personneSignalement && {errors.personneSignalement}}
setSignalement({ ...signalement, contactUrgence: e.target.value })} placeholder="Numéro de téléphone ou email" className={errors.contactUrgence ? 'p-invalid' : ''} /> {errors.contactUrgence && {errors.contactUrgence}}
setSignalement({ ...signalement, prioriteUrgence: e.target.checked })} />
setSignalement({ ...signalement, interventionImmediate: e.target.checked })} />
)} {etapeActuelle === 4 && (

Récapitulatif du signalement

{materiels.find(m => m.id === signalement.materielId)?.nom}

{signalement.personneSignalement}

{signalement.contactUrgence}

{signalement.prioriteUrgence && (
)}

{signalement.problemeSignale}

)}
); }; export default SignalerPannePage;