添加表格视图
ShipAny 内置了表格视图组件,可以很方便的渲染一个表格视图,用于展示各类数据。
比如用户列表 / 订单列表 / 积分记录等。
创建新的表格视图
以下步骤演示如何快速在用户中心渲染一个表格视图,显示用户支付订单列表。
- 先在
model
层操作操作数据库,实现一个获取用户订单列表的方法
models/order.ts
export async function getOrdersByUserUuid(
user_uuid: string
): Promise<Order[] | undefined> {
const now = new Date().toISOString();
const supabase = getSupabaseClient();
const { data, error } = await supabase
.from("orders")
.select("*")
.eq("user_uuid", user_uuid)
.eq("status", "paid")
.order("created_at", { ascending: false });
if (error) {
return undefined;
}
return data;
}
- 在用户中心模块创建一个新的页面,获取登录用户信息
getUserUuid
方法可以从 session 中获取当前登录用户的 uuid
如果用户未登录,则跳转到登录页面。
app/[locale]/(default)/(console)/my-orders/page.tsx
import { getUserUuid } from "@/services/user";
import { redirect } from "next/navigation";
export default async function MyOrdersPage() {
const user_uuid = await getUserUuid();
const callbackUrl = `${process.env.NEXT_PUBLIC_WEB_URL}/my-orders`;
if (!user_uuid) {
redirect(`/auth/signin?callbackUrl=${encodeURIComponent(callbackUrl)}`);
}
return <div>My Orders With User UUID: {user_uuid}</div>;
}
预览新页面,可以看到登录后的用户 uuid。
- 定义表格视图的数据表头
在页面文件中,
定义要显示的表头列表 columns: TableColumn[]
,
引入表格视图组件: import TableSlot from "@/components/console/slots/table";
显示表头:return <TableSlot title={t("my_orders.title")} columns={columns} data={[]} />;
完整代码:
app/[locale]/(default)/(console)/my-orders/page.tsx
import { TableColumn } from "@/types/blocks/table";
import TableSlot from "@/components/console/slots/table";
import { getTranslations } from "next-intl/server";
import { getUserUuid } from "@/services/user";
import moment from "moment";
import { redirect } from "next/navigation";
export default async function MyOrdersPage() {
const t = await getTranslations();
const user_uuid = await getUserUuid();
const callbackUrl = `${process.env.NEXT_PUBLIC_WEB_URL}/my-orders`;
if (!user_uuid) {
redirect(`/auth/signin?callbackUrl=${encodeURIComponent(callbackUrl)}`);
}
const columns: TableColumn[] = [
{ name: "order_no", title: t("my_orders.table.order_no") },
{ name: "paid_email", title: t("my_orders.table.email") },
{ name: "product_name", title: t("my_orders.table.product_name") },
{
name: "amount",
title: t("my_orders.table.amount"),
callback: (item: any) =>
`${item.currency.toUpperCase() === "CNY" ? "¥" : "$"} ${
item.amount / 100
}`,
},
{
name: "paid_at",
title: t("my_orders.table.paid_at"),
callback: (item: any) =>
moment(item.paid_at).format("YYYY-MM-DD HH:mm:ss"),
},
];
return <TableSlot title={t("my_orders.title")} columns={columns} data={[]} />;
}
预览效果:
- 在表格视图中显示数据
调用步骤 1 实现的读取数据的函数,把获取到的数据传递给表格视图组件进行显示。
完整代码:
app/[locale]/(default)/(console)/my-orders/page.tsx
import { getOrdersByPaidEmail, getOrdersByUserUuid } from "@/models/order";
import { getUserEmail, getUserUuid } from "@/services/user";
import { TableColumn } from "@/types/blocks/table";
import TableSlot from "@/components/console/slots/table";
import { Table as TableSlotType } from "@/types/slots/table";
import { getTranslations } from "next-intl/server";
import moment from "moment";
import { redirect } from "next/navigation";
export default async function () {
const t = await getTranslations();
const user_uuid = await getUserUuid();
const user_email = await getUserEmail();
const callbackUrl = `${process.env.NEXT_PUBLIC_WEB_URL}/my-orders`;
if (!user_uuid) {
redirect(`/auth/signin?callbackUrl=${encodeURIComponent(callbackUrl)}`);
}
let orders = await getOrdersByUserUuid(user_uuid);
if (!orders || orders.length === 0) {
orders = await getOrdersByPaidEmail(user_email);
}
const columns: TableColumn[] = [
{ name: "order_no", title: t("my_orders.table.order_no") },
{ name: "paid_email", title: t("my_orders.table.email") },
{ name: "product_name", title: t("my_orders.table.product_name") },
{
name: "amount",
title: t("my_orders.table.amount"),
callback: (item: any) =>
`${item.currency.toUpperCase() === "CNY" ? "¥" : "$"} ${
item.amount / 100
}`,
},
{
name: "paid_at",
title: t("my_orders.table.paid_at"),
callback: (item: any) =>
moment(item.paid_at).format("YYYY-MM-DD HH:mm:ss"),
},
];
const table: TableSlotType = {
title: t("my_orders.title"),
description: t("my_orders.description"),
toolbar: {
items: [
{
title: t("my_orders.read_docs"),
icon: "RiBookLine",
url: "https://docs.shipany.ai",
target: "_blank",
variant: "outline",
},
{
title: t("my_orders.join_discord"),
icon: "RiDiscordFill",
url: "https://discord.gg/HQNnrzjZQS",
target: "_blank",
},
],
},
columns: columns,
data: orders,
empty_message: t("my_orders.no_orders"),
};
return <TableSlot {...table} />;
}
预览效果: