用户中心添加表格视图

添加表格视图

ShipAny 内置了表格视图组件,可以很方便的渲染一个表格视图,用于展示各类数据。

比如用户列表 / 订单列表 / 积分记录等。

创建新的表格视图

以下步骤演示如何快速在用户中心渲染一个表格视图,显示用户支付订单列表。

  1. 先在 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;
}
  1. 在用户中心模块创建一个新的页面,获取登录用户信息

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。

user-console-new-page-show

  1. 定义表格视图的数据表头

在页面文件中,

定义要显示的表头列表 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={[]} />;
}

预览效果:

user-console-table-column

  1. 在表格视图中显示数据

调用步骤 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} />;
}

预览效果:

user-orders