From 89c704c02ceefe6c61c062f145182731d5340d13 Mon Sep 17 00:00:00 2001 From: ectasy663 Date: Fri, 10 Jul 2026 14:29:34 +0530 Subject: [PATCH] Refactor streak modal into a single card with top border-b iframe animation and bottom greetings, daily check-in Snapchat-like streak update/reset logic --- backend/main.py | 28 +++++ public/streak-animation.html | 12 ++- scratch/port_streak_clean.py | 13 ++- .../Dashboard/StreakOnboardingModal.tsx | 100 +++++++++++------- src/hooks/useActiveUser.ts | 1 + 5 files changed, 109 insertions(+), 45 deletions(-) diff --git a/backend/main.py b/backend/main.py index aa23c3f..fbd4a22 100644 --- a/backend/main.py +++ b/backend/main.py @@ -480,6 +480,34 @@ def get_user_profile(user_id: UUID, session: Session = Depends(get_session)): user = session.get(models.User, user_id) if not user: raise HTTPException(status_code=404, detail="User not found") + + # Snapchat-style daily active streak check + now = datetime.utcnow() + today = now.date() + last_active_date = user.last_active.date() + delta = (today - last_active_date).days + + changed = False + if user.streak_count == 0: + user.streak_count = 1 + user.longest_streak = max(user.longest_streak, 1) + user.last_active = now + changed = True + elif delta == 1: + user.streak_count += 1 + user.longest_streak = max(user.longest_streak, user.streak_count) + user.last_active = now + changed = True + elif delta > 1: + user.streak_count = 1 + user.last_active = now + changed = True + + if changed: + session.add(user) + session.commit() + session.refresh(user) + return user class UserUpdate(BaseModel): diff --git a/public/streak-animation.html b/public/streak-animation.html index 55a3a47..cae536f 100644 --- a/public/streak-animation.html +++ b/public/streak-animation.html @@ -9,7 +9,7 @@ --navy-900:#081226; --navy-800:#0c1c39; --navy-700:#13294d; --gold-200:#fdeeb8; --gold-300:#f6dd93; --gold-400:#e8c463; --gold-500:#d4af37; --gold-600:#b1892a; --gold-700:#7d5f18; - --ink:#e9eefb; --badge:230px; --grow:1.18; --halo-w:170%; + --ink:#e9eefb; --badge:190px; --grow:1.18; --halo-w:170%; --font:"Space Grotesk", ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif; } *{box-sizing:border-box} @@ -164,9 +164,13 @@ body::after { display: none !important; } - #stage, .hint { - background: transparent !important; - box-shadow: none !important; + .stage { + height: 280px !important; + width: 100% !important; + max-width: 100% !important; + padding: 0 !important; + gap: 0 !important; + justify-content: center !important; } .count, .panel, .hint { display: none !important; diff --git a/scratch/port_streak_clean.py b/scratch/port_streak_clean.py index 6430f4d..90b340f 100644 --- a/scratch/port_streak_clean.py +++ b/scratch/port_streak_clean.py @@ -19,9 +19,13 @@ def port_html(): body::after { display: none !important; } - #stage, .hint { - background: transparent !important; - box-shadow: none !important; + .stage { + height: 280px !important; + width: 100% !important; + max-width: 100% !important; + padding: 0 !important; + gap: 0 !important; + justify-content: center !important; } .count, .panel, .hint { display: none !important; @@ -54,6 +58,9 @@ def port_html(): html = html.replace("const sad = target<5;", "const sad = target<=2;") html = html.replace("Math.max(target,5)/5", "Math.max(target,3)/3") html = html.replace("(4 - target) / 3", "(3 - target) / 3") + + # 5. Adjust badge size from 230px to 190px + html = html.replace("--badge:230px;", "--badge:190px;") with open(dest_path, 'w', encoding='utf-8') as f: f.write(html) diff --git a/src/components/Dashboard/StreakOnboardingModal.tsx b/src/components/Dashboard/StreakOnboardingModal.tsx index e20ee8a..304b733 100644 --- a/src/components/Dashboard/StreakOnboardingModal.tsx +++ b/src/components/Dashboard/StreakOnboardingModal.tsx @@ -44,52 +44,76 @@ export function StreakOnboardingModal() { setIsOpen(false); }; - return ( -
- - {/* Celebration Animation Canvas & Logo Iframe */} -