Files
pragativeer-v2/src/components/Dashboard/StreakOnboardingModal.tsx

98 lines
4.3 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { Button } from "@/components/ui/button";
import { Flame, Sparkles } from "lucide-react";
import { useActiveUser } from "@/hooks/useActiveUser";
export function StreakOnboardingModal() {
const { user, loading } = useActiveUser();
const [isOpen, setIsOpen] = useState(false);
useEffect(() => {
if (loading || !user) return;
// Check sessionStorage
const hasSeen = sessionStorage.getItem(`hasSeenStreakPopup_${user.id}`);
if (!hasSeen) {
setIsOpen(true);
}
}, [user, loading]);
if (!isOpen || !user) return null;
const streak = user.streak_count;
const targetExam = user.target_exam?.replace("_", " ") || "JEE/NEET";
// Streak-based wishes and titles
let wishTitle = "Welcome to PragatiVeer! 🌟";
let wishMessage = `Prepare yourself to conquer ${targetExam}. Your daily practice starts here!`;
if (streak === 0) {
wishTitle = "Start Your Streak Today! 🚀";
wishMessage = "Today is Day 1 of your journey. Establish your streak now and build the consistency needed for IIT/AIIMS!";
} else if (streak < 4) {
wishTitle = "Keep the Fire Burning! 🔥";
wishMessage = `Great job! You have maintained a ${streak}-day study streak. Keep practicing daily to build solid muscle memory!`;
} else {
wishTitle = "Unstoppable Dedication! ⚡";
wishMessage = `Incredible! A ${streak}-day streak shows true championship discipline. You are outperforming the competition. Let's make today count!`;
}
const handleEnter = () => {
sessionStorage.setItem(`hasSeenStreakPopup_${user.id}`, "true");
setIsOpen(false);
};
return (
<div className="fixed inset-0 z-50 flex flex-col items-center justify-end pb-12 bg-black/90 backdrop-blur-lg animate-in fade-in duration-300">
{/* Celebration Animation Canvas & Logo Iframe */}
<iframe
src={`/streak-animation.html?streak=${streak}`}
className="absolute inset-0 w-full h-full border-none pointer-events-none z-10"
title="Streak Celebration"
allowtransparency="true"
/>
{/* Adaptive Modal Content Card (positioned at the bottom to let the animated logo shine in the center) */}
<div className="bg-background/85 backdrop-blur-md border border-border/60 shadow-[0_0_50px_-15px_rgba(0,240,255,0.1)] rounded-3xl w-full max-w-lg p-6 text-center space-y-4 relative overflow-hidden animate-in zoom-in-95 slide-in-from-bottom-4 duration-300 z-20 pointer-events-auto mx-4">
{/* Subtle background glow */}
<div className="absolute -right-20 -top-20 size-48 bg-[#00F0FF]/5 rounded-full blur-3xl pointer-events-none" />
<div className="absolute -left-20 -bottom-20 size-48 bg-primary/5 rounded-full blur-3xl pointer-events-none" />
{/* Text Greetings */}
<div className="space-y-2">
{streak > 0 ? (
<div className="inline-flex items-center gap-1.5 px-3 py-0.5 bg-orange-500/10 border border-orange-500/20 text-orange-500 text-xs font-extrabold rounded-full tracking-wider uppercase">
<Flame size={12} className="fill-current animate-bounce" /> {streak} Day Streak Active
</div>
) : (
<div className="inline-flex items-center gap-1.5 px-3 py-0.5 bg-blue-500/10 border border-blue-500/20 text-blue-400 text-xs font-extrabold rounded-full tracking-wider uppercase">
<Sparkles size={12} className="animate-spin" style={{ animationDuration: '4s' }} /> Day 1 Awaits
</div>
)}
<h3 className="text-xl md:text-2xl font-black tracking-tight bg-gradient-to-r from-white via-white to-gray-400 bg-clip-text text-transparent">
{wishTitle}
</h3>
<p className="text-gray-400 text-xs md:text-sm leading-relaxed max-w-sm mx-auto">
{wishMessage}
</p>
</div>
{/* Action Button */}
<div className="pt-1">
<Button
onClick={handleEnter}
className="w-full h-12 rounded-xl text-base font-black bg-[#00F0FF] text-black hover:bg-[#00F0FF]/90 shadow-[0_0_15px_-3px_#00F0FF] hover:shadow-[0_0_25px_#00F0FF] hover:-translate-y-0.5 transition-all duration-300"
>
Enter Workspace
</Button>
</div>
</div>
</div>
);
}