import React, { useState, useEffect, useCallback, useRef } from 'react'; import NavPanel from '../../components/nav-panel/NavPanel'; import { createTravaux, getHorairesSubstitution } from '../../api/travaux'; import { getAllLignes } from '../../api/lignes'; import { canPerform, getCurrentUser, getScopedRegionId } from '../../utils/userUtils'; import './Travaux.css'; import RichTextEditor from '../gares/RichTextEditor'; const JOURS_SEMAINE = [ { value: 'lundi', label: 'Lundi', short: 'Lun' }, { value: 'mardi', label: 'Mardi', short: 'Mar' }, { value: 'mercredi', label: 'Mercredi', short: 'Mer' }, { value: 'jeudi', label: 'Jeudi', short: 'Jeu' }, { value: 'vendredi', label: 'Vendredi', short: 'Ven' }, { value: 'samedi', label: 'Samedi', short: 'Sam' }, { value: 'dimanche', label: 'Dimanche', short: 'Dim' } ]; export default function CreerTravaux() { const currentUser = getCurrentUser(); const canCreateTravaux = canPerform(currentUser, 'travaux', 'create'); const [activeTabKey, setActiveTabKey] = useState('general'); const tabsRef = useRef(null); const [titre, setTitre] = useState(''); const [description, setDescription] = useState(''); const [dateDebut, setDateDebut] = useState(''); const [dateFin, setDateFin] = useState(''); const [joursTravaux, setJoursTravaux] = useState(['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi', 'dimanche']); const [heureDebut, setHeureDebut] = useState('22:00'); const [heureFin, setHeureFin] = useState('06:00'); const [actif, setActif] = useState(true); // Substitutions const [substitutionsActive, setSubstitutionsActive] = useState(false); const [searchQuery, setSearchQuery] = useState(''); const [horairesDisponibles, setHorairesDisponibles] = useState([]); const [horairesSelectionnes, setHorairesSelectionnes] = useState([]); const [loadingHoraires, setLoadingHoraires] = useState(false); const [showResults, setShowResults] = useState(false); const [saving, setSaving] = useState(false); const scopedRegionId = getScopedRegionId(getCurrentUser()); const [lignes, setLignes] = useState([]); const [selectedLigneId, setSelectedLigneId] = useState(''); const [loadingLignes, setLoadingLignes] = useState(false); useEffect(() => { const fetchLignes = async () => { setLoadingLignes(true); try { const { data, error } = await getAllLignes(scopedRegionId); if (!error && data) { setLignes(data); } } catch (err) { console.error('Erreur lors du chargement des lignes:', err); } finally { setLoadingLignes(false); } }; fetchLignes(); }, [scopedRegionId]); // Synchronisation des wcs-tabs useEffect(() => { const el = tabsRef.current; if (!el) return; const handleTabChange = (e) => { if (e.detail?.selectedKey) { setActiveTabKey(e.detail.selectedKey); } }; el.addEventListener('wcsChange', handleTabChange); return () => { el.removeEventListener('wcsChange', handleTabChange); }; }, []); const handleSearchHoraires = useCallback(async () => { setLoadingHoraires(true); setShowResults(true); try { const { data, error } = await getHorairesSubstitution(searchQuery, scopedRegionId); if (!error && data) { setHorairesDisponibles(data); } else { setHorairesDisponibles([]); } } catch (err) { setHorairesDisponibles([]); } finally { setLoadingHoraires(false); } }, [searchQuery, scopedRegionId]); const toggleHoraireSelection = (horaire) => { const existe = horairesSelectionnes.find(h => h.id === horaire.id); if (existe) { setHorairesSelectionnes(horairesSelectionnes.filter(h => h.id !== horaire.id)); } else { setHorairesSelectionnes([...horairesSelectionnes, horaire]); } }; const toggleJour = (jour) => { if (joursTravaux.includes(jour)) { setJoursTravaux(joursTravaux.filter(j => j !== jour)); } else { setJoursTravaux([...joursTravaux, jour]); } }; const selectAllDays = () => { setJoursTravaux(JOURS_SEMAINE.map(j => j.value)); }; const selectWeekdays = () => { setJoursTravaux(['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi']); }; const selectWeekend = () => { setJoursTravaux(['samedi', 'dimanche']); }; const formatHeure = (heure) => (heure ? heure.substring(0, 5) : '—'); const navigate = (path) => { window.location.href = path; }; const handleCreate = async () => { if (!canCreateTravaux) { alert("Vous n'avez pas les droits pour créer des travaux."); return; } if (!titre.trim() || !dateDebut || !dateFin || joursTravaux.length === 0 || !heureDebut || !heureFin) { alert('Veuillez remplir tous les champs obligatoires (*)'); return; } if (new Date(dateFin) < new Date(dateDebut)) { alert('La date de fin doit être postérieure ou égale à la date de début.'); return; } setSaving(true); try { const payload = { titre, description: description || null, date_debut: dateDebut, date_fin: dateFin, jours_travaux: joursTravaux, heure_debut: heureDebut, heure_fin: heureFin, actif, region_id: scopedRegionId || null, ligne_id: selectedLigneId || null, ligne_nom: selectedLigneId ? (lignes.find(l => l.id === selectedLigneId)?.nom || null) : null }; const substitutionsIds = substitutionsActive ? horairesSelectionnes.map(h => h.id) : []; const { error } = await createTravaux(payload, substitutionsIds); if (error) { alert('Erreur lors de la création des travaux : ' + (error.message || 'Erreur')); } else { navigate('/travaux'); } } catch (err) { alert("Une erreur inattendue s'est produite"); } finally { setSaving(false); } }; return (
Planifiez une coupure, des restrictions de circulation et les substitutions associées.
Définissez l'intitulé, la ligne concernée et les consignes d'exploitation.
Période de validité du chantier, jours impactés et créneaux journaliers.
Associez des cars ou trains spéciaux pour remplacer les circulations supprimées.
Recherche des circulations en cours...
Aucun horaire de substitution trouvé pour « {searchQuery} ».