import { useState } from "react"; import { useNavigate } from "react-router-dom"; import { useQuery } from "@tanstack/react-query"; import { useAuth } from "../context/AuthContext"; import Forbidden from "../components/Forbidden"; import Box from "@mui/material/Box"; import useDebounce from "../hooks/useDebounce"; import { usePaginatedQuery } from "../hooks/usePaginatedQuery"; import { formatDate } from "../utils/formatters"; import { warehouseIssueListOptions, type WarehouseIssue, } from "../lib/queries/warehouse"; import { projectListOptions, type Project } from "../lib/queries/projects"; import { Button, Card, DataTable, Pagination, TextField, Select, DateField, StatusChip, PageHeader, PageEnter, FilterBar, EmptyState, LoadingState, type DataColumn, } from "../ui"; const PER_PAGE = 20; const STATUS_COLOR: Record< string, "warning" | "success" | "error" | "info" | "default" > = { DRAFT: "warning", CONFIRMED: "success", CANCELLED: "error", }; const STATUS_LABEL: Record = { DRAFT: "Návrh", CONFIRMED: "Potvrzeno", CANCELLED: "Zrušeno", }; const PlusIcon = ( ); export default function WarehouseIssues() { const { hasPermission } = useAuth(); const navigate = useNavigate(); const [page, setPage] = useState(1); const [search, setSearch] = useState(""); const [statusFilter, setStatusFilter] = useState(""); const [projectId, setProjectId] = useState(""); const [dateFrom, setDateFrom] = useState(""); const [dateTo, setDateTo] = useState(""); const debouncedSearch = useDebounce(search, 300); const { data: projectsData } = useQuery(projectListOptions({ perPage: 100 })); const projects = projectsData?.data ?? []; const { items, pagination, isPending, isFetching } = usePaginatedQuery( warehouseIssueListOptions({ search: debouncedSearch || undefined, page, perPage: PER_PAGE, status: statusFilter || undefined, project_id: projectId ? Number(projectId) : undefined, date_from: dateFrom || undefined, date_to: dateTo || undefined, }), ); if (!hasPermission("warehouse.view")) return ; const canOperate = hasPermission("warehouse.operate"); const resetFilters = () => { setSearch(""); setStatusFilter(""); setProjectId(""); setDateFrom(""); setDateTo(""); setPage(1); }; const hasActiveFilters = !!(statusFilter || projectId || dateFrom || dateTo); if (isPending) { return ; } const total = pagination?.total ?? items.length; const subtitle = `${total} ${ total === 1 ? "doklad" : total >= 2 && total <= 4 ? "doklady" : "dokladů" }`; const columns: DataColumn[] = [ { key: "issue_number", header: "Číslo dokladu", width: "15%", mono: true, bold: true, render: (r) => r.issue_number || "—", }, { key: "project", header: "Projekt", width: "25%", render: (r) => r.project ? `${r.project.project_number} – ${r.project.name}` : "—", }, { key: "status", header: "Stav", width: "13%", render: (r) => ( ), }, { key: "issued_by_user", header: "Vydal", width: "20%", render: (r) => r.issued_by_user ? `${r.issued_by_user.first_name} ${r.issued_by_user.last_name}` : "—", }, { key: "created_at", header: "Vytvořeno", width: "14%", mono: true, render: (r) => formatDate(r.created_at), }, { key: "items_count", header: "Položek", width: "13%", mono: true, render: (r) => String(r._count?.items ?? 0), }, ]; return ( navigate("/warehouse/issues/new")} > Nová výdejka ) : undefined } /> { setSearch(e.target.value); setPage(1); }} placeholder="Hledat podle čísla dokladu..." fullWidth /> { setProjectId(val === "" ? "" : Number(val)); setPage(1); }} options={[ { value: "", label: "Všechny projekty" }, ...projects.map((p: Project) => ({ value: String(p.id), label: `${p.project_number} – ${p.name}`, })), ]} /> )} { setDateFrom(val); setPage(1); }} label="Od" /> { setDateTo(val); setPage(1); }} label="Do" /> {hasActiveFilters && ( )} columns={columns} rows={items} rowKey={(r) => r.id} onRowClick={(r) => navigate(`/warehouse/issues/${r.id}`)} empty={ search || hasActiveFilters ? ( ) : ( navigate("/warehouse/issues/new")} > Vytvořit první výdejku ) : undefined } /> ) } /> ); }