rinogeek's picture
Update for deployment
62fe6d4
/**
* Composant de navigation pour AfriDataHub
* Created by BlackBenAI Team - AfriDataHub Platform
*/
import { useState } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { Button } from '@/components/ui/button'
import {
BarChart3,
Database,
AlertTriangle,
User,
Menu,
X,
Globe,
TrendingUp,
Moon,
Sun
} from 'lucide-react'
import { useTheme } from 'next-themes'
const Navigation = ({ currentPage, onPageChange, user, onLogout }) => {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
const { theme, setTheme } = useTheme()
const menuItems = [
{ id: 'dashboard', label: 'Dashboard', icon: BarChart3 },
{ id: 'datasets', label: 'Datasets', icon: Database },
{ id: 'analytics', label: 'Analyse', icon: TrendingUp },
{ id: 'alerts', label: 'Alertes', icon: AlertTriangle },
{ id: 'api-docs', label: 'API', icon: Globe },
{ id: 'profile', label: 'Profil', icon: User },
]
const handlePageChange = (pageId) => {
onPageChange(pageId)
setIsMobileMenuOpen(false)
}
return (
<nav className="sticky top-0 z-50 glass border-b">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex justify-between h-20">
{/* Logo et titre */}
<div className="flex items-center">
<div className="flex-shrink-0 flex items-center group cursor-pointer" onClick={() => handlePageChange('dashboard')}>
<div className="p-2 bg-primary rounded-xl shadow-lg group-hover:scale-110 transition-transform duration-300">
<Globe className="h-6 w-6 text-white animate-pulse" />
</div>
<span className="ml-3 text-xl sm:text-2xl font-black tracking-tight text-foreground">
AfriDataHub
</span>
</div>
</div>
{/* Menu desktop */}
<div className="hidden lg:flex items-center space-x-1 lg:space-x-2">
{menuItems.map((item) => {
const Icon = item.icon
const isActive = currentPage === item.id
return (
<Button
key={item.id}
variant="ghost"
onClick={() => handlePageChange(item.id)}
className={`relative px-4 py-2 rounded-xl transition-all duration-300 group ${isActive
? 'text-primary bg-primary/10'
: 'text-muted-foreground hover:text-primary hover:bg-primary/5'
}`}
>
<Icon className={`h-4 w-4 mr-2 ${isActive ? 'scale-110' : 'group-hover:scale-110'} transition-transform`} />
<span className="font-semibold">{item.label}</span>
{isActive && (
<motion.div
layoutId="nav-active"
className="absolute bottom-0 left-0 right-0 h-0.5 bg-primary rounded-full"
/>
)}
</Button>
)
})}
{user && (
<div className="flex items-center ml-6 pl-6 border-l border-border">
<div className="flex items-center space-x-3 mr-4">
<div className="w-8 h-8 rounded-full bg-primary flex items-center justify-center text-white font-bold text-xs shadow-md">
{user.username.charAt(0).toUpperCase()}
</div>
<span className="text-sm font-medium text-foreground/80">
{user.username}
</span>
</div>
<Button
variant="outline"
onClick={onLogout}
className="rounded-xl border-border text-muted-foreground hover:text-destructive hover:border-destructive/30 hover:bg-destructive/10 transition-colors"
>
Déconnexion
</Button>
</div>
)}
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
className="ml-2 rounded-xl text-foreground hover:bg-primary/10"
>
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</div>
{/* Bouton menu mobile */}
<div className="lg:hidden flex items-center">
<Button
variant="ghost"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
className="rounded-xl text-foreground hover:bg-primary/10"
>
{isMobileMenuOpen ? (
<X className="h-6 w-6" />
) : (
<Menu className="h-6 w-6" />
)}
</Button>
<Button
variant="ghost"
size="icon"
onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
className="ml-2 rounded-xl text-foreground hover:bg-primary/10"
>
<Sun className="h-5 w-5 rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-5 w-5 rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<span className="sr-only">Toggle theme</span>
</Button>
</div>
</div>
</div>
{/* Menu mobile */}
<AnimatePresence>
{isMobileMenuOpen && (
<motion.div
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
className="lg:hidden glass border-t overflow-hidden"
>
<div className="px-4 pt-4 pb-6 space-y-2">
{menuItems.map((item) => {
const Icon = item.icon
const isActive = currentPage === item.id
return (
<Button
key={item.id}
variant="ghost"
onClick={() => handlePageChange(item.id)}
className={`w-full justify-start flex items-center space-x-3 p-4 rounded-xl transition-all ${isActive
? 'bg-primary/20 text-primary shadow-inner'
: 'text-muted-foreground hover:bg-primary/10 hover:text-primary'
}`}
>
<Icon className="h-5 w-5" />
<span className="font-bold">{item.label}</span>
</Button>
)
})}
{user && (
<div className="pt-4 mt-4 border-t">
<Button
variant="ghost"
onClick={onLogout}
className="w-full justify-start flex items-center space-x-3 p-4 rounded-xl text-muted-foreground hover:text-destructive hover:bg-destructive/10"
>
<X className="h-5 w-5" />
<span className="font-bold">Déconnexion</span>
</Button>
</div>
)}
</div>
</motion.div>
)}
</AnimatePresence>
</nav>
)
}
export default Navigation