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 { warehouseReceiptDetailOptions, type WarehouseReceipt, } 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", }; function formatFileSize(bytes: number): string { if (bytes < 1024) return `${bytes} B`; if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} kB`; return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; } export default function WarehouseReceiptDetail() { const { id } = useParams(); const alert = useAlert(); const { hasPermission } = useAuth(); const navigate = useNavigate(); const [cancelConfirm, setCancelConfirm] = useState(false); const { data: receipt, isPending, error, } = useQuery(warehouseReceiptDetailOptions(id)); if (!hasPermission("warehouse.view")) return ; const canOperate = hasPermission("warehouse.operate"); const confirmMutation = useApiMutation({ url: () => receipt ? `/api/admin/warehouse/receipts/${receipt.id}/confirm` : "/api/admin/warehouse/receipts/0/confirm", method: () => "POST", invalidate: ["warehouse"], onSuccess: () => { alert.success("Doklad byl potvrzen"); }, }); const cancelMutation = useApiMutation({ url: () => receipt ? `/api/admin/warehouse/receipts/${receipt.id}/cancel` : "/api/admin/warehouse/receipts/0/cancel", method: () => "POST", invalidate: ["warehouse"], onSuccess: () => { setCancelConfirm(false); alert.success("Doklad byl zrušen"); }, }); const deleteAttachmentMutation = useApiMutation< { attachmentId: number }, void >({ url: ({ attachmentId }) => receipt ? `/api/admin/warehouse/receipts/${receipt.id}/attachments/${attachmentId}` : `/api/admin/warehouse/receipts/0/attachments/0`, method: () => "DELETE", invalidate: ["warehouse"], onSuccess: () => { alert.success("Příloha byla smazána"); }, }); const handleConfirm = async () => { if (!receipt) return; try { await confirmMutation.mutateAsync(undefined); } catch (e) { alert.error(e instanceof Error ? e.message : "Chyba připojení"); } }; const handleCancel = async () => { if (!receipt) return; try { await cancelMutation.mutateAsync(undefined); } catch (e) { alert.error(e instanceof Error ? e.message : "Chyba připojení"); } }; const handleDeleteAttachment = async (attachmentId: number) => { if (!receipt) return; try { await deleteAttachmentMutation.mutateAsync({ attachmentId }); } 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 || !receipt) { return (

Doklad nebyl nalezen.

); } const r = receipt as WarehouseReceipt; const items = r.items ?? []; const attachments = r.attachments ?? []; return (
{/* Header */}

{r.receipt_number || "Nový doklad"}

{r.supplier?.name && (

{r.supplier.name}

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

Základní údaje

{r.receipt_number || "—"}
{r.supplier?.name || "—"}
{r.delivery_note_number || "—"}
{formatDate(r.delivery_note_date)}
{r.received_by_user ? `${r.received_by_user.first_name} ${r.received_by_user.last_name}` : "—"}
{formatDate(r.created_at)}
{r.notes && (
{r.notes}
)}
{/* Lines table */}

Položky

{items.length === 0 ? (
Žádné řádky
) : (
{items.map((item) => ( ))}
Položka Množství Cena/ks Celkem Lokace Poznámka
{item.item?.name || `ID: ${item.item_id}`} {Number(item.quantity)} {formatCurrency(Number(item.unit_price), "CZK")} {formatCurrency( Number(item.quantity) * Number(item.unit_price), "CZK", )} {item.location?.code || "—"} {item.notes || "—"}
)}
{/* Attachments */}

Přílohy

{attachments.length === 0 ? (
Žádné přílohy
) : (
{attachments.map((att) => ( ))}
Název souboru Velikost Datum Akce
{att.file_name} {formatFileSize(att.file_size)} {formatDate(att.created_at)}
{r.status === "DRAFT" && canOperate && ( )}
)}
{/* Cancel confirmation modal */} setCancelConfirm(false)} onConfirm={handleCancel} title="Zrušit doklad" message={`Opravdu chcete zrušit příjmový doklad „${r.receipt_number || r.id}"?`} confirmText="Zrušit doklad" confirmVariant="danger" loading={cancelling} />
); }