import { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogDescription, 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 { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/Components/ui/table"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger, } from "@/Components/ui/alert-dialog"; import { router, useForm } from "@inertiajs/react"; import { toast } from "sonner"; import { Trash2, Edit2, Check, X, Plus, Loader2 } from "lucide-react"; export interface Unit { id: string; name: string; code: string | null; } interface UnitManagerDialogProps { open: boolean; onOpenChange: (open: boolean) => void; units: Unit[]; } export default function UnitManagerDialog({ open, onOpenChange, units, }: UnitManagerDialogProps) { const [editingId, setEditingId] = useState(null); const [editName, setEditName] = useState(""); const [editCode, setEditCode] = useState(""); const { data, setData, post, processing, reset, errors, clearErrors } = useForm({ name: "", code: "", }); useEffect(() => { if (!open) { reset(); clearErrors(); setEditingId(null); } }, [open]); const handleAdd = (e: React.FormEvent) => { e.preventDefault(); if (!data.name.trim()) return; post(route("units.store"), { onSuccess: () => { reset(); }, onError: (errors) => { toast.error("新增失敗: " + (errors.name || errors.code || "未知錯誤")); } }); }; const startEdit = (unit: Unit) => { setEditingId(unit.id); setEditName(unit.name); setEditCode(unit.code || ""); }; const cancelEdit = () => { setEditingId(null); setEditName(""); setEditCode(""); }; const saveEdit = (id: string) => { if (!editName.trim()) return; router.put(route("units.update", id), { name: editName, code: editCode }, { onSuccess: () => { setEditingId(null); }, onError: (errors) => { toast.error("更新失敗: " + (errors.name || errors.code || "未知錯誤")); } }); }; const handleDelete = (id: string) => { router.delete(route("units.destroy", id), { onSuccess: () => { // 由全域 flash 處理 }, onError: () => { toast.error("刪除失敗,請確認該單位無關聯商品"); } }); }; return ( 管理單位 在此新增、修改或刪除常用單位。刪除前請確認無關聯商品。
{/* Add New Section */}

快速新增

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

{errors.name}

}
setData("code", e.target.value)} className={errors.code ? "border-red-500" : ""} /> {errors.code &&

{errors.code}

}
{/* List Section */}

現有單位

共 {units.length} 個項目
# 單位名稱 代碼 操作 {units.length === 0 ? ( 目前尚無單位,請從上方新增。 ) : ( units.map((unit, index) => ( {index + 1} {editingId === unit.id ? ( setEditName(e.target.value)} className="h-9 focus-visible:ring-1" autoFocus placeholder="單位名稱" onKeyDown={(e) => { if (e.key === 'Enter') saveEdit(unit.id); if (e.key === 'Escape') cancelEdit(); }} /> ) : ( {unit.name} )} {editingId === unit.id ? ( setEditCode(e.target.value)} className="h-9 focus-visible:ring-1" placeholder="代碼" onKeyDown={(e) => { if (e.key === 'Enter') saveEdit(unit.id); if (e.key === 'Escape') cancelEdit(); }} /> ) : ( {unit.code || '-'} )} {editingId === unit.id ? (
) : (
確認刪除單位 確定要刪除「{unit.name}」嗎?
若該單位下仍有商品,系統將會拒絕刪除。
取消 handleDelete(unit.id)} className="bg-red-600 hover:bg-red-700" > 確認刪除
)}
)) )}
); }