import { useActionQuery } from "@agent-native/core/client/hooks"; import { useT } from "@agent-native/core/client/i18n"; import { useSetHeaderActions } from "@agent-native/toolkit/app-shell"; import { IconCalendar } from "@tabler/icons-react"; import { subDays } from "date-fns"; import { useState } from "react"; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, ReferenceLine, } from "recharts"; import { QueryErrorState } from "@/components/QueryErrorState"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Skeleton } from "@/components/ui/skeleton"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { WeeklyCaloriesChart } from "@/components/WeeklyCaloriesChart"; import messages from "@/i18n/en-US"; import { formatLocalDate } from "@/lib/utils"; const GOAL_CALORIES = 2000; export function meta() { const description = messages.seo.analyticsDescription; return [ { title: messages.routeTitles.analytics }, { name: "description", content: description, }, { property: "og:description", content: description }, { name: "twitter:description", content: description }, ]; } export default function AnalyticsPage() { const t = useT(); const [timeRange, setTimeRange] = useState("30"); useSetHeaderActions( , ); const getStartDate = (range: string) => { if (range === "all") return "2000-01-01"; return formatLocalDate(subDays(new Date(), parseInt(range))); }; const endDate = formatLocalDate(new Date()); const startDate = getStartDate(timeRange); const historyQuery = useActionQuery("meals-history", { startDate, endDate, }); const { data: rawHistory, isLoading } = historyQuery; const history = Array.isArray(rawHistory) ? rawHistory : []; const weightHistoryQuery = useActionQuery("weights-history", { startDate, endDate, }); const { data: rawWeightHistory, isLoading: weightLoading } = weightHistoryQuery; const weightHistory = Array.isArray(rawWeightHistory) ? rawWeightHistory : []; const weightStats = { current: weightHistory.length > 0 ? weightHistory[weightHistory.length - 1].weight : 0, change: weightHistory.length >= 2 ? Math.round( (weightHistory[weightHistory.length - 1].trendWeight - weightHistory[0].trendWeight) * 10, ) / 10 : 0, lowest: weightHistory.length > 0 ? Math.min(...weightHistory.map((w) => w.weight)) : 0, highest: weightHistory.length > 0 ? Math.max(...weightHistory.map((w) => w.weight)) : 0, }; const getWeightYDomain = () => { if (weightHistory.length === 0) return [0, 200]; const ws = weightHistory.map((h) => h.weight); const min = Math.min(...ws); const max = Math.max(...ws); const padding = (max - min) * 0.3 || 5; return [Math.floor(min - padding), Math.ceil(max + padding)]; }; const stats = { average: history.length > 0 ? Math.round( history.reduce((sum, day) => sum + day.netCalories, 0) / history.length, ) : 0, highest: history.length > 0 ? Math.max(...history.map((day) => day.netCalories)) : 0, lowest: history.length > 0 ? Math.min(...history.map((day) => day.netCalories)) : 0, total: history.length, }; const tooltipStyle = { backgroundColor: "hsl(var(--card))", border: "1px solid hsl(var(--border))", borderRadius: "12px", boxShadow: "0 8px 32px rgba(0, 0, 0, 0.3)", }; return (
{/* Stats Cards */}
{[ { label: t("analytics.average"), value: stats.average }, { label: t("analytics.lowest"), value: stats.lowest }, { label: t("analytics.highest"), value: stats.highest }, { label: t("analytics.daysTracked"), value: stats.total, unit: t("analytics.daysUnit"), }, ].map((stat) => (

{stat.label}

{stat.value} {stat.unit || "kcal"}
))}
{/* Calorie Trend Chart */} Calorie Trend ( {timeRange === "all" ? t("analytics.allTime") : t("analytics.lastDays", { count: Number(timeRange) })} ) {t("analytics.net")} {t("analytics.consumed")} {t("analytics.burned")} {["net", "consumed", "burned"].map((tab) => ( {isLoading ? ( ) : historyQuery.isError ? ( void historyQuery.refetch()} /> ) : history.length > 0 ? ( [ `${value} kcal`, tab === "net" ? "Net Calories" : tab === "consumed" ? "Consumed" : "Burned", ]} /> {tab !== "burned" && ( )} ) : (

{t("analytics.noData")}

)}
))}
{/* Weekly Net Calories */} Weekly Net Calories vs Goal ( {timeRange === "all" ? t("analytics.allTime") : t("analytics.lastDays", { count: Number(timeRange) })} ) {historyQuery.isError ? ( void historyQuery.refetch()} /> ) : ( )} {/* Weight Chart */} Weight Trend ( {timeRange === "all" ? t("analytics.allTime") : t("analytics.lastDays", { count: Number(timeRange) })} )
{[ { label: t("analytics.current"), value: weightStats.current }, { label: t("analytics.change"), value: weightStats.change, colored: true, }, { label: t("analytics.lowest"), value: weightStats.lowest }, { label: t("analytics.highest"), value: weightStats.highest }, ].map((stat) => (

{stat.label}

0 ? "text-orange-500" : "text-foreground" : "text-foreground" }`} > {stat.colored && stat.value > 0 ? "+" : ""} {stat.value} lbs
))}
{t("analytics.trendView")} {t("analytics.actualWeight")} {["trend", "actual"].map((tab) => ( {weightLoading ? ( ) : weightHistoryQuery.isError ? ( void weightHistoryQuery.refetch()} /> ) : weightHistory.length > 0 ? (
{tab === "trend" && (

{t("analytics.trendDescription")}

)} [ `${value} lbs`, tab === "trend" ? name === "trendWeight" ? "Trend" : "Actual" : "Weight", ]} /> {tab === "trend" ? ( <> ) : ( )}
) : (

{t("analytics.noWeightData")}

{t("analytics.noWeightDescription")}

)}
))}
); }