feat: AI commentary skeleton loading - separate async endpoint
Deploy Iddaai Frontend / build-and-deploy (push) Successful in 2m20s
Deploy Iddaai Frontend / build-and-deploy (push) Successful in 2m20s
This commit is contained in:
+15
-20
@@ -1,29 +1,24 @@
|
|||||||
# ==========================================
|
# ==========================================
|
||||||
# IDDAAI - DEVELOPMENT ENVIRONMENT VARIABLES
|
# IDDAAI-FE — DEVELOPMENT ENVIRONMENT VARIABLES
|
||||||
# ==========================================
|
# ==========================================
|
||||||
|
# Bu dosya lokal geliştirme için kullanılır.
|
||||||
|
# Prod değerleri: .gitea/workflows/deploy.yml → Gitea Secrets
|
||||||
|
|
||||||
# --- FRONTEND (iddaai-fe) ---
|
# --- Next.js App ---
|
||||||
# Next.js uygulaması için gerekli ayarlar
|
|
||||||
NEXT_PUBLIC_API_URL=http://localhost:3005/api
|
NEXT_PUBLIC_API_URL=http://localhost:3005/api
|
||||||
|
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
||||||
PORT=3000
|
PORT=3000
|
||||||
HOSTNAME="0.0.0.0"
|
HOSTNAME="0.0.0.0"
|
||||||
|
|
||||||
|
# --- NextAuth ---
|
||||||
|
NEXTAUTH_URL=http://localhost:3000
|
||||||
|
NEXTAUTH_SECRET='fFw34R134jRof1H2jofh2!32hU3gfjA1'
|
||||||
|
|
||||||
# --- BACKEND (iddaai-be) ---
|
# --- Auth Config ---
|
||||||
# NestJS uygulaması için gerekli ayarlar
|
NEXT_PUBLIC_AUTH_REQUIRED=false
|
||||||
NODE_ENV=development
|
NEXT_PUBLIC_ENABLE_MOCK_MODE=false
|
||||||
|
|
||||||
# Database (Localde PostgreSQL çalışıyorsa)
|
# --- Paddle (Sandbox) ---
|
||||||
DATABASE_URL="postgresql://iddaai_user:IddaA1_S4crET!@localhost:5432/iddaai_db?schema=public"
|
NEXT_PUBLIC_PADDLE_CLIENT_TOKEN='test_...'
|
||||||
|
NEXT_PUBLIC_PADDLE_ENVIRONMENT='sandbox'
|
||||||
# Redis
|
NEXT_PUBLIC_PADDLE_SELLER_ID='...'
|
||||||
REDIS_HOST="localhost"
|
|
||||||
REDIS_PORT="6379"
|
|
||||||
REDIS_PASSWORD="IddaA1_Redis_Pass!"
|
|
||||||
|
|
||||||
# AI Engine
|
|
||||||
AI_ENGINE_URL="http://localhost:8000"
|
|
||||||
|
|
||||||
# JWT Config
|
|
||||||
JWT_SECRET="b7V8jM2wP1L5mQxs2RdfFkAsLpI2oG!w"
|
|
||||||
JWT_ACCESS_EXPIRATION="1d"
|
|
||||||
|
|||||||
+138
@@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
> iddaai-fe@0.0.1 lint
|
||||||
|
> eslint
|
||||||
|
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/admin/edit-user-modal.tsx
|
||||||
|
36:9 warning 't' is assigned a value but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
37:9 warning 'tCommon' is assigned a value but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
50:7 error Error: Calling setState synchronously within an effect can trigger cascading renders
|
||||||
|
|
||||||
|
Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:
|
||||||
|
* Update external systems with the latest state from React.
|
||||||
|
* Subscribe for updates from some external system, calling setState in a callback function when external state changes.
|
||||||
|
|
||||||
|
Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect).
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/admin/edit-user-modal.tsx:50:7
|
||||||
|
48 | useEffect(() => {
|
||||||
|
49 | if (user) {
|
||||||
|
> 50 | setRole(user.role || "user");
|
||||||
|
| ^^^^^^^ Avoid calling setState() directly within an effect
|
||||||
|
51 | setPlan(user.subscriptionStatus || "free");
|
||||||
|
52 | setIsActive(user.isActive);
|
||||||
|
53 | if (user.subscriptionExpiresAt) { react-hooks/set-state-in-effect
|
||||||
|
57:17 warning 'e' is defined but never used @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/analysis/analysis-content.tsx
|
||||||
|
14:3 warning 'SimpleGrid' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
31:9 warning 'tCommon' is assigned a value but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/coupons/coupon-builder-content.tsx
|
||||||
|
367:6 warning React Hook React.useEffect has a missing dependency: 'upcomingQuery'. Either include it or remove the dependency array react-hooks/exhaustive-deps
|
||||||
|
381:6 warning React Hook React.useEffect has a missing dependency: 'finishedQuery'. Either include it or remove the dependency array react-hooks/exhaustive-deps
|
||||||
|
403:9 warning The 'leagueGroups' logical expression could make the dependencies of useMemo Hook (at line 407) change on every render. To fix this, wrap the initialization of 'leagueGroups' in its own useMemo() Hook react-hooks/exhaustive-deps
|
||||||
|
404:9 warning The 'finishedLeagueGroups' logical expression could make the dependencies of useMemo Hook (at line 411) change on every render. To fix this, wrap the initialization of 'finishedLeagueGroups' in its own useMemo() Hook react-hooks/exhaustive-deps
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/dashboard/dashboard-content.tsx
|
||||||
|
21:3 warning 'ScrollSlideUp' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
127:3 warning 'confidence' is defined but never used. Allowed unused args must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
188:39 warning 'statsLoading' is assigned a value but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/h2h/h2h-content.tsx
|
||||||
|
21:24 warning 'HeadToHeadDto' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
24:20 warning 'useEffect' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
84:17 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/home/home-content.tsx
|
||||||
|
13:3 warning 'Icon' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
27:3 warning 'springs' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/layout/header/header.tsx
|
||||||
|
47:8 warning 'Image' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
293:13 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/leagues/league-detail-content.tsx
|
||||||
|
5:3 warning 'Flex' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
29:9 warning 't' is assigned a value but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/leagues/leagues-content.tsx
|
||||||
|
239:23 error React Hook "useColorModeValue" is called conditionally. React Hooks must be called in the exact same order in every component render react-hooks/rules-of-hooks
|
||||||
|
345:39 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
|
||||||
|
414:27 error React Hook "useColorModeValue" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks
|
||||||
|
715:23 error `"` can be escaped with `"`, `“`, `"`, `”` react/no-unescaped-entities
|
||||||
|
715:44 error `"` can be escaped with `"`, `“`, `"`, `”` react/no-unescaped-entities
|
||||||
|
762:31 warning Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/matches/match-detail-content.tsx
|
||||||
|
15:3 warning 'Grid' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
33:3 warning 'LuShield' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
34:3 warning 'LuFlag' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/matches/match-list.tsx
|
||||||
|
9:3 warning 'ScrollSlideUp' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/matches/matches-content.tsx
|
||||||
|
38:41 warning 'matchesLoading' is assigned a value but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/matches/odds-card.tsx
|
||||||
|
7:3 warning 'Badge' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/matches/v28-odds-band-panel.tsx
|
||||||
|
374:15 error React Hook "useColorModeValue" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return? react-hooks/rules-of-hooks
|
||||||
|
565:15 error React Hook "useColorModeValue" is called conditionally. React Hooks must be called in the exact same order in every component render react-hooks/rules-of-hooks
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/motion/index.tsx
|
||||||
|
417:5 error Error: Calling setState synchronously within an effect can trigger cascading renders
|
||||||
|
|
||||||
|
Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:
|
||||||
|
* Update external systems with the latest state from React.
|
||||||
|
* Subscribe for updates from some external system, calling setState in a callback function when external state changes.
|
||||||
|
|
||||||
|
Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect).
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/motion/index.tsx:417:5
|
||||||
|
415 | delay: Math.random() * 3,
|
||||||
|
416 | }));
|
||||||
|
> 417 | setSparkles(newSparkles);
|
||||||
|
| ^^^^^^^^^^^ Avoid calling setState() directly within an effect
|
||||||
|
418 | }, [count]);
|
||||||
|
419 |
|
||||||
|
420 | if (sparkles.length === 0) { react-hooks/set-state-in-effect
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/spor-toto/spor-toto-content.tsx
|
||||||
|
18:37 warning 'StaggerItem' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
29:3 warning 'SporTotoPredictionResultDto' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
52:9 warning 'tCommon' is assigned a value but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
88:11 warning 'result' is assigned a value but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/teams/team-detail-content.tsx
|
||||||
|
26:3 warning 'LuChevronDown' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
81:10 warning 'getSeasonFromTimestamp' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
107:9 warning 't' is assigned a value but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
144:9 warning The 'matches' conditional could make the dependencies of useMemo Hook (at line 157) change on every render. To fix this, wrap the initialization of 'matches' in its own useMemo() Hook react-hooks/exhaustive-deps
|
||||||
|
144:9 warning The 'matches' conditional could make the dependencies of useMemo Hook (at line 161) change on every render. To fix this, wrap the initialization of 'matches' in its own useMemo() Hook react-hooks/exhaustive-deps
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/ui/top-loader.tsx
|
||||||
|
12:5 error Error: Calling setState synchronously within an effect can trigger cascading renders
|
||||||
|
|
||||||
|
Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:
|
||||||
|
* Update external systems with the latest state from React.
|
||||||
|
* Subscribe for updates from some external system, calling setState in a callback function when external state changes.
|
||||||
|
|
||||||
|
Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect).
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/components/ui/top-loader.tsx:12:5
|
||||||
|
10 |
|
||||||
|
11 | useEffect(() => {
|
||||||
|
> 12 | setMounted(true);
|
||||||
|
| ^^^^^^^^^^ Avoid calling setState() directly within an effect
|
||||||
|
13 | }, []);
|
||||||
|
14 |
|
||||||
|
15 | if (!mounted) return null; react-hooks/set-state-in-effect
|
||||||
|
|
||||||
|
/Users/piton/Documents/GitHub/iddaai/iddaai-fe/src/lib/api/leagues/service.ts
|
||||||
|
3:15 warning 'MatchResponseDto' is defined but never used. Allowed unused vars must match /^_/u @typescript-eslint/no-unused-vars
|
||||||
|
|
||||||
|
✖ 48 problems (9 errors, 39 warnings)
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ import { useState } from "react";
|
|||||||
import { useColorModeValue } from "@/components/ui/color-mode";
|
import { useColorModeValue } from "@/components/ui/color-mode";
|
||||||
import { SlideUp, FadeIn } from "@/components/motion";
|
import { SlideUp, FadeIn } from "@/components/motion";
|
||||||
import { useMatchDetails } from "@/lib/api/matches/use-hooks";
|
import { useMatchDetails } from "@/lib/api/matches/use-hooks";
|
||||||
import { usePrediction } from "@/lib/api/predictions/use-hooks";
|
import { usePrediction, useAiCommentary } from "@/lib/api/predictions/use-hooks";
|
||||||
import { useGetMe } from "@/lib/api/users/use-hooks";
|
import { useGetMe } from "@/lib/api/users/use-hooks";
|
||||||
import { useQueryClient } from "@tanstack/react-query";
|
import { useQueryClient } from "@tanstack/react-query";
|
||||||
import { UsersQueryKeys } from "@/lib/api/users/use-hooks";
|
import { UsersQueryKeys } from "@/lib/api/users/use-hooks";
|
||||||
@@ -32,6 +32,7 @@ import {
|
|||||||
LuRefreshCw,
|
LuRefreshCw,
|
||||||
LuUser,
|
LuUser,
|
||||||
LuSparkles,
|
LuSparkles,
|
||||||
|
LuBrain,
|
||||||
LuInfo,
|
LuInfo,
|
||||||
LuChevronDown,
|
LuChevronDown,
|
||||||
LuChevronUp,
|
LuChevronUp,
|
||||||
@@ -142,6 +143,11 @@ export default function MatchDetailContent() {
|
|||||||
isFetching: isPredFetching,
|
isFetching: isPredFetching,
|
||||||
} = usePrediction(matchId);
|
} = usePrediction(matchId);
|
||||||
|
|
||||||
|
const { data: commentaryData, isLoading: commentaryLoading } = useAiCommentary(
|
||||||
|
matchId,
|
||||||
|
!!predictionData?.data, // prediction yüklendikten sonra başlat
|
||||||
|
);
|
||||||
|
|
||||||
const [officialsOpen, setOfficialsOpen] = useState(false);
|
const [officialsOpen, setOfficialsOpen] = useState(false);
|
||||||
const [activeTab, setActiveTab] = useState<string>("all");
|
const [activeTab, setActiveTab] = useState<string>("all");
|
||||||
|
|
||||||
@@ -762,7 +768,33 @@ export default function MatchDetailContent() {
|
|||||||
<Skeleton h="80px" borderRadius="xl" />
|
<Skeleton h="80px" borderRadius="xl" />
|
||||||
</VStack>
|
</VStack>
|
||||||
) : prediction ? (
|
) : prediction ? (
|
||||||
<PredictionCard prediction={prediction} />
|
<>
|
||||||
|
<PredictionCard prediction={prediction} />
|
||||||
|
{/* AI Uzman Yorumu — prediction yüklendikten sonra ayrıca çekiliyor */}
|
||||||
|
<Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
|
||||||
|
<Card.Body gap={3}>
|
||||||
|
<Flex align="center" gap={2}>
|
||||||
|
<LuBrain size={16} />
|
||||||
|
<Text fontWeight="semibold" fontSize="sm">AI Uzman Yorumu</Text>
|
||||||
|
</Flex>
|
||||||
|
{commentaryLoading ? (
|
||||||
|
<VStack align="stretch" gap={2}>
|
||||||
|
<Skeleton h="16px" borderRadius="md" />
|
||||||
|
<Skeleton h="16px" borderRadius="md" w="90%" />
|
||||||
|
<Skeleton h="16px" borderRadius="md" w="75%" />
|
||||||
|
</VStack>
|
||||||
|
) : commentaryData?.data?.commentary ? (
|
||||||
|
<Text fontSize="sm" color="fg.muted" lineHeight="1.7">
|
||||||
|
{commentaryData.data.commentary}
|
||||||
|
</Text>
|
||||||
|
) : (
|
||||||
|
<Text fontSize="sm" color="fg.subtle">
|
||||||
|
Yorum üretilemedi.
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</Card.Body>
|
||||||
|
</Card.Root>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<Card.Root borderColor={borderColor} borderRadius="xl">
|
<Card.Root borderColor={borderColor} borderRadius="xl">
|
||||||
<Card.Body>
|
<Card.Body>
|
||||||
|
|||||||
@@ -1627,23 +1627,6 @@ export default function PredictionCard({ prediction }: PredictionCardProps) {
|
|||||||
)}
|
)}
|
||||||
ui={ui}
|
ui={ui}
|
||||||
/>
|
/>
|
||||||
{(prediction as unknown as Record<string, unknown>).ai_expert_commentary ? (
|
|
||||||
<Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
|
|
||||||
<Card.Body gap={3}>
|
|
||||||
<SectionTitle
|
|
||||||
icon={LuBrain}
|
|
||||||
title={uiText("ai-expert-commentary-title", "AI Uzman Yorumu")}
|
|
||||||
info={uiText(
|
|
||||||
"ai-expert-commentary-info",
|
|
||||||
"Yapay zekanın maç verilerini okuyarak ürettiği uzman bahis analizi.",
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<Text fontSize="sm" color="fg.muted" lineHeight="1.7">
|
|
||||||
{String((prediction as unknown as Record<string, unknown>).ai_expert_commentary)}
|
|
||||||
</Text>
|
|
||||||
</Card.Body>
|
|
||||||
</Card.Root>
|
|
||||||
) : null}
|
|
||||||
{prediction.match_commentary?.headline ||
|
{prediction.match_commentary?.headline ||
|
||||||
prediction.match_commentary?.summary ? (
|
prediction.match_commentary?.summary ? (
|
||||||
<Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
|
<Card.Root bg={cardBg} borderColor={borderColor} borderRadius="2xl">
|
||||||
|
|||||||
@@ -65,6 +65,14 @@ const checkHealth = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getCommentary = (matchId: string) => {
|
||||||
|
return apiRequest<ApiResponse<{ commentary: string | null }>>({
|
||||||
|
url: `/predictions/${matchId}/commentary`,
|
||||||
|
client: "core",
|
||||||
|
method: "get",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const generateSmartCoupon = (body: SmartCouponRequestDto) => {
|
const generateSmartCoupon = (body: SmartCouponRequestDto) => {
|
||||||
return apiRequest<ApiResponse<SmartCouponResponseDto>>({
|
return apiRequest<ApiResponse<SmartCouponResponseDto>>({
|
||||||
url: "/predictions/smart-coupon",
|
url: "/predictions/smart-coupon",
|
||||||
@@ -82,4 +90,5 @@ export const predictionsService = {
|
|||||||
getHistory,
|
getHistory,
|
||||||
checkHealth,
|
checkHealth,
|
||||||
generateSmartCoupon,
|
generateSmartCoupon,
|
||||||
|
getCommentary,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ export const PredictionsQueryKeys = {
|
|||||||
all: ["predictions"] as const,
|
all: ["predictions"] as const,
|
||||||
detail: (matchId: string) =>
|
detail: (matchId: string) =>
|
||||||
[...PredictionsQueryKeys.all, "detail", matchId] as const,
|
[...PredictionsQueryKeys.all, "detail", matchId] as const,
|
||||||
|
commentary: (matchId: string) =>
|
||||||
|
[...PredictionsQueryKeys.all, "commentary", matchId] as const,
|
||||||
upcoming: () => [...PredictionsQueryKeys.all, "upcoming"] as const,
|
upcoming: () => [...PredictionsQueryKeys.all, "upcoming"] as const,
|
||||||
valueBets: () => [...PredictionsQueryKeys.all, "valueBets"] as const,
|
valueBets: () => [...PredictionsQueryKeys.all, "valueBets"] as const,
|
||||||
history: () => [...PredictionsQueryKeys.all, "history"] as const,
|
history: () => [...PredictionsQueryKeys.all, "history"] as const,
|
||||||
@@ -21,6 +23,16 @@ export const usePrediction = (matchId: string) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useAiCommentary = (matchId: string, enabled: boolean) => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: PredictionsQueryKeys.commentary(matchId),
|
||||||
|
queryFn: () => predictionsService.getCommentary(matchId),
|
||||||
|
enabled,
|
||||||
|
staleTime: 10 * 60 * 1000, // 10 dakika cache
|
||||||
|
retry: 1,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const useGeneratePrediction = () => {
|
export const useGeneratePrediction = () => {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: (body: { matchId: string; sport?: SportType }) =>
|
mutationFn: (body: { matchId: string; sport?: SportType }) =>
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import nextConfig from 'eslint-config-next';
|
||||||
|
import prettierConfig from 'eslint-config-prettier';
|
||||||
|
|
||||||
|
const eslintConfig = [
|
||||||
|
...nextConfig,
|
||||||
|
prettierConfig,
|
||||||
|
{
|
||||||
|
ignores: ['node_modules/**', '.next/**', 'out/**', 'build/**', 'next-env.d.ts'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ['**/*.ts', '**/*.tsx'],
|
||||||
|
rules: {
|
||||||
|
'@typescript-eslint/no-empty-object-type': 'off',
|
||||||
|
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default eslintConfig;
|
||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user