diff --git a/frontend/src/pages/Stats.tsx b/frontend/src/pages/Stats.tsx index fed0e82..56da074 100644 --- a/frontend/src/pages/Stats.tsx +++ b/frontend/src/pages/Stats.tsx @@ -15,7 +15,15 @@ import { ReactWordcloud } from '@cp949/react-wordcloud'; import StatsStyling from "../styles/stats_styling"; import Card from "../components/Card"; -import type { TopUser, SummaryResponse, FrequencyWord } from '../types/ApiTypes' +import { + type TopUser, + type SummaryResponse, + type FrequencyWord, + type UserAnalysisResponse, + type TimeAnalysisResponse, + type ContentAnalysisResponse, + type FilterResponse +} from '../types/ApiTypes' const styles = StatsStyling; @@ -33,14 +41,20 @@ function formatDateRange(startUnix: number, endUnix: number) { return `${fmt(start)} → ${fmt(end)}`; } +function convertFrequencyData(data: FrequencyWord[]) { + return data.map((d: FrequencyWord) => ({ + text: d.word, + value: d.count, + })) +} + const StatPage = () => { const [error, setError] = useState(''); const [loading, setLoading] = useState(false); - const [postsPerDay, setPostsPerDay] = useState([]); - const [heatmapData, setHeatmapData] = useState([]); - const [topUserData, setTopUserData] = useState([]); - const [wordFrequencyData, setWordFrequencyData] = useState([]); + const [userData, setUserData] = useState(null); + const [timeData, setTimeData] = useState(null); + const [contentData, setContentData] = useState(null); const [summary, setSummary] = useState(null); @@ -53,41 +67,16 @@ const StatPage = () => { setLoading(true); Promise.all([ - axios.get("http://localhost:5000/stats/time"), - axios.get("http://localhost:5000/stats/user"), - axios.get("http://localhost:5000/stats/content"), + axios.get("http://localhost:5000/stats/time"), + axios.get("http://localhost:5000/stats/user"), + axios.get("http://localhost:5000/stats/content"), axios.get(`http://localhost:5000/stats/summary`), ]) - .then(([timeRes, userRes, wordsRes, summaryRes]) => { - const eventsPerDay = Array.isArray(timeRes.data?.events_per_day) - ? timeRes.data.events_per_day.filter((d: any) => new Date(d.date) >= new Date("2026-01-10")) - : []; - - const topUsers = Array.isArray(userRes.data?.top_users) - ? userRes.data.top_users.slice(0, 100) - : []; - - const weekdayHourHeatmap = Array.isArray(timeRes.data?.weekday_hour_heatmap) - ? timeRes.data.weekday_hour_heatmap - : []; - - const wordFrequencies = Array.isArray(wordsRes.data?.word_frequencies) - ? wordsRes.data.word_frequencies - : []; - - setPostsPerDay( - eventsPerDay - ); - - setTopUserData(topUsers); - setHeatmapData(weekdayHourHeatmap); - setWordFrequencyData( - wordFrequencies.map((d: FrequencyWord) => ({ - text: d.word, - value: d.count, - })) - ); - setSummary(summaryRes.data ?? null); + .then(([timeRes, userRes, contentRes, summaryRes]) => { + setUserData(userRes.data || null); + setTimeData(timeRes.data || null); + setContentData(contentRes.data || null); + setSummary(summaryRes.data || null); }) .catch((e) => setError("Failed to load statistics: " + String(e))) .finally(() => setLoading(false)); @@ -249,7 +238,7 @@ return (
- + new Date(d.date) >= new Date('2026-01-10'))}> @@ -267,7 +256,7 @@ return (
Most active authors

- {topUserData.map((item) => ( + {userData?.top_users.map((item) => (
Activity density across time

- +
diff --git a/frontend/src/types/ApiTypes.ts b/frontend/src/types/ApiTypes.ts index 6b9802e..85bc92a 100644 --- a/frontend/src/types/ApiTypes.ts +++ b/frontend/src/types/ApiTypes.ts @@ -1,10 +1,15 @@ -// User Code +// User Responses type TopUser = { author: string; source: string; count: number }; +type FrequencyWord = { + word: string; + count: number; +} + type Vocab = { author: string; events: number; @@ -12,7 +17,7 @@ type Vocab = { unique_words: number; vocab_richness: number; avg_words_per_event: number; - top_words: { word: string; count: number }[]; + top_words: FrequencyWord[]; }; type User = { @@ -48,11 +53,6 @@ type TimeAnalysisResponse = { } // Content Analysis -type FrequencyWord = { - word: string; - count: number; -} - type ContentAnalysisResponse = { word_frequencies: FrequencyWord[]; }