From 06c6e242e74df5378b30ed60d8daa758cdbf072c Mon Sep 17 00:00:00 2001 From: BOHA Date: Sat, 6 Jun 2026 23:33:20 +0200 Subject: [PATCH] =?UTF-8?q?feat(mui):=20migrate=20Warehouse=20Receipts=20(?= =?UTF-8?q?P=C5=99=C3=ADjmy)=20onto=20MUI=20kit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- src/admin/pages/WarehouseReceipts.tsx | 446 ++++++++++++-------------- 1 file changed, 206 insertions(+), 240 deletions(-) diff --git a/src/admin/pages/WarehouseReceipts.tsx b/src/admin/pages/WarehouseReceipts.tsx index d06e948..21949f1 100644 --- a/src/admin/pages/WarehouseReceipts.tsx +++ b/src/admin/pages/WarehouseReceipts.tsx @@ -1,12 +1,10 @@ import { useState } from "react"; import { useNavigate } 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 AdminDatePicker from "../components/AdminDatePicker"; -import { motion, AnimatePresence } from "framer-motion"; -import Pagination from "../components/Pagination"; +import { motion } from "framer-motion"; +import Box from "@mui/material/Box"; import useDebounce from "../hooks/useDebounce"; import { usePaginatedQuery } from "../hooks/usePaginatedQuery"; @@ -16,13 +14,31 @@ import { warehouseSupplierListOptions, type WarehouseReceipt, } from "../lib/queries/warehouse"; +import { + Button, + Card, + DataTable, + Pagination, + TextField, + Select, + DateField, + StatusChip, + PageHeader, + FilterBar, + EmptyState, + LoadingState, + type DataColumn, +} from "../ui"; const PER_PAGE = 20; -const STATUS_BADGE: Record = { - DRAFT: "admin-badge-warning", - CONFIRMED: "admin-badge-active", - CANCELLED: "admin-badge-danger", +const STATUS_COLOR: Record< + string, + "warning" | "success" | "error" | "info" | "default" +> = { + DRAFT: "warning", + CONFIRMED: "success", + CANCELLED: "error", }; const STATUS_LABEL: Record = { @@ -31,8 +47,23 @@ const STATUS_LABEL: Record = { CANCELLED: "Zrušeno", }; +const PlusIcon = ( + + + + +); + export default function WarehouseReceipts() { const { hasPermission } = useAuth(); + const navigate = useNavigate(); const [page, setPage] = useState(1); const [search, setSearch] = useState(""); @@ -60,16 +91,10 @@ export default function WarehouseReceipts() { }), ); - const navigate = useNavigate(); - if (!hasPermission("warehouse.view")) return ; const canOperate = hasPermission("warehouse.operate"); - const handleRowClick = (receipt: WarehouseReceipt) => { - navigate(`/warehouse/receipts/${receipt.id}`); - }; - const resetFilters = () => { setSearch(""); setStatusFilter(""); @@ -79,252 +104,193 @@ export default function WarehouseReceipts() { setPage(1); }; - const hasActiveFilters = statusFilter || supplierId || dateFrom || dateTo; + const hasActiveFilters = !!(statusFilter || supplierId || dateFrom || dateTo); if (isPending) { - return ( -
-
-
- ); + return ; } + const total = pagination?.total ?? items.length; + const subtitle = `${total} ${ + total === 1 ? "doklad" : total >= 2 && total <= 4 ? "doklady" : "dokladů" + }`; + + const columns: DataColumn[] = [ + { + key: "receipt_number", + header: "Číslo dokladu", + width: "15%", + mono: true, + bold: true, + render: (r) => r.receipt_number || "—", + }, + { + key: "supplier", + header: "Dodavatel", + width: "22%", + render: (r) => r.supplier?.name || "—", + }, + { + key: "status", + header: "Stav", + width: "13%", + render: (r) => ( + + ), + }, + { + key: "delivery_note_number", + header: "Dodací list", + width: "18%", + mono: true, + render: (r) => r.delivery_note_number || "—", + }, + { + key: "created_at", + header: "Vytvořeno", + width: "18%", + mono: true, + render: (r) => formatDate(r.created_at), + }, + { + key: "items_count", + header: "Položek", + width: "14%", + mono: true, + render: (r) => String(r._count?.items ?? 0), + }, + ]; + return ( -
+ -
-

Příjmové doklady

-

- {pagination?.total ?? items.length}{" "} - {pagination?.total === 1 - ? "doklad" - : pagination?.total !== undefined && - pagination.total >= 2 && - pagination.total <= 4 - ? "doklady" - : "dokladů"} -

-
-
- {canOperate && ( - - )} -
+ Nový doklad + + ) : undefined + } + />
- -
-
-
- - - - - { - setSearch(e.target.value); - setPage(1); - }} - placeholder="Hledat podle čísla dokladu..." - className="admin-form-input" - /> -
- - {suppliers.length > 0 && ( - - )} - + + { + setSearch(e.target.value); + setPage(1); + }} + placeholder="Hledat podle čísla dokladu..." + fullWidth + /> + + + { - setDateFrom(val); + setSupplierId(val === "" ? "" : Number(val)); setPage(1); }} - placeholder="Od" + options={[ + { value: "", label: "Všichni dodavatelé" }, + ...suppliers.map((s) => ({ + value: String(s.id), + label: s.name, + })), + ]} /> - { - setDateTo(val); - setPage(1); - }} - placeholder="Do" - /> - {hasActiveFilters && ( - - )} -
+ + )} + + { + setDateFrom(val); + setPage(1); + }} + label="Od" + /> + + + { + setDateTo(val); + setPage(1); + }} + label="Do" + /> + + {hasActiveFilters && ( + + )} + - - - {items.length === 0 && ( -
-
- - - - - - -
-

- {search || hasActiveFilters - ? "Žádné doklady pro zadaný filtr." - : "Zatím nejsou žádné příjmové doklady."} -

- {canOperate && !search && !hasActiveFilters && ( - - )} -
- )} - {items.length > 0 && ( -
- - - - - - - - - - - - - {items.map((receipt) => ( - handleRowClick(receipt)} - style={{ cursor: "pointer" }} - > - - - - - - - - ))} - -
Číslo dokladuDodavatelStavDodací listVytvořenoPoložek
- {receipt.receipt_number || "—"} - - {receipt.supplier?.name || "—"} - - - {STATUS_LABEL[receipt.status] ?? receipt.status} - - - {receipt.delivery_note_number || "—"} - - {formatDate(receipt.created_at)} - - {receipt._count?.items ?? 0} -
-
- )} -
-
- - -
-
-
+ + ) : undefined + } + /> + ) + } + /> + + + ); }