mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-03 18:22:57 +00:00
303 lines
12 KiB
TypeScript
303 lines
12 KiB
TypeScript
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}>E‑shop <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;
|