From 601db41a09a56726a0b2ab16fed0f7f3f1bcf105 Mon Sep 17 00:00:00 2001 From: BOHA Date: Sun, 7 Jun 2026 08:04:57 +0200 Subject: [PATCH] feat(mui): migrate WarehouseReceiptForm onto MUI kit Co-Authored-By: Claude Opus 4.8 (1M context) --- src/admin/pages/WarehouseReceiptForm.tsx | 514 ++++++++++++++++------- 1 file changed, 365 insertions(+), 149 deletions(-) diff --git a/src/admin/pages/WarehouseReceiptForm.tsx b/src/admin/pages/WarehouseReceiptForm.tsx index 9969536..93d7cff 100644 --- a/src/admin/pages/WarehouseReceiptForm.tsx +++ b/src/admin/pages/WarehouseReceiptForm.tsx @@ -1,20 +1,34 @@ import { useState, useEffect, useRef, useCallback, useId } from "react"; -import { useParams, useNavigate, Link } from "react-router-dom"; +import { useParams, useNavigate, Link as RouterLink } from "react-router-dom"; import { useQuery, useQueryClient } from "@tanstack/react-query"; +import { motion } from "framer-motion"; +import Box from "@mui/material/Box"; +import Typography from "@mui/material/Typography"; +import IconButton from "@mui/material/IconButton"; +import CircularProgress from "@mui/material/CircularProgress"; import { useAlert } from "../context/AlertContext"; import { useAuth } from "../context/AuthContext"; import Forbidden from "../components/Forbidden"; -import { motion } from "framer-motion"; -import FormField from "../components/FormField"; -import AdminDatePicker from "../components/AdminDatePicker"; -import SupplierSelect from "../components/warehouse/SupplierSelect"; -import WarehouseMovementTable, { - type MovementItem, -} from "../components/warehouse/WarehouseMovementTable"; +import ItemPicker from "../components/warehouse/ItemPicker"; import apiFetch from "../utils/api"; -import { warehouseReceiptDetailOptions } from "../lib/queries/warehouse"; +import { + warehouseReceiptDetailOptions, + warehouseSupplierListOptions, + warehouseLocationListOptions, + type WarehouseSupplier, + type WarehouseLocation, +} from "../lib/queries/warehouse"; import { useApiMutation } from "../lib/queries/mutations"; +import { + Button, + Card, + TextField, + Select, + DateField, + Field, + LoadingState, +} from "../ui"; interface ReceiptForm { supplier_id: number | null; @@ -23,6 +37,84 @@ interface ReceiptForm { notes: string; } +interface MovementItem { + key: string; + item_id: number | null; + item_name?: string; + quantity: number; + unit_price: number; + location_id: number | null; + batch_id: number | null; + reservation_id: number | null; + notes: string | null; +} + +function parseDecimal(raw: string): number { + const cleaned = raw.replace(/[eE+\-]/g, ""); + const n = Number(cleaned); + return Number.isFinite(n) ? n : 0; +} + +const BackIcon = ( + + + +); + +const RemoveIcon = ( + + + + +); + +const PlusIcon = ( + + + + +); + +const UploadIcon = ( + + + + + +); + export default function WarehouseReceiptForm() { const { id } = useParams(); const alert = useAlert(); @@ -68,6 +160,13 @@ export default function WarehouseReceiptForm() { warehouseReceiptDetailOptions(isEdit ? id : undefined), ); + const { data: suppliersData } = useQuery( + warehouseSupplierListOptions({ perPage: 100 }), + ); + const suppliers: WarehouseSupplier[] = suppliersData?.data ?? []; + + const { data: locations } = useQuery(warehouseLocationListOptions()); + useEffect(() => { formInitialized.current = false; }, [id]); @@ -119,6 +218,22 @@ export default function WarehouseReceiptForm() { ]); }; + const removeItem = (index: number) => { + setItems((prev) => prev.filter((_, i) => i !== index)); + }; + + const updateItem = ( + index: number, + field: keyof MovementItem, + value: unknown, + ) => { + setItems((prev) => { + const updated = [...prev]; + updated[index] = { ...updated[index], [field]: value }; + return updated; + }); + }; + const validate = (): boolean => { const newErrors: Record = {}; const validItems = items.filter((l) => l.item_id !== null); @@ -275,167 +390,263 @@ export default function WarehouseReceiptForm() { }, []); if (isEdit && isPending) { - return ( -
-
-
- ); + return ; } + const supplierOptions = [ + { value: "", label: "-- bez dodavatele --" }, + ...suppliers.map((s) => ({ + value: String(s.id), + label: `${s.name}${s.ico ? ` (${s.ico})` : ""}`, + })), + ]; + + const locationOptions = [ + { value: "", label: "-- bez lokace --" }, + ...(locations ?? []).map((loc: WarehouseLocation) => ({ + value: String(loc.id), + label: `${loc.code} - ${loc.name}`, + })), + ]; + return ( -
+ {/* Header */} -
- - + + - - - -
-

+ {BackIcon} + + {isEdit ? "Upravit příjmový doklad" : "Nový příjmový doklad"} -

-
-
-
- - -
+ +
+ + + + + {/* Header fields */} -
-

Základní údaje

-
- - - setForm((prev) => ({ ...prev, supplier_id: val })) - } - /> - -
- - - setForm((prev) => ({ - ...prev, - delivery_note_number: e.target.value, - })) - } - className="admin-form-input" - placeholder="Např. DL-2024-001" - /> - - - - setForm((prev) => ({ - ...prev, - delivery_note_date: val, - })) - } - /> - -
- -