import React, { useEffect, useState, useRef } from 'react'; import { Link } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { EllipsisVerticalIcon } from '@heroicons/react/24/outline'; import ConfirmDialog from './Shared/ConfirmDialog'; import AreaModal from './Area/AreaModal'; import { useStore } from '../store/useStore'; import { fetchAreas, createArea, updateArea, deleteArea, } from '../utils/areasService'; import { Area } from '../entities/Area'; const Areas: React.FC = () => { const { t } = useTranslation(); // Use global store for consistency const { areas, isLoading: loading, hasLoaded, loadAreas, } = useStore((state: any) => state.areasStore); const [isAreaModalOpen, setIsAreaModalOpen] = useState(false); const [selectedArea, setSelectedArea] = useState(null); const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false); const [areaToDelete, setAreaToDelete] = useState(null); const [dropdownOpen, setDropdownOpen] = useState(null); const justOpenedRef = useRef(false); const dropdownRef = useRef(null); useEffect(() => { if (!hasLoaded && !loading) { loadAreas(); } }, [hasLoaded, loading, loadAreas]); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { // Skip if dropdown was just opened if (justOpenedRef.current) { justOpenedRef.current = false; return; } const clickedElement = event.target as Node; if ( dropdownRef.current && !dropdownRef.current.contains(clickedElement) ) { setDropdownOpen(null); } }; if (dropdownOpen !== null) { // Add a small delay to prevent immediate closing const timeoutId = setTimeout(() => { document.addEventListener('mousedown', handleClickOutside); }, 100); return () => { clearTimeout(timeoutId); document.removeEventListener('mousedown', handleClickOutside); }; } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [dropdownOpen]); const handleSaveArea = async (areaData: Partial) => { try { useStore.getState().areasStore.setLoading(true); let result: Area; if (areaData.id && areaData.id !== 0) { result = await updateArea(areaData.id, { name: areaData.name, description: areaData.description, }); // Update the existing area in the list const currentAreas = useStore.getState().areasStore.areas; useStore .getState() .areasStore.setAreas( currentAreas.map((area: any) => area.id === result.id ? result : area ) ); } else { result = await createArea({ name: areaData.name, description: areaData.description, }); // Add the new area immediately to global state const currentAreas = useStore.getState().areasStore.areas; const newAreas = [...currentAreas, result]; useStore.getState().areasStore.setAreas(newAreas); // Force a re-fetch to ensure consistency setTimeout(async () => { const freshAreas = await fetchAreas(); useStore.getState().areasStore.setAreas(freshAreas); }, 100); } // Close modal only on success setIsAreaModalOpen(false); setSelectedArea(null); useStore.getState().areasStore.setError(false); } catch (error) { console.error('Error saving area:', error); useStore.getState().areasStore.setError(true); } finally { useStore.getState().areasStore.setLoading(false); } }; const handleEditArea = (area: Area) => { setSelectedArea(area); setIsAreaModalOpen(true); }; const openConfirmDialog = (area: Area) => { setAreaToDelete(area); setIsConfirmDialogOpen(true); }; const handleDeleteArea = async () => { if (!areaToDelete) return; useStore.getState().areasStore.setLoading(true); try { await deleteArea(areaToDelete.id!); // Remove the area from global state immediately const currentAreas = useStore.getState().areasStore.areas; useStore .getState() .areasStore.setAreas( currentAreas.filter( (area: any) => area.id !== areaToDelete.id ) ); setIsConfirmDialogOpen(false); setAreaToDelete(null); useStore.getState().areasStore.setError(false); } catch (error) { console.error('Error deleting area:', error); useStore.getState().areasStore.setError(true); } finally { useStore.getState().areasStore.setLoading(false); } }; const closeConfirmDialog = () => { setIsConfirmDialogOpen(false); setAreaToDelete(null); }; return (
{/* Areas Header */}

{t('areas.title')}

{/* Areas Grid */} {areas.length === 0 ? (

{t('areas.noAreasFound')}

) : (
{areas.map((area: any) => ( {/* Area Content - Centered */}

{area.name}

{area.description && (

{area.description}

)}
{/* Three Dots Dropdown - Bottom Right */}
{dropdownOpen === area.id && (
)}
))}
)} {/* AreaModal */} {isAreaModalOpen && ( setIsAreaModalOpen(false)} onSave={handleSaveArea} onDelete={async (areaId) => { try { await deleteArea(areaId); const updatedAreas = await fetchAreas(); useStore .getState() .areasStore.setAreas(updatedAreas); setIsAreaModalOpen(false); setSelectedArea(null); } catch (error) { console.error( 'Error deleting area from modal:', error ); useStore.getState().areasStore.setError(true); } }} area={selectedArea} /> )} {/* ConfirmDialog */} {isConfirmDialogOpen && areaToDelete && ( )}
); }; export default Areas;