first
Deploy Iddaai Frontend / build-and-deploy (push) Successful in 4m0s

This commit is contained in:
2026-04-16 13:36:34 +03:00
parent de5e145c4e
commit fc7a1ba567
218 changed files with 32370 additions and 0 deletions
+162
View File
@@ -0,0 +1,162 @@
"use client";
import { Box, VStack, Text, Badge, Flex, Image } from "@chakra-ui/react";
import { useTranslations } from "next-intl";
import { useColorModeValue } from "@/components/ui/color-mode";
import type { ActiveLeagueDto } from "@/lib/api/matches/types";
interface LeagueSidebarProps {
leagues: ActiveLeagueDto[];
selectedLeagueId: string | null;
onSelect: (leagueId: string | null) => void;
isLoading?: boolean;
}
export default function LeagueSidebar({
leagues,
selectedLeagueId,
onSelect,
isLoading,
}: LeagueSidebarProps) {
const t = useTranslations("matches");
const bg = useColorModeValue("white", "gray.800");
const borderColor = useColorModeValue("gray.100", "gray.700");
const activeBg = useColorModeValue("primary.50", "primary.900");
const hoverBg = useColorModeValue("gray.50", "gray.750");
if (isLoading) {
return (
<Box
bg={bg}
borderRadius="xl"
borderWidth="1px"
borderColor={borderColor}
p={4}
>
<VStack gap={3}>
{Array.from({ length: 6 }).map((_, i) => (
<Box
key={i}
h="40px"
w="100%"
bg="bg.muted"
borderRadius="lg"
animation="pulse 1.5s ease-in-out infinite"
/>
))}
</VStack>
</Box>
);
}
return (
<Box
bg={bg}
borderRadius="xl"
borderWidth="1px"
borderColor={borderColor}
overflow="hidden"
>
{/* Header */}
<Box px={4} py={3} borderBottomWidth="1px" borderColor={borderColor}>
<Text
fontSize="sm"
fontWeight="bold"
textTransform="uppercase"
letterSpacing="wide"
color="fg.muted"
>
{t("active-leagues")}
</Text>
</Box>
{/* All Leagues Option */}
<Box
px={4}
py={2.5}
cursor="pointer"
bg={selectedLeagueId === null ? activeBg : "transparent"}
_hover={{ bg: selectedLeagueId === null ? activeBg : hoverBg }}
onClick={() => onSelect(null)}
transition="background 0.15s"
borderBottomWidth="1px"
borderColor={borderColor}
>
<Text
fontSize="sm"
fontWeight={selectedLeagueId === null ? "bold" : "medium"}
color={selectedLeagueId === null ? "primary.fg" : "fg"}
>
{t("all-leagues")}
</Text>
</Box>
{/* League List */}
<VStack gap={0} align="stretch" maxH="60vh" overflowY="auto">
{leagues.map((league) => {
const isActive = selectedLeagueId === league.id;
return (
<Box
key={league.id}
px={4}
py={2.5}
cursor="pointer"
bg={isActive ? activeBg : "transparent"}
_hover={{ bg: isActive ? activeBg : hoverBg }}
onClick={() => onSelect(league.id)}
transition="background 0.15s"
borderBottomWidth="1px"
borderColor={borderColor}
>
<Flex justify="space-between" align="center">
<Flex align="center" gap={2} minW={0} flex={1}>
{league.countryFlag && (
<Image
src={league.countryFlag}
alt={league.countryName || ""}
boxSize="16px"
objectFit="contain"
flexShrink={0}
/>
)}
<Text
fontSize="sm"
fontWeight={isActive ? "bold" : "medium"}
color={isActive ? "primary.fg" : "fg"}
truncate
>
{league.name}
</Text>
</Flex>
<Flex gap={1.5} flexShrink={0}>
{league.liveCount > 0 && (
<Badge
colorPalette="red"
variant="solid"
borderRadius="full"
fontSize="2xs"
px={1.5}
>
{league.liveCount}
</Badge>
)}
<Badge
colorPalette="gray"
variant="subtle"
borderRadius="full"
fontSize="2xs"
px={1.5}
>
{league.matchCount}
</Badge>
</Flex>
</Flex>
</Box>
);
})}
</VStack>
</Box>
);
}