Files
auto-virtual-tryon-frontend/src/features/orders/orders-home.tsx
2026-03-28 00:25:45 +08:00

230 lines
6.3 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { MetricChip } from "@/components/ui/metric-chip";
import { PageHeader } from "@/components/ui/page-header";
import type { OrderSummaryVM } from "@/lib/types/view-models";
import {
OrdersToolbar,
type OrderFilterServiceMode,
type OrderFilterStatus,
} from "@/features/orders/components/orders-toolbar";
import { OrdersTable } from "@/features/orders/components/orders-table";
type PaginationData = {
page: number;
limit: number;
total: number;
totalPages: number;
};
type OrdersHomeProps = {
currentPage?: number;
isLoadingRecent?: boolean;
message?: string;
onOpenOrder?: (orderId: string) => void;
onOpenWorkflow?: (orderId: string) => void;
onPageChange?: (page: number) => void;
onQuerySubmit?: (query: string) => void;
onStatusChange?: (status: OrderFilterStatus) => void;
recentOrders: OrderSummaryVM[];
selectedQuery?: string;
selectedStatus?: OrderFilterStatus;
totalPages?: number;
};
type OrdersOverviewEnvelope = {
data?: {
limit?: number;
items?: OrderSummaryVM[];
page?: number;
total?: number;
totalPages?: number;
};
message?: string;
};
const TITLE_MESSAGE = "最近订单已接入真实后端接口";
const DEFAULT_MESSAGE = "当前页面直接展示真实订单列表,支持关键词、状态和分页操作。";
const DEFAULT_PAGINATION: PaginationData = {
page: 1,
limit: 6,
total: 0,
totalPages: 0,
};
export function OrdersHome({
currentPage = 1,
isLoadingRecent = false,
message = DEFAULT_MESSAGE,
onOpenOrder,
onOpenWorkflow,
onPageChange,
onQuerySubmit,
onStatusChange,
recentOrders,
selectedQuery = "",
selectedStatus = "all",
totalPages = 0,
}: OrdersHomeProps) {
const [queryValue, setQueryValue] = useState(selectedQuery);
const [serviceModeFilter, setServiceModeFilter] =
useState<OrderFilterServiceMode>("all");
useEffect(() => {
setQueryValue(selectedQuery);
}, [selectedQuery]);
const visibleOrders =
serviceModeFilter === "all"
? recentOrders
: recentOrders.filter((order) => order.serviceMode === serviceModeFilter);
return (
<section className="space-y-6">
<PageHeader
eyebrow="Orders home"
title="订单总览"
description="订单页直接承担扫描、筛选和跳转职责,不再把首屏浪费在入口说明和大卡片上。"
meta="真实列表页"
/>
<div className="flex flex-wrap gap-2">
<MetricChip label="mode" value="真实订单列表" />
<MetricChip label="rows" value={visibleOrders.length} />
<MetricChip label="message" value={TITLE_MESSAGE} />
</div>
<p className="text-sm text-[var(--ink-muted)]">{message}</p>
<OrdersToolbar
currentPage={currentPage}
query={queryValue}
serviceMode={serviceModeFilter}
status={selectedStatus}
totalPages={totalPages}
onPageChange={onPageChange}
onQueryChange={setQueryValue}
onQuerySubmit={onQuerySubmit}
onServiceModeChange={setServiceModeFilter}
onStatusChange={onStatusChange}
/>
<OrdersTable
isLoading={isLoadingRecent}
items={visibleOrders}
onOpenOrder={onOpenOrder}
onOpenWorkflow={onOpenWorkflow}
/>
</section>
);
}
export function OrdersHomeScreen() {
const router = useRouter();
const [recentOrders, setRecentOrders] = useState<OrderSummaryVM[]>([]);
const [message, setMessage] = useState(DEFAULT_MESSAGE);
const [isLoadingRecent, setIsLoadingRecent] = useState(true);
const [selectedQuery, setSelectedQuery] = useState("");
const [selectedStatus, setSelectedStatus] =
useState<OrderFilterStatus>("all");
const [pagination, setPagination] = useState<PaginationData>(DEFAULT_PAGINATION);
useEffect(() => {
let active = true;
async function loadRecentOrders() {
setIsLoadingRecent(true);
try {
const params = new URLSearchParams({
page: String(pagination.page),
limit: String(pagination.limit),
});
if (selectedStatus !== "all") {
params.set("status", selectedStatus);
}
if (selectedQuery.length > 0) {
params.set("query", selectedQuery);
}
const response = await fetch(`/api/dashboard/orders-overview?${params.toString()}`);
const payload = (await response.json()) as OrdersOverviewEnvelope;
if (!active) {
return;
}
setRecentOrders(payload.data?.items ?? []);
setPagination((current) => ({
page: payload.data?.page ?? current.page,
limit: payload.data?.limit ?? current.limit,
total: payload.data?.total ?? current.total,
totalPages: payload.data?.totalPages ?? current.totalPages,
}));
setMessage(payload.message ?? DEFAULT_MESSAGE);
} catch {
if (!active) {
return;
}
setRecentOrders([]);
setPagination((current) => ({
...current,
total: 0,
totalPages: 0,
}));
setMessage("最近访问记录加载失败,请稍后重试。");
} finally {
if (active) {
setIsLoadingRecent(false);
}
}
}
void loadRecentOrders();
return () => {
active = false;
};
}, [pagination.limit, pagination.page, selectedQuery, selectedStatus]);
return (
<OrdersHome
currentPage={pagination.page}
isLoadingRecent={isLoadingRecent}
message={message}
onPageChange={(page) =>
setPagination((current) => ({
...current,
page,
}))
}
onQuerySubmit={(query) => {
setSelectedQuery(query);
setPagination((current) => ({
...current,
page: 1,
}));
}}
recentOrders={recentOrders}
onStatusChange={(status) => {
setSelectedStatus(status);
setPagination((current) => ({
...current,
page: 1,
}));
}}
onOpenOrder={(orderId) => router.push(`/orders/${orderId}`)}
onOpenWorkflow={(orderId) => router.push(`/workflows/${orderId}`)}
selectedQuery={selectedQuery}
selectedStatus={selectedStatus}
totalPages={pagination.totalPages}
/>
);
}