turash/bugulma/frontend/components/layout/TopBar.tsx
2025-12-15 10:06:41 +01:00

118 lines
3.7 KiB
TypeScript

import BrandIdentity from '@/components/layout/BrandIdentity.tsx';
import { HeaderLayout, HeaderSection } from '@/components/layout/Header.tsx';
import HeaderActions from '@/components/layout/HeaderActions.tsx';
import Button from '@/components/ui/Button';
import { DropdownMenu } from '@/components/ui/DropdownMenu';
import SearchBar from '@/components/ui/SearchBar.tsx';
import { useAuth } from '@/contexts/AuthContext';
import { useTranslation } from '@/hooks/useI18n';
import { useScrollListener } from '@/hooks/useScrollListener.ts';
import React from 'react';
import { useNavigate } from 'react-router-dom';
interface TopBarProps {
showSearch?: boolean;
searchTerm?: string;
onSearchChange?: (term: string) => void;
onSearchSubmit?: () => void;
}
const TopBar = ({
showSearch = false,
searchTerm = '',
onSearchChange,
onSearchSubmit,
}: TopBarProps) => {
const { t } = useTranslation();
const { isAuthenticated } = useAuth();
const navigate = useNavigate();
const isScrolled = useScrollListener(10);
return (
<HeaderLayout
variant="transparent"
className={`sticky top-0 z-30 transition-all duration-300 ${isScrolled ? 'bg-background/80 backdrop-blur-lg shadow-sm border-b border-border/50' : 'bg-transparent'}`}
>
<HeaderSection>
<BrandIdentity showPulse />
</HeaderSection>
{/* Navigation Menu */}
<HeaderSection align="center" className="hidden md:flex order-2">
<nav className="flex items-center gap-6">
<Button
variant="ghost"
size="sm"
onClick={() => navigate('/map')}
className="text-sm font-medium"
>
{t('navigation.map')}
</Button>
<Button
variant="ghost"
size="sm"
onClick={() => navigate('/discovery')}
className="text-sm font-medium"
>
{t('navigation.discover')}
</Button>
{isAuthenticated && (
<DropdownMenu
trigger={
<Button variant="ghost" size="sm" className="text-sm font-medium">
{t('navigation.community')}
</Button>
}
items={[
{
label: t('navigation.communityMenu.impact'),
value: 'impact',
onClick: () => navigate('/community/impact'),
},
{
label: t('navigation.communityMenu.stories'),
value: 'stories',
onClick: () => navigate('/community/stories'),
},
{
label: t('navigation.communityMenu.news'),
value: 'news',
onClick: () => navigate('/community/news'),
},
{
label: t('navigation.communityMenu.events'),
value: 'events',
onClick: () => navigate('/community/events'),
},
]}
align="left"
/>
)}
</nav>
</HeaderSection>
{showSearch && (
<HeaderSection align="center" className="order-3 md:order-3">
<SearchBar
value={searchTerm}
onChange={onSearchChange || (() => {})}
onSubmit={onSearchSubmit}
navigateOnEnter={!onSearchSubmit}
containerClassName="w-full md:w-auto md:flex-1 max-w-md"
/>
</HeaderSection>
)}
<HeaderSection
align="right"
className={`gap-3 ${showSearch ? 'order-4 md:order-4' : 'order-3'}`}
>
<HeaderActions />
</HeaderSection>
</HeaderLayout>
);
};
export default React.memo(TopBar);