Files
star-erp/resources/js/Pages/PurchaseOrder/Index.tsx

133 lines
4.4 KiB
TypeScript
Raw Normal View History

2025-12-30 15:03:19 +08:00
/**
*
*/
import { useState, useCallback } from "react";
import { Plus } from "lucide-react";
import { Button } from "@/Components/ui/button";
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
import { Head, router } from "@inertiajs/react";
import PurchaseOrderTable from "@/Components/PurchaseOrder/PurchaseOrderTable";
import { PurchaseOrderFilters } from "@/Components/PurchaseOrder/PurchaseOrderFilters";
import { type DateRange } from "@/Components/PurchaseOrder/DateFilter";
import type { PurchaseOrder } from "@/types/purchase-order";
import { debounce } from "lodash";
import Pagination from "@/Components/shared/Pagination";
interface Props {
orders: {
data: PurchaseOrder[];
links: any[];
total: number;
from: number;
to: number;
};
filters: {
search?: string;
status?: string;
warehouse_id?: string;
sort_field?: string;
sort_direction?: string;
};
warehouses: { id: number; name: string }[];
}
export default function PurchaseOrderIndex({ orders, filters, warehouses }: Props) {
const [searchQuery, setSearchQuery] = useState(filters.search || "");
const [statusFilter, setStatusFilter] = useState<string>(filters.status || "all");
const [requesterFilter, setRequesterFilter] = useState<string>(filters.warehouse_id || "all");
const [dateRange, setDateRange] = useState<DateRange | null>(null);
const handleFilterChange = (newFilters: any) => {
router.get("/purchase-orders", {
...filters,
...newFilters,
page: 1,
}, {
preserveState: true,
replace: true,
});
};
const handleSearch = useCallback(
debounce((value: string) => {
handleFilterChange({ search: value });
}, 500),
[filters]
);
const onSearchChange = (value: string) => {
setSearchQuery(value);
handleSearch(value);
};
const onStatusChange = (value: string) => {
setStatusFilter(value);
handleFilterChange({ status: value });
};
const onWarehouseChange = (value: string) => {
setRequesterFilter(value);
handleFilterChange({ warehouse_id: value });
};
const handleClearFilters = () => {
setSearchQuery("");
setStatusFilter("all");
setRequesterFilter("all");
setDateRange(null);
router.get("/purchase-orders");
};
const hasActiveFilters = searchQuery !== "" || statusFilter !== "all" || requesterFilter !== "all" || dateRange !== null;
const handleNavigateToCreateOrder = () => {
router.get("/purchase-orders/create");
};
return (
<AuthenticatedLayout>
<Head title="採購管理 - 管理採購單" />
<div className="container mx-auto p-6 max-w-7xl">
<div className="flex items-center justify-between mb-6">
<div>
<h1 className="mb-2"></h1>
<p className="text-gray-600"></p>
</div>
<Button
onClick={handleNavigateToCreateOrder}
className="gap-2 button-filled-primary"
>
<Plus className="h-4 w-4" />
</Button>
</div>
<div className="mb-6">
<PurchaseOrderFilters
searchQuery={searchQuery}
statusFilter={statusFilter}
requesterFilter={requesterFilter}
warehouses={warehouses}
onSearchChange={onSearchChange}
onStatusChange={onStatusChange}
onRequesterChange={onWarehouseChange}
onClearFilters={handleClearFilters}
hasActiveFilters={hasActiveFilters}
dateRange={dateRange}
onDateRangeChange={setDateRange}
/>
</div>
<PurchaseOrderTable
orders={orders.data}
/>
<div className="mt-6 flex justify-center">
<Pagination links={orders.links} />
</div>
</div>
</AuthenticatedLayout>
);
}