'use client'; import { useEffect, useState } from 'react'; import Link from 'next/link'; import { apiFetch } from '@/lib/auth'; import { Skeleton } from '@/components/ui/skeleton'; import { useT } from '@/i18n'; interface Domain { id: string; name: string; sessionCount: number; mastery: number; lastActive: string | null; weak: boolean } interface Recommendation { title: string; url: string } interface Analytics { domains: Domain[]; totalSessions: number; weakDomains: string[]; recommendations: Recommendation[] } export default function LearningAnalyticsPage() { const t = useT(); const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); useEffect(() => { loadAnalytics(); }, []); async function loadAnalytics() { try { const res = await apiFetch('/learning/analytics'); if (!res.ok) throw new Error('加载失败'); setData(await res.json()); } catch (e: any) { setError(e.message); } setLoading(false); } if (loading) return (
{[1,2,3].map(i => )}
); if (error) return (

{error}

); const coveredDomains = data?.domains.filter(d => d.sessionCount > 0) || []; const weakDomains = data?.domains.filter(d => d.weak) || []; const avgMastery = data?.domains.length ? Math.round(data.domains.reduce((sum, d) => sum + d.mastery, 0) / data.domains.length) : 0; return (
← {t.path.back}

{t.learning.analytics}

{t.learning.analyticsDesc}

{t.learning.totalSessions}
{data?.totalSessions || 0}
{t.learning.domainsCovered}
{coveredDomains.length}/{data?.domains.length || 0}
{t.learning.avgMastery}
{avgMastery}%
{data && data.domains.length > 0 && (

{t.learning.knowledgeDomains}

{data.domains.map(domain => (
{domain.name} {domain.weak && {t.learning.toStrengthen}}
{t.learning.conversations.replace('{count}', String(domain.sessionCount))} = 60 ? 'text-green-600' : domain.mastery >= 30 ? 'text-amber-600' : 'text-red-500'}`}>{domain.mastery}%
= 60 ? 'bg-green-500' : domain.mastery >= 30 ? 'bg-amber-500' : 'bg-red-500'}`} style={{ width: `${domain.mastery}%` }} />
))}
)} {weakDomains.length > 0 && (

{t.learning.weakAreas}

{t.learning.weakDesc}

{weakDomains.map(d => ( {d.name} ))}
)} {data && data.recommendations.length > 0 && (

{t.learning.recommendations}

{t.learning.recDesc}

{data.recommendations.map((rec, i) => (
{rec.title[0]}
{rec.title}
{t.learning.clickToGo}
))}
)}
); }