Files
MyClub/frontend/src/components/layout/Footer.tsx
T
Tomas Dvorak 3d621e2187 dev day #71
2025-10-25 16:33:53 +02:00

303 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { Box, Container, HStack, Link, Text, Stack, Wrap, WrapItem, Button, Image, VStack, IconButton, SimpleGrid, Heading } from '@chakra-ui/react';
import React, { useEffect, useState } from 'react';
import { FiArrowUpRight, FiMail } from 'react-icons/fi';
import { FaFacebook, FaInstagram, FaYoutube } from 'react-icons/fa';
import { trackNavigation } from '../../utils/umami';
import { useClubTheme } from '../../contexts/ClubThemeContext';
import { usePublicSettings } from '../../hooks/usePublicSettings';
import { assetUrl } from '../../utils/url';
import { API_URL } from '../../services/api';
const resolveBackendUrl = (path: string) => {
try {
if (/^https?:\/\//i.test(path)) return path;
if (path.startsWith('/cache') || path.startsWith('/uploads')) {
const origin = new URL(API_URL, typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000').origin;
return new URL(path, origin).toString();
}
return path;
} catch {
return path;
}
};
interface Sponsor {
id: number | string;
name: string;
logo_url?: string;
website_url?: string;
is_active?: boolean;
}
const Footer: React.FC = () => {
const currentYear = new Date().getFullYear();
const [clubName, setClubName] = useState<string>('Fotbal Club');
const [shopUrl, setShopUrl] = useState<string | null>(null);
const [sponsors, setSponsors] = useState<Sponsor[]>([]);
const theme = useClubTheme();
const { data: settings } = usePublicSettings();
useEffect(() => {
let cancelled = false;
(async () => {
try {
const res = await fetch(resolveBackendUrl('/cache/prefetch/facr_club_info.json'), { cache: 'no-cache' });
if (!res.ok) return;
const json = await res.json();
if (cancelled) return;
if (json?.name) setClubName(String(json.name));
} catch {}
try {
const res = await fetch(resolveBackendUrl('/cache/prefetch/settings.json'), { cache: 'no-cache' });
if (res?.ok) {
const s = await res.json();
if (!cancelled && s) {
setShopUrl(s?.shop_url || s?.eshop_url || null);
}
}
} catch {}
// Fetch sponsors
try {
const sponsorsRes = await fetch(`${API_URL}/sponsors`);
if (sponsorsRes.ok) {
const data = await sponsorsRes.json();
if (!cancelled && Array.isArray(data)) {
// Filter active sponsors only
const activeSponsors = data.filter((s: Sponsor) => s.is_active !== false);
setSponsors(activeSponsors);
}
}
} catch {}
})();
return () => { cancelled = true; };
}, []);
return (
<>
{/* Navigation Footer */}
<Box bg="gray.800" color="white" mt={12} py={8} borderTop="1px" borderColor="whiteAlpha.200">
<Container maxW="container.xl">
<Stack direction={{ base: 'column', lg: 'row' }} spacing={6} justify="space-between" align={{ base: 'flex-start', lg: 'center' }} w="100%">
{/* Brand */}
<HStack spacing={3} align="center">
<Text fontWeight="700" fontSize="lg">{clubName}</Text>
</HStack>
{/* Navigation links */}
<Wrap spacing={4} shouldWrapChildren>
<WrapItem><Link href="/blog" color="whiteAlpha.900" fontWeight="600" _hover={{ color: 'white', textDecoration: 'underline' }}>Články</Link></WrapItem>
<WrapItem><Link href="/kalendar" color="whiteAlpha.800" _hover={{ color: 'white', textDecoration: 'underline' }}>Zápasy</Link></WrapItem>
<WrapItem><Link href="/tabulky" color="whiteAlpha.800" _hover={{ color: 'white', textDecoration: 'underline' }}>Tabulka</Link></WrapItem>
<WrapItem><Link href="/sponzori" color="whiteAlpha.800" _hover={{ color: 'white', textDecoration: 'underline' }}>Sponzoři</Link></WrapItem>
<WrapItem><Link href="/kontakt" color="whiteAlpha.800" _hover={{ color: 'white', textDecoration: 'underline' }}>Kontakt</Link></WrapItem>
<WrapItem><Link href="/pravidla-cookies" color="whiteAlpha.800" _hover={{ color: 'white', textDecoration: 'underline' }}>Cookies</Link></WrapItem>
<WrapItem><Link href="/obchodni-podminky" color="whiteAlpha.800" _hover={{ color: 'white', textDecoration: 'underline' }}>Obchodní podmínky</Link></WrapItem>
<WrapItem><Link href="/zasady-ochrany-osobnich-udaju" color="whiteAlpha.800" _hover={{ color: 'white', textDecoration: 'underline' }}>Zásady ochrany osobních údajů</Link></WrapItem>
{shopUrl && (
<WrapItem><Link href={shopUrl} color="whiteAlpha.800" _hover={{ color: 'white', textDecoration: 'underline' }} isExternal display="inline-flex" alignItems="center" gap={1}>Eshop <FiArrowUpRight /></Link></WrapItem>
)}
</Wrap>
</Stack>
</Container>
</Box>
{/* Sponsors Section */}
{sponsors.length > 0 && (
<Box bg="gray.700" color="white" py={8} borderTop="1px" borderColor="whiteAlpha.200">
<Container maxW="container.xl">
<VStack spacing={6}>
<Heading size="md" color="whiteAlpha.900">
Naši partneři
</Heading>
<SimpleGrid
columns={{ base: 2, sm: 3, md: 4, lg: 6 }}
spacing={6}
w="full"
>
{sponsors.map((sponsor) => (
<Link
key={sponsor.id}
href={sponsor.website_url || '#'}
isExternal={!!sponsor.website_url}
target={sponsor.website_url ? '_blank' : undefined}
rel={sponsor.website_url ? 'noopener noreferrer' : undefined}
display="flex"
alignItems="center"
justifyContent="center"
p={3}
bg="whiteAlpha.100"
borderRadius="md"
_hover={{ bg: 'whiteAlpha.200', transform: 'translateY(-2px)' }}
transition="all 0.2s"
onClick={() => trackNavigation('footer', `sponsor_${sponsor.name}`)}
>
<Image
src={assetUrl(sponsor.logo_url) || '/logo192.png'}
alt={sponsor.name}
maxH="60px"
maxW="full"
objectFit="contain"
filter="brightness(0) invert(1)"
opacity={0.9}
_hover={{ opacity: 1 }}
/>
</Link>
))}
</SimpleGrid>
</VStack>
</Container>
</Box>
)}
{/* Social Media Section */}
{(settings?.facebook_url || settings?.instagram_url || settings?.youtube_url) && (
<Box bg="gray.600" color="white" py={6} borderTop="1px" borderColor="whiteAlpha.200">
<Container maxW="container.xl">
<VStack spacing={4}>
<Text fontSize="lg" fontWeight="600" color="whiteAlpha.900">
Sledujte nás
</Text>
<HStack spacing={4}>
{settings?.facebook_url && (
<IconButton
as="a"
href={settings.facebook_url}
target="_blank"
rel="noopener noreferrer"
aria-label="Facebook"
icon={<FaFacebook />}
size="lg"
colorScheme="facebook"
variant="ghost"
color="white"
_hover={{
bg: 'whiteAlpha.200',
transform: 'translateY(-2px)',
color: '#1877F2'
}}
transition="all 0.2s"
onClick={() => trackNavigation('footer', 'social_facebook')}
/>
)}
{settings?.instagram_url && (
<IconButton
as="a"
href={settings.instagram_url}
target="_blank"
rel="noopener noreferrer"
aria-label="Instagram"
icon={<FaInstagram />}
size="lg"
variant="ghost"
color="white"
_hover={{
bg: 'whiteAlpha.200',
transform: 'translateY(-2px)',
color: '#E4405F'
}}
transition="all 0.2s"
onClick={() => trackNavigation('footer', 'social_instagram')}
/>
)}
{settings?.youtube_url && (
<IconButton
as="a"
href={settings.youtube_url}
target="_blank"
rel="noopener noreferrer"
aria-label="YouTube"
icon={<FaYoutube />}
size="lg"
variant="ghost"
color="white"
_hover={{
bg: 'whiteAlpha.200',
transform: 'translateY(-2px)',
color: '#FF0000'
}}
transition="all 0.2s"
onClick={() => trackNavigation('footer', 'social_youtube')}
/>
)}
</HStack>
</VStack>
</Container>
</Box>
)}
{/* Copyright Bar */}
<Box bg="gray.900" color="whiteAlpha.900" py={4}>
<Container maxW="container.xl">
<Text fontSize="sm" textAlign="center">
© {currentYear} {clubName}. Všechna práva vyhrazena.
</Text>
</Container>
</Box>
{/* MyClub Watermark - Clean White Branding */}
<Box bg="white" borderTop="1px" borderColor="gray.200" py={6} data-watermark="myclub">
<Container maxW="container.xl">
<Stack
direction={{ base: 'column', md: 'row' }}
spacing={6}
justify="space-between"
align="center"
>
{/* Left: MyClub Logo & Text */}
<HStack spacing={4} align="center">
<Image
src="https://myclub.sportcreative.eu/logo.svg"
alt="MyClub"
h={{ base: '32px', md: '40px' }}
w="auto"
fallbackSrc="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 50'%3E%3Ctext x='10' y='35' font-family='Arial' font-size='24' font-weight='bold' fill='%23000'%3EMyClub%3C/text%3E%3C/svg%3E"
/>
<VStack align="start" spacing={0}>
<Text fontSize={{ base: 'sm', md: 'md' }} fontWeight="600" color="gray.800">
Stránku provozuje MyClub
</Text>
<Text fontSize={{ base: 'xs', md: 'sm' }} color="gray.600">
Profesionální webové stránky pro sportovní kluby
</Text>
</VStack>
</HStack>
{/* Right: CTA Buttons */}
<HStack spacing={3}>
<Button
as="a"
href="https://myclub.sportcreative.eu/kontakt"
target="_blank"
rel="noopener noreferrer"
size={{ base: 'sm', md: 'md' }}
colorScheme="blue"
variant="solid"
leftIcon={<FiMail />}
_hover={{ transform: 'translateY(-2px)', boxShadow: 'lg' }}
transition="all 0.2s"
>
Objednat
</Button>
<Button
as="a"
href="https://myclub.sportcreative.eu"
target="_blank"
rel="noopener noreferrer"
size={{ base: 'sm', md: 'md' }}
variant="outline"
colorScheme="gray"
rightIcon={<FiArrowUpRight />}
_hover={{ bg: 'gray.50' }}
>
Více info
</Button>
</HStack>
</Stack>
</Container>
</Box>
</>
);
};
export default Footer;