feat: complete pragativeer v2 frontend and backend, docker setup, and cbt engine

This commit is contained in:
2026-07-06 17:08:13 +05:30
parent ce01795aa9
commit 426b98ddab
66 changed files with 7949 additions and 363 deletions

View File

@@ -0,0 +1,99 @@
"use client"
import { Card, CardContent } from "@/components/ui/card"
import { Flame, Gift, Star, Trophy, Target, ArrowRight, CheckCircle2 } from "lucide-react"
export default function StreaksPage() {
const currentStreak = 12;
const bestStreak = 45;
const rewards = [
{ streak: 7, title: "Consistent Learner", reward: "1 Free Premium DPP", unlocked: true },
{ streak: 14, title: "Dedicated Scholar", reward: "AI Performance Analysis Report", unlocked: false },
{ streak: 30, title: "Exam Warrior", reward: "1 Full Length Mock Test", unlocked: false },
{ streak: 50, title: "PragatiVeer Champion", reward: "1-on-1 AI Tutor Session", unlocked: false },
{ streak: 100, title: "Unstoppable", reward: "Merch + 50% Off Next Renewal", unlocked: false },
];
return (
<div className="p-8 space-y-8 animate-in fade-in slide-in-from-bottom-4 duration-500 max-w-5xl mx-auto">
<div className="flex items-center gap-4">
<div className="size-16 rounded-2xl bg-orange-500/10 text-orange-500 flex items-center justify-center">
<Flame size={32} />
</div>
<div>
<h1 className="text-3xl font-bold tracking-tight">Your Learning Streak</h1>
<p className="text-muted-foreground mt-1 font-medium">Build daily habits to unlock premium rewards and boost your rank.</p>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Card className="bg-gradient-to-br from-orange-500/20 to-rose-500/5 border-orange-500/30">
<CardContent className="p-8 flex flex-col items-center justify-center text-center h-full">
<Flame size={64} className="text-orange-500 mb-4 animate-pulse" />
<h2 className="text-6xl font-black text-foreground mb-2">{currentStreak} <span className="text-2xl text-muted-foreground">Days</span></h2>
<p className="text-sm font-bold text-orange-500">CURRENT STREAK</p>
<p className="text-xs text-muted-foreground mt-4 max-w-xs">Complete a Daily Practice Problem (DPP) or CBT Exam every day to keep your streak alive.</p>
</CardContent>
</Card>
<Card className="bg-secondary/20 border-border">
<CardContent className="p-8 h-full flex flex-col justify-between">
<div>
<div className="flex justify-between items-center mb-6">
<p className="text-sm font-bold text-muted-foreground">STREAK STATS</p>
<Target size={20} className="text-primary" />
</div>
<div className="space-y-6">
<div>
<p className="text-sm text-muted-foreground mb-1">Personal Best</p>
<p className="text-3xl font-bold text-foreground">{bestStreak} <span className="text-lg text-muted-foreground">Days</span></p>
</div>
<div>
<p className="text-sm text-muted-foreground mb-1">Total Streak Points Earned</p>
<p className="text-3xl font-bold text-[#00F0FF]">1,450</p>
</div>
</div>
</div>
<div className="mt-8 pt-6 border-t border-border">
<p className="text-xs text-muted-foreground leading-relaxed">
<strong className="text-foreground">Pro Tip:</strong> Your streak directly multiplies your leaderboard score. A longer streak gives you a higher Consistency Bonus.
</p>
</div>
</CardContent>
</Card>
</div>
<div className="pt-8">
<h2 className="text-2xl font-bold mb-6 flex items-center gap-2"><Gift className="text-[#00F0FF]" /> Streak Rewards</h2>
<div className="space-y-4">
{rewards.map((reward, i) => (
<div key={i} className={`p-5 rounded-2xl border flex items-center justify-between transition-colors ${reward.unlocked ? 'bg-primary/5 border-primary/30' : 'bg-secondary/10 border-border opacity-70'}`}>
<div className="flex items-center gap-6">
<div className={`size-14 rounded-full flex items-center justify-center font-bold text-xl ${reward.unlocked ? 'bg-primary text-primary-foreground shadow-[0_0_15px_-5px_var(--color-primary)]' : 'bg-secondary text-muted-foreground'}`}>
{reward.streak}
</div>
<div>
<h3 className={`font-bold ${reward.unlocked ? 'text-foreground' : 'text-muted-foreground'}`}>{reward.title}</h3>
<p className={`text-sm ${reward.unlocked ? 'text-primary font-medium' : 'text-muted-foreground'}`}>{reward.reward}</p>
</div>
</div>
<div className="hidden sm:block">
{reward.unlocked ? (
<div className="flex items-center gap-2 text-primary font-bold text-sm bg-primary/10 px-4 py-2 rounded-xl">
<CheckCircle2 size={18} /> Unlocked
</div>
) : (
<div className="text-xs font-bold text-muted-foreground bg-secondary px-4 py-2 rounded-xl">
{reward.streak - currentStreak} days to go
</div>
)}
</div>
</div>
))}
</div>
</div>
</div>
)
}