知识库首页 模版 dashboard-page.tsx.md

dashboard page.tsx

本地来源:模版/template/模版文档对比说明/04-仪表板系统/dashboard-page.tsx.md

仪表板页面 (app/dashboard/page.tsx) 逐行分析

文件概述

这是项目的主要仪表板页面文件,展示用户的订阅状态、积分余额和快速操作等核心功能。

导入语句分析

import { createClient } from "@/utils/supabase/server";
  • 导入服务器端的 Supabase 客户端
  • 用于在服务器组件中访问 Supabase 数据库
import { redirect } from "next/navigation";
  • 导入 Next.js 的重定向功能
  • 用于在服务器端进行页面重定向
import { SubscriptionStatusCard } from "@/components/dashboard/subscription-status-card";
import { CreditsBalanceCard } from "@/components/dashboard/credits-balance-card";
import { QuickActionsCard } from "@/components/dashboard/quick-actions-card";
  • 导入三个仪表板专用组件
  • 分别用于显示订阅状态、积分余额和快速操作

组件定义分析

export default async function DashboardPage() {
  • 定义异步服务器组件函数
  • 使用 async 关键字表示该组件需要异步操作

用户认证检查

const supabase = await createClient();
  • 创建 Supabase 客户端实例
  • 使用 await 等待客户端创建完成
const {
  data: { user },
} = await supabase.auth.getUser();
  • 获取当前用户信息
  • 使用解构赋值从 data 中提取 user 对象
if (!user) {
  return redirect("/sign-in");
}
  • 检查用户是否已登录
  • 如果未登录,重定向到登录页面

数据获取

const { data: customerData } = await supabase
  .from("customers")
  .select(
    `
    *,
    subscriptions (
      status,
      current_period_end,
      creem_product_id
    ),
    credits_history (
      amount,
      type,
      created_at
    )
  `
  )
  .eq("user_id", user.id)
  .single();
  • 从 customers 表获取客户数据
  • 使用关联查询获取订阅信息和积分历史
  • subscriptions 关联查询获取状态、期限和产品ID
  • credits_history 关联查询获取积分变动记录
  • 使用 .eq() 过滤当前用户的数据
  • 使用 .single() 获取单条记录

数据处理

const subscription = customerData?.subscriptions?.[0];
const credits = customerData?.credits || 0;
const recentCreditsHistory = customerData?.credits_history?.slice(0, 2) || [];
  • 提取订阅信息(取第一条)
  • 获取积分余额,默认为0
  • 获取最近的积分历史记录(最多2条)

渲染结构分析

主容器

<div className="flex-1 w-full flex flex-col gap-6 sm:gap-8 px-4 sm:px-8 container">
  • 使用 Flexbox 布局,垂直排列
  • 响应式间距设计:小屏幕 gap-6,大屏幕 gap-8
  • 响应式内边距:小屏幕 px-4,大屏幕 px-8

欢迎横幅

<div className="bg-gradient-to-r from-primary/5 via-primary/10 to-primary/5 border rounded-lg p-6 sm:p-8 mt-6 sm:mt-8">
  • 使用渐变背景色
  • 从左到右的渐变:5% -> 10% -> 5% 透明度
  • 圆角边框设计
  • 响应式内边距和外边距
<h1 className="text-2xl sm:text-3xl font-bold mb-2 break-words">
  Welcome back,{" "}
  <span className="block sm:inline mt-1 sm:mt-0">{user.email}</span>
</h1>
  • 响应式字体大小
  • 文字换行处理
  • 邮箱地址在小屏幕上独占一行,大屏幕上内联显示
<p className="text-sm sm:text-base text-muted-foreground">
  Manage your subscription and credits from your personal dashboard.
</p>
  • 副标题描述
  • 使用 muted-foreground 颜色类

统计卡片网格

<div className="grid gap-4 sm:gap-6 md:grid-cols-2 lg:grid-cols-3">
  • 使用 CSS Grid 布局
  • 响应式设计:中等屏幕2列,大屏幕3列
  • 响应式间距
<SubscriptionStatusCard subscription={subscription} />
<CreditsBalanceCard
  credits={credits}
  recentHistory={recentCreditsHistory}
/>
<QuickActionsCard />
  • 三个功能卡片组件
  • 传递相应的数据作为 props

账户详情部分

<div className="rounded-xl border bg-card p-4 sm:p-6 mb-6">
  • 圆角卡片设计
  • 使用 bg-card 背景色
  • 响应式内边距
<h2 className="font-bold text-lg sm:text-xl mb-4">Account Details</h2>
  • 二级标题
  • 响应式字体大小
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 text-sm">
  • 网格布局:小屏幕1列,大屏幕2列
  • 小字体显示详细信息
<div className="space-y-1">
  <p className="text-muted-foreground">Email</p>
  <p className="font-medium break-all">{user.email}</p>
</div>
<div className="space-y-1">
  <p className="text-muted-foreground">User ID</p>
  <p className="font-medium break-all">{user.id}</p>
</div>
  • 显示用户邮箱和ID
  • 使用 break-all 确保长文本正确换行
  • 标签使用 muted-foreground 颜色
  • 值使用 font-medium 加粗

设计模式分析

服务器组件模式

  • 使用 Next.js 13+ 的服务器组件
  • 在服务器端进行数据获取和认证检查
  • 减少客户端JavaScript包大小

响应式设计

  • 全面的响应式布局设计
  • 使用 Tailwind CSS 的响应式前缀
  • 适配不同屏幕尺寸

数据获取模式

  • 使用 Supabase 的关联查询
  • 一次性获取所有需要的数据
  • 减少数据库查询次数

错误处理

  • 简单的用户认证检查
  • 使用重定向处理未认证用户

最佳实践总结

  1. 性能优化:使用服务器组件减少客户端负载
  2. 用户体验:响应式设计适配所有设备
  3. 安全性:服务器端认证检查
  4. 数据效率:使用关联查询减少数据库调用
  5. 代码可维护性:组件化设计,职责分离
  6. 可访问性:语义化HTML结构
  7. 设计一致性:使用主题色彩和间距系统

这个文件展示了现代 Next.js 应用的最佳实践,包括服务器组件、响应式设计、数据获取和用户认证等核心功能。

本文档为站内渲染。原始文件本地路径:saas/source/templates/模版-template-模版文档对比说明-04-仪表板系统-dashboard-page-tsx-df54b7.md(仅本地保留,不入库不部署)