// New Registration View Component const { useState, useEffect } = React; const NewRegistrationView = ({ emailSettings, setEmailSettings, onJobAdded, prepopulatedData, onClearPrepopulated }) => { const toast = useToast(); const [personalData, setPersonalData] = useState({}); const [crifMode, setCrifMode] = useState(false); const [crifOnly, setCrifOnly] = useState(false); const [existingEmail, setExistingEmail] = useState(''); const [submitting, setSubmitting] = useState(false); const [showUpload, setShowUpload] = useState(false); const [loadingSample, setLoadingSample] = useState(false); const [linkedProjectId, setLinkedProjectId] = useState(null); const [linkedProjectName, setLinkedProjectName] = useState(null); const { DATI_ANAGRAFICI_FIELDS, DATI_RESIDENZA_FIELDS, DOCUMENTO_FIELDS, FORM_SECTIONS } = FormConstants; const { fetchRandomSample } = ApiUtils; // Load prepopulated data when it arrives from a project useEffect(() => { if (prepopulatedData) { const data = prepopulatedData.personalData || {}; setPersonalData(data); setLinkedProjectId(prepopulatedData.projectId); setLinkedProjectName(prepopulatedData.projectName); // Enable CRIF mode if residence or document data is present const hasResidenceData = data.address || data.residence_city; const hasDocumentData = data.document_type || data.document_number; if (hasResidenceData && hasDocumentData) { setCrifMode(true); } toast(`Dati caricati da pratica: ${prepopulatedData.projectName}`, 'info'); } else { // Reset state when prepopulated data is cleared setLinkedProjectId(null); setLinkedProjectName(null); } }, [prepopulatedData]); // Clear linked project when unmounting useEffect(() => { return () => { if (onClearPrepopulated) onClearPrepopulated(); }; }, []); const handleFieldChange = (key, value) => { setPersonalData(prev => ({ ...prev, [key]: value })); }; const loadSample = (sample) => { setPersonalData(sample.personal_data); setEmailSettings(prev => ({ ...prev, mail_provider: sample.additional_data.mail_provider || 'virgilio', phone_number: sample.additional_data.phone_number || '', email: sample.additional_data.email || '' })); setCrifMode(sample.additional_data.crif_mode || false); toast(`Caricato: ${sample.label}`, 'info'); }; const loadRandomSample = async (forCrif = true) => { setLoadingSample(true); try { const sample = await fetchRandomSample(forCrif); if (sample) { loadSample(sample); } else { toast('Errore nel caricamento dati casuali', 'error'); } } catch (error) { toast(`Errore: ${error.message}`, 'error'); } finally { setLoadingSample(false); } }; const handleSubmit = async () => { // Validate basic personal data fields const missing = DATI_ANAGRAFICI_FIELDS.filter(f => f.required && !personalData[f.key]).map(f => f.label); if (missing.length > 0) { toast(`Campi mancanti: ${missing.join(', ')}`, 'error'); return; } // Validate CRIF fields for both CRIF mode and CRIF-only mode if (crifMode || crifOnly) { const missingRes = DATI_RESIDENZA_FIELDS.filter(f => f.required && !personalData[f.key]).map(f => f.label); const missingDoc = DOCUMENTO_FIELDS.filter(f => f.required && !personalData[f.key]).map(f => f.label); if (missingRes.length + missingDoc.length > 0) { toast(`Campi CRIF mancanti: ${[...missingRes, ...missingDoc].join(', ')}`, 'error'); return; } } // For CRIF-only mode: require existing email, don't require phone/recovery email if (crifOnly) { if (!existingEmail || !existingEmail.trim()) { toast('Email esistente obbligatoria per modalità Solo CRIF', 'error'); return; } } else { // For email creation modes: require phone and recovery email if (!emailSettings.phone_number) { toast('Numero di telefono obbligatorio', 'error'); return; } if (!emailSettings.email) { toast('Email di recupero obbligatoria', 'error'); return; } } setSubmitting(true); try { // Build additional_data with optional project link const additionalData = { ...emailSettings, crif_mode: crifMode && !crifOnly, // crif_mode is false when crif_only is true crif_only: crifOnly, existing_email: crifOnly ? existingEmail.trim() : undefined, }; if (linkedProjectId) { additionalData.project_id = linkedProjectId; additionalData.project_name = linkedProjectName; } const payload = { personal_data: personalData, additional_data: additionalData }; const response = await fetch('/queue/add', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const data = await response.json(); if (response.ok && data.status === 'success') { const modeLabel = crifOnly ? '(Solo CRIF)' : crifMode ? '(Email + CRIF)' : '(Solo Email)'; const msg = linkedProjectId ? `Lavoro #${data.job_id} ${modeLabel} collegato alla pratica!` : `Lavoro #${data.job_id} ${modeLabel} aggiunto alla coda!`; toast(msg, 'success'); setPersonalData({}); setCrifMode(false); setCrifOnly(false); setExistingEmail(''); setLinkedProjectId(null); setLinkedProjectName(null); setEmailSettings({ mail_provider: 'virgilio', phone_number: '', email: '' }); onJobAdded?.(); } else { toast(data.detail || 'Errore durante l\'aggiunta', 'error'); } } catch (error) { toast(`Errore: ${error.message}`, 'error'); } finally { setSubmitting(false); } }; // Handle unlinking from project const handleUnlink = () => { setLinkedProjectId(null); setLinkedProjectName(null); if (onClearPrepopulated) onClearPrepopulated(); }; return (
{/* Project Link Banner */} {linkedProjectId && (
🔗 Collegato a pratica: {linkedProjectName}

I risultati della registrazione saranno salvati automaticamente sulla pratica.

)} {/* Quick Load */}
🧪 Genera Dati Casuali:
{/* Job Mode Selector */}

⚙️ Modalità Lavoro

{/* Email Only */}
{ setCrifMode(false); setCrifOnly(false); }} >
📧
Solo Email

Crea solo l'account email

{/* Email + CRIF */}
{ setCrifMode(true); setCrifOnly(false); }} >
📧+📊
Email + CRIF

Crea email e invia richiesta CRIF

{/* CRIF Only */}
{ setCrifMode(false); setCrifOnly(true); }} >
📊
Solo CRIF

Usa email esistente per CRIF

{/* Email Settings - only show for email creation modes */} {!crifOnly && (

📧 Impostazioni Email

)} {/* Existing Email - only show for CRIF-only mode */} {crifOnly && (

📧 Email Esistente per CRIF

Inserisci l'indirizzo email esistente da usare per la richiesta CRIF. Non verrà creato un nuovo account email.
setExistingEmail(e.target.value)} />
)} {/* Form Sections */} {FORM_SECTIONS.map(section => ( ))}
{/* Upload Modal */} {showUpload && setShowUpload(false)} onExtracted={(data) => { if (data.personal_data) setPersonalData(data.personal_data); setShowUpload(false); }} />}
); }; window.NewRegistrationView = NewRegistrationView;