"use client"; import { Box, Card, Flex, HStack, Text, VStack, Badge, SimpleGrid, Icon, } from "@chakra-ui/react"; import { useColorModeValue } from "@/components/ui/color-mode"; import { useTranslations } from "next-intl"; import { LuUsers, LuUser, LuInfo, LuShieldCheck, LuClock, } from "react-icons/lu"; import type { MatchResponseDto } from "@/lib/api/matches/types"; import type { MatchPredictionDto } from "@/lib/api/predictions/types"; interface LineupsCardProps { match: MatchResponseDto; prediction?: MatchPredictionDto | null; } /** * Lineup source metadata used for title, badge, and informational banners. */ function getLineupSourceMeta( source: string | undefined, t: ReturnType, ) { switch (source) { case "confirmed_live": return { title: t("lineup-official-xi"), badge: t("lineup-confirmed-squad"), badgeColor: "green" as const, icon: LuShieldCheck, description: t("lineup-confirmed-live-desc"), }; case "confirmed_participation": return { title: t("lineup-confirmed-squad"), badge: t("lineup-confirmed"), badgeColor: "green" as const, icon: LuShieldCheck, description: t("lineup-participation-desc"), }; case "probable_xi": return { title: t("lineup-probable-squad"), badge: t("lineup-probable"), badgeColor: "orange" as const, icon: LuUsers, description: t("lineup-probable-desc"), }; case "none": default: return { title: t("lineup-info"), badge: t("lineup-pending"), badgeColor: "gray" as const, icon: LuClock, description: t("lineup-pending-desc"), }; } } export default function LineupsCard({ match, prediction }: LineupsCardProps) { const t = useTranslations("matches"); const cardBg = useColorModeValue("white", "gray.800"); const borderColor = useColorModeValue("gray.100", "gray.700"); const headerBg = useColorModeValue("gray.50", "whiteAlpha.50"); const infoBg = useColorModeValue("blue.50", "whiteAlpha.100"); const infoBorder = useColorModeValue("blue.200", "blue.800"); let homeLineups = match.lineups?.home?.filter((p) => p.isStarting) || []; let awayLineups = match.lineups?.away?.filter((p) => p.isStarting) || []; // Determine lineup source from prediction data quality const source = prediction?.data_quality?.lineup_source; const meta = getLineupSourceMeta(source, t); // Fallback: If no starting players are marked, but we have players, treat them as probable XI if ( homeLineups.length === 0 && match.lineups?.home && match.lineups.home.length > 0 ) { homeLineups = match.lineups.home.slice(0, 11); } if ( awayLineups.length === 0 && match.lineups?.away && match.lineups.away.length > 0 ) { awayLineups = match.lineups.away.slice(0, 11); } const hasLineups = homeLineups.length > 0 || awayLineups.length > 0; return ( {/* ── Header ────────────────────────────────── */} {meta.title} {meta.badge} {/* ── Info Banner ───────────────────────────── */} {source !== "confirmed_live" && ( {meta.description} )} {/* ── Lineups Grid ─────────────────────────── */} {hasLineups ? ( {/* Home Team Lineup */} {match.homeTeamName} Ev Sahibi {homeLineups.length > 0 ? ( {homeLineups.map((p, idx) => ( {p.shirtNumber && ( {p.shirtNumber} )} {p.player?.name || "Bilinmiyor"} {p.position && ( {p.position} )} ))} ) : ( {t("lineup-tbd")} {t("lineup-tbd-sub")} )} {/* Away Team Lineup */} {match.awayTeamName} Deplasman {awayLineups.length > 0 ? ( {awayLineups.map((p, idx) => ( {p.shirtNumber && ( {p.shirtNumber} )} {p.player?.name || "Bilinmiyor"} {p.position && ( {p.position} )} ))} ) : ( {t("lineup-tbd")} {t("lineup-tbd-sub")} )} ) : ( /* ── Empty State: No lineups at all ─────── */ {t("lineup-not-announced")} {t("lineup-not-announced-desc", { home: match.homeTeamName, away: match.awayTeamName, })} )} ); }