clone

a daily shikaku puzzle for phones: one seeded puzzle per date, solved by dragging rectangles

main
rect.run / islands / HomeStats.tsx
HomeStats.tsx 1.6K
1import { useEffect, useState } from "preact/hooks";23import { dateToSlug } from "@/lib/date/daily.ts";4import { DAILY_STREAK_START_DATE } from "@/lib/shikaku/catalog.ts";5import { getInitialStackIndex } from "@/lib/shikaku/day_stack_state.ts";6import {7 getDailyStreak,8 getPlayableStackIndex,9 getSelectedStackIndex,10} from "@/lib/storage/local_progress.ts";1112interface HomeStatsProps {13 fallbackDate: string;14}1516export default function HomeStats({ fallbackDate }: HomeStatsProps) {17 const [stats, setStats] = useState({18 day: dayNumber(fallbackDate),19 streak: 0,20 floor: 1,21 });2223 useEffect(() => {24 const localDate = dateToSlug(new Date());25 const storage = globalThis.localStorage;26 const stackIndex = getInitialStackIndex({27 date: localDate,28 today: localDate,29 selectedStackIndex: getSelectedStackIndex(storage, localDate),30 playableStackIndex: getPlayableStackIndex(storage, localDate),31 });32 setStats({33 day: dayNumber(localDate),34 streak: getDailyStreak(storage, localDate),35 floor: stackIndex + 1,36 });37 }, []);3839 return (40 <div class="home__stats" aria-label="Your progress">41 <span>42 DAY <b>{stats.day}</b>43 </span>44 <span>45 STREAK <b>{stats.streak}</b>46 </span>47 <span>48 FLOOR <b>{stats.floor}</b>49 </span>50 </div>51 );52}5354function dayNumber(date: string): number {55 const [y1, m1, d1] = DAILY_STREAK_START_DATE.split("-").map(Number);56 const [y2, m2, d2] = date.split("-").map(Number);57 const start = Date.UTC(y1, m1 - 1, d1);58 const end = Date.UTC(y2, m2 - 1, d2);59 return Math.max(1, Math.round((end - start) / 86_400_000) + 1);60}