import { useState } from "react"; import { useParams, Link as RouterLink } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; import { useAlert } from "../context/AlertContext"; import { useAuth } from "../context/AuthContext"; import Forbidden from "../components/Forbidden"; import { formatDate } from "../utils/formatters"; import { warehouseInventoryDetailOptions, type WarehouseInventorySession, type WarehouseInventoryItem, } from "../lib/queries/warehouse"; import { useApiMutation } from "../lib/queries/mutations"; import { Button, Card, DataTable, StatusChip, EmptyState, LoadingState, PageHeader, PageEnter, ConfirmDialog, headerActionsSx, type DataColumn, } from "../ui"; const STATUS_COLOR: Record< string, "default" | "success" | "error" | "warning" | "info" > = { DRAFT: "warning", CONFIRMED: "success", }; const STATUS_LABEL: Record = { DRAFT: "Návrh", CONFIRMED: "Potvrzeno", }; const BackIcon = ( ); export default function WarehouseInventoryDetail() { const { id } = useParams(); const alert = useAlert(); const { hasPermission } = useAuth(); const [showConfirmModal, setShowConfirmModal] = useState(false); const { data: session, isPending, error, } = useQuery(warehouseInventoryDetailOptions(id)); const confirmMutation = useApiMutation({ url: (sessionId) => `/api/admin/warehouse/inventory-sessions/${sessionId}/confirm`, method: () => "POST", invalidate: ["warehouse"], onSuccess: () => { setShowConfirmModal(false); alert.success("Inventura byla potvrzena"); }, }); // All hooks above this line — permission gate is the last thing before render. if (!hasPermission("warehouse.inventory")) return ; const handleConfirm = async () => { if (!session) return; try { await confirmMutation.mutateAsync(session.id); } catch (e) { alert.error(e instanceof Error ? e.message : "Chyba připojení"); } }; const confirming = confirmMutation.isPending; if (isPending) { return ; } if (error || !session) { return ( Zpět } /> ); } const s = session as WarehouseInventorySession; const items = s.items ?? []; const itemColumns: DataColumn[] = [ { key: "item", header: "Položka", width: "25%", bold: true, render: (row) => row.item?.name || `ID: ${row.item_id}`, }, { key: "location", header: "Lokace", width: "15%", mono: true, render: (row) => row.location?.code || "—", }, { key: "system_qty", header: "Systémové množství", width: "18%", mono: true, render: (row) => String(Number(row.system_qty)), }, { key: "actual_qty", header: "Skutečné množství", width: "18%", mono: true, render: (row) => String(Number(row.actual_qty)), }, { key: "difference", header: "Rozdíl", width: "12%", render: (row) => { const diff = Number(row.difference); const color = diff > 0 ? "success.main" : diff < 0 ? "error.main" : "text.secondary"; return ( {diff > 0 ? `+${diff}` : diff} ); }, }, { key: "notes", header: "Poznámka", width: "12%", render: (row) => row.notes || "—", }, ]; return ( {/* Header */} {s.status === "DRAFT" && ( )} } /> {/* Header info */} Základní údaje Číslo inventury {s.session_number || "—"} Vytvořeno {formatDate(s.created_at)} {s.notes && ( Poznámky {s.notes} )} {/* Lines table */} Položky columns={itemColumns} rows={items} rowKey={(row) => row.id} empty={} /> {/* Confirm modal */} setShowConfirmModal(false)} onConfirm={handleConfirm} title="Potvrdit inventuru" message={`Opravdu chcete potvrdit inventuru „${s.session_number || s.id}"? Potvrzením se aktualizují skladové zásoby.`} confirmText="Potvrdit inventuru" loading={confirming} /> ); }