perf: eliminate demo account switch lag - no more page reload, parallel fetches, settings cache

This commit is contained in:
2026-09-20 12:15:33 +05:30
parent 896073ea2d
commit 0fab60b710
2 changed files with 124 additions and 46 deletions

View File

@@ -20,7 +20,7 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
const [dropdownOpen, setDropdownOpen] = useState(false)
const dropdownRef = useRef<HTMLDivElement>(null)
const { userId, user, globalSettings, switchUser, logout, hasAccessTo, loading, trialInfo } = useActiveUser();
const { userId, user, globalSettings, switchUser, logout, hasAccessTo, loading, switching, trialInfo } = useActiveUser();
const [maintenance, setMaintenance] = useState(false);
const [checkingMaintenance, setCheckingMaintenance] = useState(true);
@@ -75,6 +75,22 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
return (
<div className="flex h-screen bg-background overflow-hidden text-foreground selection:bg-primary/20">
{/* Demo Account Switch — slim top progress bar, no full-page reload */}
{switching && (
<div className="fixed top-0 left-0 right-0 z-[9999] h-0.5 overflow-hidden">
<div
className="h-full bg-[#00F0FF] animate-[slideProgress_0.8s_ease-in-out_infinite]"
style={{ width: '60%', animation: 'slideProgress 0.9s ease-in-out infinite' }}
/>
<style>{`
@keyframes slideProgress {
0% { transform: translateX(-100%); width: 60%; }
50% { transform: translateX(70%); width: 80%; }
100% { transform: translateX(200%); width: 60%; }
}
`}</style>
</div>
)}
{/* Sidebar */}
<aside className="w-64 border-r border-border/60 bg-background/95 backdrop-blur-xl flex flex-col hidden md:flex relative">
{/* Subtle gradient overlay */}
@@ -350,11 +366,17 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
{/* Demo Switcher — only visible when logged in as a known demo account */}
{isDemoUser(userId) && (
<div className="flex items-center gap-2">
<span className="text-xs text-muted-foreground font-bold hidden lg:inline">Demo:</span>
{switching && (
<span className="text-xs text-[#00F0FF] font-bold animate-pulse hidden lg:inline">Switching…</span>
)}
{!switching && (
<span className="text-xs text-muted-foreground font-bold hidden lg:inline">Demo:</span>
)}
<select
value={userId}
disabled={switching}
onChange={(e) => switchUser(e.target.value)}
className="bg-secondary border border-border text-foreground px-2.5 py-1.5 rounded-xl text-xs font-bold focus:ring-2 focus:ring-[#00F0FF] outline-none cursor-pointer hover:bg-secondary/80 transition-colors"
className="bg-secondary border border-border text-foreground px-2.5 py-1.5 rounded-xl text-xs font-bold focus:ring-2 focus:ring-[#00F0FF] outline-none cursor-pointer hover:bg-secondary/80 transition-colors disabled:opacity-50 disabled:cursor-wait"
>
<option value={DEMO_USERS.NEHA.id}>Neha Verma (AI Coach)</option>
<option value={DEMO_USERS.AI_COACH.id}>Rahul (AI Coach)</option>