import React, { useMemo, useState } from 'react'; import { useParams } from 'react-router-dom'; import { PlusIcon } from '@heroicons/react/24/outline'; import PageHeader from '../components/ui/PageHeader'; import DataTable, { type Column } from '../components/ui/DataTable'; import Modal from '../components/ui/Modal'; import ConfirmDialog from '../components/ui/ConfirmDialog'; import { ActiveBadge } from '../components/ui/StatusBadge'; import { useUrlState } from '../hooks/useUrlState'; import { usePermissions } from '../hooks/usePermissions'; import { useBranchRooms, useBranches } from '../hooks/useBranches'; import type { Room, RoomPayload } from '../types'; /** اتاق‌های یک شعبه. ظرفیت = چند بیمار هم‌زمان، نه چند اتاق. */ export default function BranchRoomsPage() { const { branchUuid } = useParams<{ branchUuid: string }>(); const { rooms, loading, create, update, remove } = useBranchRooms(branchUuid); const { branches } = useBranches(); const { can } = usePermissions(); const canUpdate = can('appointment_settings', 'update'); const branch = branches.find((b) => b.uuid === branchUuid); const [urlState, setUrlState] = useUrlState({ search: '' }); const [editing, setEditing] = useState<{ open: boolean; room: Room | null }>({ open: false, room: null }); const [toDelete, setToDelete] = useState(null); const rows = useMemo(() => { const q = urlState.search.trim(); return q === '' ? rooms : rooms.filter((r) => `${r.name} ${r.room_type ?? ''}`.includes(q)); }, [rooms, urlState.search]); const columns: Column[] = [ { key: 'name', header: 'نام اتاق', render: (r) => {r.name} }, { key: 'room_type', header: 'نوع', render: (r) => {r.room_type || '—'} }, { key: 'capacity', header: 'ظرفیت هم‌زمان', render: (r) => {r.capacity} نفر, }, { key: 'floor', header: 'طبقه', render: (r) => {r.floor || '—'} }, { key: 'active', header: 'وضعیت', render: (r) => }, ]; const save = (payload: RoomPayload) => { const opts = { onSuccess: () => setEditing({ open: false, room: null }) }; if (editing.room) update.mutate({ uuid: editing.room.uuid, d: payload }, opts); else create.mutate(payload, opts); }; return (
setEditing({ open: true, room: null })}> افزودن اتاق ) : undefined } /> setUrlState({ search: v })} searchPlaceholder="جستجو در اتاق‌ها..." emptyMessage="هنوز اتاقی برای این شعبه ثبت نشده است" actions={ canUpdate ? (r) => (
) : undefined } /> setEditing({ open: false, room: null })} onSave={save} /> toDelete && remove.mutate(toDelete.uuid, { onSuccess: () => setToDelete(null) })} onCancel={() => setToDelete(null)} />
); } function RoomModal({ open, room, saving, onClose, onSave, }: { open: boolean; room: Room | null; saving: boolean; onClose: () => void; onSave: (payload: RoomPayload) => void; }) { const [name, setName] = useState(''); const [roomType, setRoomType] = useState(''); const [capacity, setCapacity] = useState('1'); const [floor, setFloor] = useState(''); const [active, setActive] = useState(true); // فرم با هر بازشدن از روی اتاقِ هدف بازنشانی می‌شود؛ key در والد باعث remount // نمی‌شود چون Modal همیشه mounted است. React.useEffect(() => { if (!open) return; setName(room?.name ?? ''); setRoomType(room?.room_type ?? ''); setCapacity(String(room?.capacity ?? 1)); setFloor(room?.floor ?? ''); setActive(room?.active ?? true); }, [open, room]); const parsedCapacity = Number(capacity); const invalid = name.trim() === '' || !Number.isFinite(parsedCapacity) || parsedCapacity < 1; return (
setName(e.target.value)} placeholder="اتاق تزریق" /> setRoomType(e.target.value)} placeholder="تزریقات" /> setCapacity(e.target.value)} /> setFloor(e.target.value)} placeholder="۲" />
); } function Field({ label, children }: { label: string; children: React.ReactNode }) { return (
{children}
); }