import { useCallback, useEffect, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { useAuth } from '@/contexts/AuthContext.tsx'; import { useCreateOrganization } from '@/hooks/api/useOrganizationsAPI.ts'; import { useCreateResourceFlow } from '@/hooks/api/useResourcesAPI.ts'; import { useCreateSite } from '@/hooks/api/useSitesAPI.ts'; import { useOrganizationWizard } from '@/hooks/features/useOrganizationWizard.ts'; import { useTranslation } from '@/hooks/useI18n.tsx'; import { convertNeedsAndOffersToResourceFlows } from '@/lib/resource-flow-mapper.ts'; import { OrganizationFormData } from '@/types.ts'; import ErrorMessage from '@/components/ui/ErrorMessage.tsx'; import Wizard from '@/components/wizard/Wizard.tsx'; import WizardContent from '@/components/add-organization/WizardContent.tsx'; import WizardFooter from '@/components/add-organization/WizardFooter.tsx'; interface AddOrganizationWizardProps { isOpen: boolean; onClose: () => void; } const AddOrganizationWizard = ({ isOpen, onClose }: AddOrganizationWizardProps) => { const { t } = useTranslation(); const { isAuthenticated } = useAuth(); const navigate = useNavigate(); const [error, setError] = useState(null); const createOrgMutation = useCreateOrganization(); const createSiteMutation = useCreateSite(); const createResourceFlowMutation = useCreateResourceFlow(); // Redirect to login if not authenticated useEffect(() => { if (isOpen && !isAuthenticated) { navigate('/login'); onClose(); } }, [isOpen, isAuthenticated, navigate, onClose]); const onSuccess = useCallback( async (data: OrganizationFormData) => { try { setError(null); // Step 1: Create organization (backend API only accepts basic fields) const orgPayload = { name: data.name, sector: data.sector, description: data.description, subtype: data.subtype, website: data.website || '', address: data.address ? `${data.address.street}, ${data.address.city}, ${data.address.state} ${data.address.zip}`.trim() : '', logoUrl: data.logoUrl || '', galleryImages: data.galleryImages || [], }; const newOrg = await createOrgMutation.mutateAsync(orgPayload); if (!newOrg?.ID) { throw new Error('Failed to create organization'); } // Step 2: Create a default Site for the organization const sitePayload = { name: `${data.name} - Main Site`, address: orgPayload.address, latitude: data.location.lat, longitude: data.location.lng, owner_organization_id: newOrg.ID, }; const newSite = await createSiteMutation.mutateAsync(sitePayload); if (!newSite?.ID) { throw new Error('Failed to create site'); } // Step 3: Convert user-friendly needs/offers to ResourceFlows and create them const resourceFlows = convertNeedsAndOffersToResourceFlows(data, newOrg.ID, newSite.ID); // Create all ResourceFlows in parallel await Promise.all( resourceFlows.map((flow) => createResourceFlowMutation.mutateAsync(flow)) ); onClose(); navigate('/map'); } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Failed to create organization'; setError(errorMessage); console.error('Error creating organization:', error); } }, [createOrgMutation, createSiteMutation, createResourceFlowMutation, onClose, navigate] ); const { wizardState, form, smartFill, descriptionGeneration, actions } = useOrganizationWizard({ onSuccess, }); // Track previous isOpen value to detect when it changes from true to false const prevIsOpenRef = useRef(isOpen); // Reset form and wizard state when dialog closes (transitions from open to closed) useEffect(() => { if (prevIsOpenRef.current && !isOpen) { actions.resetWizard(); } prevIsOpenRef.current = isOpen; }, [isOpen, actions]); return ( <> {error && (
)} {wizardState.currentStep > 1 && ( )} ); }; export default AddOrganizationWizard;