Spaces:
Running
Running
| import { useState } from 'react'; | |
| import { useLocation } from 'react-router-dom'; | |
| import Sidebar from './Sidebar'; | |
| import { Menu, Zap } from 'lucide-react'; | |
| import { motion, AnimatePresence } from 'framer-motion'; | |
| export default function Layout({ children }) { | |
| const [sidebarOpen, setSidebarOpen] = useState(false); | |
| const location = useLocation(); | |
| return ( | |
| <div className="relative flex min-h-screen z-10"> | |
| <Sidebar isOpen={sidebarOpen} onClose={() => setSidebarOpen(false)} /> | |
| <main className="flex-1 min-h-screen flex flex-col"> | |
| {/* Top bar */} | |
| <header className="flex items-center gap-4 px-4 sm:px-8 py-4 lg:py-5"> | |
| <button | |
| onClick={() => setSidebarOpen(true)} | |
| className="lg:hidden p-2.5 hover:bg-white/5 rounded-xl transition-all border border-white/[0.06] active:scale-95" | |
| > | |
| <Menu size={20} /> | |
| </button> | |
| <div className="flex-1" /> | |
| {/* Status badge */} | |
| <div className="flex items-center gap-3"> | |
| <div className="hidden sm:flex items-center gap-2 px-3 py-1.5 rounded-xl bg-white/[0.03] border border-white/[0.06] text-xs text-slate-400"> | |
| <Zap size={12} className="text-amber-400" /> | |
| <span>Models Loaded</span> | |
| </div> | |
| <div className="flex items-center gap-2 px-3 py-1.5 rounded-full bg-emerald-500/10 border border-emerald-500/20"> | |
| <span className="relative flex h-2 w-2"> | |
| <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75" /> | |
| <span className="relative inline-flex rounded-full h-2 w-2 bg-emerald-500" /> | |
| </span> | |
| <span className="text-xs font-semibold text-emerald-400">Online</span> | |
| </div> | |
| </div> | |
| </header> | |
| {/* Content */} | |
| <div className="flex-1 px-4 sm:px-8 pb-8"> | |
| <AnimatePresence mode="wait"> | |
| <motion.div | |
| key={location.pathname} | |
| initial={{ opacity: 0, y: 16, filter: 'blur(4px)' }} | |
| animate={{ opacity: 1, y: 0, filter: 'blur(0px)' }} | |
| exit={{ opacity: 0, y: -8, filter: 'blur(4px)' }} | |
| transition={{ duration: 0.35, ease: [0.4, 0, 0.2, 1] }} | |
| > | |
| {children} | |
| </motion.div> | |
| </AnimatePresence> | |
| </div> | |
| </main> | |
| </div> | |
| ); | |
| } | |