UI: Premium sidebar redesign with gradient dividers, glassmorphism, and polished section headers

This commit is contained in:
2026-08-05 13:27:22 +05:30
parent 1f0ec0ec4d
commit fbc9025535

View File

@@ -72,25 +72,30 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
return ( return (
<div className="flex h-screen bg-background overflow-hidden text-foreground selection:bg-primary/20"> <div className="flex h-screen bg-background overflow-hidden text-foreground selection:bg-primary/20">
{/* Sidebar */} {/* Sidebar */}
<aside className="w-64 border-r border-border bg-background flex flex-col hidden md:flex"> <aside className="w-64 border-r border-border/60 bg-background/95 backdrop-blur-xl flex flex-col hidden md:flex relative">
<div className="px-6 py-5"> {/* Subtle gradient overlay */}
<Logo href="/dashboard" className="w-full" imageClassName="object-contain object-left scale-110 origin-left" height={56} /> <div className="absolute inset-0 bg-gradient-to-b from-[#00F0FF]/[0.02] via-transparent to-purple-500/[0.02] pointer-events-none" />
{/* Logo */}
<div className="px-5 py-4 border-b border-border/40">
<Logo href="/dashboard" className="w-full" imageClassName="object-contain object-left scale-105 origin-left" height={52} />
</div> </div>
<nav className="flex-1 min-h-0 px-4 pb-16 space-y-1.5 mt-4 overflow-y-auto custom-scrollbar">
{/* <div className="pt-2 pb-2"> <nav className="flex-1 min-h-0 px-3 py-3 overflow-y-auto custom-scrollbar space-y-0.5">
<p className="px-3 text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-2">
<span className="w-1.5 h-1.5 rounded-full bg-white"></span> Free Tier
</p>
</div> */}
<div className="pt-3 pb-1"> {/* PRO TIER Section */}
<p className="px-4 text-[11px] font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-2"> <div className="px-2 pt-2 pb-2">
<span className="w-1.5 h-1.5 rounded-full bg-yellow-500"></span> Pro Tier <div className="flex items-center gap-2">
</p> <div className="h-px flex-1 bg-gradient-to-r from-transparent via-yellow-500/40 to-transparent" />
<span className="text-[10px] font-black uppercase tracking-[0.15em] text-yellow-600 dark:text-yellow-400 flex items-center gap-1.5 shrink-0">
<span className="w-1 h-1 rounded-full bg-yellow-500 shadow-[0_0_4px_#EAB308]"></span>
Pro Tier
</span>
<div className="h-px flex-1 bg-gradient-to-l from-transparent via-yellow-500/40 to-transparent" />
</div>
</div> </div>
<NavItem href="/dashboard" icon={<LayoutDashboard size={17} />} label="Overview" active={pathname === "/dashboard"} /> <NavItem href="/dashboard" icon={<LayoutDashboard size={17} />} label="Overview" active={pathname === "/dashboard"} />
{/* <NavItem href="/dashboard/dpp" icon={<FileText size={17} />} label="Target DPPs" active={pathname.startsWith("/dashboard/dpp")} /> */}
<NavItem href="/dashboard/leaderboard" icon={<Trophy size={17} />} label="Leaderboard" active={pathname.startsWith("/dashboard/leaderboard")} /> <NavItem href="/dashboard/leaderboard" icon={<Trophy size={17} />} label="Leaderboard" active={pathname.startsWith("/dashboard/leaderboard")} />
<NavItem <NavItem
href="/dashboard/progress" href="/dashboard/progress"
@@ -128,11 +133,18 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
isLocked={!hasAccessTo("doubt-resolution-community")} isLocked={!hasAccessTo("doubt-resolution-community")}
/> />
<div className="pt-4 pb-1"> {/* AI COACH Section */}
<p className="px-4 text-[11px] font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-2"> <div className="px-2 pt-4 pb-2">
<span className="w-1.5 h-1.5 rounded-full bg-cyan-500"></span> AI Coach <div className="flex items-center gap-2">
</p> <div className="h-px flex-1 bg-gradient-to-r from-transparent via-cyan-500/50 to-transparent" />
<span className="text-[10px] font-black uppercase tracking-[0.15em] text-cyan-600 dark:text-cyan-400 flex items-center gap-1.5 shrink-0">
<span className="w-1 h-1 rounded-full bg-cyan-500 shadow-[0_0_6px_#00F0FF] dark:shadow-[0_0_8px_#00F0FF]"></span>
AI Coach
</span>
<div className="h-px flex-1 bg-gradient-to-l from-transparent via-cyan-500/50 to-transparent" />
</div>
</div> </div>
<NavItem <NavItem
href="/dashboard/ai-coach/tutor" href="/dashboard/ai-coach/tutor"
icon={<BrainCircuitIcon />} icon={<BrainCircuitIcon />}
@@ -205,28 +217,29 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
/> />
</nav> </nav>
<div className="p-4 border-t border-border space-y-2 bg-secondary/30"> {/* Bottom Settings + Profile */}
<div className="p-3 border-t border-border/40 bg-secondary/10 space-y-1.5">
<Link <Link
href="/dashboard/settings" href="/dashboard/settings"
className={`flex items-center gap-3 px-3 py-2.5 rounded-xl transition-all duration-300 border ${ className={`flex items-center gap-3 px-3 py-2.5 rounded-xl transition-all duration-200 border ${
pathname.startsWith("/dashboard/settings") pathname.startsWith("/dashboard/settings")
? "bg-background text-foreground font-medium border-border shadow-sm" ? "bg-[#00F0FF]/10 text-foreground font-semibold border-[#00F0FF]/20"
: "text-muted-foreground hover:bg-background/80 hover:text-foreground border-transparent hover:border-border/50" : "text-muted-foreground hover:bg-secondary/60 hover:text-foreground border-transparent"
}`} }`}
> >
<Settings size={18} /> <Settings size={17} className="shrink-0" />
<span className="text-sm">Settings</span> <span className="text-[13px] font-medium">Settings</span>
</Link> </Link>
{/* Functional User Dropdown */} {/* Functional User Dropdown */}
<div className="relative mt-2" ref={dropdownRef}> <div className="relative" ref={dropdownRef}>
{dropdownOpen && user && ( {dropdownOpen && user && (
<div className="absolute bottom-full left-0 w-full mb-2 bg-background border border-border rounded-xl shadow-lg shadow-black/10 overflow-hidden animate-in fade-in slide-in-from-bottom-2 duration-200 z-50"> <div className="absolute bottom-full left-0 w-full mb-2 bg-background border border-border rounded-xl shadow-xl shadow-black/20 overflow-hidden animate-in fade-in slide-in-from-bottom-2 duration-200 z-50">
<div className="px-4 py-3 border-b border-border"> <div className="px-4 py-3 border-b border-border bg-secondary/30">
<p className="text-sm font-bold text-foreground truncate">{user.name}</p> <p className="text-sm font-bold text-foreground truncate">{user.name}</p>
<p className="text-xs text-muted-foreground truncate">{user.email || user.phone}</p> <p className="text-xs text-muted-foreground truncate">{user.email || user.phone}</p>
</div> </div>
<div className="p-1"> <div className="p-1.5">
<Link href="/dashboard/settings" className="flex items-center gap-2 px-3 py-2 text-sm text-foreground hover:bg-secondary rounded-lg transition-colors"> <Link href="/dashboard/settings" className="flex items-center gap-2 px-3 py-2 text-sm text-foreground hover:bg-secondary rounded-lg transition-colors">
<User size={16} /> Edit Profile <User size={16} /> Edit Profile
</Link> </Link>
@@ -242,10 +255,10 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
<button <button
onClick={() => setDropdownOpen(!dropdownOpen)} onClick={() => setDropdownOpen(!dropdownOpen)}
className="w-full flex items-center justify-between p-2 rounded-xl bg-background/50 hover:bg-background transition-colors border border-border/50 shadow-sm mt-3" className="w-full flex items-center justify-between p-2.5 rounded-xl bg-secondary/40 hover:bg-secondary/70 transition-all duration-200 border border-border/50 hover:border-border group"
> >
<div className="flex items-center gap-3 text-left"> <div className="flex items-center gap-3 text-left">
<div className="h-8 w-8 rounded-full bg-cyan-500/20 text-cyan-700 dark:bg-cyan-500/20 dark:text-cyan-400 flex items-center justify-center font-bold text-sm shadow-none dark:shadow-[0_0_10px_-2px_#00F0FF] shrink-0"> <div className="h-8 w-8 rounded-full bg-cyan-500/20 text-cyan-700 dark:bg-cyan-500/20 dark:text-cyan-400 flex items-center justify-center font-bold text-sm shrink-0 border border-cyan-500/20 dark:shadow-[0_0_10px_-2px_#00F0FF]">
{userInitials} {userInitials}
</div> </div>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
@@ -253,7 +266,7 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
<div className="mt-1"><TierBadge tier={user ? (user.tier === "Al_Coach" ? "AI Coach" : user.tier) : "Free"} /></div> <div className="mt-1"><TierBadge tier={user ? (user.tier === "Al_Coach" ? "AI Coach" : user.tier) : "Free"} /></div>
</div> </div>
</div> </div>
<ChevronUp size={16} className={`text-muted-foreground transition-transform shrink-0 ${dropdownOpen ? "rotate-180" : ""}`} /> <ChevronUp size={15} className={`text-muted-foreground transition-transform shrink-0 ${dropdownOpen ? "rotate-180" : ""}`} />
</button> </button>
</div> </div>
</div> </div>