import Rewind from "~/components/rewind/Rewind"; import type { Route } from "./+types/Home"; import { imageUrl, type RewindStats } from "api/api"; import { useEffect, useState } from "react"; import type { LoaderFunctionArgs } from "react-router"; import { useLoaderData } from "react-router"; import { getRewindParams, getRewindYear } from "~/utils/utils"; import { useNavigate } from "react-router"; import { average } from "color.js"; import { ChevronLeft, ChevronRight } from "lucide-react"; // TODO: Bind year and month selectors to what data actually exists const months = [ "Full Year", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ]; export async function clientLoader({ request }: LoaderFunctionArgs) { const url = new URL(request.url); const year = parseInt(url.searchParams.get("year") || "0") || getRewindParams().year; const month = parseInt(url.searchParams.get("month") || "0") || getRewindParams().month; const res = await fetch(`/apis/web/v1/summary?year=${year}&month=${month}`); if (!res.ok) { throw new Response("Failed to load summary", { status: 500 }); } const stats: RewindStats = await res.json(); stats.title = `Your ${month === 0 ? "" : months[month]} ${year} Rewind`; return { stats }; } export default function RewindPage() { const currentParams = new URLSearchParams(location.search); let year = parseInt(currentParams.get("year") || "0") || getRewindParams().year; let month = parseInt(currentParams.get("month") || "0") || getRewindParams().month; const navigate = useNavigate(); const [showTime, setShowTime] = useState(false); const { stats: stats } = useLoaderData<{ stats: RewindStats }>(); const [bgColor, setBgColor] = useState("(--color-bg)"); useEffect(() => { if (!stats.top_artists[0]) return; const img = (stats.top_artists[0] as any)?.item.image; if (!img) return; average(imageUrl(img, "small"), { amount: 1 }).then((color) => { setBgColor(`rgba(${color[0]},${color[1]},${color[2]},0.4)`); }); }, [stats]); const updateParams = (params: Record) => { const nextParams = new URLSearchParams(location.search); for (const key in params) { const val = params[key]; if (val !== null && val !== "0") { nextParams.set(key, val); } else { nextParams.delete(key); } } const url = `/rewind?${nextParams.toString()}`; navigate(url, { replace: false }); }; const navigateMonth = (direction: "prev" | "next") => { if (direction === "next") { if (month === 12) { month = 0; } else { month += 1; } } else { if (month === 0) { month = 12; } else { month -= 1; } } updateParams({ year: year.toString(), month: month.toString(), }); }; const navigateYear = (direction: "prev" | "next") => { if (direction === "next") { year += 1; } else { year -= 1; } updateParams({ year: year.toString(), month: month.toString(), }); }; const pgTitle = `${stats.title} - Koito`; return (
{pgTitle}

{months[month]}

{year}

setShowTime(!showTime)} >
{stats !== undefined && ( )}
); }