Compare commits
2 Commits
c450661cf8
...
96b9653a7e
| Author | SHA1 | Date | |
|---|---|---|---|
| 96b9653a7e | |||
| 30592394ef |
@@ -19,7 +19,7 @@ import { yupResolver } from "@hookform/resolvers/yup";
|
|||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import { signIn } from "next-auth/react";
|
import { signIn } from "next-auth/react";
|
||||||
import { toaster } from "@/components/ui/feedback/toaster";
|
import { toaster } from "@/components/ui/feedback/toaster";
|
||||||
import { useState } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { MdMail } from "react-icons/md";
|
import { MdMail } from "react-icons/md";
|
||||||
import { BiUser } from "react-icons/bi";
|
import { BiUser } from "react-icons/bi";
|
||||||
import { authService } from "@/lib/api/auth/service";
|
import { authService } from "@/lib/api/auth/service";
|
||||||
@@ -45,15 +45,23 @@ type RegisterForm = yup.InferType<typeof registerSchema>;
|
|||||||
interface LoginModalProps {
|
interface LoginModalProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onOpenChange: (open: boolean) => void;
|
onOpenChange: (open: boolean) => void;
|
||||||
|
initialMode?: "login" | "register";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ────────────────────────── Component ────────────────────────── */
|
/* ────────────────────────── Component ────────────────────────── */
|
||||||
|
|
||||||
export function LoginModal({ open, onOpenChange }: LoginModalProps) {
|
export function LoginModal({ open, onOpenChange, initialMode = "login" }: LoginModalProps) {
|
||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const [mode, setMode] = useState<"login" | "register">("login");
|
const [mode, setMode] = useState<"login" | "register">(initialMode);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
|
// Update mode when modal opens
|
||||||
|
useEffect(() => {
|
||||||
|
if (open) {
|
||||||
|
setMode(initialMode);
|
||||||
|
}
|
||||||
|
}, [open, initialMode]);
|
||||||
|
|
||||||
/* ── Login form ── */
|
/* ── Login form ── */
|
||||||
const loginForm = useForm<LoginForm>({
|
const loginForm = useForm<LoginForm>({
|
||||||
resolver: yupResolver(loginSchema),
|
resolver: yupResolver(loginSchema),
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ export default function Header() {
|
|||||||
const t = useTranslations();
|
const t = useTranslations();
|
||||||
const [isSticky, setIsSticky] = useState(false);
|
const [isSticky, setIsSticky] = useState(false);
|
||||||
const [loginModalOpen, setLoginModalOpen] = useState(false);
|
const [loginModalOpen, setLoginModalOpen] = useState(false);
|
||||||
|
const [loginModalMode, setLoginModalMode] = useState<"login" | "register">("login");
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { data: session, status } = useSession();
|
const { data: session, status } = useSession();
|
||||||
|
|
||||||
@@ -63,10 +64,15 @@ export default function Header() {
|
|||||||
const handleLogout = async () => {
|
const handleLogout = async () => {
|
||||||
await signOut({ redirect: false });
|
await signOut({ redirect: false });
|
||||||
if (authConfig.isAuthRequired) {
|
if (authConfig.isAuthRequired) {
|
||||||
router.replace("/signin");
|
router.replace("/home");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openAuthModal = (mode: "login" | "register") => {
|
||||||
|
setLoginModalMode(mode);
|
||||||
|
setLoginModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
// Desktop auth section
|
// Desktop auth section
|
||||||
const renderAuthSection = () => {
|
const renderAuthSection = () => {
|
||||||
if (isLoading) return <Skeleton boxSize="10" rounded="full" />;
|
if (isLoading) return <Skeleton boxSize="10" rounded="full" />;
|
||||||
@@ -97,16 +103,27 @@ export default function Header() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<HStack gap={2}>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
colorPalette="gray"
|
||||||
|
size="sm"
|
||||||
|
borderRadius="full"
|
||||||
|
onClick={() => openAuthModal("register")}
|
||||||
|
>
|
||||||
|
{t("auth.sign-up")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
colorPalette="primary"
|
colorPalette="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
borderRadius="full"
|
borderRadius="full"
|
||||||
onClick={() => setLoginModalOpen(true)}
|
onClick={() => openAuthModal("login")}
|
||||||
>
|
>
|
||||||
<LuLogIn />
|
<LuLogIn />
|
||||||
{t("auth.sign-in")}
|
{t("auth.sign-in")}
|
||||||
</Button>
|
</Button>
|
||||||
|
</HStack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -150,17 +167,29 @@ export default function Header() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<VStack gap={2} w="full">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
colorPalette="gray"
|
||||||
|
size="sm"
|
||||||
|
width="full"
|
||||||
|
borderRadius="full"
|
||||||
|
onClick={() => openAuthModal("register")}
|
||||||
|
>
|
||||||
|
{t("auth.sign-up")}
|
||||||
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="solid"
|
variant="solid"
|
||||||
colorPalette="primary"
|
colorPalette="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
width="full"
|
width="full"
|
||||||
borderRadius="full"
|
borderRadius="full"
|
||||||
onClick={() => setLoginModalOpen(true)}
|
onClick={() => openAuthModal("login")}
|
||||||
>
|
>
|
||||||
<LuLogIn />
|
<LuLogIn />
|
||||||
{t("auth.sign-in")}
|
{t("auth.sign-in")}
|
||||||
</Button>
|
</Button>
|
||||||
|
</VStack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -296,7 +325,7 @@ export default function Header() {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
{/* Login Modal */}
|
{/* Login Modal */}
|
||||||
<LoginModal open={loginModalOpen} onOpenChange={setLoginModalOpen} />
|
<LoginModal open={loginModalOpen} onOpenChange={setLoginModalOpen} initialMode={loginModalMode} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,143 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Card,
|
||||||
|
Flex,
|
||||||
|
HStack,
|
||||||
|
Text,
|
||||||
|
VStack,
|
||||||
|
Badge,
|
||||||
|
SimpleGrid,
|
||||||
|
Icon,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
|
import { useColorModeValue } from "@/components/ui/color-mode";
|
||||||
|
import { LuUsers, LuUser } 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function LineupsCard({ match, prediction }: LineupsCardProps) {
|
||||||
|
const cardBg = useColorModeValue("white", "gray.800");
|
||||||
|
const borderColor = useColorModeValue("gray.100", "gray.700");
|
||||||
|
const headerBg = useColorModeValue("gray.50", "whiteAlpha.50");
|
||||||
|
|
||||||
|
const homeLineups = match.lineups?.home?.filter((p) => p.isStarting) || [];
|
||||||
|
const awayLineups = match.lineups?.away?.filter((p) => p.isStarting) || [];
|
||||||
|
|
||||||
|
if (homeLineups.length === 0 && awayLineups.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine if it's confirmed or probable
|
||||||
|
const source = prediction?.data_quality?.lineup_source;
|
||||||
|
const isConfirmed = source === "confirmed_live";
|
||||||
|
const title = isConfirmed ? "İlk 11" : "Muhtemel Kadro";
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card.Root bg={cardBg} borderColor={borderColor} borderRadius="xl" mb={6}>
|
||||||
|
<Card.Body>
|
||||||
|
<Flex justify="space-between" align="center" mb={4}>
|
||||||
|
<HStack gap={2}>
|
||||||
|
<Icon as={LuUsers} boxSize={5} color="fg.muted" />
|
||||||
|
<Text fontSize="lg" fontWeight="semibold">
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
|
</HStack>
|
||||||
|
<Badge
|
||||||
|
colorPalette={isConfirmed ? "green" : "orange"}
|
||||||
|
variant="subtle"
|
||||||
|
>
|
||||||
|
{isConfirmed ? "Onaylı" : "Muhtemel"}
|
||||||
|
</Badge>
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<SimpleGrid columns={{ base: 1, md: 2 }} gap={6}>
|
||||||
|
{/* Home Team Lineup */}
|
||||||
|
<Box>
|
||||||
|
<Flex
|
||||||
|
bg={headerBg}
|
||||||
|
p={3}
|
||||||
|
borderRadius="md"
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
mb={3}
|
||||||
|
>
|
||||||
|
<Text fontWeight="bold">{match.homeTeamName}</Text>
|
||||||
|
</Flex>
|
||||||
|
<VStack align="stretch" gap={2}>
|
||||||
|
{homeLineups.map((p, idx) => (
|
||||||
|
<HStack
|
||||||
|
key={p.player?.id || idx}
|
||||||
|
p={2}
|
||||||
|
borderWidth="1px"
|
||||||
|
borderColor={borderColor}
|
||||||
|
borderRadius="md"
|
||||||
|
>
|
||||||
|
<Icon as={LuUser} color="fg.muted" />
|
||||||
|
{p.shirtNumber && (
|
||||||
|
<Text fontSize="xs" fontWeight="bold" w="20px">
|
||||||
|
{p.shirtNumber}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
<Text fontSize="sm" fontWeight="medium">
|
||||||
|
{p.player?.name || "Bilinmiyor"}
|
||||||
|
</Text>
|
||||||
|
{p.position && (
|
||||||
|
<Badge ml="auto" size="sm" variant="surface">
|
||||||
|
{p.position}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</HStack>
|
||||||
|
))}
|
||||||
|
</VStack>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* Away Team Lineup */}
|
||||||
|
<Box>
|
||||||
|
<Flex
|
||||||
|
bg={headerBg}
|
||||||
|
p={3}
|
||||||
|
borderRadius="md"
|
||||||
|
align="center"
|
||||||
|
justify="center"
|
||||||
|
mb={3}
|
||||||
|
>
|
||||||
|
<Text fontWeight="bold">{match.awayTeamName}</Text>
|
||||||
|
</Flex>
|
||||||
|
<VStack align="stretch" gap={2}>
|
||||||
|
{awayLineups.map((p, idx) => (
|
||||||
|
<HStack
|
||||||
|
key={p.player?.id || idx}
|
||||||
|
p={2}
|
||||||
|
borderWidth="1px"
|
||||||
|
borderColor={borderColor}
|
||||||
|
borderRadius="md"
|
||||||
|
>
|
||||||
|
<Icon as={LuUser} color="fg.muted" />
|
||||||
|
{p.shirtNumber && (
|
||||||
|
<Text fontSize="xs" fontWeight="bold" w="20px">
|
||||||
|
{p.shirtNumber}
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
<Text fontSize="sm" fontWeight="medium">
|
||||||
|
{p.player?.name || "Bilinmiyor"}
|
||||||
|
</Text>
|
||||||
|
{p.position && (
|
||||||
|
<Badge ml="auto" size="sm" variant="surface">
|
||||||
|
{p.position}
|
||||||
|
</Badge>
|
||||||
|
)}
|
||||||
|
</HStack>
|
||||||
|
))}
|
||||||
|
</VStack>
|
||||||
|
</Box>
|
||||||
|
</SimpleGrid>
|
||||||
|
</Card.Body>
|
||||||
|
</Card.Root>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ import { useMatchDetails } from "@/lib/api/matches/use-hooks";
|
|||||||
import { usePrediction } from "@/lib/api/predictions/use-hooks";
|
import { usePrediction } from "@/lib/api/predictions/use-hooks";
|
||||||
import PredictionCard from "@/components/matches/prediction-card";
|
import PredictionCard from "@/components/matches/prediction-card";
|
||||||
import OddsCard from "@/components/matches/odds-card";
|
import OddsCard from "@/components/matches/odds-card";
|
||||||
|
import LineupsCard from "@/components/matches/lineups-card";
|
||||||
import { LuArrowLeft, LuRefreshCw } from "react-icons/lu";
|
import { LuArrowLeft, LuRefreshCw } from "react-icons/lu";
|
||||||
|
|
||||||
export default function MatchDetailContent() {
|
export default function MatchDetailContent() {
|
||||||
@@ -237,6 +238,9 @@ export default function MatchDetailContent() {
|
|||||||
</Card.Body>
|
</Card.Body>
|
||||||
</Card.Root>
|
</Card.Root>
|
||||||
|
|
||||||
|
{/* Lineups Section */}
|
||||||
|
<LineupsCard match={match} prediction={prediction} />
|
||||||
|
|
||||||
{/* Prediction Section */}
|
{/* Prediction Section */}
|
||||||
<Box>
|
<Box>
|
||||||
<Flex justify="space-between" align="center" mb={4}>
|
<Flex justify="space-between" align="center" mb={4}>
|
||||||
|
|||||||
@@ -57,11 +57,6 @@ function getLeagueLabel(match: MatchResponseDto): string {
|
|||||||
return String(match.leagueName || match.league?.name || "");
|
return String(match.leagueName || match.league?.name || "");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Football season logic: Aug–Jun
|
|
||||||
* If month >= August (8) → season starts this year: "YYYY-(YYYY+1)"
|
|
||||||
* If month < August → season started last year: "(YYYY-1)-YYYY"
|
|
||||||
*/
|
|
||||||
function getSeasonFromTimestamp(timestampMs: number): string {
|
function getSeasonFromTimestamp(timestampMs: number): string {
|
||||||
const date = new Date(timestampMs);
|
const date = new Date(timestampMs);
|
||||||
const year = date.getFullYear();
|
const year = date.getFullYear();
|
||||||
@@ -73,28 +68,12 @@ function getSeasonFromTimestamp(timestampMs: number): string {
|
|||||||
return `${year - 1}-${year}`;
|
return `${year - 1}-${year}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
const SEASONS = (() => {
|
||||||
* Group matches by season string, returning a Map ordered by newest season first.
|
const currentYear = new Date().getFullYear();
|
||||||
*/
|
const currentMonth = new Date().getMonth() + 1;
|
||||||
function groupMatchesBySeason(matches: MatchResponseDto[]): Map<string, MatchResponseDto[]> {
|
const startYear = currentMonth >= 8 ? currentYear : currentYear - 1;
|
||||||
const groups = new Map<string, MatchResponseDto[]>();
|
return Array.from({ length: 5 }, (_, i) => `${startYear - i}-${startYear - i + 1}`);
|
||||||
|
})();
|
||||||
for (const match of matches) {
|
|
||||||
const ts = getMatchTimestamp(match);
|
|
||||||
const season = ts ? getSeasonFromTimestamp(ts) : "Bilinmiyor";
|
|
||||||
if (!groups.has(season)) {
|
|
||||||
groups.set(season, []);
|
|
||||||
}
|
|
||||||
groups.get(season)!.push(match);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by season key descending (newest first)
|
|
||||||
const sorted = new Map(
|
|
||||||
[...groups.entries()].sort((a, b) => b[0].localeCompare(a[0]))
|
|
||||||
);
|
|
||||||
|
|
||||||
return sorted;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ─────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────
|
||||||
// Main Component
|
// Main Component
|
||||||
@@ -107,13 +86,14 @@ export default function TeamDetailContent() {
|
|||||||
|
|
||||||
const teamId = params.id as string;
|
const teamId = params.id as string;
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
const [activeSeason, setActiveSeason] = useState<string>(SEASONS[0]);
|
||||||
|
|
||||||
const { data: teamData, isLoading: teamLoading } = useTeamById(teamId);
|
const { data: teamData, isLoading: teamLoading } = useTeamById(teamId);
|
||||||
const {
|
const {
|
||||||
data: matchesResponse,
|
data: matchesResponse,
|
||||||
isLoading: matchesLoading,
|
isLoading: matchesLoading,
|
||||||
isFetching: matchesFetching,
|
isFetching: matchesFetching,
|
||||||
} = useTeamMatches(teamId, { page: currentPage, limit: 20 });
|
} = useTeamMatches(teamId, { page: currentPage, limit: 20, season: activeSeason });
|
||||||
|
|
||||||
const cardBg = useColorModeValue("white", "gray.800");
|
const cardBg = useColorModeValue("white", "gray.800");
|
||||||
const borderColor = useColorModeValue("gray.100", "gray.700");
|
const borderColor = useColorModeValue("gray.100", "gray.700");
|
||||||
@@ -136,30 +116,16 @@ export default function TeamDetailContent() {
|
|||||||
[matches]
|
[matches]
|
||||||
);
|
);
|
||||||
|
|
||||||
// Group past matches by season
|
|
||||||
const seasonGroups = useMemo(
|
|
||||||
() => groupMatchesBySeason(pastMatches),
|
|
||||||
[pastMatches]
|
|
||||||
);
|
|
||||||
const seasonKeys = useMemo(() => [...seasonGroups.keys()], [seasonGroups]);
|
|
||||||
|
|
||||||
// Active season selection
|
|
||||||
const [activeSeason, setActiveSeason] = useState<string | null>(null);
|
|
||||||
const displaySeason = activeSeason ?? seasonKeys[0] ?? null;
|
|
||||||
const displayMatches = displaySeason ? seasonGroups.get(displaySeason) ?? [] : [];
|
|
||||||
|
|
||||||
// Pagination handlers
|
// Pagination handlers
|
||||||
const handleNextPage = useCallback(() => {
|
const handleNextPage = useCallback(() => {
|
||||||
if (currentPage < totalPages) {
|
if (currentPage < totalPages) {
|
||||||
setCurrentPage((p) => p + 1);
|
setCurrentPage((p) => p + 1);
|
||||||
setActiveSeason(null); // Reset season on page change
|
|
||||||
}
|
}
|
||||||
}, [currentPage, totalPages]);
|
}, [currentPage, totalPages]);
|
||||||
|
|
||||||
const handlePrevPage = useCallback(() => {
|
const handlePrevPage = useCallback(() => {
|
||||||
if (currentPage > 1) {
|
if (currentPage > 1) {
|
||||||
setCurrentPage((p) => p - 1);
|
setCurrentPage((p) => p - 1);
|
||||||
setActiveSeason(null);
|
|
||||||
}
|
}
|
||||||
}, [currentPage]);
|
}, [currentPage]);
|
||||||
|
|
||||||
@@ -296,11 +262,10 @@ export default function TeamDetailContent() {
|
|||||||
</Flex>
|
</Flex>
|
||||||
|
|
||||||
{/* Season Tabs */}
|
{/* Season Tabs */}
|
||||||
{seasonKeys.length > 0 && (
|
{SEASONS.length > 0 && (
|
||||||
<HStack gap={2} mb={4} flexWrap="wrap">
|
<HStack gap={2} mb={4} flexWrap="wrap">
|
||||||
{seasonKeys.map((season) => {
|
{SEASONS.map((season) => {
|
||||||
const isActive = season === displaySeason;
|
const isActive = season === activeSeason;
|
||||||
const count = seasonGroups.get(season)?.length ?? 0;
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
key={season}
|
key={season}
|
||||||
@@ -312,14 +277,17 @@ export default function TeamDetailContent() {
|
|||||||
fontWeight={isActive ? "700" : "500"}
|
fontWeight={isActive ? "700" : "500"}
|
||||||
fontSize="xs"
|
fontSize="xs"
|
||||||
px={4}
|
px={4}
|
||||||
onClick={() => setActiveSeason(season)}
|
onClick={() => {
|
||||||
|
setActiveSeason(season);
|
||||||
|
setCurrentPage(1);
|
||||||
|
}}
|
||||||
_hover={{
|
_hover={{
|
||||||
transform: "translateY(-1px)",
|
transform: "translateY(-1px)",
|
||||||
shadow: "sm",
|
shadow: "sm",
|
||||||
}}
|
}}
|
||||||
transition="all 0.2s"
|
transition="all 0.2s"
|
||||||
>
|
>
|
||||||
🏆 {season} ({count})
|
🏆 {season}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@@ -330,17 +298,13 @@ export default function TeamDetailContent() {
|
|||||||
<Flex justify="center" py={8}>
|
<Flex justify="center" py={8}>
|
||||||
<Spinner size="md" color="primary.500" />
|
<Spinner size="md" color="primary.500" />
|
||||||
</Flex>
|
</Flex>
|
||||||
) : displayMatches.length === 0 && pastMatches.length === 0 ? (
|
) : pastMatches.length === 0 ? (
|
||||||
<Text color="fg.muted" textAlign="center" py={8}>
|
<Text color="fg.muted" textAlign="center" py={8}>
|
||||||
Bu sayfada geçmiş maç bulunamadı
|
Bu sezonda geçmiş maç bulunamadı
|
||||||
</Text>
|
|
||||||
) : displayMatches.length === 0 ? (
|
|
||||||
<Text color="fg.muted" textAlign="center" py={8}>
|
|
||||||
Bu sezonda maç bulunamadı
|
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
<VStack gap={2} align="stretch">
|
<VStack gap={2} align="stretch">
|
||||||
{displayMatches.map((match: MatchResponseDto) => (
|
{pastMatches.map((match: MatchResponseDto) => (
|
||||||
<MatchRow
|
<MatchRow
|
||||||
key={match.id}
|
key={match.id}
|
||||||
match={match}
|
match={match}
|
||||||
@@ -390,7 +354,6 @@ export default function TeamDetailContent() {
|
|||||||
minW="36px"
|
minW="36px"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCurrentPage(pageNum);
|
setCurrentPage(pageNum);
|
||||||
setActiveSeason(null);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{pageNum}
|
{pageNum}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export interface HeadToHeadParams {
|
|||||||
export interface TeamMatchesParams {
|
export interface TeamMatchesParams {
|
||||||
page?: number;
|
page?: number;
|
||||||
limit?: number;
|
limit?: number;
|
||||||
|
season?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PaginatedMatchesResponse {
|
export interface PaginatedMatchesResponse {
|
||||||
|
|||||||
@@ -90,6 +90,22 @@ export interface MatchResponseDto {
|
|||||||
country?: { name: string; flag?: string };
|
country?: { name: string; flag?: string };
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
};
|
};
|
||||||
|
lineups?: {
|
||||||
|
home: Array<{
|
||||||
|
player?: { name: string; id: string; [key: string]: unknown };
|
||||||
|
position?: string | null;
|
||||||
|
shirtNumber?: number | null;
|
||||||
|
isStarting?: boolean;
|
||||||
|
[key: string]: unknown;
|
||||||
|
}>;
|
||||||
|
away: Array<{
|
||||||
|
player?: { name: string; id: string; [key: string]: unknown };
|
||||||
|
position?: string | null;
|
||||||
|
shirtNumber?: number | null;
|
||||||
|
isStarting?: boolean;
|
||||||
|
[key: string]: unknown;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
|
||||||
[key: string]: unknown;
|
[key: string]: unknown;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,10 +111,6 @@ export const authOptions: NextAuthOptions = {
|
|||||||
return session;
|
return session;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pages: {
|
|
||||||
signIn: "/signin",
|
|
||||||
error: "/signin",
|
|
||||||
},
|
|
||||||
session: { strategy: "jwt" },
|
session: { strategy: "jwt" },
|
||||||
secret: process.env.NEXTAUTH_SECRET,
|
secret: process.env.NEXTAUTH_SECRET,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user