139 lines
5.0 KiB
TypeScript
139 lines
5.0 KiB
TypeScript
import React, { useState, useMemo, useEffect } from 'react';
|
|
import { Location, Coop, Floor } from '../types.ts';
|
|
import { SitemapIcon } from './icons/Icons.tsx';
|
|
import StructureColumn from './location/StructureColumn.tsx';
|
|
import FloorDetails from './location/FloorDetails.tsx';
|
|
import FormModal from './location/FormModal.tsx';
|
|
import { useAppContext } from '../context/AppContext.tsx';
|
|
|
|
type ModalState = {
|
|
mode: 'add' | 'edit' | null;
|
|
type: 'location' | 'coop' | 'floor' | null;
|
|
data?: Location | Coop | Floor;
|
|
};
|
|
|
|
const LocationManagementPage: React.FC = () => {
|
|
const {
|
|
locations,
|
|
coops,
|
|
floors,
|
|
cameras,
|
|
iotDevices,
|
|
onAddLocation,
|
|
onUpdateLocation,
|
|
onDeleteLocation,
|
|
onAddCoop,
|
|
onUpdateCoop,
|
|
onDeleteCoop,
|
|
onAddFloor,
|
|
onUpdateFloor,
|
|
onDeleteFloor,
|
|
} = useAppContext();
|
|
|
|
const [selectedLocationId, setSelectedLocationId] = useState<string | null>(
|
|
locations[0]?.id || null
|
|
);
|
|
const [selectedCoopId, setSelectedCoopId] = useState<string | null>(null);
|
|
const [modalState, setModalState] = useState<ModalState>({ mode: null, type: null });
|
|
|
|
useEffect(() => {
|
|
if (selectedLocationId && !coops.some((c) => c.locationId === selectedLocationId)) {
|
|
setSelectedCoopId(null);
|
|
} else if (selectedLocationId) {
|
|
const firstCoop = coops.find((c) => c.locationId === selectedLocationId);
|
|
setSelectedCoopId(firstCoop?.id || null);
|
|
}
|
|
}, [selectedLocationId, coops]);
|
|
|
|
useEffect(() => {
|
|
if (!locations.some((l) => l.id === selectedLocationId)) {
|
|
setSelectedLocationId(locations[0]?.id || null);
|
|
}
|
|
}, [locations]);
|
|
|
|
const filteredCoops = useMemo(() => {
|
|
return coops.filter((c) => c.locationId === selectedLocationId);
|
|
}, [coops, selectedLocationId]);
|
|
|
|
const handleSelectLocation = (id: string) => {
|
|
setSelectedLocationId(id);
|
|
const firstCoop = coops.find((c) => c.locationId === id);
|
|
setSelectedCoopId(firstCoop?.id || null);
|
|
};
|
|
|
|
const handleSelectCoop = (id: string) => {
|
|
setSelectedCoopId(id);
|
|
};
|
|
|
|
const handleSave = (name: string) => {
|
|
if (modalState.mode === 'add') {
|
|
if (modalState.type === 'location') onAddLocation(name);
|
|
if (modalState.type === 'coop' && selectedLocationId) onAddCoop(name, selectedLocationId);
|
|
if (modalState.type === 'floor' && selectedCoopId) onAddFloor(name, selectedCoopId);
|
|
} else if (modalState.mode === 'edit' && modalState.data) {
|
|
if (modalState.type === 'location')
|
|
onUpdateLocation({ ...(modalState.data as Location), name });
|
|
if (modalState.type === 'coop') onUpdateCoop({ ...(modalState.data as Coop), name });
|
|
if (modalState.type === 'floor') onUpdateFloor({ ...(modalState.data as Floor), name });
|
|
}
|
|
setModalState({ mode: null, type: null });
|
|
};
|
|
|
|
return (
|
|
<main className="px-4 sm:px-6 lg:px-8 pb-8">
|
|
<div className="flex items-center mb-6">
|
|
<SitemapIcon className="text-3xl text-red-600 mr-4" />
|
|
<div>
|
|
<h1 className="text-3xl font-bold text-gray-800">Manajemen Struktur Peternakan</h1>
|
|
<p className="mt-1 text-gray-600">
|
|
Atur lokasi, kandang, dan lantai untuk semua fasilitas Anda.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 h-[calc(100vh-200px)]">
|
|
<StructureColumn
|
|
title="Lokasi"
|
|
items={locations}
|
|
selectedId={selectedLocationId}
|
|
onSelect={handleSelectLocation}
|
|
onAdd={() => setModalState({ mode: 'add', type: 'location' })}
|
|
onEdit={(item) => setModalState({ mode: 'edit', type: 'location', data: item })}
|
|
onDelete={onDeleteLocation}
|
|
/>
|
|
<StructureColumn
|
|
title="Kandang"
|
|
items={filteredCoops}
|
|
selectedId={selectedCoopId}
|
|
onSelect={handleSelectCoop}
|
|
onAdd={() => selectedLocationId && setModalState({ mode: 'add', type: 'coop' })}
|
|
onEdit={(item) => setModalState({ mode: 'edit', type: 'coop', data: item })}
|
|
onDelete={onDeleteCoop}
|
|
disabled={!selectedLocationId}
|
|
/>
|
|
<FloorDetails
|
|
selectedCoop={coops.find((c) => c.id === selectedCoopId) || null}
|
|
floors={floors.filter((f) => f.coopId === selectedCoopId)}
|
|
cameras={cameras}
|
|
iotDevices={iotDevices}
|
|
onAddFloor={() => selectedCoopId && setModalState({ mode: 'add', type: 'floor' })}
|
|
onEditFloor={(floor) => setModalState({ mode: 'edit', type: 'floor', data: floor })}
|
|
onDeleteFloor={onDeleteFloor}
|
|
/>
|
|
</div>
|
|
|
|
{modalState.mode && (
|
|
<FormModal
|
|
isOpen={!!modalState.mode}
|
|
onClose={() => setModalState({ mode: null, type: null })}
|
|
onSave={handleSave}
|
|
title={`${modalState.mode === 'add' ? 'Tambah' : 'Edit'} ${modalState.type === 'location' ? 'Lokasi' : modalState.type === 'coop' ? 'Kandang' : 'Lantai'}`}
|
|
initialValue={modalState.mode === 'edit' && modalState.data ? modalState.data.name : ''}
|
|
/>
|
|
)}
|
|
</main>
|
|
);
|
|
};
|
|
|
|
export default LocationManagementPage;
|