Files
star-erp/resources/js/Components/Product/ProductImportDialog.tsx
sky121113 f87310e707
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Has been skipped
Koori-ERP-Deploy-System / deploy-production (push) Successful in 52s
fix: 更新商品代號驗證規則為 2-8 碼
1. ProductImport.php: 匯入規則調整
2. ProductController.php: 新增/編輯 API 規則調整
3. UI: 匯入與編輯視窗提示更新
2026-02-02 15:07:12 +08:00

143 lines
5.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogDescription } from "@/Components/ui/dialog";
import { Button } from "@/Components/ui/button";
import { Input } from "@/Components/ui/input";
import { Label } from "@/Components/ui/label";
import { Upload, Download, FileSpreadsheet, AlertCircle, Info } from "lucide-react";
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/Components/ui/accordion";
import { useForm } from "@inertiajs/react";
import { Alert, AlertDescription } from "@/Components/ui/alert";
interface ProductImportDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
}
export default function ProductImportDialog({ open, onOpenChange }: ProductImportDialogProps) {
const { data, setData, post, processing, errors, reset, clearErrors } = useForm<{
file: File | null;
}>({
file: null,
});
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files && e.target.files[0]) {
setData("file", e.target.files[0]);
clearErrors("file");
}
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
post(route("products.import"), {
onSuccess: () => {
reset();
onOpenChange(false);
},
});
};
const handleDownloadTemplate = () => {
window.location.href = route('products.template');
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
</DialogDescription>
</DialogHeader>
<form onSubmit={handleSubmit} className="space-y-6">
{/* 步驟 1: 下載範本 */}
<div className="space-y-2 p-4 bg-gray-50 rounded-lg border border-gray-100">
<Label className="font-medium flex items-center gap-2">
<FileSpreadsheet className="w-4 h-4 text-green-600" />
1 Excel
</Label>
<div className="text-sm text-gray-500 mb-2">
</div>
<Button
type="button"
variant="outline"
size="sm"
onClick={handleDownloadTemplate}
className="w-full sm:w-auto button-outlined-primary"
>
<Download className="w-4 h-4 mr-2" />
(.xlsx)
</Button>
</div>
{/* 步驟 2: 上傳檔案 */}
<div className="space-y-2">
<Label className="font-medium flex items-center gap-2">
<Upload className="w-4 h-4 text-blue-600" />
2
</Label>
<div className="grid w-full max-w-sm items-center gap-1.5">
<Input
id="file"
type="file"
accept=".xlsx, .xls"
onChange={handleFileChange}
className="cursor-pointer"
/>
</div>
{errors.file && (
<Alert variant="destructive" className="mt-2">
<AlertCircle className="h-4 w-4" />
<AlertDescription className="whitespace-pre-wrap">
{errors.file}
</AlertDescription>
</Alert>
)}
</div>
{/* 欄位說明 */}
<Accordion type="single" collapsible className="w-full border rounded-lg px-2">
<AccordionItem value="item-1" className="border-b-0">
<AccordionTrigger className="text-sm text-gray-500 hover:no-underline py-3">
<div className="flex items-center gap-2">
<Info className="h-4 w-4" />
</div>
</AccordionTrigger>
<AccordionContent>
<div className="text-sm text-gray-600 space-y-2 pb-2 pl-6">
<ul className="list-disc space-y-1">
<li><span className="font-medium text-gray-700"></span> (2-8 )</li>
<li><span className="font-medium text-gray-700"></span></li>
<li><span className="font-medium text-gray-700"></span></li>
<li><span className="font-medium text-gray-700"></span> 0</li>
</ul>
</div>
</AccordionContent>
</AccordionItem>
</Accordion>
<DialogFooter>
<Button
type="button"
variant="outline"
onClick={() => onOpenChange(false)}
disabled={processing}
className="button-outlined-primary"
>
</Button>
<Button type="submit" disabled={!data.file || processing} className="button-filled-primary">
{processing ? "匯入中..." : "開始匯入"}
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
}