mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-05 03:02:56 +00:00
upload
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
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';
|
||||
|
||||
const resolveBackendUrl = (path: string) => {
|
||||
try {
|
||||
if (/^https?:\/\//i.test(path)) return path;
|
||||
if (path.startsWith('/cache') || path.startsWith('/uploads')) {
|
||||
const base = process.env.REACT_APP_API_BASE_URL || process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
|
||||
const u = new URL(base);
|
||||
u.pathname = path;
|
||||
return u.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 apiUrl = process.env.REACT_APP_API_BASE_URL || process.env.REACT_APP_API_URL || 'http://localhost:8080/api/v1';
|
||||
const sponsorsRes = await fetch(`${apiUrl}/public/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}>
|
||||
<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;
|
||||
Reference in New Issue
Block a user