更新:優化配方詳情彈窗 UI 與一般修正
All checks were successful
Koori-ERP-Deploy-System / deploy-demo (push) Has been skipped
Koori-ERP-Deploy-System / deploy-production (push) Successful in 49s

This commit is contained in:
2026-01-29 16:13:56 +08:00
parent 7619dc24f7
commit 746eeb6f01
23 changed files with 1925 additions and 79 deletions

View File

@@ -3,7 +3,7 @@
*/
import { useState, useEffect } from "react";
import { Plus, Search, RotateCcw, Pencil, Trash2, BookOpen } from 'lucide-react';
import { Plus, Search, RotateCcw, Pencil, Trash2, BookOpen, Eye } from 'lucide-react';
import { Button } from "@/Components/ui/button";
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
import { Head, router, Link } from "@inertiajs/react";
@@ -15,6 +15,8 @@ import { Label } from "@/Components/ui/label";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/Components/ui/table";
import { Badge } from "@/Components/ui/badge";
import { Can } from "@/Components/Permission/Can";
import { RecipeDetailModal } from "./Components/RecipeDetailModal";
import axios from 'axios';
import {
AlertDialog,
AlertDialogAction,
@@ -59,6 +61,11 @@ export default function RecipeIndex({ recipes, filters }: Props) {
const [search, setSearch] = useState(filters.search || "");
const [perPage, setPerPage] = useState<string>(filters.per_page || "10");
// View Modal State
const [viewRecipe, setViewRecipe] = useState<any | null>(null);
const [isViewModalOpen, setIsViewModalOpen] = useState(false);
const [isViewLoading, setIsViewLoading] = useState(false);
useEffect(() => {
setSearch(filters.search || "");
setPerPage(filters.per_page || "10");
@@ -95,6 +102,20 @@ export default function RecipeIndex({ recipes, filters }: Props) {
}
};
const handleView = async (id: number) => {
setIsViewModalOpen(true);
setIsViewLoading(true);
setViewRecipe(null);
try {
const response = await axios.get(route('recipes.show', id));
setViewRecipe(response.data);
} catch (error) {
console.error("Failed to load recipe details", error);
} finally {
setIsViewLoading(false);
}
};
return (
<AuthenticatedLayout breadcrumbs={getBreadcrumbs("recipes")}>
<Head title="配方管理" />
@@ -171,7 +192,7 @@ export default function RecipeIndex({ recipes, filters }: Props) {
<TableHead className="text-right"></TableHead>
<TableHead className="text-center w-[100px]"></TableHead>
<TableHead className="w-[150px]"></TableHead>
<TableHead className="text-center w-[120px]"></TableHead>
<TableHead className="text-center w-[150px]"></TableHead>
</TableRow>
</TableHeader>
<TableBody>
@@ -221,6 +242,17 @@ export default function RecipeIndex({ recipes, filters }: Props) {
</TableCell>
<TableCell className="text-center">
<div className="flex items-center justify-center gap-2">
<Can permission="recipes.view">
<Button
variant="outline"
size="sm"
className="button-outlined-primary"
title="查看明細"
onClick={() => handleView(recipe.id)}
>
<Eye className="h-4 w-4" />
</Button>
</Can>
<Can permission="recipes.edit">
<Link href={route('recipes.edit', recipe.id)}>
<Button
@@ -296,6 +328,13 @@ export default function RecipeIndex({ recipes, filters }: Props) {
<Pagination links={recipes.links} />
</div>
</div>
<RecipeDetailModal
isOpen={isViewModalOpen}
onClose={() => setIsViewModalOpen(false)}
recipe={viewRecipe}
isLoading={isViewLoading}
/>
</div>
</AuthenticatedLayout>
);