From bc4b5527eb4462eadb314e6f2048b6bfeb9d04b4 Mon Sep 17 00:00:00 2001 From: javayhu Date: Sun, 9 Mar 2025 14:42:04 +0800 Subject: [PATCH] feat: add changelog page with localized release notes - Implement releases collection in content-collections.ts for tracking version updates - Create changelog page with dynamic release rendering for multiple locales - Add ReleaseCard component to display version details and changes - Implement getReleases utility function to fetch and sort release notes - Update internationalization messages for changelog page - Add English and Chinese release notes for v1.0.0, v1.1.0, and v1.2.0 --- content-collections.ts | 70 ++++++++++++++++- content/en/release/v1-0-0.md | 30 ++++++++ content/en/release/v1-1-0.md | 30 ++++++++ content/en/release/v1-2-0.md | 37 +++++++++ content/zh/release/v1-0-0.md | 30 ++++++++ content/zh/release/v1-1-0.md | 30 ++++++++ content/zh/release/v1-2-0.md | 37 +++++++++ messages/en.json | 4 + messages/zh.json | 4 + .../(marketing)/(pages)/changelog/page.tsx | 75 +++++++++++++++++++ src/components/page/custom-page.tsx | 32 ++++---- src/components/release/release-card.tsx | 43 +++++++++++ src/lib/release/get-releases.ts | 32 ++++++++ 13 files changed, 438 insertions(+), 16 deletions(-) create mode 100644 content/en/release/v1-0-0.md create mode 100644 content/en/release/v1-1-0.md create mode 100644 content/en/release/v1-2-0.md create mode 100644 content/zh/release/v1-0-0.md create mode 100644 content/zh/release/v1-1-0.md create mode 100644 content/zh/release/v1-2-0.md create mode 100644 src/app/[locale]/(marketing)/(pages)/changelog/page.tsx create mode 100644 src/components/release/release-card.tsx create mode 100644 src/lib/release/get-releases.ts diff --git a/content-collections.ts b/content-collections.ts index 706d717..3dfa076 100644 --- a/content-collections.ts +++ b/content-collections.ts @@ -232,6 +232,74 @@ export const pages = defineCollection({ } }); +/** + * Releases collection for changelog + * + * 1. For a release at content/en/release/v1-0-0.md: + * locale: en + * slug: /release/v1-0-0 + * slugAsParams: v1-0-0 + * + * 2. For a release at content/zh/release/v1-0-0.md: + * locale: zh + * slug: /release/v1-0-0 + * slugAsParams: v1-0-0 + */ +export const releases = defineCollection({ + name: 'release', + directory: 'content', + include: '**/release/**/*.{md,mdx}', + schema: (z) => ({ + title: z.string(), + description: z.string(), + date: z.string().datetime(), + version: z.string(), + published: z.boolean().default(true), + locale: z.enum(LOCALES as [string, ...string[]]).optional() + }), + transform: async (data, context) => { + const body = await compileMDX(context, data, { + remarkPlugins: [ + remarkGfm, + codeImport + ], + rehypePlugins: [ + rehypeSlug, + rehypeAutolinkHeadings, + [rehypePrettyCode, prettyCodeOptions] + ] + }); + + // Determine the locale from the file path or use the provided locale + const pathParts = data._meta.path.split(path.sep); + const localeFromPath = LOCALES.includes(pathParts[0]) ? pathParts[0] : null; + const locale = data.locale || localeFromPath || DEFAULT_LOCALE; + + // Create a slug without the locale in the path + let slugPath = data._meta.path; + if (localeFromPath) { + // Remove the locale from the path for the slug + const pathWithoutLocale = pathParts.slice(1).join(path.sep); + slugPath = pathWithoutLocale; + } + + // Create slugAsParams without the locale + const slugParamsParts = slugPath.split(path.sep).slice(1); + const slugAsParams = slugParamsParts.join('/'); + + return { + ...data, + locale, + slug: `/${slugPath}`, + slugAsParams, + body: { + raw: data.content, + code: body + } + }; + } +}); + const prettyCodeOptions: Options = { theme: 'github-dark', getHighlighter: (options) => @@ -260,5 +328,5 @@ const prettyCodeOptions: Options = { }; export default defineConfig({ - collections: [authors, categories, posts, pages] + collections: [authors, categories, posts, pages, releases] }); \ No newline at end of file diff --git a/content/en/release/v1-0-0.md b/content/en/release/v1-0-0.md new file mode 100644 index 0000000..d88d215 --- /dev/null +++ b/content/en/release/v1-0-0.md @@ -0,0 +1,30 @@ +--- +title: "Initial Release" +description: "Our first official release with core features and functionality" +date: "2024-03-01T00:00:00Z" +version: "v1.0.0" +published: true +--- + +### Core Features + +We're excited to announce the initial release of our platform with the following core features: + +- **User Authentication**: Secure login and registration with email verification +- **Dashboard**: Intuitive dashboard for managing your projects and resources +- **Project Management**: Create, edit, and organize your projects with ease +- **Team Collaboration**: Invite team members and collaborate on projects +- **API Integration**: Connect with third-party services through our API + +### Technical Improvements + +- Built with Next.js 14 and React Server Components for optimal performance +- Implemented Drizzle ORM for type-safe database operations +- Added comprehensive error handling and logging +- Optimized for mobile and desktop experiences + +### Bug Fixes + +- Fixed issues with user registration flow +- Resolved authentication token expiration handling +- Improved form validation and error messages \ No newline at end of file diff --git a/content/en/release/v1-1-0.md b/content/en/release/v1-1-0.md new file mode 100644 index 0000000..5487f95 --- /dev/null +++ b/content/en/release/v1-1-0.md @@ -0,0 +1,30 @@ +--- +title: "Feature Update" +description: "New features and improvements to enhance your experience" +date: "2024-03-15T00:00:00Z" +version: "v1.1.0" +published: true +--- + +### New Features + +We've added several new features to improve your experience: + +- **Dark Mode**: Toggle between light and dark themes based on your preference +- **Export Options**: Export your data in multiple formats (CSV, JSON, PDF) +- **Advanced Search**: Find what you need faster with our improved search functionality +- **Custom Templates**: Create and save templates for recurring projects + +### Enhancements + +- **Performance Optimization**: Reduced page load times by 40% +- **UI Improvements**: Refreshed design with better accessibility +- **Mobile Experience**: Enhanced responsive design for all device sizes +- **Notification System**: Improved notification delivery and management + +### Bug Fixes + +- Fixed issue with project duplication +- Resolved calendar sync problems +- Fixed data import validation errors +- Improved error handling for API requests \ No newline at end of file diff --git a/content/en/release/v1-2-0.md b/content/en/release/v1-2-0.md new file mode 100644 index 0000000..0c86c99 --- /dev/null +++ b/content/en/release/v1-2-0.md @@ -0,0 +1,37 @@ +--- +title: "AI Integration" +description: "Introducing AI-powered features to boost productivity" +date: "2024-03-30T00:00:00Z" +version: "v1.2.0" +published: true +--- + +### AI-Powered Features + +We're thrilled to introduce our new AI capabilities: + +- **Smart Suggestions**: Get intelligent recommendations based on your usage patterns +- **Content Generation**: Generate high-quality content with our AI assistant +- **Automated Tagging**: Let AI organize your content with smart tagging +- **Predictive Analytics**: Forecast trends and outcomes with AI-powered insights + +### Platform Improvements + +- **Webhooks**: Set up custom webhooks to integrate with your workflow +- **Enhanced Security**: Added two-factor authentication and improved password policies +- **Custom Domains**: Use your own domain for your workspace +- **Audit Logs**: Track all activities with comprehensive audit logging + +### Developer Tools + +- **Expanded API**: New endpoints for advanced integrations +- **SDK Updates**: Updated SDKs for all major programming languages +- **Developer Console**: Improved developer experience with better documentation +- **Rate Limiting Controls**: Manage API usage with flexible rate limiting + +### Bug Fixes + +- Fixed issues with file uploads on certain browsers +- Resolved synchronization issues between devices +- Improved error handling for third-party integrations +- Fixed accessibility issues in the dashboard \ No newline at end of file diff --git a/content/zh/release/v1-0-0.md b/content/zh/release/v1-0-0.md new file mode 100644 index 0000000..4a45171 --- /dev/null +++ b/content/zh/release/v1-0-0.md @@ -0,0 +1,30 @@ +--- +title: "初始版本" +description: "我们的第一个正式版本,包含核心功能" +date: "2024-03-01T00:00:00Z" +version: "v1.0.0" +published: true +--- + +### 核心功能 + +我们很高兴宣布平台的初始版本,包含以下核心功能: + +- **用户认证**:安全的登录和注册,带有电子邮件验证 +- **仪表盘**:直观的仪表盘,用于管理您的项目和资源 +- **项目管理**:轻松创建、编辑和组织您的项目 +- **团队协作**:邀请团队成员并在项目上协作 +- **API集成**:通过我们的API连接第三方服务 + +### 技术改进 + +- 使用Next.js 14和React服务器组件构建,以获得最佳性能 +- 实现Drizzle ORM进行类型安全的数据库操作 +- 添加全面的错误处理和日志记录 +- 针对移动和桌面体验进行优化 + +### 错误修复 + +- 修复了用户注册流程中的问题 +- 解决了身份验证令牌过期处理 +- 改进了表单验证和错误消息 \ No newline at end of file diff --git a/content/zh/release/v1-1-0.md b/content/zh/release/v1-1-0.md new file mode 100644 index 0000000..d0f0fde --- /dev/null +++ b/content/zh/release/v1-1-0.md @@ -0,0 +1,30 @@ +--- +title: "功能更新" +description: "新功能和改进,提升您的使用体验" +date: "2024-03-15T00:00:00Z" +version: "v1.1.0" +published: true +--- + +### 新功能 + +我们添加了几个新功能来改善您的体验: + +- **深色模式**:根据您的偏好在浅色和深色主题之间切换 +- **导出选项**:以多种格式(CSV、JSON、PDF)导出您的数据 +- **高级搜索**:通过我们改进的搜索功能更快地找到您需要的内容 +- **自定义模板**:为重复项目创建和保存模板 + +### 增强功能 + +- **性能优化**:页面加载时间减少40% +- **UI改进**:更新设计,提高可访问性 +- **移动体验**:为所有设备尺寸增强响应式设计 +- **通知系统**:改进通知传递和管理 + +### 错误修复 + +- 修复了项目复制问题 +- 解决了日历同步问题 +- 修复了数据导入验证错误 +- 改进了API请求的错误处理 \ No newline at end of file diff --git a/content/zh/release/v1-2-0.md b/content/zh/release/v1-2-0.md new file mode 100644 index 0000000..fd6de58 --- /dev/null +++ b/content/zh/release/v1-2-0.md @@ -0,0 +1,37 @@ +--- +title: "AI集成" +description: "引入AI驱动的功能,提高生产力" +date: "2024-03-30T00:00:00Z" +version: "v1.2.0" +published: true +--- + +### AI驱动功能 + +我们很高兴介绍我们的新AI功能: + +- **智能建议**:根据您的使用模式获取智能推荐 +- **内容生成**:使用我们的AI助手生成高质量内容 +- **自动标记**:让AI通过智能标记组织您的内容 +- **预测分析**:使用AI驱动的洞察力预测趋势和结果 + +### 平台改进 + +- **Webhooks**:设置自定义webhooks以集成到您的工作流程中 +- **增强安全性**:添加双因素认证和改进的密码策略 +- **自定义域名**:为您的工作空间使用自己的域名 +- **审计日志**:通过全面的审计日志跟踪所有活动 + +### 开发者工具 + +- **扩展API**:用于高级集成的新端点 +- **SDK更新**:更新了所有主要编程语言的SDK +- **开发者控制台**:通过更好的文档改善开发者体验 +- **速率限制控制**:通过灵活的速率限制管理API使用 + +### 错误修复 + +- 修复了某些浏览器上文件上传的问题 +- 解决了设备之间的同步问题 +- 改进了第三方集成的错误处理 +- 修复了仪表板中的可访问性问题 \ No newline at end of file diff --git a/messages/en.json b/messages/en.json index ea3d07f..8d8324d 100644 --- a/messages/en.json +++ b/messages/en.json @@ -20,6 +20,10 @@ "tryAgain": "Try again", "backToHome": "Back to home" }, + "ChangelogPage": { + "title": "Changelog", + "subtitle": "Stay up to date with the latest changes in our product." + }, "AuthPage": { "login": { "title": "Login", diff --git a/messages/zh.json b/messages/zh.json index 5c0738d..26f2389 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -17,6 +17,10 @@ "tryAgain": "重试", "backToHome": "返回首页" }, + "ChangelogPage": { + "title": "更新日志", + "subtitle": "查看我们产品的最新动态" + }, "AuthPage": { "login": { "title": "登录", diff --git a/src/app/[locale]/(marketing)/(pages)/changelog/page.tsx b/src/app/[locale]/(marketing)/(pages)/changelog/page.tsx new file mode 100644 index 0000000..c2c09a6 --- /dev/null +++ b/src/app/[locale]/(marketing)/(pages)/changelog/page.tsx @@ -0,0 +1,75 @@ +import { ReleaseCard } from '@/components/release/release-card'; +import { getReleases } from '@/lib/release/get-releases'; +import { getBaseUrl } from '@/lib/urls/get-base-url'; +import type { NextPageProps } from '@/types/next-page-props'; +import type { Metadata } from 'next'; +import { getTranslations } from 'next-intl/server'; +import { notFound } from 'next/navigation'; + +import '@/styles/mdx.css'; + +export async function generateMetadata( + props: NextPageProps +): Promise { + const params = await props.params; + if (!params) { + return {}; + } + + const locale = params.locale as string; + + return { + title: 'Changelog', + description: 'Track all updates and improvements to our platform', + openGraph: { + title: 'Changelog', + description: 'Track all updates and improvements to our platform', + type: 'article', + url: `${getBaseUrl()}/changelog` + } + }; +} + +export default async function ChangelogPage(props: NextPageProps) { + const params = await props.params; + if (!params) { + notFound(); + } + + const locale = params.locale as string; + const releases = await getReleases(locale); + + if (!releases || releases.length === 0) { + notFound(); + } + + const t = await getTranslations('ChangelogPage'); + + return ( +
+ {/* Header */} +
+

+ {t('title')} +

+

+ {t('subtitle')} +

+
+ + {/* Releases */} +
+ {releases.map((release) => ( + + ))} +
+
+ ); +} diff --git a/src/components/page/custom-page.tsx b/src/components/page/custom-page.tsx index 190900e..0372ed6 100644 --- a/src/components/page/custom-page.tsx +++ b/src/components/page/custom-page.tsx @@ -13,23 +13,25 @@ export function CustomPage({ title, description, date, content }: CustomPageProp const formattedDate = getLocaleDate(date); return ( -
-
- {/* Header */} -
-

{title}

-

{description}

-
- -

{formattedDate}

-
-
- - {/* Content */} -
- +
+ {/* Header */} +
+

+ {title} +

+

+ {description} +

+
+ +

{formattedDate}

+ + {/* Content */} +
+ +
); } \ No newline at end of file diff --git a/src/components/release/release-card.tsx b/src/components/release/release-card.tsx new file mode 100644 index 0000000..d4be94e --- /dev/null +++ b/src/components/release/release-card.tsx @@ -0,0 +1,43 @@ +import { Mdx } from '@/components/shared/mdx-component'; +import { getLocaleDate } from '@/lib/utils'; +import { CalendarIcon, TagIcon } from 'lucide-react'; +import { Badge } from '@/components/ui/badge'; +import { Card, CardContent, CardHeader } from '@/components/ui/card'; +import { Separator } from '@/components/ui/separator'; + +interface ReleaseCardProps { + title: string; + description: string; + date: string; + version: string; + content: any; // MDX content +} + +export function ReleaseCard({ title, description, date, version, content }: ReleaseCardProps) { + const formattedDate = getLocaleDate(date); + + return ( + + +
+

{title}

+ + + {version} + +
+

{description}

+
+ +

{formattedDate}

+
+ +
+ +
+ +
+
+
+ ); +} \ No newline at end of file diff --git a/src/lib/release/get-releases.ts b/src/lib/release/get-releases.ts new file mode 100644 index 0000000..100ee51 --- /dev/null +++ b/src/lib/release/get-releases.ts @@ -0,0 +1,32 @@ +import { allReleases } from 'content-collections'; + +/** + * Gets all releases for the changelog page + * @param locale The locale to get releases for + * @returns An array of releases sorted by date (newest first) + */ +export async function getReleases(locale: string) { + // Find all published releases with matching locale + const releases = allReleases.filter( + (release) => + release.published && + release.locale === locale + ); + + // If no releases found with the current locale, try to find ones with any locale + if (releases.length === 0) { + const defaultReleases = allReleases.filter( + (release) => release.published + ); + + // Sort by date (newest first) + return defaultReleases.sort( + (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() + ); + } + + // Sort by date (newest first) + return releases.sort( + (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime() + ); +} \ No newline at end of file