This commit is contained in:
Tomas Dvorak
2025-10-23 22:26:50 +02:00
parent 63700eedb2
commit 70ea0c3c91
75 changed files with 3337 additions and 1160 deletions
+26 -4
View File
@@ -33,6 +33,7 @@ import {
InputGroup,
InputLeftElement,
Input,
useToast,
} from '@chakra-ui/react';
import { MoonIcon, SunIcon, HamburgerIcon, EditIcon, ChevronDownIcon } from '@chakra-ui/icons';
import { FaFacebook, FaInstagram, FaYoutube, FaPhotoVideo, FaExternalLinkAlt, FaShoppingBag, FaCamera, FaSearch } from 'react-icons/fa';
@@ -49,6 +50,7 @@ import { getPlayers } from '../services/public';
import { getArticles } from '../services/articles';
import { getCachedYouTube } from '../services/youtube';
import { getZoneramaManifestWithFallbacks } from '../services/zonerama';
import { getMyNewsletterToken } from '../services/public/newsletter';
type NavLink = { label: string; to?: string; items?: { label: string; to: string }[]; external?: boolean };
@@ -236,7 +238,7 @@ const MobileMenu = ({ isOpen, onClose, isAdmin, menuBg, dividerColor, settings,
</Drawer>
);
const Navbar = () => {
const Navbar: React.FC<{ fullWidth?: boolean }> = ({ fullWidth = false }) => {
const { colorMode, toggleColorMode } = useColorMode();
const { isAuthenticated, logout, user } = useAuth();
const { isOpen, onOpen, onClose } = useDisclosure();
@@ -246,12 +248,14 @@ const Navbar = () => {
const theme = useClubTheme();
const location = useLocation();
const navigate = useNavigate();
const toast = useToast();
const menuBg = useColorModeValue('white', '#0f1115');
const dividerColor = useColorModeValue('gray.600', 'gray.300');
const hoverBg = useColorModeValue('blackAlpha.100', 'whiteAlpha.200');
const activeBg = useColorModeValue('blackAlpha.50', 'whiteAlpha.100');
const activeTextColor = useColorModeValue('brand.primary', 'brand.accent');
const navTextColor = useColorModeValue('gray.700', 'gray.200');
const topBarBg = useColorModeValue('gray.50', 'blackAlpha.500');
const [scrolled, setScrolled] = useState(false);
const [hasTables, setHasTables] = useState<boolean | null>(null);
const [hasActivities, setHasActivities] = useState<boolean | null>(null);
@@ -261,6 +265,7 @@ const Navbar = () => {
const [hasGallery, setHasGallery] = useState<boolean | null>(null);
const [dynamicNavItems, setDynamicNavItems] = useState<NavigationItem[]>([]);
const [navLoading, setNavLoading] = useState(true);
const containerMaxW = fullWidth ? 'full' as const : '7xl' as const;
// Search modal state
const [query, setQuery] = useState('');
@@ -279,6 +284,21 @@ const Navbar = () => {
return () => window.removeEventListener('scroll', onScroll as any);
}, []);
// Open newsletter preferences for logged-in user (fetch token and redirect)
const openMyNewsletterPrefs = async () => {
try {
const { token } = await getMyNewsletterToken();
navigate(`/newsletter/preferences?token=${encodeURIComponent(token)}`);
} catch (err: any) {
toast({
title: 'Chyba',
description: 'Nelze načíst odkaz na emailové preference. Zkuste to prosím znovu.',
status: 'error',
duration: 4000,
});
}
};
// Also set document title to club name ASAP (SEO component will refine further)
useEffect(() => {
const name = settings?.club_name || theme.name;
@@ -607,8 +627,8 @@ const Navbar = () => {
<Box position="sticky" top={0} zIndex={1000}>
{/* Top bar with socials and quick external links */}
{(settings?.facebook_url || settings?.instagram_url || settings?.youtube_url || settings?.shop_url) && (
<Box bg={useColorModeValue('gray.50', 'blackAlpha.500')} borderBottomWidth="1px" borderColor="border.subtle" py={1}>
<Container maxW="7xl">
<Box bg={topBarBg} borderBottomWidth="1px" borderColor="border.subtle" py={1}>
<Container maxW={containerMaxW}>
<Flex align="center" justify="space-between" gap={2}>
<HStack spacing={2}>
{settings?.shop_url && (
@@ -643,7 +663,7 @@ const Navbar = () => {
transition="box-shadow 0.2s ease, background-color 0.2s ease, backdrop-filter 0.2s ease"
>
<MobileMenu isOpen={isOpen} onClose={onClose} isAdmin={isAdmin} menuBg={menuBg} dividerColor={dividerColor} settings={settings} categories={navCategories} galleryHref={galleryHref} galleryLabel={galleryLabel} hasTables={hasTables} hasActivities={hasActivities} hasPlayers={hasPlayers} hasArticles={hasArticles} hasVideos={hasVideos} hasGallery={hasGallery} dynamicNavItems={dynamicNavItems} navLoading={navLoading} />
<Container maxW="7xl">
<Container maxW={containerMaxW}>
<Flex h={16} alignItems="center" justifyContent="space-between">
<HStack spacing={4} alignItems="center">
{/* Club Logo only */}
@@ -768,6 +788,8 @@ const Navbar = () => {
</MenuButton>
<MenuList>
<MenuItem as={RouterLink} to="/admin/nastaveni">Můj účet</MenuItem>
<MenuItem onClick={openMyNewsletterPrefs}>Emailové preference</MenuItem>
<MenuItem as={RouterLink} to="/profil/nastaveni">Nastavení stránky</MenuItem>
{isAdmin && <MenuItem as={RouterLink} to="/admin">Administrace</MenuItem>}
<MenuItem onClick={logout}>Odhlásit se</MenuItem>
</MenuList>