spb/earth-now Public License
earth-now.co — real-time planetary dashboard: live world metrics modeled, not streamed.
TypeScript 93%
Shell 2.3%
SQL 1.4%
JavaScript 1.3%
Dockerfile 1.2%
CSS 0.8%
1/**2 * earth-now.co3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File: apps/web/components/YearProgress.tsx6 * Purpose: Live progress of the current UTC year — deterministic astronomy-style ticker with a thin accent meter7 */89"use client";1011import { useEffect, useState } from "react";12import { formatValue, startOfUtcYear } from "@earth-now/counter";13import { useI18n } from "@/lib/i18n";1415const PERCENT_HINTS = { decimals: 6, unit: "%" } as const;1617export default function YearProgress() {18 const { locale, t } = useI18n();19 const [now, setNow] = useState<number | null>(null);2021 useEffect(() => {22 let raf = 0;23 const tick = () => {24 setNow(Date.now());25 raf = requestAnimationFrame(tick);26 };27 raf = requestAnimationFrame(tick);28 return () => cancelAnimationFrame(raf);29 }, []);3031 if (now === null) return null;32 const start = startOfUtcYear(now);33 const end = Date.UTC(new Date(now).getUTCFullYear() + 1, 0, 1);34 const fraction = (now - start) / (end - start);35 const year = new Date(now).getUTCFullYear();3637 return (38 <div className="mb-8 flex items-center gap-3 text-xs text-ink2">39 <span className="shrink-0">40 {year} : {formatValue(fraction * 100, PERCENT_HINTS, { locale })} % {t("year.elapsed")}41 </span>42 <span className="h-1 min-w-0 flex-1 rounded-full bg-line" aria-hidden>43 <span44 className="block h-1 rounded-full bg-accent"45 style={{ width: `${fraction * 100}%` }}46 />47 </span>48 </div>49 );50}51