feat: 添加关键词词云页面国际化支持
This commit is contained in:
@@ -15,12 +15,15 @@ export interface KeywordData {
|
||||
word: string;
|
||||
trendScore: number;
|
||||
description: string;
|
||||
descriptionEn?: string | null;
|
||||
detailPoints: string[];
|
||||
detailPointsEn?: string[] | null;
|
||||
visualConfig: VisualConfig;
|
||||
}
|
||||
|
||||
interface CloudWordProps {
|
||||
data: KeywordData;
|
||||
locale: string;
|
||||
}
|
||||
|
||||
// 颜色映射
|
||||
@@ -31,11 +34,15 @@ const colorMap: Record<string, string> = {
|
||||
gray: 'bg-gray-100 dark:bg-gray-700',
|
||||
};
|
||||
|
||||
export function CloudWord({ data }: CloudWordProps) {
|
||||
const { word, visualConfig, description, detailPoints } = data;
|
||||
export function CloudWord({ data, locale }: CloudWordProps) {
|
||||
const { word, visualConfig, description, descriptionEn, detailPoints, detailPointsEn } = data;
|
||||
const { color, size, border, rotation } = visualConfig;
|
||||
const colorClass = colorMap[color];
|
||||
|
||||
// 根据语言选择内容
|
||||
const displayDescription = locale === 'en' && descriptionEn ? descriptionEn : description;
|
||||
const displayPoints = locale === 'en' && detailPointsEn ? detailPointsEn : detailPoints;
|
||||
|
||||
return (
|
||||
<span
|
||||
className={cn(
|
||||
@@ -63,8 +70,8 @@ export function CloudWord({ data }: CloudWordProps) {
|
||||
{word}
|
||||
<WordPopover
|
||||
title={word}
|
||||
description={description}
|
||||
points={detailPoints}
|
||||
description={displayDescription}
|
||||
points={displayPoints}
|
||||
titleColor={color}
|
||||
/>
|
||||
</span>
|
||||
|
||||
@@ -6,7 +6,18 @@ import { QuarterNavigator } from './QuarterNavigator';
|
||||
import { ProgressIndicator } from './ProgressIndicator';
|
||||
import { useKeywordCloud } from '@/hooks/useKeywordCloudClient';
|
||||
|
||||
export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
||||
interface KeywordCloudProps {
|
||||
initialQuarter: string;
|
||||
locale: string;
|
||||
texts: {
|
||||
loading: string;
|
||||
loadFailed: string;
|
||||
retry: string;
|
||||
hotKeyword: string;
|
||||
};
|
||||
}
|
||||
|
||||
export function KeywordCloud({ initialQuarter, locale, texts }: KeywordCloudProps) {
|
||||
const [currentQuarter, setCurrentQuarter] = useState(initialQuarter);
|
||||
const [quarters, setQuarters] = useState<string[]>([]);
|
||||
const { data, isLoading, error } = useKeywordCloud(currentQuarter);
|
||||
@@ -41,7 +52,7 @@ export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<div className="text-center">
|
||||
<div className="inline-block animate-spin rounded-full h-12 w-12 border-4 border-black border-t-primary mb-4" />
|
||||
<p className="font-display font-bold text-lg">加载中...</p>
|
||||
<p className="font-display font-bold text-lg">{texts.loading}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -52,13 +63,13 @@ export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
||||
<div className="flex items-center justify-center min-h-[400px]">
|
||||
<div className="text-center">
|
||||
<p className="font-display font-bold text-lg text-red-500 mb-4">
|
||||
加载失败
|
||||
{texts.loadFailed}
|
||||
</p>
|
||||
<button
|
||||
onClick={() => window.location.reload()}
|
||||
className="bg-primary text-black border-2 border-black px-4 py-2 font-bold hover:bg-yellow-500 transition-colors"
|
||||
>
|
||||
重试
|
||||
{texts.retry}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -87,7 +98,7 @@ export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
||||
<div className="relative py-12 px-4">
|
||||
<div className="word-cluster flex flex-wrap gap-3 items-center justify-center max-w-full">
|
||||
{data.keywords.map((keyword) => (
|
||||
<CloudWord key={keyword.id} data={keyword} />
|
||||
<CloudWord key={keyword.id} data={keyword} locale={locale} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
@@ -95,7 +106,7 @@ export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
||||
{/* 装饰元素 */}
|
||||
{data.keywords.length > 0 && firstKeyword && (
|
||||
<div className="absolute -top-16 -right-8 md:right-0 bg-black text-white p-5 rounded-xl text-sm md:text-base font-display w-64 shadow-hard rotate-6 hidden lg:block">
|
||||
“{firstKeyword.word}” 是本季度最热门词汇!
|
||||
{texts.hotKeyword.replace('{word}', firstKeyword.word)}
|
||||
<div className="absolute -bottom-2 left-1/2 -translate-x-1/2 w-4 h-4 bg-black transform rotate-45" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { KeywordCloud } from './components/KeywordCloud';
|
||||
import { getTranslations } from 'next-intl/server';
|
||||
|
||||
interface PageProps {
|
||||
params: {
|
||||
@@ -9,27 +10,51 @@ interface PageProps {
|
||||
};
|
||||
}
|
||||
|
||||
export default function KeywordCloudPage({ searchParams }: PageProps) {
|
||||
export async function generateMetadata({
|
||||
params
|
||||
}: {
|
||||
params: Promise<{ locale: string }>
|
||||
}) {
|
||||
const { locale } = await params;
|
||||
const t = await getTranslations('keywordCloud');
|
||||
|
||||
return {
|
||||
title: t('metaTitle'),
|
||||
description: t('metaDescription'),
|
||||
};
|
||||
}
|
||||
|
||||
export default async function KeywordCloudPage({ searchParams, params }: PageProps) {
|
||||
const { locale } = await params;
|
||||
const t = await getTranslations('keywordCloud');
|
||||
|
||||
// 如果 URL 中有 quarter 参数,使用它;否则使用默认季度
|
||||
const quarter = searchParams.quarter || '2024-Q1';
|
||||
|
||||
const texts = {
|
||||
loading: t('loading'),
|
||||
loadFailed: t('loadFailed'),
|
||||
retry: t('retry'),
|
||||
hotKeyword: t('hotKeyword'),
|
||||
};
|
||||
|
||||
return (
|
||||
<main className="relative z-10 max-w-6xl mx-auto px-4 pb-32 overflow-visible">
|
||||
{/* 页面标题 */}
|
||||
<header className="relative z-10 pt-16 pb-8 text-center max-w-4xl mx-auto px-4">
|
||||
<div className="inline-block bg-accent dark:bg-purple-700 border-2 border-black px-3 py-1 font-display font-bold text-xs mb-4 shadow-hard-sm rotate-[-2deg]">
|
||||
AI 热点追踪
|
||||
{t('badge')}
|
||||
</div>
|
||||
<h1 className="font-display text-5xl md:text-7xl font-bold mb-6 tracking-tighter leading-tight">
|
||||
季度 AI <span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-500 to-purple-500" style={{ WebkitTextStroke: '1.5px black' }}>热点词云</span>
|
||||
{t('title')} <span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-500 to-purple-500" style={{ WebkitTextStroke: '1.5px black' }}>{t('titleHighlight')}</span>
|
||||
</h1>
|
||||
<p className="text-lg md:text-xl max-w-2xl mx-auto font-medium text-gray-700 dark:text-gray-300 mb-8">
|
||||
从 “大型语言模型” 到 “Agent 工作流”。探索 AI 话语的演变历程。
|
||||
{t('subtitle')}
|
||||
</p>
|
||||
</header>
|
||||
|
||||
{/* 词云组件 */}
|
||||
<KeywordCloud initialQuarter={quarter} />
|
||||
<KeywordCloud initialQuarter={quarter} locale={locale} texts={texts} />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -95,5 +95,17 @@
|
||||
"followUs": "Follow Us",
|
||||
"copyright": "© 2025 Agent Park. All rights reserved.",
|
||||
"designedFor": "DESIGNED FOR AI BUILDERS"
|
||||
},
|
||||
"keywordCloud": {
|
||||
"metaTitle": "AI Hotspot Word Cloud - Agent Park",
|
||||
"metaDescription": "Explore the evolution of quarterly AI hotspots, from Large Language Models to Agent Workflows",
|
||||
"badge": "AI Trend Tracker",
|
||||
"title": "Quarterly AI",
|
||||
"titleHighlight": "Hotspot Word Cloud",
|
||||
"subtitle": "From “Large Language Models” to “Agent Workflows”. Explore the evolution of AI discourse.",
|
||||
"loading": "Loading...",
|
||||
"loadFailed": "Failed to load",
|
||||
"retry": "Retry",
|
||||
"hotKeyword": "“{word}” is the hottest keyword this quarter!"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,5 +95,17 @@
|
||||
"followUs": "关注我们",
|
||||
"copyright": "© 2025 Agent Park. 保留所有权利。",
|
||||
"designedFor": "专为 AI 构建者设计"
|
||||
},
|
||||
"keywordCloud": {
|
||||
"metaTitle": "AI 热点词云 - Agent Park",
|
||||
"metaDescription": "探索季度 AI 热点词汇的演变历程,从大型语言模型到 Agent 工作流",
|
||||
"badge": "AI 热点追踪",
|
||||
"title": "季度 AI",
|
||||
"titleHighlight": "热点词云",
|
||||
"subtitle": "从 “大型语言模型” 到 “Agent 工作流”。探索 AI 话语的演变历程。",
|
||||
"loading": "加载中...",
|
||||
"loadFailed": "加载失败",
|
||||
"retry": "重试",
|
||||
"hotKeyword": "“{word}” 是本季度最热门词汇!"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user