import { useEffect, useState } from 'react'; import { motion } from 'motion/react'; import { PrimaryButton } from '@/components/ui'; import { toFa } from '@/lib/format'; import { sounds } from '@/lib/sound'; /** * سه حالتِ زنجیره، مثلِ دولینگو: * lit امروز تمرین شده؛ آتشِ نارنجیِ زنده (لرزشِ آرامِ شعله‌ها). * risk زنجیره هست ولی امروز هنوز نه؛ همان شعله خاکستری، تا کاربر ببیند چیزی منتظرش است. * frozen زنجیره دیروز شکست؛ شعله‌ی یخ‌زده‌ی آبی، با برق. * none هیچ‌وقت زنجیره نداشته؛ مثلِ risk. * فقط SVG و CSS (transform/opacity)، بی‌تصویر. */ export type FlameState = 'lit' | 'risk' | 'frozen' | 'none'; export function flameState(streak: { current: number; activeToday?: boolean; lost?: number } | undefined | null): FlameState { if (!streak) return 'none'; if (streak.activeToday) return 'lit'; if (streak.current > 0) return 'risk'; if ((streak.lost ?? 0) > 0) return 'frozen'; return 'none'; } const PALETTE: Record = { lit: ['#FF7A3D', '#FFB23F', '#FFE58A'], risk: ['#C9C6DA', '#DCDAE8', '#EEEDF5'], none: ['#C9C6DA', '#DCDAE8', '#EEEDF5'], frozen: ['#5BB8F0', '#9ED8FA', '#E6F6FF'], }; export function StreakFlame({ state, size = 20, className = '' }: { state: FlameState; size?: number; className?: string }) { const [outer, middle, core] = PALETTE[state]; const alive = state === 'lit'; return ( {state === 'frozen' && ( <> {/* برقِ یخ و ترک‌های ریز */} )} ); } const WEEKDAYS = ['ش', 'ی', 'د', 'س', 'چ', 'پ', 'ج']; /** * صفحه‌ی «زنجیره‌ت روشن ماند!» بعد از اولین درس/جزیره‌ی امروز. عدد از مقدارِ قبلی به تازه می‌رود و روزهای این * هفته که در زنجیره‌اند روشن می‌شوند (از طولِ زنجیره حساب می‌شود، بی‌درخواستِ دیگر). */ export function StreakCelebration({ from, to, onDone }: { from: number; to: number; onDone: () => void }) { const [shown, setShown] = useState(from); useEffect(() => { sounds.streak(); const t = setTimeout(() => setShown(to), 650); return () => clearTimeout(t); }, [to]); const today = (new Date().getDay() + 1) % 7; // شنبه = ۰ const message = to === 1 ? 'اولین روز زنجیره‌ت! فردا هم بیا تا آتیشش بزرگ‌تر بشه.' : `${toFa(to)} روزه که هر روز ریاضی تمرین می‌کنی. فردا هم بیا تا خاموش نشه!`; return (
{[14, 30, 48, 66, 82].map((x, i) => ( ))}
{toFa(shown)}

روز پیاپی!

{message}

{WEEKDAYS.map((d, i) => { const inStreak = i <= today && today - i < to; return ( {inStreak ? : null} {d} ); })}
ادامه
); }