Files
leetcode/apps/docs/components/progress/RecentSolves.tsx
T

79 lines
2.8 KiB
TypeScript
Raw Normal View History

2026-10-05 14:22:28 -04:00
/**
* The ten most recently solved problems — LeetCode's "Recent AC" list. Each
* row is dated by the problem's first pass (an ET calendar date: the Worker
* logs days, not times), read relative to today in ET with the full date on
* hover. A row links to the problem's docs page when one exists: the
* sync-generated short links (`redirects.ts`) are exactly the pages built.
*/
import { Card, CardContent, CardHeader, CardTitle } from "../ui/card";
import { useStats, utcDate } from "../../lib/stats";
import redirects from "../../redirects";
import { StatsPending } from "./shared";
2026-10-05 14:22:28 -04:00
const PAGES = new Map(redirects.map((r) => [r.from, r.to]));
const ET_TODAY = new Intl.DateTimeFormat("en-CA", { timeZone: "America/New_York" });
const RELATIVE = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
const FULL = new Intl.DateTimeFormat("en-US", { dateStyle: "medium", timeZone: "UTC" });
const DAY_MS = 86_400_000;
export default function RecentSolves() {
const load = useStats();
if (load.phase !== "ready") {
return (
<Card>
<CardHeader>
<CardTitle>Recently solved</CardTitle>
</CardHeader>
<CardContent>
<StatsPending load={load} className="h-80 w-full" />
</CardContent>
</Card>
);
}
const today = utcDate(ET_TODAY.format(new Date())).getTime();
return (
<Card>
<CardHeader>
<CardTitle>Recently solved</CardTitle>
</CardHeader>
<CardContent>
{load.stats.recent.length === 0 ? (
<p className="my-0! text-muted-foreground text-sm">Nothing solved yet.</p>
) : (
<ol className="my-0! flex flex-col">
{load.stats.recent.map((p) => {
const date = utcDate(p.date);
const page = PAGES.get(`/${p.lc}`);
const name = (
<>
<span className="text-muted-foreground tabular-nums">{p.lc}.</span> {p.title}
</>
);
return (
<li
key={p.lc}
className="flex items-center justify-between gap-4 rounded-lg px-4 py-3 text-sm odd:bg-muted"
>
{page ? (
<a href={page} className="truncate font-normal! text-foreground no-underline! hover:underline!">
{name}
</a>
) : (
<span className="truncate">{name}</span>
)}
<time dateTime={p.date} title={FULL.format(date)} className="shrink-0 text-muted-foreground">
{RELATIVE.format(Math.round((date.getTime() - today) / DAY_MS), "day")}
</time>
</li>
);
})}
</ol>
)}
</CardContent>
</Card>
);
}