ActivityChartWrapper 组件

ActivityChartWrapper 组件

概述

ActivityChartWrapperActivityChart 的包装组件,处理 URL 查询参数与活动图表的交互,实现日期筛选功能。

文件路径

src/components/user/activity-chart-wrapper.tsx

功能特性

  • URL 同步: 将选中的日期同步到 URL 查询参数
  • 自动切换 Tab: 筛选时自动切换到 Prompts 标签
  • 页面重置: 筛选时重置到第 1 页
  • 无滚动跳转: 更新 URL 时不滚动页面

接口定义

interface ActivityChartWrapperProps {
  data: { date: string; count: number }[];  // 活动数据
  locale?: string;                          // 语言区域
}

使用示例

import { ActivityChartWrapper } from "@/components/user/activity-chart-wrapper";

export default function UserProfile({ activityData }: { activityData: ActivityData[] }) {
  return (
    <ActivityChartWrapper
      data={activityData}
      locale="zh-CN"
    />
  );
}

工作流程

用户点击日期
    ↓
读取当前 URL 查询参数
    ↓
设置/删除 date 参数
    ↓
删除 page 参数(重置分页)
    ↓
设置 tab=prompts(切换到 Prompts)
    ↓
更新 URL(不滚动)
    ↓
触发页面数据重新获取

URL 参数处理

选择日期

当前: ?tab=prompts&page=2
点击: 2024-01-15
结果: ?tab=prompts&date=2024-01-15

取消选择

当前: ?tab=prompts&date=2024-01-15
再次点击: 2024-01-15
结果: ?tab=prompts(date 参数被移除)

实现代码

const handleDateClick = useCallback((date: string | null) => {
  const params = new URLSearchParams(searchParams?.toString() || "");
  
  if (date) {
    params.set("date", date);
    params.delete("page");  // 重置分页
  } else {
    params.delete("date");
  }
  
  // 切换到 Prompts 标签
  if (date) {
    params.set("tab", "prompts");
  }
  
  const newUrl = `?${params.toString()}`;
  router.push(newUrl, { scroll: false });
}, [router, searchParams]);

依赖

  • next/navigation - useRouter, useSearchParams
  • ./activity-chart - 底层图表组件

与 ActivityChart 的关系

ActivityChartWrapper
├── 处理 URL 参数
├── 管理路由状态
└── ActivityChart
    ├── 渲染热力图
    └── 触发 onDateClick

注意事项

  1. 该组件必须在 Next.js App Router 中使用
  2. 依赖 searchParams 读取当前 URL 状态
  3. 使用 scroll: false 防止页面跳动
  4. 父页面需要根据 date 参数筛选数据
  5. 服务端组件获取数据,客户端组件处理交互

服务端集成

在服务端组件中使用:

// page.tsx (Server Component)
export default async function ProfilePage({
  searchParams
}: {
  searchParams: { date?: string; tab?: string; page?: string }
}) {
  const date = searchParams.date;
  const page = parseInt(searchParams.page || "1");
  
  // 根据日期筛选数据
  const prompts = await getPrompts({ 
    date, 
    page 
  });
  
  const activityData = await getActivityData();
  
  return (
    <>
      <ActivityChartWrapper data={activityData} />
      <PromptList prompts={prompts} />
    </>
  );
}
← 返回目录