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
+56
View File
@@ -0,0 +1,56 @@
import { apiRequest } from "@/lib/api/api-service";
import { ApiResponse, PaginatedData } from "@/types/api-response";
import {
MatchResponseDto,
MatchListParams,
MatchQueryDto,
ActiveLeagueDto,
LeagueWithMatchesDto,
} from "./types";
/**
* Matches Service
* Backend: /api/matches/*
*/
const listMatches = (params?: MatchListParams) => {
return apiRequest<ApiResponse<PaginatedData<MatchResponseDto>>>({
url: "/matches",
client: "core",
method: "get",
params,
});
};
const getMatchDetails = (id: string) => {
return apiRequest<ApiResponse<MatchResponseDto>>({
url: `/matches/${id}`,
client: "core",
method: "get",
});
};
const queryMatches = (queryDto: MatchQueryDto) => {
return apiRequest<ApiResponse<LeagueWithMatchesDto[]>>({
url: "/matches/query",
client: "core",
method: "post",
data: queryDto,
});
};
const getActiveLeagues = (sport?: string) => {
return apiRequest<ApiResponse<ActiveLeagueDto[]>>({
url: "/matches/leagues/active",
client: "core",
method: "get",
params: sport ? { sport } : undefined,
});
};
export const matchesService = {
listMatches,
getMatchDetails,
queryMatches,
getActiveLeagues,
};
+118
View File
@@ -0,0 +1,118 @@
// ========================
// Enums & Constants
// ========================
export type SportType = "football" | "basketball";
export type MatchStatus =
| "LIVE"
| "Finished"
| "Not Started"
| "UPCOMING"
| "NOT_STARTED"
| string;
// ========================
// Query DTOs
// ========================
export interface TeamFilterDto {
name?: string;
id?: string;
}
export interface OddFilterDto {
market: string;
minOdd?: number;
maxOdd?: number;
}
export interface DateRangeDto {
from: string;
to: string;
}
export interface MatchQueryDto {
sport: SportType;
limit?: number;
leagueId?: string;
status?: MatchStatus;
date?: string; // YYYY-MM-DD
team?: TeamFilterDto;
odds?: OddFilterDto[];
dateRange?: DateRangeDto;
}
export interface MatchListParams {
page?: number;
limit?: number;
sport?: SportType;
}
// ========================
// Response DTOs
// ========================
export interface MatchResponseDto {
id: string;
matchName: string;
matchSlug?: string;
mstUtc: number | string; // Timestamp
date?: string | Date;
status: MatchStatus;
state?: string;
// Scores
scoreHome?: number;
scoreAway?: number;
score?: { home: number; away: number };
htScoreHome?: number;
htScoreAway?: number;
// Teams
homeTeamName: string;
homeTeamLogo?: string;
awayTeamName: string;
awayTeamLogo?: string;
// League & Country
leagueName?: string;
countryName?: string;
// Odds (dynamic key-value)
odds?: Record<string, Record<string, { odd: string }>>;
// Nested Objects (from Backend include)
homeTeam?: { name: string; logo?: string; [key: string]: unknown };
awayTeam?: { name: string; logo?: string; [key: string]: unknown };
league?: {
name: string;
country?: { name: string; flag?: string };
[key: string]: unknown;
};
[key: string]: unknown;
}
export interface ActiveLeagueDto {
id: string;
name: string;
code?: string;
countryName?: string;
countryFlag?: string;
matchCount: number;
liveCount: number;
}
export interface LeagueWithMatchesDto {
id: string;
name: string;
code?: string;
country: {
id: string;
name: string;
flagUrl?: string; // Backend uses flagUrl
};
sport: SportType;
matches: MatchResponseDto[];
}
+41
View File
@@ -0,0 +1,41 @@
import { useQuery, useMutation } from "@tanstack/react-query";
import { matchesService } from "./service";
import type { MatchListParams, MatchQueryDto } from "./types";
export const MatchesQueryKeys = {
all: ["matches"] as const,
list: (params?: MatchListParams) =>
[...MatchesQueryKeys.all, "list", params] as const,
detail: (id: string) => [...MatchesQueryKeys.all, "detail", id] as const,
activeLeagues: (sport?: string) =>
[...MatchesQueryKeys.all, "activeLeagues", sport] as const,
};
export const useListMatches = (params?: MatchListParams) => {
return useQuery({
queryKey: MatchesQueryKeys.list(params),
queryFn: () => matchesService.listMatches(params),
});
};
export const useMatchDetails = (id: string) => {
return useQuery({
queryKey: MatchesQueryKeys.detail(id),
queryFn: () => matchesService.getMatchDetails(id),
enabled: !!id,
});
};
export const useQueryMatches = () => {
return useMutation({
mutationFn: (queryDto: MatchQueryDto) =>
matchesService.queryMatches(queryDto),
});
};
export const useActiveLeagues = (sport?: string) => {
return useQuery({
queryKey: MatchesQueryKeys.activeLeagues(sport),
queryFn: () => matchesService.getActiveLeagues(sport),
});
};