import { useEffect, useMemo, useState } from "react"; import { AudioOutlined, ArrowRightOutlined, VideoCameraOutlined, VideoCameraAddOutlined } from "@ant-design/icons"; import { Button, Empty, Skeleton, Tag, Typography } from "antd"; import { useNavigate } from "react-router-dom"; import dayjs from "dayjs"; import { getRecentTasks } from "@/api/business/dashboard"; import type { MeetingVO } from "@/api/business/meeting"; import "./index.less"; import RightVisual from "./RightVisual"; const { Text, Title } = Typography; type QuickEntry = { title: string; icon: React.ReactNode; description: string[]; accent: string; badge: string; onClick: () => void; }; type RecentCard = { id: number | string; title: string; duration: string; time: string; tags: string[]; }; const RECENT_CARD_READ_STORAGE_KEY = "home_recent_card_read_ids"; const fallbackRecentCards: RecentCard[] = [ { id: "sample-1", title: "2026-03-25 16:05 记录", duration: "01:10", time: "今天 16:05", tags: ["发言人", "降噪", "速度", "模仿", "暂停"] }, { id: "sample-2", title: "【示例】开会用通义听悟,高效又省心", duration: "02:14", time: "2026-03-24 11:04", tags: ["会议日程", "笔记", "发言人", "协同", "纪要"] }, { id: "sample-3", title: "【示例】上课用通义听悟,学习效率 UPUP", duration: "02:01", time: "2026-03-23 11:04", tags: ["转写", "笔记", "学习", "教学音频", "课程音频"] } ]; function buildRecentCards(tasks: MeetingVO[]): RecentCard[] { if (!tasks.length) { return fallbackRecentCards; } return tasks.slice(0, 3).map((task, index) => ({ id: task.id, title: task.title, duration: `0${index + 1}:${10 + index * 12}`, time: dayjs(task.meetingTime || task.createdAt).format("YYYY-MM-DD HH:mm"), tags: task.tags?.split(",").filter(Boolean).slice(0, 5) || [] })); } export default function HomePage() { const navigate = useNavigate(); const [recentTasks, setRecentTasks] = useState([]); const [loading, setLoading] = useState(true); const [readCardIds, setReadCardIds] = useState(() => { if (typeof window === "undefined") { return []; } try { const rawValue = window.localStorage.getItem(RECENT_CARD_READ_STORAGE_KEY); if (!rawValue) { return []; } const parsed = JSON.parse(rawValue); return Array.isArray(parsed) ? parsed.map(String) : []; } catch { return []; } }); const [wordIndex, setWordIndex] = useState(0); const ROTATING_WORDS = useMemo(() => ["都有迹可循", "都能被听见", "都值得记录", "都清晰可见"], []); useEffect(() => { const interval = setInterval(() => { setWordIndex((prev) => (prev + 1) % ROTATING_WORDS.length); }, 3000); return () => clearInterval(interval); }, [ROTATING_WORDS.length]); useEffect(() => { const fetchRecentTasks = async () => { try { const response = await getRecentTasks(); const payload: any = (response as any).data || response; setRecentTasks(payload?.data || payload || []); } catch (error) { console.error("Home recent tasks load failed", error); } finally { setLoading(false); } }; void fetchRecentTasks(); }, []); useEffect(() => { if (typeof window === "undefined") { return; } window.localStorage.setItem(RECENT_CARD_READ_STORAGE_KEY, JSON.stringify(readCardIds)); }, [readCardIds]); const quickEntries = useMemo( () => [ { title: "开启实时记录", icon: , description: ["实时语音转文字", "同步翻译,智能总结要点"], accent: "violet", badge: "会议神器", onClick: () => navigate("/meetings?action=create&type=realtime") }, { title: "上传音视频", icon: , description: ["音视频转文字", "区分发言人,一键导出"], accent: "cyan", badge: "iMeeting", onClick: () => navigate("/meetings?create=true") } ], [navigate] ); const recentCards = useMemo(() => buildRecentCards(recentTasks), [recentTasks]); const handleRecentCardClick = (card: RecentCard) => { const cardId = String(card.id); setReadCardIds((prev) => (prev.includes(cardId) ? prev : [...prev, cardId])); if (typeof card.id === "number") { navigate(`/meetings/${card.id}`); } }; return (
{/* Massive Abstract Background Sphere matching the design/img.png */}
); }