gg
Deploy Iddaai Frontend / build-and-deploy (push) Failing after 34s

This commit is contained in:
2026-05-10 22:59:27 +03:00
parent 6dadc5f613
commit 5c8619b282
161 changed files with 6708 additions and 3435 deletions
+104 -24
View File
@@ -21,10 +21,20 @@ import { useColorModeValue } from "@/components/ui/color-mode";
import { SlideUp, FadeIn } from "@/components/motion";
import { useMatchDetails } from "@/lib/api/matches/use-hooks";
import { usePrediction } from "@/lib/api/predictions/use-hooks";
import { useGetMe } from "@/lib/api/users/use-hooks";
import { useQueryClient } from "@tanstack/react-query";
import { UsersQueryKeys } from "@/lib/api/users/use-hooks";
import PredictionCard from "@/components/matches/prediction-card";
import OddsCard from "@/components/matches/odds-card";
import LineupsCard from "@/components/matches/lineups-card";
import { LuArrowLeft, LuRefreshCw, LuShield, LuFlag, LuUser } from "react-icons/lu";
import {
LuArrowLeft,
LuRefreshCw,
LuShield,
LuFlag,
LuUser,
LuSparkles,
} from "react-icons/lu";
import type { MatchResponseDto } from "@/lib/api/matches/types";
// ─────────────────────────────────────────────────
@@ -60,6 +70,10 @@ interface SidelinedData {
export default function MatchDetailContent() {
const t = useTranslations("matches");
const tPred = useTranslations("predictions");
const queryClient = useQueryClient();
const { data: meData } = useGetMe();
const usageLimit = meData?.data?.usageLimit;
const hasLimit = usageLimit ? (usageLimit.maxAnalyses - usageLimit.analysisCount > 0) : true;
const tCommon = useTranslations("common");
const params = useParams();
const router = useRouter();
@@ -70,9 +84,16 @@ export default function MatchDetailContent() {
const {
data: predictionData,
isLoading: predLoading,
refetch: refetchPrediction,
refetch: refetchPredictionRaw,
isFetching: isPredFetching,
} = usePrediction(matchId);
const refetchPrediction = async () => {
await refetchPredictionRaw();
// After refetching, update the limits in the header
queryClient.invalidateQueries({ queryKey: UsersQueryKeys.me() });
};
const headerBg = useColorModeValue("white", "gray.800");
const cardBg = useColorModeValue("white", "gray.800");
const borderColor = useColorModeValue("gray.100", "gray.700");
@@ -139,7 +160,13 @@ export default function MatchDetailContent() {
>
{/* League Banner */}
{match.league && (
<Box bg={subtleBg} px={4} py={2.5} borderBottomWidth="1px" borderColor={borderColor}>
<Box
bg={subtleBg}
px={4}
py={2.5}
borderBottomWidth="1px"
borderColor={borderColor}
>
<Flex justify="center" align="center" gap={2}>
{match.league.country?.flag && (
<Image
@@ -151,7 +178,8 @@ export default function MatchDetailContent() {
/>
)}
<Text fontSize="sm" fontWeight="semibold" color="fg.muted">
{match.league.country?.name && `${match.league.country.name}`}
{match.league.country?.name &&
`${match.league.country.name}`}
{match.league.name}
</Text>
<Badge
@@ -300,7 +328,10 @@ export default function MatchDetailContent() {
>
<LuUser size={14} />
<Text fontSize="xs" color="fg.muted">
{t("referee")}: <Text as="span" fontWeight="semibold" color="fg">{match.refereeName}</Text>
{t("referee")}:{" "}
<Text as="span" fontWeight="semibold" color="fg">
{match.refereeName}
</Text>
</Text>
</Flex>
)}
@@ -312,7 +343,12 @@ export default function MatchDetailContent() {
{/* ═══════════════════════════════════════════ */}
{hasSidelined && (
<FadeIn>
<Card.Root bg={cardBg} borderColor={borderColor} borderRadius="xl" mb={6}>
<Card.Root
bg={cardBg}
borderColor={borderColor}
borderRadius="xl"
mb={6}
>
<Card.Body>
<Heading as="h2" size="md" mb={4}>
🏥 {t("sidelined")}
@@ -361,6 +397,7 @@ export default function MatchDetailContent() {
variant="outline"
size="sm"
onClick={() => refetchPrediction()}
disabled={!hasLimit}
gap={1.5}
>
<LuRefreshCw />
@@ -368,7 +405,7 @@ export default function MatchDetailContent() {
</Button>
</Flex>
{predLoading ? (
{predLoading || isPredFetching ? (
<Flex justify="center" py={10}>
<Spinner size="md" color="primary.500" />
</Flex>
@@ -377,8 +414,21 @@ export default function MatchDetailContent() {
) : (
<Card.Root borderColor={borderColor} borderRadius="xl">
<Card.Body>
<Flex justify="center" align="center" py={8}>
<Text color="fg.muted">{tPred("no-predictions")}</Text>
<Flex direction="column" justify="center" align="center" py={8} gap={4}>
<Text color="fg.muted">{tPred("no-predictions", { defaultValue: "Tahmin bulunmuyor." })}</Text>
<Button
colorPalette="primary"
onClick={() => refetchPrediction()}
disabled={!hasLimit}
loading={isPredFetching}
>
<LuSparkles /> {tPred("generate", { defaultValue: "Yapay Zeka ile Analiz Et" })}
</Button>
{!hasLimit && (
<Text fontSize="sm" color="red.500">
{tCommon("limits.out_of_analysis", { defaultValue: "Günlük analiz limitiniz doldu." })}
</Text>
)}
</Flex>
</Card.Body>
</Card.Root>
@@ -409,15 +459,31 @@ interface SidelinedColumnProps {
t: ReturnType<typeof useTranslations>;
}
function SidelinedColumn({ team, teamName, teamLogo, injuryBg, injuryBorder, t }: SidelinedColumnProps) {
function SidelinedColumn({
team,
teamName,
teamLogo,
injuryBg,
injuryBorder,
t,
}: SidelinedColumnProps) {
const players = team?.players || [];
if (players.length === 0) {
return (
<Box>
<HStack gap={2} mb={3}>
{teamLogo && <Image src={teamLogo} alt={teamName} boxSize="20px" objectFit="contain" />}
<Text fontSize="sm" fontWeight="bold">{teamName}</Text>
{teamLogo && (
<Image
src={teamLogo}
alt={teamName}
boxSize="20px"
objectFit="contain"
/>
)}
<Text fontSize="sm" fontWeight="bold">
{teamName}
</Text>
</HStack>
<Text fontSize="xs" color="fg.muted" fontStyle="italic">
{t("no-sidelined")}
@@ -429,9 +495,23 @@ function SidelinedColumn({ team, teamName, teamLogo, injuryBg, injuryBorder, t }
return (
<Box>
<HStack gap={2} mb={3}>
{teamLogo && <Image src={teamLogo} alt={teamName} boxSize="20px" objectFit="contain" />}
<Text fontSize="sm" fontWeight="bold">{teamName}</Text>
<Badge colorPalette="red" variant="subtle" fontSize="2xs" borderRadius="full">
{teamLogo && (
<Image
src={teamLogo}
alt={teamName}
boxSize="20px"
objectFit="contain"
/>
)}
<Text fontSize="sm" fontWeight="bold">
{teamName}
</Text>
<Badge
colorPalette="red"
variant="subtle"
fontSize="2xs"
borderRadius="full"
>
{players.length}
</Badge>
</HStack>
@@ -458,21 +538,21 @@ function SidelinedColumn({ team, teamName, teamLogo, injuryBg, injuryBorder, t }
</Badge>
)}
<Text fontSize="xs" color="fg.muted">
{player.description || (
player.type === "injury"
{player.description ||
(player.type === "injury"
? t("injury")
: player.type === "suspended"
? t("suspended")
: t("other-reason")
)}
: t("other-reason"))}
</Text>
</HStack>
</VStack>
{player.matchesMissed !== undefined && player.matchesMissed > 0 && (
<Badge colorPalette="red" variant="subtle" fontSize="2xs">
{player.matchesMissed} {t("matches-missed")}
</Badge>
)}
{player.matchesMissed !== undefined &&
player.matchesMissed > 0 && (
<Badge colorPalette="red" variant="subtle" fontSize="2xs">
{player.matchesMissed} {t("matches-missed")}
</Badge>
)}
</Flex>
</Box>
))}