Code — how this page is built

Under the hood

The actual source of the components on this page, read straight from the repo. Copy it, read it, or open it on GitHub.


Stores visited ISO dates in a localStorage set; computes the current streak by walking back day-by-day, and renders the last 49 days as a grid.

'use client';

import * as React from 'react';

const KEY = 'kaspirius:streak:days';
const iso = (d: Date) => d.toISOString().slice(0, 10);

export function StreakGame() {
  const [days, setDays] = React.useState<Set<string>>(new Set());

  React.useEffect(() => {
    let set: Set<string>;
    try {
      set = new Set<string>(JSON.parse(localStorage.getItem(KEY) ?? '[]'));
    } catch {
      set = new Set();
    }
    set.add(iso(new Date()));
    localStorage.setItem(KEY, JSON.stringify([...set]));
    setDays(set);
  }, []);

  // current streak: count back from today while each day is present
  let streak = 0;
  const cursor = new Date();
  while (days.has(iso(cursor))) {
    streak++;
    cursor.setDate(cursor.getDate() - 1);
  }

  // grid: last 49 days (7 weeks), oldest first
  const cells: { date: string; on: boolean; today: boolean }[] = [];
  const todayIso = iso(new Date());
  for (let i = 48; i >= 0; i--) {
    const d = new Date();
    d.setDate(d.getDate() - i);
    cells.push({ date: iso(d), on: days.has(iso(d)), today: iso(d) === todayIso });
  }

  return (
    <div className="flex w-full max-w-md flex-col items-center gap-7">
      <div className="text-center">
        <div className="text-6xl font-bold leading-none">{streak}</div>
        <div className="mt-2 font-mono text-[11px] uppercase tracking-[0.12em] opacity-55">
          day{streak === 1 ? '' : 's'} in a row
        </div>
      </div>

      <div className="grid grid-cols-7 gap-1.5">
        {cells.map((c) => (
          <span
            key={c.date}
            title={c.date}
            className={`h-6 w-6 rounded-[4px] ${c.today ? 'ring-2 ring-foreground ring-offset-1 ring-offset-[var(--paper)]' : ''}`}
            style={{ background: c.on ? 'var(--accent-olive)' : 'rgba(20,17,11,0.1)' }}
          />
        ))}
      </div>
      <p className="text-center font-mono text-[11px] uppercase tracking-[0.12em] opacity-45">
        come back tomorrow — the chain is the reward
      </p>
    </div>
  );
}
↖ kaspirius