import { useState, useCallback } from "react"; import { debounce } from "lodash"; import { Head, Link, router } from "@inertiajs/react"; import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout"; import { Search, TrendingUp, Eye, Trash2, } from "lucide-react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/Components/ui/table"; import { StatusBadge, StatusVariant } from "@/Components/shared/StatusBadge"; import { Button } from "@/Components/ui/button"; import { Input } from "@/Components/ui/input"; import { SearchableSelect } from "@/Components/ui/searchable-select"; import Pagination from "@/Components/shared/Pagination"; import { formatDate } from "@/lib/date"; import { formatNumber } from "@/utils/format"; import { Can } from "@/Components/Permission/Can"; interface SalesOrder { id: number; external_order_id: string; name: string | null; status: string; payment_method: string; total_amount: string; total_qty: string; sold_at: string; created_at: string; source: string; source_label: string | null; } interface PaginationLink { url: string | null; label: string; active: boolean; } interface Props { orders: { data: SalesOrder[]; total: number; per_page: number; current_page: number; last_page: number; links: PaginationLink[]; }; filters: { search?: string; per_page?: string; source?: string; status?: string; payment_method?: string; }; } // 來源篩選選項 const sourceOptions = [ { label: "全部來源", value: "" }, { label: "POS 收銀機", value: "pos" }, { label: "販賣機", value: "vending" }, { label: "手動匯入", value: "manual_import" }, ]; const paymentMethodOptions = [ { label: "全部付款方式", value: "" }, { label: "現金", value: "cash" }, { label: "信用卡", value: "credit_card" }, { label: "Line Pay", value: "line_pay" }, { label: "悠遊卡", value: "easycard" }, ]; const getSourceLabel = (source: string): string => { switch (source) { case 'pos': return 'POS'; case 'vending': return '販賣機'; case 'manual_import': return '手動匯入'; default: return source; } }; const getSourceVariant = (source: string): StatusVariant => { switch (source) { case 'pos': return 'info'; case 'vending': return 'warning'; case 'manual_import': return 'neutral'; default: return 'neutral'; } }; const getStatusVariant = (status: string): StatusVariant => { switch (status) { case 'completed': return 'success'; case 'pending': return 'warning'; case 'cancelled': return 'destructive'; default: return 'neutral'; } }; const getStatusLabel = (status: string): string => { switch (status) { case 'completed': return "已完成"; case 'pending': return "待處理"; case 'cancelled': return "已取消"; default: return status; } }; export default function SalesOrderIndex({ orders, filters }: Props) { const [search, setSearch] = useState(filters.search || ""); const [perPage, setPerPage] = useState(filters.per_page || "10"); const debouncedFilter = useCallback( debounce((params: any) => { router.get(route("integration.sales-orders.index"), params, { preserveState: true, replace: true, preserveScroll: true, }); }, 300), [] ); const handleSearchChange = (term: string) => { setSearch(term); debouncedFilter({ ...filters, search: term, page: 1, }); }; const handleFilterChange = (key: string, value: string) => { debouncedFilter({ ...filters, [key]: value || undefined, page: 1, }); }; const handlePerPageChange = (value: string) => { setPerPage(value); router.get( route("integration.sales-orders.index"), { ...filters, per_page: value, page: 1 }, { preserveState: false, replace: true, preserveScroll: true } ); }; const startIndex = (orders.current_page - 1) * orders.per_page + 1; return (

銷售訂單管理

檢視從 POS 或販賣機同步進來的銷售訂單紀錄

{/* 篩選列 */}
handleSearchChange(e.target.value)} placeholder="搜尋訂單名稱或外部訂單號 (External Order ID)..." className="pl-10 pr-10 h-9" /> {search && ( )}
handleFilterChange("source", val)} options={sourceOptions} className="w-[140px] h-9" showSearch={false} placeholder="篩選來源" /> handleFilterChange("payment_method", val)} options={paymentMethodOptions} className="w-[160px] h-9" showSearch={false} placeholder="篩選付款方式" />
{/* 表格 */}
# 外部訂單號 名稱 來源 狀態 付款方式 總數量 總金額 銷售時間 操作 {orders.data.length === 0 ? ( 無符合條件的資料 ) : ( orders.data.map((order, index) => ( {startIndex + index} {order.external_order_id} {order.name || "—"} {order.source_label || getSourceLabel(order.source)} {getStatusLabel(order.status)} {order.payment_method || "—"} {formatNumber(parseFloat(order.total_qty))} ${formatNumber(parseFloat(order.total_amount))} {formatDate(order.sold_at)}
)) )}
{/* 分頁 */}
每頁顯示
共 {orders.total} 筆資料
); }