From e60c6faeb2251de43e7805d0285482dd2175d05d Mon Sep 17 00:00:00 2001 From: Caihaohan Date: Tue, 27 Jan 2026 20:18:26 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20KeywordCloud=20?= =?UTF-8?q?=E4=B8=BB=E5=AE=B9=E5=99=A8=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../keyword-cloud/components/KeywordCloud.tsx | 125 ++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/app/[locale]/keyword-cloud/components/KeywordCloud.tsx diff --git a/src/app/[locale]/keyword-cloud/components/KeywordCloud.tsx b/src/app/[locale]/keyword-cloud/components/KeywordCloud.tsx new file mode 100644 index 0000000..6ccf4ef --- /dev/null +++ b/src/app/[locale]/keyword-cloud/components/KeywordCloud.tsx @@ -0,0 +1,125 @@ +'use client'; + +import React, { useState, useEffect } from 'react'; +import { CloudWord } from './CloudWord'; +import { QuarterNavigator } from './QuarterNavigator'; +import { ProgressIndicator } from './ProgressIndicator'; +import { useKeywordCloud } from '@/hooks/useKeywordCloudClient'; + +interface KeywordData { + id: number; + word: string; + trendScore: number; + description: string; + detailPoints: string[]; + visualConfig: { + color: string; + size: string; + border: string; + rotation?: string; + }; +} + +interface QuarterData { + quarter: string; + title: string; + titleEn?: string; + subtitle?: string; + subtitleEn?: string; + keywords: KeywordData[]; +} + +export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) { + const [currentQuarter, setCurrentQuarter] = useState(initialQuarter); + const [quarters, setQuarters] = useState([]); + const { data, isLoading, error } = useKeywordCloud(currentQuarter); + + // 加载季度列表 + useEffect(() => { + async function loadQuarters() { + try { + const response = await fetch('/api/keyword-cloud/quarters'); + const json = await response.json(); + if (json.success) { + const quarterStrings = json.quarters.map((q: any) => q.quarter); + setQuarters(quarterStrings); + } + } catch (error) { + console.error('Failed to load quarters:', error); + } + } + loadQuarters(); + }, []); + + const handleNavigate = (quarter: string) => { + setCurrentQuarter(quarter); + // 更新 URL 而不刷新页面 + const url = new URL(window.location.href); + url.searchParams.set('quarter', quarter); + window.history.pushState({}, '', url.toString()); + }; + + if (isLoading) { + return ( +
+
+
+

加载中...

+
+
+ ); + } + + if (error || !data) { + return ( +
+
+

+ 加载失败 +

+ +
+
+ ); + } + + return ( +
+ {/* 进度条 */} + + + {/* 季度导航 */} + + + {/* 词云区域 */} +
+
+ {data.keywords.map((keyword: KeywordData) => ( + + ))} +
+
+ + {/* 装饰元素 */} + {data.keywords.length > 0 && ( +
+ "{data.keywords[0].word}" 是本季度最热门词汇! +
+
+ )} +
+ ); +}