知识库首页 模版 subscription-status-card.tsx.md

subscription status card.tsx

本地来源:模版/模版文档对比说明/05-组件系统/subscription-status-card.tsx.md

订阅状态卡片组件 (components/dashboard/subscription-status-card.tsx) 逐行分析

文件概述

这是一个用于显示用户订阅状态的智能卡片组件。它能够根据不同的订阅状态显示相应的颜色、图标和消息,并提供订阅管理入口。

导入语句分析

"use client";
  • 指示这是客户端组件
  • 因为组件使用了交互功能
import {
  CreditCard,
  Package2,
  AlertCircle,
  Clock,
  Ban,
  PauseCircle,
  LucideIcon,
} from "lucide-react";
  • 导入多个图标组件
  • 每个图标对应不同的订阅状态
  • LucideIcon 用于类型定义
import { SubscriptionPortalDialog } from "./subscription-portal-dialog";
import { SubscriptionState } from "@/types/subscriptions";
  • 导入订阅门户对话框组件
  • 导入订阅状态类型定义

类型定义分析

StatusConfig 类型

type StatusConfig = {
  color: string;
  icon: LucideIcon;
  message: string;
  iconColor: string;
};

字段说明

  • color: 文本颜色类名
  • icon: 显示的图标组件
  • message: 状态描述消息
  • iconColor: 图标颜色类名

StatusConfigs 类型

type StatusConfigs = {
  [key in SubscriptionState]: StatusConfig;
};
  • 映射每个订阅状态到其配置
  • 确保所有状态都有对应的配置

工具函数分析

formatDate 函数

function formatDate(date: string) {
  return new Date(date).toLocaleDateString();
}
  • 将ISO日期字符串格式化为本地日期
  • 使用浏览器的本地化设置

isFutureDate 函数

function isFutureDate(date: string) {
  return new Date(date) > new Date();
}
  • 检查给定日期是否在未来
  • 用于判断宽限期状态

核心函数分析

getStatusConfig 函数

function getStatusConfig(
  status: string,
  current_period_end: string
): StatusConfig {
  const inGracePeriod = isFutureDate(current_period_end);

  // 配置对象...
}

宽限期判断

const inGracePeriod = isFutureDate(current_period_end);
  • 判断是否处于宽限期
  • 影响取消状态的显示

状态配置对象

const configs: StatusConfigs = {
  active: {
    color: "text-green-500",
    icon: Package2,
    message: `Renews on ${formatDate(current_period_end)}`,
    iconColor: "text-green-500",
  },
  trialing: {
    color: "text-primary",
    icon: Clock,
    message: `Trial ends on ${formatDate(current_period_end)}`,
    iconColor: "text-primary",
  },
  // ... 其他状态
};
各状态分析

Active 状态 - 绿色主题,表示正常 - Package2 图标,表示服务 - 显示续费日期

Trialing 状态 - 主题色,表示试用 - Clock 图标,表示时间限制 - 显示试用结束日期

Canceled 状态

canceled: {
  color: inGracePeriod ? "text-yellow-500" : "text-destructive",
  icon: Ban,
  message: inGracePeriod
    ? `Access until ${formatDate(current_period_end)}`
    : `Ended on ${formatDate(current_period_end)}`,
  iconColor: inGracePeriod ? "text-yellow-500" : "text-destructive",
},
  • 动态颜色:宽限期内为黄色,过期为红色
  • Ban 图标,表示禁止
  • 动态消息:显示访问期限或结束日期

Past_due 状态 - 黄色主题,表示警告 - AlertCircle 图标,表示需要注意 - 显示付款到期信息

其他状态 - unpaid: 红色,需要付款 - paused: 黄色,暂停状态 - incomplete: 黄色,设置不完整 - expired: 红色,已过期

默认配置

return (
  configs[status as SubscriptionState] || {
    color: "text-muted-foreground",
    icon: AlertCircle,
    message: "No active plan",
    iconColor: "text-muted-foreground",
  }
);
  • 处理未知状态
  • 提供安全的默认配置

