import React, { useEffect, useState, memo } from 'react'; import Modal from './ui/modal/Modal'; import './FolderModal.css'; import type { FolderData } from '../lib/4nk/models/FolderData'; type FolderType = 'contrat' | 'projet' | 'rapport' | 'finance' | 'rh' | 'marketing' | 'autre'; interface FolderModalProps { folder?: FolderData; onSave?: (folderData: FolderData) => void; onCancel?: () => void; readOnly?: boolean; isOpen: boolean; onClose: () => void; folderType?: FolderType; renderExtraFields?: ( folderData: FolderData, setFolderData: React.Dispatch> ) => React.ReactNode; } const defaultFolder: FolderData = { folderNumber: '', name: '', deedType: '', description: '', archived_description: '', status: 'active', created_at: new Date().toISOString(), updated_at: new Date().toISOString(), customers: [], documents: [], notes: [], stakeholders: [] }; function capitalize(s?: string) { if (!s) return ''; return s.charAt(0).toUpperCase() + s.slice(1); } function FolderModal({ folder = defaultFolder, onSave, onCancel, readOnly = false, isOpen, onClose, folderType = 'autre', renderExtraFields }: FolderModalProps) { const [folderData, setFolderData] = useState({ ...defaultFolder, ...folder }); const [currentCustomer, setCurrentCustomer] = useState(''); const [currentStakeholder, setCurrentStakeholder] = useState(''); const [currentNote, setCurrentNote] = useState(''); // Sync when modal opens or when folder prop changes (useful pour Edit) useEffect(() => { if (isOpen) { // Merge with defaultFolder to ensure arrays exist setFolderData({ ...defaultFolder, ...(folder || {}) }); setCurrentCustomer(''); setCurrentStakeholder(''); setCurrentNote(''); } }, [isOpen, folder]); // Generic input change handler const handleInputChange = ( e: React.ChangeEvent ) => { const { name, value } = e.target; // cast to avoid TS complaints when updating dynamic fields setFolderData(prev => ({ ...(prev as any), [name]: value } as FolderData)); }; /* ---------- Customers ---------- */ const addCustomer = () => { const v = currentCustomer.trim(); if (!v) return; if (!Array.isArray(folderData.customers)) folderData.customers = []; if (!folderData.customers.includes(v)) { setFolderData(prev => ({ ...prev, customers: [...(prev.customers || []), v] })); } setCurrentCustomer(''); }; const removeCustomer = (customer: string) => { setFolderData(prev => ({ ...prev, customers: (prev.customers || []).filter(c => c !== customer) })); }; /* ---------- Stakeholders ---------- */ const addStakeholder = () => { const v = currentStakeholder.trim(); if (!v) return; if (!Array.isArray(folderData.stakeholders)) folderData.stakeholders = []; if (!folderData.stakeholders.includes(v)) { setFolderData(prev => ({ ...prev, stakeholders: [...(prev.stakeholders || []), v] })); } setCurrentStakeholder(''); }; const removeStakeholder = (stakeholder: string) => { setFolderData(prev => ({ ...prev, stakeholders: (prev.stakeholders || []).filter(s => s !== stakeholder) })); }; /* ---------- Notes ---------- */ const addNote = () => { const v = currentNote.trim(); if (!v) return; if (!Array.isArray(folderData.notes)) folderData.notes = []; if (!folderData.notes.includes(v)) { setFolderData(prev => ({ ...prev, notes: [...(prev.notes || []), v] })); } setCurrentNote(''); }; const removeNote = (note: string) => { setFolderData(prev => ({ ...prev, notes: (prev.notes || []).filter(n => n !== note) })); }; /* ---------- Submit / Cancel ---------- */ const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (onSave) { onSave({ ...folderData, updated_at: new Date().toISOString() }); } if (onClose) { onClose(); // ← ça ferme le modal après sauvegarde } }; const handleCancel = () => { if (onCancel) { onCancel(); // ton callback spécifique } else if (onClose) { onClose(); // fallback si pas de onCancel } }; // Title text const title = `Créer un dossier ${capitalize(folderType)}`; return ( // On ne fait PAS "if (!isOpen) return null" : Modal gère l'animation/visibilité
{/* Informations principales */}

Informations principales