83 lines
3.1 KiB
TypeScript
83 lines
3.1 KiB
TypeScript
import React from 'react';
|
|
import { NavLink, useParams, useLocation } from 'react-router-dom';
|
|
import { CheckSquare, GalleryHorizontal, Home, Trophy } from 'lucide-react';
|
|
import { useEventData } from '../hooks/useEventData';
|
|
import { useTranslation } from '../i18n/useTranslation';
|
|
|
|
function TabLink({
|
|
to,
|
|
children,
|
|
isActive,
|
|
}: {
|
|
to: string;
|
|
children: React.ReactNode;
|
|
isActive: boolean;
|
|
}) {
|
|
return (
|
|
<NavLink
|
|
to={to}
|
|
className={`
|
|
flex flex-col items-center gap-1 h-14 p-2 transition-all duration-200 rounded-lg backdrop-blur-md
|
|
${isActive
|
|
? 'bg-gradient-to-t from-pink-500/90 to-pink-400/90 text-white shadow-lg scale-105 border border-white/30'
|
|
: 'text-gray-300 hover:bg-white/10 hover:text-pink-300 hover:scale-105 hover:border-white/20 border border-transparent'
|
|
}`}
|
|
>
|
|
{children}
|
|
</NavLink>
|
|
);
|
|
}
|
|
|
|
export default function BottomNav() {
|
|
const { token } = useParams();
|
|
const location = useLocation();
|
|
const { event, status } = useEventData();
|
|
const { t } = useTranslation();
|
|
|
|
const isReady = status === 'ready' && !!event;
|
|
|
|
if (!token || !isReady) return null; // Only show bottom nav within event context
|
|
const base = `/e/${encodeURIComponent(token)}`;
|
|
const currentPath = location.pathname;
|
|
|
|
const labels = {
|
|
home: t('navigation.home'),
|
|
tasks: t('navigation.tasks'),
|
|
achievements: t('navigation.achievements'),
|
|
gallery: t('navigation.gallery'),
|
|
};
|
|
|
|
// Improved active state logic
|
|
const isHomeActive = currentPath === base || currentPath === `/${token}`;
|
|
const isTasksActive = currentPath.startsWith(`${base}/tasks`) || currentPath === `${base}/upload`;
|
|
const isAchievementsActive = currentPath.startsWith(`${base}/achievements`);
|
|
const isGalleryActive = currentPath.startsWith(`${base}/gallery`) || currentPath.startsWith(`${base}/photos`);
|
|
|
|
return (
|
|
<div className="fixed inset-x-0 bottom-0 z-30 border-t border-white/20 bg-black/30 px-2 py-2 backdrop-blur-xl shadow-xl dark:bg-black/40 dark:border-gray-800/50">
|
|
<div className="mx-auto flex max-w-sm items-center justify-around">
|
|
<TabLink to={`${base}`} isActive={isHomeActive}>
|
|
<div className="flex flex-col items-center gap-1">
|
|
<Home className="h-5 w-5" /> <span className="text-xs">{labels.home}</span>
|
|
</div>
|
|
</TabLink>
|
|
<TabLink to={`${base}/tasks`} isActive={isTasksActive}>
|
|
<div className="flex flex-col items-center gap-1">
|
|
<CheckSquare className="h-5 w-5" /> <span className="text-xs">{labels.tasks}</span>
|
|
</div>
|
|
</TabLink>
|
|
<TabLink to={`${base}/achievements`} isActive={isAchievementsActive}>
|
|
<div className="flex flex-col items-center gap-1">
|
|
<Trophy className="h-5 w-5" /> <span className="text-xs">{labels.achievements}</span>
|
|
</div>
|
|
</TabLink>
|
|
<TabLink to={`${base}/gallery`} isActive={isGalleryActive}>
|
|
<div className="flex flex-col items-center gap-1">
|
|
<GalleryHorizontal className="h-5 w-5" /> <span className="text-xs">{labels.gallery}</span>
|
|
</div>
|
|
</TabLink>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|