refactor: 完善项目详情与侧边栏组件国际化实现
将 ProjectDetail 和 ProjectSidebar 组件中的硬编码文本替换为国际化翻译键,提升中英文支持一致性。 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
import { getTranslations } from 'next-intl/server'
|
||||||
import { MarkdownContent } from './MarkdownContent'
|
import { MarkdownContent } from './MarkdownContent'
|
||||||
import { ShareButtons } from './ShareButtons'
|
import { ShareButtons } from './ShareButtons'
|
||||||
|
|
||||||
@@ -46,6 +47,8 @@ function formatDate(date: Date | string, locale: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function ProjectDetail({ project, locale }: ProjectDetailProps) {
|
export async function ProjectDetail({ project, locale }: ProjectDetailProps) {
|
||||||
|
const t = await getTranslations('project')
|
||||||
|
|
||||||
const displayName = locale === 'en' && project.nameEn ? project.nameEn : project.name
|
const displayName = locale === 'en' && project.nameEn ? project.nameEn : project.name
|
||||||
const displayDescription =
|
const displayDescription =
|
||||||
locale === 'en' && project.descriptionEn ? project.descriptionEn : project.description
|
locale === 'en' && project.descriptionEn ? project.descriptionEn : project.description
|
||||||
@@ -84,7 +87,7 @@ export async function ProjectDetail({ project, locale }: ProjectDetailProps) {
|
|||||||
<span className="hidden sm:inline text-gray-300">|</span>
|
<span className="hidden sm:inline text-gray-300">|</span>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="material-icons text-base">code</span>
|
<span className="material-icons text-base">code</span>
|
||||||
<span>Open Source</span>
|
<span>{t('openSource')}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -114,7 +117,7 @@ export async function ProjectDetail({ project, locale }: ProjectDetailProps) {
|
|||||||
<span className="material-icons text-6xl text-gray-400 dark:text-gray-600 mb-2">
|
<span className="material-icons text-6xl text-gray-400 dark:text-gray-600 mb-2">
|
||||||
smart_toy
|
smart_toy
|
||||||
</span>
|
</span>
|
||||||
<p className="text-gray-500 dark:text-gray-400 font-display text-sm">Project Preview</p>
|
<p className="text-gray-500 dark:text-gray-400 font-display text-sm">{t('projectPreview')}</p>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -133,8 +136,8 @@ export async function ProjectDetail({ project, locale }: ProjectDetailProps) {
|
|||||||
{/* Installation section if GitHub link exists */}
|
{/* Installation section if GitHub link exists */}
|
||||||
{project.links.some((l) => l.type === 'GITHUB') && (
|
{project.links.some((l) => l.type === 'GITHUB') && (
|
||||||
<>
|
<>
|
||||||
<h3>Getting Started</h3>
|
<h3>{t('gettingStarted')}</h3>
|
||||||
<p>To install this project, clone the repository and install dependencies:</p>
|
<p>{t('installInstructions')}</p>
|
||||||
<pre className="bg-gray-100 dark:bg-gray-800 border border-black dark:border-gray-600 p-4 font-mono text-sm overflow-x-auto">
|
<pre className="bg-gray-100 dark:bg-gray-800 border border-black dark:border-gray-600 p-4 font-mono text-sm overflow-x-auto">
|
||||||
<code>{`git clone ${
|
<code>{`git clone ${
|
||||||
project.links.find((l) => l.type === 'GITHUB')?.url || 'https://github.com/example/project'
|
project.links.find((l) => l.type === 'GITHUB')?.url || 'https://github.com/example/project'
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
import { getTranslations } from 'next-intl/server'
|
||||||
|
|
||||||
interface ProjectSidebarProps {
|
interface ProjectSidebarProps {
|
||||||
project: {
|
project: {
|
||||||
@@ -16,23 +17,24 @@ interface ProjectSidebarProps {
|
|||||||
locale: string
|
locale: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to get icon and label for link type
|
// Helper function to get icon for link type
|
||||||
function getLinkInfo(type: string): { icon: string; label: string } {
|
function getLinkIcon(type: string): string {
|
||||||
switch (type.toUpperCase()) {
|
switch (type.toUpperCase()) {
|
||||||
case 'WEBSITE':
|
case 'WEBSITE':
|
||||||
return { icon: 'language', label: 'Official Website' }
|
return 'language'
|
||||||
case 'GITHUB':
|
case 'GITHUB':
|
||||||
return { icon: 'code', label: 'GitHub Repo' }
|
return 'code'
|
||||||
case 'HUGGINGFACE':
|
case 'HUGGINGFACE':
|
||||||
return { icon: 'model_training', label: 'Hugging Face' }
|
return 'model_training'
|
||||||
case 'PAPER':
|
case 'PAPER':
|
||||||
return { icon: 'description', label: 'Paper' }
|
return 'description'
|
||||||
default:
|
default:
|
||||||
return { icon: 'link', label: 'External Link' }
|
return 'link'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
export async function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
||||||
|
const t = await getTranslations('project')
|
||||||
const displayName = locale === 'en' && project.nameEn ? project.nameEn : project.name
|
const displayName = locale === 'en' && project.nameEn ? project.nameEn : project.name
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -41,11 +43,18 @@ export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
|||||||
{project.links.length > 0 && (
|
{project.links.length > 0 && (
|
||||||
<div className="bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 shadow-brutal dark:shadow-brutal-dark">
|
<div className="bg-white dark:bg-surface-dark border-2 border-black dark:border-gray-600 p-6 shadow-brutal dark:shadow-brutal-dark">
|
||||||
<h3 className="font-display font-bold text-lg mb-6 uppercase border-b-2 border-primary pb-2 inline-block">
|
<h3 className="font-display font-bold text-lg mb-6 uppercase border-b-2 border-primary pb-2 inline-block">
|
||||||
Project Links
|
{t('projectLinks')}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{project.links.map((link) => {
|
{project.links.map((link) => {
|
||||||
const { icon, label } = getLinkInfo(link.type)
|
const icon = getLinkIcon(link.type)
|
||||||
|
const labelMap: Record<string, string> = {
|
||||||
|
WEBSITE: t('officialWebsite'),
|
||||||
|
GITHUB: t('githubRepo'),
|
||||||
|
HUGGINGFACE: t('huggingface'),
|
||||||
|
PAPER: t('paper'),
|
||||||
|
}
|
||||||
|
const label = labelMap[link.type] || t('externalLinks')
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
key={link.id}
|
key={link.id}
|
||||||
@@ -70,20 +79,20 @@ export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
|||||||
<div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
|
<div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">License</span>
|
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">{t('license')}</span>
|
||||||
<span className="font-bold text-sm">MIT</span>
|
<span className="font-bold text-sm">MIT</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">Pricing</span>
|
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">{t('pricing')}</span>
|
||||||
<span className="font-bold text-sm">Free</span>
|
<span className="font-bold text-sm">Free</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">Status</span>
|
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">{t('status')}</span>
|
||||||
<span className="font-bold text-sm">Active</span>
|
<span className="font-bold text-sm">Active</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">Type</span>
|
<span className="text-xs text-gray-500 uppercase font-mono block mb-1">{t('type')}</span>
|
||||||
<span className="font-bold text-sm">Open Source</span>
|
<span className="font-bold text-sm">{t('openSource')}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -98,13 +107,13 @@ export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
|||||||
<div className="w-12 h-12 bg-white rounded-full border-2 border-black flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform">
|
<div className="w-12 h-12 bg-white rounded-full border-2 border-black flex items-center justify-center mx-auto mb-4 group-hover:scale-110 transition-transform">
|
||||||
<span className="material-icons text-2xl">rocket_launch</span>
|
<span className="material-icons text-2xl">rocket_launch</span>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="font-display font-bold text-xl mb-2">Build Your Own Agent?</h3>
|
<h3 className="font-display font-bold text-xl mb-2">{t('buildYourOwnAgent')}</h3>
|
||||||
<p className="text-sm font-medium mb-6">Start using our API to build custom agents in minutes.</p>
|
<p className="text-sm font-medium mb-6">{t('buildAgentDesc')}</p>
|
||||||
<Link
|
<Link
|
||||||
href={`/${locale}/projects`}
|
href={`/${locale}/projects`}
|
||||||
className="block w-full bg-black text-white font-display font-bold py-3 text-sm uppercase hover:bg-gray-800 transition-colors shadow-none text-center"
|
className="block w-full bg-black text-white font-display font-bold py-3 text-sm uppercase hover:bg-gray-800 transition-colors shadow-none text-center"
|
||||||
>
|
>
|
||||||
Get Started Now
|
{t('getStartedNow')}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -113,7 +122,7 @@ export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
|||||||
{locale === 'en' && (
|
{locale === 'en' && (
|
||||||
<div className="sticky top-24 bg-background-light dark:bg-background-dark border border-gray-300 dark:border-gray-700 p-6 hidden lg:block">
|
<div className="sticky top-24 bg-background-light dark:bg-background-dark border border-gray-300 dark:border-gray-700 p-6 hidden lg:block">
|
||||||
<h3 className="font-display font-bold text-sm uppercase tracking-widest mb-4 text-gray-500 dark:text-gray-400">
|
<h3 className="font-display font-bold text-sm uppercase tracking-widest mb-4 text-gray-500 dark:text-gray-400">
|
||||||
On this page
|
{t('onThisPage')}
|
||||||
</h3>
|
</h3>
|
||||||
<ul className="space-y-3 text-sm border-l-2 border-gray-200 dark:border-gray-700 pl-4">
|
<ul className="space-y-3 text-sm border-l-2 border-gray-200 dark:border-gray-700 pl-4">
|
||||||
<li>
|
<li>
|
||||||
@@ -121,7 +130,7 @@ export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
|||||||
href="#overview"
|
href="#overview"
|
||||||
className="text-black dark:text-white font-bold border-l-2 border-black dark:border-white -ml-[18px] pl-4 block"
|
className="text-black dark:text-white font-bold border-l-2 border-black dark:border-white -ml-[18px] pl-4 block"
|
||||||
>
|
>
|
||||||
Overview
|
{t('overview')}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -129,7 +138,7 @@ export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
|||||||
href="#features"
|
href="#features"
|
||||||
className="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block"
|
className="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block"
|
||||||
>
|
>
|
||||||
Key Features
|
{t('keyFeatures')}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -137,7 +146,7 @@ export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
|||||||
href="#getting-started"
|
href="#getting-started"
|
||||||
className="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block"
|
className="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block"
|
||||||
>
|
>
|
||||||
Getting Started
|
{t('gettingStarted')}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -145,7 +154,7 @@ export function ProjectSidebar({ project, locale }: ProjectSidebarProps) {
|
|||||||
href="#use-cases"
|
href="#use-cases"
|
||||||
className="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block"
|
className="text-gray-600 dark:text-gray-400 hover:text-black dark:hover:text-white transition-colors block"
|
||||||
>
|
>
|
||||||
Use Cases
|
{t('useCases')}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
+19
-1
@@ -29,7 +29,25 @@
|
|||||||
"submitYourProject": "Submit Your Project",
|
"submitYourProject": "Submit Your Project",
|
||||||
"submitProjectTitle": "Submit Your Project",
|
"submitProjectTitle": "Submit Your Project",
|
||||||
"submitProjectDescription": "Have an AI tool worth sharing? Add it to Agent Park.",
|
"submitProjectDescription": "Have an AI tool worth sharing? Add it to Agent Park.",
|
||||||
"submitNow": "SUBMIT NOW"
|
"submitNow": "SUBMIT NOW",
|
||||||
|
"projectLinks": "Project Links",
|
||||||
|
"officialWebsite": "Official Website",
|
||||||
|
"githubRepo": "GitHub Repo",
|
||||||
|
"license": "License",
|
||||||
|
"pricing": "Pricing",
|
||||||
|
"status": "Status",
|
||||||
|
"type": "Type",
|
||||||
|
"openSource": "Open Source",
|
||||||
|
"projectPreview": "Project Preview",
|
||||||
|
"gettingStarted": "Getting Started",
|
||||||
|
"installInstructions": "To install this project, clone the repository and install dependencies:",
|
||||||
|
"buildYourOwnAgent": "Build Your Own Agent?",
|
||||||
|
"buildAgentDesc": "Start using our API to build custom agents in minutes.",
|
||||||
|
"getStartedNow": "Get Started Now",
|
||||||
|
"onThisPage": "On this page",
|
||||||
|
"overview": "Overview",
|
||||||
|
"keyFeatures": "Key Features",
|
||||||
|
"useCases": "Use Cases"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"home": "Home",
|
"home": "Home",
|
||||||
|
|||||||
+19
-1
@@ -29,7 +29,25 @@
|
|||||||
"submitYourProject": "提交你的项目",
|
"submitYourProject": "提交你的项目",
|
||||||
"submitProjectTitle": "提交你的项目",
|
"submitProjectTitle": "提交你的项目",
|
||||||
"submitProjectDescription": "有值得分享的 AI 工具吗?将其添加到 Agent Park。",
|
"submitProjectDescription": "有值得分享的 AI 工具吗?将其添加到 Agent Park。",
|
||||||
"submitNow": "立即提交"
|
"submitNow": "立即提交",
|
||||||
|
"projectLinks": "项目链接",
|
||||||
|
"officialWebsite": "官方网站",
|
||||||
|
"githubRepo": "GitHub 仓库",
|
||||||
|
"license": "许可证",
|
||||||
|
"pricing": "定价",
|
||||||
|
"status": "状态",
|
||||||
|
"type": "类型",
|
||||||
|
"openSource": "开源",
|
||||||
|
"projectPreview": "项目预览",
|
||||||
|
"gettingStarted": "快速开始",
|
||||||
|
"installInstructions": "要安装此项目,请克隆仓库并安装依赖:",
|
||||||
|
"buildYourOwnAgent": "构建你自己的 Agent?",
|
||||||
|
"buildAgentDesc": "开始使用我们的 API,在几分钟内构建自定义 Agent。",
|
||||||
|
"getStartedNow": "立即开始",
|
||||||
|
"onThisPage": "本页内容",
|
||||||
|
"overview": "概述",
|
||||||
|
"keyFeatures": "核心功能",
|
||||||
|
"useCases": "使用场景"
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"home": "首页",
|
"home": "首页",
|
||||||
|
|||||||
Reference in New Issue
Block a user