import { useEffect } from "react"; import { Wand2 } from "lucide-react"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/Components/ui/dialog"; import { Button } from "@/Components/ui/button"; import { Input } from "@/Components/ui/input"; import { Label } from "@/Components/ui/label"; import { Textarea } from "@/Components/ui/textarea"; import { SearchableSelect } from "@/Components/ui/searchable-select"; import { useForm } from "@inertiajs/react"; import { toast } from "sonner"; import type { Product, Category } from "@/Pages/Product/Index"; import type { Unit } from "@/Components/Unit/UnitManagerDialog"; interface ProductDialogProps { open: boolean; onOpenChange: (open: boolean) => void; product: Product | null; categories: Category[]; units: Unit[]; onSave?: (product: any) => void; // Legacy prop, can be removed if fully switching to Inertia submit within dialog } export default function ProductDialog({ open, onOpenChange, product, categories, units, }: ProductDialogProps) { const { data, setData, post, put, processing, errors, reset, clearErrors } = useForm({ code: "", barcode: "", name: "", category_id: "", brand: "", specification: "", base_unit_id: "", large_unit_id: "", conversion_rate: "", purchase_unit_id: "", }); useEffect(() => { if (open) { clearErrors(); if (product) { setData({ code: product.code, barcode: product.barcode || "", name: product.name, category_id: product.categoryId.toString(), brand: product.brand || "", specification: product.specification || "", base_unit_id: product.baseUnitId?.toString() || "", large_unit_id: product.largeUnitId?.toString() || "", conversion_rate: product.conversionRate ? product.conversionRate.toString() : "", purchase_unit_id: product.purchaseUnitId?.toString() || "", }); } else { reset(); // Set default category if available if (categories.length > 0) { setData("category_id", categories[0].id.toString()); } } } }, [open, product, categories]); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (product) { put(route("products.update", product.id), { onSuccess: () => { toast.success("商品已更新"); onOpenChange(false); reset(); }, onError: () => { toast.error("更新失敗,請檢查輸入資料"); } }); } else { post(route("products.store"), { onSuccess: () => { toast.success("商品已新增"); onOpenChange(false); reset(); }, onError: () => { toast.error("新增失敗,請檢查輸入資料"); } }); } }; const generateRandomBarcode = () => { const randomDigits = Math.floor(Math.random() * 9000000000) + 1000000000; setData("barcode", randomDigits.toString()); }; return ( {product ? "編輯商品" : "新增商品"} {product ? "修改商品資料" : "建立新的商品資料"}
{/* 基本資訊區塊 */}

基本資訊

setData("category_id", value)} options={categories.map((c) => ({ label: c.name, value: c.id.toString() }))} placeholder="選擇分類" searchPlaceholder="搜尋分類..." className={errors.category_id ? "border-red-500" : ""} /> {errors.category_id &&

{errors.category_id}

}
setData("name", e.target.value)} placeholder="例:法國麵粉" className={errors.name ? "border-red-500" : ""} /> {errors.name &&

{errors.name}

}
setData("code", e.target.value)} placeholder="例:A1 (2-8碼)" maxLength={8} className={errors.code ? "border-red-500" : ""} /> {errors.code &&

{errors.code}

}
setData("barcode", e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); // 掃描後自動跳轉到下一個欄位(品牌) document.getElementById('brand')?.focus(); } }} placeholder="輸入條碼或自動生成" className={`flex-1 ${errors.barcode ? "border-red-500" : ""}`} />
{errors.barcode &&

{errors.barcode}

}
setData("brand", e.target.value)} placeholder="例:鳥越製粉" /> {errors.brand &&

{errors.brand}

}