gg
Deploy Iddaai Frontend / build-and-deploy (push) Successful in 2m38s

This commit is contained in:
2026-05-20 21:59:52 +03:00
parent fc369db123
commit 5df5145104
6 changed files with 787 additions and 2 deletions
+91
View File
@@ -3,8 +3,13 @@ import { ApiResponse, PaginatedData } from "@/types/api-response";
import type {
AdminPaginationParams,
AdminUserDto,
AddLeagueTierDto,
AnalyticsOverviewDto,
LeagueTierDto,
LeagueTierStatsDto,
RetrainStatusDto,
SettingDto,
UpdateLeagueTierDto,
UpdateSettingDto,
UpdateUserRoleDto,
UpdateUserSubscriptionDto,
@@ -121,6 +126,82 @@ const toggleUserActive = (id: string) => {
});
};
// League Tiers
const getLeagueTiers = (active?: boolean) => {
return apiRequest<ApiResponse<LeagueTierDto[]>>({
url: "/admin/league-tiers",
client: "admin",
method: "get",
params: active !== undefined ? { active: String(active) } : undefined,
});
};
const getLeagueTierStats = () => {
return apiRequest<ApiResponse<LeagueTierStatsDto>>({
url: "/admin/league-tiers/stats",
client: "admin",
method: "get",
});
};
const addLeagueTier = (dto: AddLeagueTierDto) => {
return apiRequest<ApiResponse<LeagueTierDto>>({
url: "/admin/league-tiers",
client: "admin",
method: "post",
data: dto,
});
};
const updateLeagueTier = (leagueId: string, dto: UpdateLeagueTierDto) => {
return apiRequest<ApiResponse<LeagueTierDto>>({
url: `/admin/league-tiers/${leagueId}/tier`,
client: "admin",
method: "put",
data: dto,
});
};
const deactivateLeagueTier = (leagueId: string) => {
return apiRequest<ApiResponse<LeagueTierDto>>({
url: `/admin/league-tiers/${leagueId}/deactivate`,
client: "admin",
method: "put",
});
};
const deleteLeagueTier = (leagueId: string) => {
return apiRequest<ApiResponse<null>>({
url: `/admin/league-tiers/${leagueId}`,
client: "admin",
method: "delete",
});
};
const syncLeagueTiers = () => {
return apiRequest<ApiResponse<{ count: number; path: string }>>({
url: "/admin/league-tiers/sync",
client: "admin",
method: "post",
});
};
const triggerRetrain = () => {
return apiRequest<ApiResponse<{ status: string; message: string }>>({
url: "/admin/league-tiers/retrain",
client: "admin",
method: "post",
});
};
const getRetrainStatus = () => {
return apiRequest<ApiResponse<RetrainStatusDto>>({
url: "/admin/league-tiers/retrain/status",
client: "admin",
method: "get",
});
};
export const adminService = {
getAnalyticsOverview,
getAllSettings,
@@ -134,4 +215,14 @@ export const adminService = {
updateUserRole,
updateUserSubscription,
toggleUserActive,
// League Tiers
getLeagueTiers,
getLeagueTierStats,
addLeagueTier,
updateLeagueTier,
deactivateLeagueTier,
deleteLeagueTier,
syncLeagueTiers,
triggerRetrain,
getRetrainStatus,
};
+49
View File
@@ -66,6 +66,55 @@ export interface UpdateUserSubscriptionDto {
expiresAt?: string | null;
}
// ========================
// League Tiers
// ========================
export interface LeagueTierDto {
id: number;
leagueId: string;
tier: number;
isActive: boolean;
addedBy?: string;
notes?: string;
createdAt: string;
updatedAt: string;
league: {
id: string;
name: string;
country?: {
id: string;
name: string;
code?: string;
};
};
}
export interface LeagueTierStatsDto {
tiers: { tier: number; count: number }[];
totalActiveLeagues: number;
totalQualifiedMatches: number;
}
export interface AddLeagueTierDto {
leagueId: string;
tier?: number;
notes?: string;
addedBy?: string;
}
export interface UpdateLeagueTierDto {
tier: number;
}
export interface RetrainStatusDto {
running: boolean;
last_started?: string;
last_completed?: string;
last_status?: string;
last_error?: string;
}
// ========================
// Analytics
// ========================
+105
View File
@@ -1,7 +1,9 @@
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { adminService } from "./service";
import type {
AddLeagueTierDto,
AdminPaginationParams,
UpdateLeagueTierDto,
UpdateSettingDto,
UpdateUserRoleDto,
UpdateUserSubscriptionDto,
@@ -17,6 +19,8 @@ export const AdminQueryKeys = {
users: (params?: AdminPaginationParams) =>
[...AdminQueryKeys.usersList(), params] as const,
user: (id: string) => [...AdminQueryKeys.all, "user", id] as const,
leagueTiers: () => [...AdminQueryKeys.all, "leagueTiers"] as const,
leagueTierStats: () => [...AdminQueryKeys.all, "leagueTierStats"] as const,
};
// Analytics
@@ -144,3 +148,104 @@ export const useToggleUserActive = () => {
},
});
};
// ========================
// League Tiers
// ========================
export const useLeagueTiers = (enabled = true) => {
return useQuery({
queryKey: AdminQueryKeys.leagueTiers(),
queryFn: () => adminService.getLeagueTiers(),
enabled,
});
};
export const useLeagueTierStats = (enabled = true) => {
return useQuery({
queryKey: AdminQueryKeys.leagueTierStats(),
queryFn: () => adminService.getLeagueTierStats(),
enabled,
});
};
export const useAddLeagueTier = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (dto: AddLeagueTierDto) => adminService.addLeagueTier(dto),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.leagueTiers() });
queryClient.invalidateQueries({
queryKey: AdminQueryKeys.leagueTierStats(),
});
},
});
};
export const useUpdateLeagueTier = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({
leagueId,
dto,
}: {
leagueId: string;
dto: UpdateLeagueTierDto;
}) => adminService.updateLeagueTier(leagueId, dto),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.leagueTiers() });
queryClient.invalidateQueries({
queryKey: AdminQueryKeys.leagueTierStats(),
});
},
});
};
export const useDeactivateLeagueTier = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (leagueId: string) =>
adminService.deactivateLeagueTier(leagueId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.leagueTiers() });
queryClient.invalidateQueries({
queryKey: AdminQueryKeys.leagueTierStats(),
});
},
});
};
export const useDeleteLeagueTier = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (leagueId: string) =>
adminService.deleteLeagueTier(leagueId),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.leagueTiers() });
queryClient.invalidateQueries({
queryKey: AdminQueryKeys.leagueTierStats(),
});
},
});
};
export const useSyncLeagueTiers = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: () => adminService.syncLeagueTiers(),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: AdminQueryKeys.leagueTiers() });
},
});
};
export const useTriggerRetrain = () => {
return useMutation({
mutationFn: () => adminService.triggerRetrain(),
});
};