"use client" import { ReactNode, useState, useEffect, useRef } from "react" import { BookOpen, LayoutDashboard, Settings, FileText, Activity, LineChart, Trophy, User, ChevronUp, Lock, ShieldAlert, Flame, Target, Gauge, Zap, Calendar, Clock, BrainCircuit, BarChart3, School, CheckSquare } from "lucide-react" import Link from "next/link" import { usePathname } from "next/navigation" import { LanguageToggle } from "@/components/LanguageToggle" import { Logo } from "@/components/Logo" import { ThemeToggle } from "@/components/ThemeToggle" import { TierBadge } from "@/components/TierBadge" import { StreakCounter } from "@/components/StreakCounter" import { AITutorChat } from "@/components/AI/AITutorChat" import { useActiveUser, DEMO_USERS, isDemoUser } from "@/hooks/useActiveUser" import { StreakOnboardingModal } from "@/components/Dashboard/StreakOnboardingModal" import { Badge } from "@/components/ui/badge" import MaintenanceScreen from "@/components/MaintenanceScreen" export default function DashboardLayout({ children }: { children: ReactNode }) { const pathname = usePathname() const [dropdownOpen, setDropdownOpen] = useState(false) const dropdownRef = useRef(null) const { userId, user, globalSettings, switchUser, logout, hasAccessTo, loading, trialInfo } = useActiveUser(); const [maintenance, setMaintenance] = useState(false); const [checkingMaintenance, setCheckingMaintenance] = useState(true); useEffect(() => { if (globalSettings !== undefined && globalSettings !== null) { if (globalSettings.maintenance_mode) { setMaintenance(true); } else { setMaintenance(false); } setCheckingMaintenance(false); } else if (globalSettings === null && !loading) { // If we finished loading but settings failed to load setCheckingMaintenance(false); } }, [globalSettings, loading]); // Close dropdown when clicking outside useEffect(() => { function handleClickOutside(event: MouseEvent) { if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) { setDropdownOpen(false) } } document.addEventListener("mousedown", handleClickOutside) return () => document.removeEventListener("mousedown", handleClickOutside) }, []) const userInitials = user ? user.name.split(" ").filter(n => /^[a-zA-Z]/.test(n)).slice(0, 2).map(n => n[0]).join("").toUpperCase() : "DS" const targetExamLabel = user?.target_exam === "JEE_Main" ? "JEE" : user?.target_exam === "JEE_Advanced" ? "JEE Advanced" : user?.target_exam === "NEET" ? "NEET" : "NEET/JEE" // Trial logic removed as requested if (maintenance) { return ; } if (loading || !user) { return (
); } return (
{/* Sidebar */} {/* Main Content Area */}
{/* Top Header Static Bar */}

{user ? `Welcome back, ${user.name.split(" ")[0]}!` : "Welcome back!"}

{user && ( {targetExamLabel} Target )} {/* Trial countdown badge — shown to trial users in top header */} {trialInfo.isTrialActive && ( Day {trialInfo.trialDayNumber}/{trialInfo.trialTotalDays} Trial · {trialInfo.trialDaysRemaining}d left )}
{/* Streak count moved to top header */} {user && ( )} {/* Demo Switcher — only visible when logged in as a known demo account */} {isDemoUser(userId) && (
Demo:
)}
{/* */}
{/* Scrollable page body */}
{children}
{/* Global AI Tutor Chat */} {hasAccessTo("ai-tutor-chat") && } {/* Onboarding Motivation Popup */}
) } function NavItem({ href, icon, label, active, isLocked, section }: { href: string, icon: React.ReactNode, label: string, active?: boolean, isLocked?: boolean, section?: "pro" | "ai" }) { // Section-aware active color tokens (light mode only, dark mode falls back to cyan) const activeClasses = active ? section === "pro" ? "bg-yellow-50 light:bg-yellow-50 text-yellow-700 dark:bg-[#00F0FF]/10 dark:text-[#00F0FF] font-semibold border border-yellow-300/60 dark:border-[#00F0FF]/20 shadow-[0_0_12px_-4px_rgba(234,179,8,0.2)] dark:shadow-[0_0_12px_-4px_rgba(0,240,255,0.3)]" : section === "ai" ? "bg-cyan-50 dark:bg-[#00F0FF]/10 text-cyan-800 dark:text-[#00F0FF] font-semibold border border-cyan-300/60 dark:border-[#00F0FF]/20 shadow-[0_0_12px_-4px_rgba(6,182,212,0.2)] dark:shadow-[0_0_12px_-4px_rgba(0,240,255,0.3)]" : "bg-[#00F0FF]/10 text-[#00F0FF] font-semibold border border-[#00F0FF]/20 shadow-[0_0_12px_-4px_rgba(0,240,255,0.3)]" : isLocked ? "text-muted-foreground/40 cursor-not-allowed border border-transparent" : "text-muted-foreground/80 hover:bg-secondary/60 hover:text-foreground border border-transparent hover:border-border/40" const iconActiveClass = active ? section === "pro" ? "text-yellow-600 dark:text-[#00F0FF]" : section === "ai" ? "text-cyan-700 dark:text-[#00F0FF]" : "text-[#00F0FF]" : isLocked ? "text-muted-foreground/30" : "text-muted-foreground/60 group-hover:text-foreground/80" const activeBarClass = active ? section === "pro" ? "w-1 h-4 rounded-full bg-yellow-500 dark:bg-[#00F0FF] shrink-0 shadow-[0_0_6px_rgba(234,179,8,0.6)] dark:shadow-[0_0_6px_rgba(0,240,255,0.8)]" : section === "ai" ? "w-1 h-4 rounded-full bg-cyan-600 dark:bg-[#00F0FF] shrink-0 shadow-[0_0_6px_rgba(6,182,212,0.6)] dark:shadow-[0_0_6px_rgba(0,240,255,0.8)]" : "w-1 h-4 rounded-full bg-[#00F0FF] shrink-0 shadow-[0_0_6px_rgba(0,240,255,0.8)]" : "" return (
{icon} {label}
{isLocked && } {active && } ) } function BrainCircuitIcon() { return ( ) }