import { useState } from "react"; import { useParams, useNavigate, Link } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import { useAlert } from "../context/AlertContext"; import { useAuth } from "../context/AuthContext"; import Forbidden from "../components/Forbidden"; import { motion } from "framer-motion"; import ConfirmModal from "../components/ConfirmModal"; import FormField from "../components/FormField"; import { formatCurrency, formatDate } from "../utils/formatters"; import { warehouseIssueDetailOptions, type WarehouseIssue, } from "../lib/queries/warehouse"; import { useApiMutation } from "../lib/queries/mutations"; const STATUS_BADGE: Record = { DRAFT: "admin-badge-warning", CONFIRMED: "admin-badge-active", CANCELLED: "admin-badge-danger", }; const STATUS_LABEL: Record = { DRAFT: "Návrh", CONFIRMED: "Potvrzeno", CANCELLED: "Zrušeno", }; export default function WarehouseIssueDetail() { const { id } = useParams(); const alert = useAlert(); const { hasPermission } = useAuth(); const navigate = useNavigate(); const [cancelConfirm, setCancelConfirm] = useState(false); const { data: issue, isPending, error, } = useQuery(warehouseIssueDetailOptions(id)); if (!hasPermission("warehouse.view")) return ; const canOperate = hasPermission("warehouse.operate"); const confirmMutation = useApiMutation({ url: () => issue ? `/api/admin/warehouse/issues/${issue.id}/confirm` : "/api/admin/warehouse/issues/0/confirm", method: () => "POST", invalidate: ["warehouse"], onSuccess: () => { alert.success("Výdejka byla potvrzena"); }, }); const cancelMutation = useApiMutation({ url: () => issue ? `/api/admin/warehouse/issues/${issue.id}/cancel` : "/api/admin/warehouse/issues/0/cancel", method: () => "POST", invalidate: ["warehouse"], onSuccess: () => { setCancelConfirm(false); alert.success("Výdejka byla zrušena"); }, }); const handleConfirm = async () => { if (!issue) return; try { await confirmMutation.mutateAsync(undefined); } catch (e) { alert.error(e instanceof Error ? e.message : "Chyba připojení"); } }; const handleCancel = async () => { if (!issue) return; try { await cancelMutation.mutateAsync(undefined); } catch (e) { alert.error(e instanceof Error ? e.message : "Chyba připojení"); } }; const confirming = confirmMutation.isPending; const cancelling = cancelMutation.isPending; if (isPending) { return (
); } if (error || !issue) { return (

Výdejka nebyla nalezena.

); } const iss = issue as WarehouseIssue; const items = iss.items ?? []; return (
{/* Header */}

{iss.issue_number || "Nová výdejka"}

{iss.project && (

{iss.project.project_number} – {iss.project.name}

)}
{STATUS_LABEL[iss.status] ?? iss.status}
{canOperate && (
{iss.status === "DRAFT" && ( <> )} {iss.status === "CONFIRMED" && ( )}
)}
{/* Header info */}

Základní údaje

{iss.issue_number || "—"}
{iss.issued_by_user ? `${iss.issued_by_user.first_name} ${iss.issued_by_user.last_name}` : "—"}
{formatDate(iss.created_at)}
{iss.notes && (
{iss.notes}
)}
{/* Lines table */}

Položky

{items.length === 0 ? (
Žádné řádky
) : (
{items.map((item) => ( ))}
Položka Šarže Množství Cena/ks Celkem Lokace Rezervace Poznámka
{item.item?.name || `ID: ${item.item_id}`} {item.batch ? `${formatDate(item.batch.received_at)} – ${formatCurrency(Number(item.batch.unit_price), "CZK")}` : "—"} {Number(item.quantity)} {item.batch ? formatCurrency(Number(item.batch.unit_price), "CZK") : "—"} {item.batch ? formatCurrency( Number(item.quantity) * Number(item.batch.unit_price), "CZK", ) : "—"} {item.location?.code || "—"} {item.reservation ? `ID: ${item.reservation.id} (${Number(item.reservation.remaining_qty)} ks)` : "—"} {item.notes || "—"}
)}
{/* Cancel confirmation modal */} setCancelConfirm(false)} onConfirm={handleCancel} title="Zrušit výdejku" message={`Opravdu chcete zrušit výdejku „${iss.issue_number || iss.id}"?`} confirmText="Zrušit výdejku" confirmVariant="danger" loading={cancelling} />
); }