Files
dashboard/components/LocationManagementPage.tsx
T
Alberto-Audrix 32a36cceff
CI / lint-and-test (push) Canceled after 0s
first commit
2026-07-28 08:55:05 +07:00

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;