180 lines
3.6 KiB
TypeScript
180 lines
3.6 KiB
TypeScript
'use client';
|
||
|
||
import Link from 'next/link';
|
||
import { useEffect, useState } from 'react';
|
||
import { usePathname } from 'next/navigation';
|
||
|
||
const leftItems = [
|
||
{ href: '/feed', label: 'Feed', icon: '🏠' },
|
||
{ href: '/explore', label: 'Entdecken', icon: '🔍' },
|
||
];
|
||
|
||
const rightItems = [
|
||
{ href: '/pets', label: 'Tiere', icon: '🐾' },
|
||
{ href: '/profile', label: 'Profil', icon: '👤' },
|
||
];
|
||
|
||
function NavItem({
|
||
item,
|
||
pathname,
|
||
}: {
|
||
item: { href: string; label: string; icon: string };
|
||
pathname: string;
|
||
}) {
|
||
const isActive =
|
||
item.href === '/feed'
|
||
? pathname === '/feed'
|
||
: pathname.startsWith(item.href);
|
||
|
||
return (
|
||
<Link
|
||
href={item.href}
|
||
style={{
|
||
textDecoration: 'none',
|
||
color: isActive ? '#000' : '#777',
|
||
fontSize: '0.7rem',
|
||
display: 'flex',
|
||
flexDirection: 'column',
|
||
alignItems: 'center',
|
||
gap: '2px',
|
||
transition: 'transform 0.15s ease, color 0.15s ease',
|
||
}}
|
||
onMouseDown={(e) => {
|
||
(e.currentTarget as HTMLElement).style.transform = 'scale(0.9)';
|
||
}}
|
||
onMouseUp={(e) => {
|
||
(e.currentTarget as HTMLElement).style.transform = 'scale(1)';
|
||
}}
|
||
onMouseLeave={(e) => {
|
||
(e.currentTarget as HTMLElement).style.transform = 'scale(1)';
|
||
}}
|
||
|
||
>
|
||
<span style={{ fontSize: '1.1rem' }}>{item.icon}</span>
|
||
{item.label}
|
||
{isActive && (
|
||
<span
|
||
style={{
|
||
marginTop: '2px',
|
||
width: '6px',
|
||
height: '2px',
|
||
borderRadius: '2px',
|
||
backgroundColor: '#2E7D32',
|
||
}}
|
||
/>
|
||
)}
|
||
|
||
</Link>
|
||
);
|
||
}
|
||
|
||
export default function BottomNav() {
|
||
const [isLoggedIn, setIsLoggedIn] = useState(false);
|
||
const pathname = usePathname();
|
||
|
||
useEffect(() => {
|
||
const hasAuthCookie = document.cookie
|
||
.split('; ')
|
||
.some((c) => c.startsWith('onlypets-auth=true'));
|
||
|
||
setIsLoggedIn(hasAuthCookie);
|
||
}, []);
|
||
|
||
if (!isLoggedIn) return null;
|
||
|
||
return (
|
||
<nav
|
||
style={{
|
||
position: 'fixed',
|
||
bottom: 0,
|
||
left: 0,
|
||
right: 0,
|
||
height: '70px',
|
||
borderTop: '1px solid #eee',
|
||
backgroundColor: '#fff',
|
||
zIndex: 100,
|
||
}}
|
||
>
|
||
{/* Linke Seite */}
|
||
<div
|
||
style={{
|
||
position: 'absolute',
|
||
left: 0,
|
||
bottom: 0,
|
||
height: '70px',
|
||
width: '50%',
|
||
display: 'flex',
|
||
justifyContent: 'space-evenly',
|
||
alignItems: 'center',
|
||
}}
|
||
>
|
||
{leftItems.map((item) => (
|
||
<NavItem key={item.href} item={item} pathname={pathname} />
|
||
))}
|
||
</div>
|
||
|
||
{/* Rechte Seite */}
|
||
<div
|
||
style={{
|
||
position: 'absolute',
|
||
right: 0,
|
||
bottom: 0,
|
||
height: '70px',
|
||
width: '50%',
|
||
display: 'flex',
|
||
justifyContent: 'space-evenly',
|
||
alignItems: 'center',
|
||
}}
|
||
>
|
||
{rightItems.map((item) => (
|
||
<NavItem key={item.href} item={item} pathname={pathname} />
|
||
))}
|
||
</div>
|
||
|
||
{/* Zentrierter Post-Button */}
|
||
<Link
|
||
href="/post/new"
|
||
style={{
|
||
position: 'absolute',
|
||
left: '50%',
|
||
transform: 'translateX(-50%) translateY(-18px)',
|
||
textDecoration: 'none',
|
||
}}
|
||
>
|
||
<div
|
||
style={{
|
||
width: '56px',
|
||
height: '56px',
|
||
borderRadius: '50%',
|
||
backgroundColor: '#2E7D32',
|
||
color: 'white',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
fontSize: '1.3rem',
|
||
boxShadow: '0 6px 16px rgba(0,0,0,0.25)',
|
||
transition: 'transform 0.25s cubic-bezier(0.4, 0, 0.2, 1)',
|
||
transform: 'translateY(0) scale(1)', // 🔑 Ausgangszustand
|
||
}}
|
||
onClick={(e) => {
|
||
const el = e.currentTarget as HTMLElement;
|
||
|
||
// Jump
|
||
el.style.transform = 'translateY(-8px) scale(0.95)';
|
||
|
||
// Rückkehr
|
||
setTimeout(() => {
|
||
el.style.transform = 'translateY(0) scale(1)';
|
||
}, 180);
|
||
}}
|
||
>
|
||
➕
|
||
</div>
|
||
</Link>
|
||
|
||
|
||
</nav>
|
||
|
||
);
|
||
}
|