89 lines
3.7 KiB
TypeScript
89 lines
3.7 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { usePathname } from "next/navigation";
|
|
|
|
const TABS = [
|
|
{
|
|
href: "/",
|
|
label: "Aujourd'hui",
|
|
icon: (active: boolean) => (
|
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={active ? 2.5 : 1.8} strokeLinecap="round" strokeLinejoin="round">
|
|
<rect x="3" y="4" width="18" height="18" rx="2"/>
|
|
<line x1="16" y1="2" x2="16" y2="6"/>
|
|
<line x1="8" y1="2" x2="8" y2="6"/>
|
|
<line x1="3" y1="10" x2="21" y2="10"/>
|
|
<path d="M8 14h.01M12 14h.01M16 14h.01M8 18h.01M12 18h.01" strokeWidth={2.5}/>
|
|
</svg>
|
|
),
|
|
},
|
|
{
|
|
href: "/levels",
|
|
label: "Entraînement",
|
|
icon: (active: boolean) => (
|
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={active ? 2.5 : 1.8} strokeLinecap="round" strokeLinejoin="round">
|
|
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
|
|
</svg>
|
|
),
|
|
},
|
|
{
|
|
href: "/stats",
|
|
label: "Stats",
|
|
icon: (active: boolean) => (
|
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={active ? 2.5 : 1.8} strokeLinecap="round" strokeLinejoin="round">
|
|
<line x1="18" y1="20" x2="18" y2="10"/>
|
|
<line x1="12" y1="20" x2="12" y2="4"/>
|
|
<line x1="6" y1="20" x2="6" y2="14"/>
|
|
</svg>
|
|
),
|
|
},
|
|
{
|
|
href: "/settings",
|
|
label: "Réglages",
|
|
icon: (active: boolean) => (
|
|
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={active ? 2.5 : 1.8} strokeLinecap="round" strokeLinejoin="round">
|
|
<circle cx="12" cy="12" r="3"/>
|
|
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/>
|
|
</svg>
|
|
),
|
|
},
|
|
];
|
|
|
|
export default function BottomNav() {
|
|
const pathname = usePathname();
|
|
|
|
function isActive(href: string) {
|
|
if (href === "/") return pathname === "/";
|
|
if (href === "/levels") return pathname.includes("/levels") || pathname.includes("/level/");
|
|
return pathname.startsWith(href);
|
|
}
|
|
|
|
return (
|
|
<nav
|
|
className="fixed bottom-0 left-0 right-0 z-40 bg-white/95 backdrop-blur-xl border-t border-gray-100"
|
|
style={{ paddingBottom: "env(safe-area-inset-bottom)" }}
|
|
>
|
|
<div className="flex items-stretch h-14">
|
|
{TABS.map(tab => {
|
|
const active = isActive(tab.href);
|
|
return (
|
|
<Link
|
|
key={tab.href}
|
|
href={tab.href}
|
|
className="flex-1 flex flex-col items-center justify-center gap-0.5 transition-colors"
|
|
style={{ color: active ? "#111827" : "#9ca3af" }}
|
|
>
|
|
{tab.icon(active)}
|
|
<span className={`text-[9px] font-semibold tracking-tight leading-none ${active ? "text-gray-900" : "text-gray-400"}`}>
|
|
{tab.label}
|
|
</span>
|
|
{active && (
|
|
<span className="absolute bottom-0 w-8 h-0.5 bg-gray-900 rounded-t-full" style={{ marginBottom: "calc(env(safe-area-inset-bottom) + 2px)" }} />
|
|
)}
|
|
</Link>
|
|
);
|
|
})}
|
|
</div>
|
|
</nav>
|
|
);
|
|
}
|