组件Props分析

type SubscriptionStatusCardProps = {
  subscription?: {
    status: string;
    current_period_end: string;
  } | null;
};
  • 接受可选的订阅对象
  • 包含状态和结束时间信息
  • 可以为 null 处理无订阅情况

组件结构分析

主容器

<div className="rounded-xl border bg-card p-6">
  • 圆角卡片样式
  • 使用主题色彩
  • 内边距设计

头部区域

<div className="flex items-center gap-4">
  <div className="p-2 bg-primary/10 rounded-lg">
    <CreditCard className="h-6 w-6 text-primary" />
  </div>
  <div>
    <p className="text-sm text-muted-foreground">Subscription Status</p>
    {/* 状态显示 */}
  </div>
</div>

图标区域

  • 固定的 CreditCard 图标
  • 主题色背景的容器
  • 一致的视觉识别

标题和状态

{subscription && (
  <h3
    className={`text-2xl font-bold capitalize mt-1 ${
      getStatusConfig(
        subscription.status,
        subscription.current_period_end
      ).color
    }`}
  >
    {subscription.status}
  </h3>
)}
{!subscription && (
  <h3 className="text-2xl font-bold mt-1 text-muted-foreground">
    No Active Plan
  </h3>
)}
  • 动态颜色显示状态
  • 状态文字首字母大写
  • 处理无订阅情况

状态详情区域

{subscription && (
  <div className="mt-4 flex items-center text-sm gap-2">
    {(() => {
      const config = getStatusConfig(
        subscription.status,
        subscription.current_period_end
      );
      const Icon = config.icon;
      return (
        <>
          <Icon className={`h-4 w-4 ${config.iconColor}`} />
          <span className="text-muted-foreground">{config.message}</span>
        </>
      );
    })()}
  </div>
)}

IIFE 模式使用

  • 使用立即执行函数表达式
  • 避免在 JSX 中重复计算配置
  • 保持组件清洁

动态图标和消息

  • 根据状态显示不同图标
  • 动态颜色和消息
  • 统一的样式规范

操作区域

<div className="mt-4">
  <SubscriptionPortalDialog />
</div>
  • 订阅管理入口
  • 固定位置显示
  • 与卡片内容分离

设计模式分析

状态机模式

  • 明确定义每个状态的显示方式
  • 统一的状态处理逻辑
  • 易于扩展新状态

配置驱动模式

  • 使用配置对象驱动显示
  • 分离数据和展示逻辑
  • 提高可维护性

组合模式

  • 图标、颜色、消息的组合
  • 可复用的配置单元
  • 灵活的组合方式

响应式和可访问性

响应式设计

  • 使用 Flexbox 布局
  • 合适的间距设计
  • 移动端友好

可访问性考虑

  • 语义化的HTML结构
  • 颜色和图标双重指示
  • 清晰的文字描述

最佳实践总结

  1. 状态管理: 清晰的状态映射和处理
  2. 视觉设计: 一致的颜色和图标系统
  3. 用户体验: 直观的状态显示和操作入口
  4. 代码组织: 配置驱动的清洁架构
  5. 类型安全: 完整的TypeScript类型定义
  6. 可维护性: 模块化的函数和配置
  7. 性能: 避免不必要的重复计算

使用示例

// 使用组件
<SubscriptionStatusCard 
  subscription={{
    status: "active",
    current_period_end: "2024-01-31T23:59:59Z"
  }}
/>

// 无订阅状态
<SubscriptionStatusCard subscription={null} />

这个组件提供了完整的订阅状态可视化功能,通过智能的状态处理和直观的用户界面,为用户提供了清晰的订阅信息展示和管理入口。

本文档为站内渲染。原始文件本地路径:saas/source/templates/模版-模版文档对比说明-05-组件系统-subscription-status-card-tsx-3661d6.md(仅本地保留,不入库不部署)