import { useState } from 'react';
import { Link } from 'react-router-dom';
import { useGetHome } from '../generated/anthoLumeAPIV1';
import type {
HomeResponse,
LeaderboardData,
LeaderboardEntry,
UserStreak,
} from '../generated/model';
import ReadingHistoryGraph from '../components/ReadingHistoryGraph';
import { formatNumber, formatDuration } from '../utils/formatters';
interface InfoCardProps {
title: string;
size: string | number;
link?: string;
}
function InfoCard({ title, size, link }: InfoCardProps) {
if (link) {
return (
);
}
return (
);
}
interface StreakCardProps {
window: 'DAY' | 'WEEK';
currentStreak: number;
currentStreakStartDate: string;
currentStreakEndDate: string;
maxStreak: number;
maxStreakStartDate: string;
maxStreakEndDate: string;
}
function StreakCard({
window,
currentStreak,
currentStreakStartDate,
currentStreakEndDate,
maxStreak,
maxStreakStartDate,
maxStreakEndDate,
}: StreakCardProps) {
return (
{window === 'WEEK' ? 'Weekly Read Streak' : 'Daily Read Streak'}
{window === 'WEEK' ? 'Current Weekly Streak' : 'Current Daily Streak'}
{currentStreakStartDate} ➞ {currentStreakEndDate}
{currentStreak}
{window === 'WEEK' ? 'Best Weekly Streak' : 'Best Daily Streak'}
{maxStreakStartDate} ➞ {maxStreakEndDate}
{maxStreak}
);
}
interface LeaderboardCardProps {
name: string;
data: LeaderboardData;
}
type TimePeriod = 'all' | 'year' | 'month' | 'week';
function LeaderboardCard({ name, data }: LeaderboardCardProps) {
const [selectedPeriod, setSelectedPeriod] = useState('all');
const formatValue = (value: number): string => {
switch (name) {
case 'WPM':
return `${value.toFixed(2)} WPM`;
case 'Duration':
return formatDuration(value);
case 'Words':
return formatNumber(value);
default:
return value.toString();
}
};
const currentData = data[selectedPeriod];
const handlePeriodChange = (period: TimePeriod) => {
setSelectedPeriod(period);
};
return (
{name} Leaderboard
{/* Current period data */}
{currentData?.length === 0 ? (
N/A
) : (
{currentData[0]?.user_id || 'N/A'}
)}
{currentData?.slice(0, 3).map((item: LeaderboardEntry, index: number) => (
0 ? 'border-t border-gray-200' : ''}`}
>
{formatValue(item.value)}
))}
);
}
export default function HomePage() {
const { data: homeData, isLoading: homeLoading } = useGetHome();
const homeResponse = homeData?.status === 200 ? (homeData.data as HomeResponse) : null;
const dbInfo = homeResponse?.database_info;
const streaks = homeResponse?.streaks?.streaks;
const graphData = homeResponse?.graph_data?.graph_data;
const userStats = homeResponse?.user_statistics;
if (homeLoading) {
return Loading...
;
}
return (
{/* Daily Read Totals Graph */}
{/* Info Cards */}
{/* Streak Cards */}
{streaks?.map((streak: UserStreak, index: number) => (
))}
{/* Leaderboard Cards */}
);
}