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
+139 -30
View File
@@ -19,7 +19,12 @@ import { useSession } from "next-auth/react";
import { useColorModeValue } from "@/components/ui/color-mode";
import { SlideUp, FadeIn } from "@/components/motion";
import { useTeamById, useTeamMatches } from "@/lib/api/leagues/use-hooks";
import { LuArrowLeft, LuCalendar, LuTrophy, LuChevronDown } from "react-icons/lu";
import {
LuArrowLeft,
LuCalendar,
LuTrophy,
LuChevronDown,
} from "react-icons/lu";
import type { MatchResponseDto } from "@/lib/api/matches/types";
import { useState, useMemo, useCallback } from "react";
import { LoginModal } from "@/components/auth/login-modal";
@@ -29,7 +34,8 @@ import { LoginModal } from "@/components/auth/login-modal";
// ─────────────────────────────────────────────────
function getMatchTimestamp(match: MatchResponseDto): number {
const raw = typeof match.mstUtc === "string" ? Number(match.mstUtc) : match.mstUtc;
const raw =
typeof match.mstUtc === "string" ? Number(match.mstUtc) : match.mstUtc;
return Number.isFinite(raw) ? raw : 0;
}
@@ -39,19 +45,32 @@ function getMatchStatus(match: MatchResponseDto): string {
function isMatchFinished(match: MatchResponseDto): boolean {
const status = getMatchStatus(match);
return status === "FT" || status === "FINISHED" || status === "POSTGAME" || status === "POST_GAME";
return (
status === "FT" ||
status === "FINISHED" ||
status === "POSTGAME" ||
status === "POST_GAME"
);
}
function isMatchLive(match: MatchResponseDto): boolean {
const status = getMatchStatus(match);
return status === "LIVE" || status === "INPROGRESS" || status === "IN_PROGRESS";
return (
status === "LIVE" || status === "INPROGRESS" || status === "IN_PROGRESS"
);
}
function getTeamSideName(team: MatchResponseDto["homeTeam"] | MatchResponseDto["awayTeam"], fallback?: unknown): string {
function getTeamSideName(
team: MatchResponseDto["homeTeam"] | MatchResponseDto["awayTeam"],
fallback?: unknown,
): string {
return String(team?.name || fallback || "");
}
function getTeamSideLogo(team: MatchResponseDto["homeTeam"] | MatchResponseDto["awayTeam"], fallback?: unknown): string {
function getTeamSideLogo(
team: MatchResponseDto["homeTeam"] | MatchResponseDto["awayTeam"],
fallback?: unknown,
): string {
return String(team?.logo || fallback || "");
}
@@ -74,7 +93,10 @@ const SEASONS = (() => {
const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth() + 1;
const startYear = currentMonth >= 8 ? currentYear : currentYear - 1;
return Array.from({ length: 5 }, (_, i) => `${startYear - i}-${startYear - i + 1}`);
return Array.from(
{ length: 5 },
(_, i) => `${startYear - i}-${startYear - i + 1}`,
);
})();
// ─────────────────────────────────────────────────
@@ -97,7 +119,11 @@ export default function TeamDetailContent() {
data: matchesResponse,
isLoading: matchesLoading,
isFetching: matchesFetching,
} = useTeamMatches(teamId, { page: currentPage, limit: 20, season: activeSeason });
} = useTeamMatches(teamId, {
page: currentPage,
limit: 20,
season: activeSeason,
});
const cardBg = useColorModeValue("white", "gray.800");
const borderColor = useColorModeValue("gray.100", "gray.700");
@@ -109,20 +135,30 @@ export default function TeamDetailContent() {
const team = teamWrapper?.data as Record<string, unknown> | undefined;
// matchesResponse = { success, status, message, data: { data: [...], total, page, limit, totalPages } }
const paginationWrapper = matchesResponse as Record<string, unknown> | undefined;
const paginationData = paginationWrapper?.data as Record<string, unknown> | undefined;
const matches: MatchResponseDto[] = (Array.isArray(paginationData?.data) ? paginationData.data : paginationData?.data ? [] : []) as MatchResponseDto[];
const paginationWrapper = matchesResponse as
| Record<string, unknown>
| undefined;
const paginationData = paginationWrapper?.data as
| Record<string, unknown>
| undefined;
const matches: MatchResponseDto[] = (
Array.isArray(paginationData?.data)
? paginationData.data
: paginationData?.data
? []
: []
) as MatchResponseDto[];
const totalPages = (paginationData?.totalPages as number) ?? 1;
const totalMatches = (paginationData?.total as number) ?? 0;
// Separate past and upcoming matches
const pastMatches = useMemo(
() => matches.filter((m) => isMatchFinished(m)),
[matches]
[matches],
);
const upcomingMatches = useMemo(
() => matches.filter((m) => !isMatchFinished(m)),
[matches]
[matches],
);
// Pagination handlers
@@ -169,7 +205,9 @@ export default function TeamDetailContent() {
if (!team) {
return (
<Flex justify="center" py={20} direction="column" align="center" gap={4}>
<Text color="fg.muted" fontSize="lg">Takım bulunamadı</Text>
<Text color="fg.muted" fontSize="lg">
Takım bulunamadı
</Text>
<Button variant="outline" onClick={() => router.back()}>
<LuArrowLeft /> Geri
</Button>
@@ -181,13 +219,24 @@ export default function TeamDetailContent() {
<SlideUp>
<Box>
{/* Back Button */}
<Button variant="ghost" size="sm" mb={4} onClick={() => router.back()} gap={1.5}>
<Button
variant="ghost"
size="sm"
mb={4}
onClick={() => router.back()}
gap={1.5}
>
<LuArrowLeft />
Geri
</Button>
{/* Team Header */}
<Card.Root bg={cardBg} borderColor={borderColor} borderRadius="xl" mb={6}>
<Card.Root
bg={cardBg}
borderColor={borderColor}
borderRadius="xl"
mb={6}
>
<Card.Body>
<HStack gap={6} justify="center" align="center">
{(team as Record<string, unknown>).logo ? (
@@ -206,7 +255,9 @@ export default function TeamDetailContent() {
justify="center"
>
<Text fontSize="3xl" fontWeight="bold" color="primary.fg">
{String((team as Record<string, unknown>).name || "T").charAt(0)}
{String(
(team as Record<string, unknown>).name || "T",
).charAt(0)}
</Text>
</Flex>
)}
@@ -249,7 +300,11 @@ export default function TeamDetailContent() {
cardBg={cardBg}
borderColor={borderColor}
statusBadge={getStatusBadge(match)}
onClick={() => session ? router.push(`/matches/${match.id}`) : setLoginModalOpen(true)}
onClick={() =>
session
? router.push(`/matches/${match.id}`)
: setLoginModalOpen(true)
}
/>
))}
</VStack>
@@ -260,7 +315,13 @@ export default function TeamDetailContent() {
{/* Past Matches — Season Grouped */}
<FadeIn>
<Box>
<Flex align="center" justify="space-between" mb={4} flexWrap="wrap" gap={2}>
<Flex
align="center"
justify="space-between"
mb={4}
flexWrap="wrap"
gap={2}
>
<Heading as="h2" size="lg">
📊 Geçmiş Maçlar
</Heading>
@@ -320,7 +381,11 @@ export default function TeamDetailContent() {
cardBg={cardBg}
borderColor={borderColor}
statusBadge={getStatusBadge(match)}
onClick={() => session ? router.push(`/matches/${match.id}`) : setLoginModalOpen(true)}
onClick={() =>
session
? router.push(`/matches/${match.id}`)
: setLoginModalOpen(true)
}
/>
))}
</VStack>
@@ -357,7 +422,9 @@ export default function TeamDetailContent() {
key={pageNum}
size="sm"
variant={pageNum === currentPage ? "solid" : "ghost"}
bg={pageNum === currentPage ? seasonActiveBg : undefined}
bg={
pageNum === currentPage ? seasonActiveBg : undefined
}
color={pageNum === currentPage ? "white" : undefined}
borderRadius="full"
minW="36px"
@@ -407,7 +474,13 @@ interface MatchRowProps {
onClick: () => void;
}
function MatchRow({ match, cardBg, borderColor, statusBadge, onClick }: MatchRowProps) {
function MatchRow({
match,
cardBg,
borderColor,
statusBadge,
onClick,
}: MatchRowProps) {
const hoverBg = useColorModeValue("gray.50", "gray.700");
const matchTimestamp = getMatchTimestamp(match);
const homeTeamName = getTeamSideName(match.homeTeam, match.homeTeamName);
@@ -436,17 +509,34 @@ function MatchRow({ match, cardBg, borderColor, statusBadge, onClick }: MatchRow
{homeTeamName}
</Text>
{homeTeamLogo ? (
<Image src={homeTeamLogo} alt="" boxSize="24px" objectFit="contain" flexShrink={0} />
<Image
src={homeTeamLogo}
alt=""
boxSize="24px"
objectFit="contain"
flexShrink={0}
/>
) : (
<Flex boxSize="24px" bg="primary.subtle" borderRadius="full" align="center" justify="center" flexShrink={0}>
<Text fontSize="xs" fontWeight="bold">{homeTeamName?.charAt(0)}</Text>
<Flex
boxSize="24px"
bg="primary.subtle"
borderRadius="full"
align="center"
justify="center"
flexShrink={0}
>
<Text fontSize="xs" fontWeight="bold">
{homeTeamName?.charAt(0)}
</Text>
</Flex>
)}
</HStack>
{/* Score / VS */}
<VStack gap={0} flexShrink={0} minW="60px">
{hasScore && match.scoreHome !== undefined && match.scoreHome !== null ? (
{hasScore &&
match.scoreHome !== undefined &&
match.scoreHome !== null ? (
<Text fontSize="md" fontWeight="900">
{match.scoreHome} - {match.scoreAway}
</Text>
@@ -468,10 +558,25 @@ function MatchRow({ match, cardBg, borderColor, statusBadge, onClick }: MatchRow
{/* Away Team */}
<HStack gap={2} flex={1}>
{awayTeamLogo ? (
<Image src={awayTeamLogo} alt="" boxSize="24px" objectFit="contain" flexShrink={0} />
<Image
src={awayTeamLogo}
alt=""
boxSize="24px"
objectFit="contain"
flexShrink={0}
/>
) : (
<Flex boxSize="24px" bg="primary.subtle" borderRadius="full" align="center" justify="center" flexShrink={0}>
<Text fontSize="xs" fontWeight="bold">{awayTeamName?.charAt(0)}</Text>
<Flex
boxSize="24px"
bg="primary.subtle"
borderRadius="full"
align="center"
justify="center"
flexShrink={0}
>
<Text fontSize="xs" fontWeight="bold">
{awayTeamName?.charAt(0)}
</Text>
</Flex>
)}
<Text fontSize="sm" fontWeight="600" truncate>
@@ -483,7 +588,11 @@ function MatchRow({ match, cardBg, borderColor, statusBadge, onClick }: MatchRow
{/* Status + League */}
<HStack gap={2} flexShrink={0} ml={3}>
{leagueLabel && (
<Text fontSize="2xs" color="fg.muted" display={{ base: "none", md: "block" }}>
<Text
fontSize="2xs"
color="fg.muted"
display={{ base: "none", md: "block" }}
>
{leagueLabel}
</Text>
)}
+12 -2
View File
@@ -69,7 +69,13 @@ export default function TeamsContent() {
<Spinner size="lg" color="primary.500" />
</Flex>
) : query.length < 2 ? (
<Flex justify="center" py={16} direction="column" align="center" gap={3}>
<Flex
justify="center"
py={16}
direction="column"
align="center"
gap={3}
>
<Text fontSize="5xl"></Text>
<Text color="fg.muted" fontSize="lg">
Aramak istediğiniz takımın adını yazın
@@ -117,7 +123,11 @@ export default function TeamsContent() {
align="center"
justify="center"
>
<Text fontSize="xl" fontWeight="bold" color="primary.fg">
<Text
fontSize="xl"
fontWeight="bold"
color="primary.fg"
>
{team.name?.charAt(0) || "T"}
</Text>
</Flex>