新增單位管理以及一些功能修正
This commit is contained in:
@@ -21,19 +21,15 @@ import {
|
||||
import { useForm } from "@inertiajs/react";
|
||||
import { toast } from "sonner";
|
||||
import type { Product, Category } from "@/Pages/Product/Index";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/Components/ui/dropdown-menu";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
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
|
||||
}
|
||||
|
||||
@@ -42,16 +38,17 @@ export default function ProductDialog({
|
||||
onOpenChange,
|
||||
product,
|
||||
categories,
|
||||
units,
|
||||
}: ProductDialogProps) {
|
||||
const { data, setData, post, put, processing, errors, reset, clearErrors } = useForm({
|
||||
name: "",
|
||||
category_id: "",
|
||||
brand: "",
|
||||
specification: "",
|
||||
base_unit: "公斤",
|
||||
large_unit: "",
|
||||
base_unit_id: "",
|
||||
large_unit_id: "",
|
||||
conversion_rate: "",
|
||||
purchase_unit: "",
|
||||
purchase_unit_id: "",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -63,10 +60,10 @@ export default function ProductDialog({
|
||||
category_id: product.category_id.toString(),
|
||||
brand: product.brand || "",
|
||||
specification: product.specification || "",
|
||||
base_unit: product.base_unit,
|
||||
large_unit: product.large_unit || "",
|
||||
base_unit_id: product.base_unit_id?.toString() || "",
|
||||
large_unit_id: product.large_unit_id?.toString() || "",
|
||||
conversion_rate: product.conversion_rate ? product.conversion_rate.toString() : "",
|
||||
purchase_unit: product.purchase_unit || "",
|
||||
purchase_unit_id: product.purchase_unit_id?.toString() || "",
|
||||
});
|
||||
} else {
|
||||
reset();
|
||||
@@ -188,50 +185,52 @@ export default function ProductDialog({
|
||||
<h3 className="text-lg font-medium border-b pb-2">單位設定</h3>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="base_unit">
|
||||
<Label htmlFor="base_unit_id">
|
||||
基本庫存單位 <span className="text-red-500">*</span>
|
||||
</Label>
|
||||
<div className="flex gap-2">
|
||||
<Input
|
||||
id="base_unit"
|
||||
value={data.base_unit}
|
||||
onChange={(e) => setData("base_unit", e.target.value)}
|
||||
placeholder="可輸入或選擇..."
|
||||
className={errors.base_unit ? "border-red-500 flex-1" : "flex-1"}
|
||||
/>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="outline" size="icon" className="shrink-0">
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end">
|
||||
{["公斤", "公克", "公升", "毫升", "個", "支", "包", "罐", "瓶", "箱", "袋"].map((u) => (
|
||||
<DropdownMenuItem key={u} onClick={() => setData("base_unit", u)}>
|
||||
{u}
|
||||
</DropdownMenuItem>
|
||||
))}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
{errors.base_unit && <p className="text-sm text-red-500">{errors.base_unit}</p>}
|
||||
<Select
|
||||
value={data.base_unit_id}
|
||||
onValueChange={(value) => setData("base_unit_id", value)}
|
||||
>
|
||||
<SelectTrigger id="base_unit_id" className={errors.base_unit_id ? "border-red-500" : ""}>
|
||||
<SelectValue placeholder="選擇單位" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{units.map((unit) => (
|
||||
<SelectItem key={unit.id} value={unit.id.toString()}>
|
||||
{unit.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.base_unit_id && <p className="text-sm text-red-500">{errors.base_unit_id}</p>}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="large_unit">大單位</Label>
|
||||
<Input
|
||||
id="large_unit"
|
||||
value={data.large_unit}
|
||||
onChange={(e) => setData("large_unit", e.target.value)}
|
||||
placeholder="例:箱、袋"
|
||||
/>
|
||||
{errors.large_unit && <p className="text-sm text-red-500">{errors.large_unit}</p>}
|
||||
<Label htmlFor="large_unit_id">大單位</Label>
|
||||
<Select
|
||||
value={data.large_unit_id}
|
||||
onValueChange={(value) => setData("large_unit_id", value)}
|
||||
>
|
||||
<SelectTrigger id="large_unit_id" className={errors.large_unit_id ? "border-red-500" : ""}>
|
||||
<SelectValue placeholder="無" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="none">無</SelectItem>
|
||||
{units.map((unit) => (
|
||||
<SelectItem key={unit.id} value={unit.id.toString()}>
|
||||
{unit.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.large_unit_id && <p className="text-sm text-red-500">{errors.large_unit_id}</p>}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="conversion_rate">
|
||||
換算率
|
||||
{data.large_unit && <span className="text-red-500">*</span>}
|
||||
{data.large_unit_id && <span className="text-red-500">*</span>}
|
||||
</Label>
|
||||
<Input
|
||||
id="conversion_rate"
|
||||
@@ -239,27 +238,37 @@ export default function ProductDialog({
|
||||
step="0.0001"
|
||||
value={data.conversion_rate}
|
||||
onChange={(e) => setData("conversion_rate", e.target.value)}
|
||||
placeholder={data.large_unit ? `1 ${data.large_unit} = ? ${data.base_unit}` : ""}
|
||||
disabled={!data.large_unit}
|
||||
placeholder={data.large_unit_id && data.base_unit_id ? `1 ${units.find(u => u.id.toString() === data.large_unit_id)?.name} = ? ${units.find(u => u.id.toString() === data.base_unit_id)?.name}` : ""}
|
||||
disabled={!data.large_unit_id}
|
||||
/>
|
||||
{errors.conversion_rate && <p className="text-sm text-red-500">{errors.conversion_rate}</p>}
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="purchase_unit">採購單位</Label>
|
||||
<Input
|
||||
id="purchase_unit"
|
||||
value={data.purchase_unit}
|
||||
onChange={(e) => setData("purchase_unit", e.target.value)}
|
||||
placeholder="通常同大單位"
|
||||
/>
|
||||
{errors.purchase_unit && <p className="text-sm text-red-500">{errors.purchase_unit}</p>}
|
||||
<Label htmlFor="purchase_unit_id">採購單位</Label>
|
||||
<Select
|
||||
value={data.purchase_unit_id}
|
||||
onValueChange={(value) => setData("purchase_unit_id", value)}
|
||||
>
|
||||
<SelectTrigger id="purchase_unit_id" className={errors.purchase_unit_id ? "border-red-500" : ""}>
|
||||
<SelectValue placeholder="通常同大單位" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="none">無</SelectItem>
|
||||
{units.map((unit) => (
|
||||
<SelectItem key={unit.id} value={unit.id.toString()}>
|
||||
{unit.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{errors.purchase_unit_id && <p className="text-sm text-red-500">{errors.purchase_unit_id}</p>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{data.large_unit && data.base_unit && data.conversion_rate && (
|
||||
{data.large_unit_id && data.base_unit_id && data.conversion_rate && (
|
||||
<div className="bg-blue-50 p-3 rounded text-sm text-blue-700">
|
||||
預覽:1 {data.large_unit} = {data.conversion_rate} {data.base_unit}
|
||||
預覽:1 {units.find(u => u.id.toString() === data.large_unit_id)?.name} = {data.conversion_rate} {units.find(u => u.id.toString() === data.base_unit_id)?.name}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -121,11 +121,11 @@ export default function ProductTable({
|
||||
{product.category?.name || '-'}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell>{product.base_unit}</TableCell>
|
||||
<TableCell>{product.baseUnit?.name || '-'}</TableCell>
|
||||
<TableCell>
|
||||
{product.large_unit ? (
|
||||
{product.largeUnit ? (
|
||||
<span className="text-sm text-gray-500">
|
||||
1 {product.large_unit} = {Number(product.conversion_rate)} {product.base_unit}
|
||||
1 {product.largeUnit?.name} = {Number(product.conversion_rate)} {product.baseUnit?.name}
|
||||
</span>
|
||||
) : (
|
||||
'-'
|
||||
|
||||
Reference in New Issue
Block a user