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
+80
View File
@@ -0,0 +1,80 @@
import { apiRequest } from "@/lib/api/api-service";
import { ApiResponse } from "@/types/api-response";
import {
CreateCouponDto,
SuggestCouponDto,
AnalyzeMatchDto,
CouponResponseDto,
CouponHistoryDto,
UserBettingStatsDto,
MatchAnalysisResultDto,
DailyBankoResponseDto,
SmartCouponResultDto,
} from "./types";
/**
* Coupons Service
* Backend: /api/coupon/*
*/
const analyzeMatch = (dto: AnalyzeMatchDto) => {
return apiRequest<ApiResponse<MatchAnalysisResultDto>>({
url: "/coupon/analyze",
client: "core",
method: "post",
data: dto,
});
};
const createCoupon = (dto: CreateCouponDto) => {
return apiRequest<ApiResponse<CouponResponseDto>>({
url: "/coupon",
client: "core",
method: "post",
data: dto,
});
};
const getDailyBanko = (matchIds: string[]) => {
return apiRequest<ApiResponse<DailyBankoResponseDto>>({
url: "/coupon/daily-banko",
client: "core",
method: "post",
data: { matchIds },
});
};
const getHistory = (limit: number) => {
return apiRequest<ApiResponse<CouponHistoryDto>>({
url: "/coupon/history",
client: "core",
method: "get",
params: { limit },
});
};
const getUserStats = () => {
return apiRequest<ApiResponse<UserBettingStatsDto>>({
url: "/coupon/my-stats",
client: "core",
method: "get",
});
};
const suggestCoupon = (dto: SuggestCouponDto) => {
return apiRequest<ApiResponse<SmartCouponResultDto>>({
url: "/coupon/suggest",
client: "core",
method: "post",
data: dto,
});
};
export const couponsService = {
analyzeMatch,
createCoupon,
getDailyBanko,
getHistory,
getUserStats,
suggestCoupon,
};
+108
View File
@@ -0,0 +1,108 @@
import type { CouponStrategy } from "@/lib/api/predictions/types";
// ========================
// Request DTOs
// ========================
export interface CreateCouponDto {
name?: string;
items: CouponItemDto[];
strategy?: CouponStrategy;
}
export interface CouponItemDto {
matchId: string;
matchName?: string;
market: string;
pick: string;
odd: number;
}
export interface SuggestCouponDto {
matchIds: string[];
strategy?: CouponStrategy;
maxMatches?: number;
minConfidence?: number;
}
export interface AnalyzeMatchDto {
matchIds: string[];
}
// ========================
// Response DTOs
// ========================
export interface CouponResponseDto {
id: string;
name?: string;
items: CouponItemDto[];
strategy?: CouponStrategy;
totalOdd: number;
createdAt: string;
status?: string;
[key: string]: unknown;
}
export interface CouponHistoryDto {
coupons: CouponResponseDto[];
total: number;
}
export interface UserBettingStatsDto {
totalCoupons: number;
totalBets: number;
wonBets: number;
lostBets: number;
pendingBets: number;
winRate: number;
[key: string]: unknown;
}
export interface MatchAnalysisResultDto {
matchId: string;
analysis: Record<string, unknown>;
predictions: Record<string, unknown>;
[key: string]: unknown;
}
export interface DailyBankoResponseDto {
picks: Array<{
matchId: string;
matchName: string;
pick: string;
confidence: number;
odd: number;
[key: string]: unknown;
}>;
totalOdd: number;
[key: string]: unknown;
}
export interface SuggestedCouponBetDto {
match_id: string;
match_name: string;
market: string;
pick: string;
probability: number;
confidence: number;
odds: number;
risk_level: string;
data_quality: string;
}
export interface SuggestedCouponRejectedMatchDto {
match_id: string;
reason: string;
threshold?: number;
}
export interface SmartCouponResultDto {
strategy: CouponStrategy;
generated_at: string;
match_count: number;
bets: SuggestedCouponBetDto[];
total_odds: number;
expected_win_rate: number;
rejected_matches: SuggestedCouponRejectedMatchDto[];
}
+57
View File
@@ -0,0 +1,57 @@
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { couponsService } from "./service";
import type {
CreateCouponDto,
SuggestCouponDto,
AnalyzeMatchDto,
} from "./types";
export const CouponsQueryKeys = {
all: ["coupons"] as const,
history: (limit?: number) =>
[...CouponsQueryKeys.all, "history", limit] as const,
stats: () => [...CouponsQueryKeys.all, "stats"] as const,
};
export const useAnalyzeMatch = () => {
return useMutation({
mutationFn: (dto: AnalyzeMatchDto) => couponsService.analyzeMatch(dto),
});
};
export const useCreateCoupon = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (dto: CreateCouponDto) => couponsService.createCoupon(dto),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: CouponsQueryKeys.all });
},
});
};
export const useDailyBanko = () => {
return useMutation({
mutationFn: (matchIds: string[]) => couponsService.getDailyBanko(matchIds),
});
};
export const useCouponHistory = (limit: number = 20) => {
return useQuery({
queryKey: CouponsQueryKeys.history(limit),
queryFn: () => couponsService.getHistory(limit),
});
};
export const useUserBettingStats = () => {
return useQuery({
queryKey: CouponsQueryKeys.stats(),
queryFn: () => couponsService.getUserStats(),
});
};
export const useSuggestCoupon = () => {
return useMutation({
mutationFn: (dto: SuggestCouponDto) => couponsService.suggestCoupon(dto),
});
};