SPB Git

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.5 KB · 51 lines tsx
Raw Blame History
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