AI_ChemTutor / Layouts /Layouts.txt
Abbasaabdul's picture
Upload 7 files
b3a7bda verified
import React, { useState, useEffect } from "react";
import { Link, useLocation } from "react-router-dom";
import { createPageUrl } from "@/utils";
import {
BookOpen,
Brain,
Target,
BarChart3,
Atom,
User,
Menu,
X,
Sparkles,
Trophy
} from "lucide-react";
import { User as UserEntity } from "@/entities/User";
import {
Sidebar,
SidebarContent,
SidebarGroup,
SidebarGroupContent,
SidebarGroupLabel,
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
SidebarHeader,
SidebarFooter,
SidebarProvider,
SidebarTrigger,
} from "@/components/ui/sidebar";
const navigationItems = [
{
title: "Dashboard",
url: createPageUrl("Dashboard"),
icon: BarChart3,
description: "Overview & Progress"
},
{
title: "Practice",
url: createPageUrl("Practice"),
icon: Brain,
description: "AI-Generated Problems"
},
{
title: "Molecular Viewer",
url: createPageUrl("MolecularViewer"),
icon: Atom,
description: "3D Visualizations"
},
{
title: "Study Materials",
url: createPageUrl("StudyMaterials"),
icon: BookOpen,
description: "Custom Learning Resources"
}
];
export default function Layout({ children, currentPageName }) {
const location = useLocation();
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
loadUser();
}, []);
const loadUser = async () => {
try {
const userData = await UserEntity.me();
setUser(userData);
} catch (error) {
console.log("User not logged in");
}
setLoading(false);
};
if (loading) {
return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 to-blue-50 flex items-center justify-center">
<div className="flex items-center gap-3">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
<span className="text-slate-600 font-medium">Loading ChemTutor AI...</span>
</div>
</div>
);
}
return (
<SidebarProvider>
<div className="min-h-screen flex w-full bg-gradient-to-br from-slate-50 to-blue-50">
<Sidebar className="border-r border-slate-200 bg-white/80 backdrop-blur-sm">
<SidebarHeader className="border-b border-slate-200 p-6">
<div className="flex items-center gap-3">
<div className="relative w-10 h-10 bg-gradient-to-br from-blue-600 to-indigo-700 rounded-xl flex items-center justify-center shadow-lg">
<Atom className="w-6 h-6 text-white" />
<div className="absolute -top-1 -right-1 w-4 h-4 bg-gradient-to-r from-emerald-400 to-teal-500 rounded-full flex items-center justify-center">
<Sparkles className="w-2.5 h-2.5 text-white" />
</div>
</div>
<div>
<h2 className="text-xl font-bold bg-gradient-to-r from-blue-600 to-indigo-700 bg-clip-text text-transparent">
ChemTutor AI
</h2>
<p className="text-sm text-slate-500">Intelligent Chemistry Learning</p>
</div>
</div>
</SidebarHeader>
<SidebarContent className="p-4">
<SidebarGroup>
<SidebarGroupLabel className="text-xs font-semibold text-slate-500 uppercase tracking-wider px-3 py-2">
Learning Hub
</SidebarGroupLabel>
<SidebarGroupContent>
<SidebarMenu>
{navigationItems.map((item) => (
<SidebarMenuItem key={item.title}>
<SidebarMenuButton
asChild
className={`group hover:bg-blue-50 hover:text-blue-700 transition-all duration-200 rounded-xl mb-1 ${
location.pathname === item.url
? 'bg-gradient-to-r from-blue-50 to-indigo-50 text-blue-700 shadow-sm border border-blue-100'
: ''
}`}
>
<Link to={item.url} className="flex items-center gap-4 px-4 py-3">
<item.icon className="w-5 h-5 group-hover:scale-110 transition-transform duration-200" />
<div>
<span className="font-semibold">{item.title}</span>
<p className="text-xs text-slate-500 group-hover:text-blue-600 transition-colors">
{item.description}
</p>
</div>
</Link>
</SidebarMenuButton>
</SidebarMenuItem>
))}
</SidebarMenu>
</SidebarGroupContent>
</SidebarGroup>
{user && (
<SidebarGroup className="mt-6">
<SidebarGroupLabel className="text-xs font-semibold text-slate-500 uppercase tracking-wider px-3 py-2">
Your Progress
</SidebarGroupLabel>
<SidebarGroupContent>
<div className="px-4 py-3 space-y-3">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Trophy className="w-4 h-4 text-amber-500" />
<span className="text-sm font-medium text-slate-700">Problems Solved</span>
</div>
<span className="text-lg font-bold text-blue-600">
{user.total_problems_solved || 0}
</span>
</div>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Target className="w-4 h-4 text-emerald-500" />
<span className="text-sm font-medium text-slate-700">Current Streak</span>
</div>
<span className="text-lg font-bold text-emerald-600">
{user.current_streak || 0} days
</span>
</div>
<div className="bg-gradient-to-r from-blue-50 to-indigo-50 rounded-lg p-3 border border-blue-100">
<p className="text-xs font-medium text-blue-700 mb-1">Learning Level</p>
<p className="text-sm font-bold text-blue-900 capitalize">
{user.learning_level || 'Beginner'}
</p>
</div>
</div>
</SidebarGroupContent>
</SidebarGroup>
)}
</SidebarContent>
<SidebarFooter className="border-t border-slate-200 p-4">
{user ? (
<div className="flex items-center gap-3 p-3 rounded-xl bg-gradient-to-r from-slate-50 to-blue-50 border border-slate-200">
<div className="w-10 h-10 bg-gradient-to-br from-blue-600 to-indigo-700 rounded-full flex items-center justify-center">
<User className="w-5 h-5 text-white" />
</div>
<div className="flex-1 min-w-0">
<p className="font-semibold text-slate-900 text-sm truncate">
{user.full_name || 'Student'}
</p>
<p className="text-xs text-slate-500 truncate">{user.email}</p>
</div>
</div>
) : (
<button
onClick={() => UserEntity.login()}
className="w-full bg-gradient-to-r from-blue-600 to-indigo-700 text-white font-semibold py-3 px-4 rounded-xl hover:from-blue-700 hover:to-indigo-800 transition-all duration-200 shadow-lg hover:shadow-xl"
>
Start Learning
</button>
)}
</SidebarFooter>
</Sidebar>
<main className="flex-1 flex flex-col">
{/* Mobile header */}
<header className="bg-white/80 backdrop-blur-sm border-b border-slate-200 px-6 py-4 md:hidden">
<div className="flex items-center gap-4">
<SidebarTrigger className="hover:bg-slate-100 p-2 rounded-lg transition-colors duration-200" />
<div className="flex items-center gap-2">
<Atom className="w-6 h-6 text-blue-600" />
<h1 className="text-lg font-bold text-slate-900">ChemTutor AI</h1>
</div>
</div>
</header>
{/* Main content area */}
<div className="flex-1 overflow-auto">
{children}
</div>
</main>
</div>
</SidebarProvider>
);
}