Showing AI reviews for super-admin
Project AI Score ?
72%
Quality Avg ?
77%
Security Avg ?
64%
Reviews ?
91

Review Result ?

solutionbowl/super-admin · 0c2cc101
The commit improves date filtering logic in bets and adds detailed support for multi bet views and refreshing features. It enhances user interface with real-time refresh and leg details for multi bets, improving user experience and business value. The use of TypeScript and React best practices is mostly solid, with memoization and effect hooks for performance and clarity. Date handling takes care of local day boundaries and invalid input. However, there are some minor concerns about input types in the date range filter and missing clarification of the 'unknown' type argument. The commit message is not descriptive, which impacts maintainability and review ease.
Quality ?
85%
Security ?
90%
Business Value ?
80%
Maintainability ?
83%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Very Vague Commit Message
Where commit message
Issue / Evidence very vague commit message
Suggested Fix provide a descriptive summary of the changes to improve maintainability and reviewability
'Datevalue' Is Typed As Unknown In Isdatei...
Where src/routes/bet-list.tsx:675
Issue / Evidence 'dateValue' is typed as unknown in isDateInRange
Suggested Fix clarify or refine the type to reduce bugs and improve type safety
Check For Empty String Falsy Case When Dat...
Where src/routes/bet-list.tsx:677
Issue / Evidence check for empty string falsy case when dateValue is not a string
Suggested Fix improve robustness of date filtering
'Todate' Uses Value?.To Fallback To Value?...
Where src/routes/bet-list.tsx:664
Issue / Evidence 'toDate' uses value?.to fallback to value?.from without explicit null checks
Suggested Fix confirm this behavior matches business expectations
122
Where src/routes/net-exposure-bet.tsx:110
Issue / Evidence 122
Suggested Fix add cleanup or error handling for async refetch calls triggered on refresh countdown zero
321
Where src/routes/net-exposure-bet.tsx:318
Issue / Evidence 321
Suggested Fix ensure proper keying and stable component behavior for dynamic expansion of bet legs to avoid UI bugs
67
Where src/routes/net-exposure-bet.tsx:53
Issue / Evidence 67
Suggested Fix Add deeper type validation for BetLeg properties if possible to catch data inconsistencies early
Code Change Preview · src/routes/bet-list.tsx ?
Removed / Before Commit
- diff --git a/src/routes/bet-list.tsx b/src/routes/bet-list.tsx
- index ef27ba7..94f8630 100644
- });
- 
- const pagination = isAgentMode ? undefined : data?.pagination;
-   const bets = isAgentMode
- ? ((agentBetsQuery.data as { bets?: Bet[] })?.bets ?? (Array.isArray(agentBetsQuery.data) ? (agentBetsQuery.data as Bet[]) : []))
- : (data?.bets ?? []);
- const activeIsLoading = isAgentMode ? agentBetsQuery.isLoading : isLoading;
- const activeError = isAgentMode ? agentBetsQuery.error : error;
- 
- 
- function parseDateRange(value?: DateRange) {
- return {
-     fromDate: value?.from ? format(value.from, "dd/MM/yyyy 00:00:00") : undefined,
-     toDate: value?.to ? format(value.to, "dd/MM/yyyy 23:59:59") : undefined,
- };
- }
Added / After Commit
+ diff --git a/src/routes/bet-list.tsx b/src/routes/bet-list.tsx
+ index ef27ba7..94f8630 100644
+ });
+ 
+ const pagination = isAgentMode ? undefined : data?.pagination;
+   const rawBets = isAgentMode
+ ? ((agentBetsQuery.data as { bets?: Bet[] })?.bets ?? (Array.isArray(agentBetsQuery.data) ? (agentBetsQuery.data as Bet[]) : []))
+ : (data?.bets ?? []);
+   const bets = useMemo(
+     () =>
+       rawBets.filter((bet) =>
+         isDateInRange(bet.placed_at ?? bet.createdAt, appliedFilters.dateRange),
+       ),
+     [appliedFilters.dateRange, rawBets],
+   );
+ const activeIsLoading = isAgentMode ? agentBetsQuery.isLoading : isLoading;
+ const activeError = isAgentMode ? agentBetsQuery.error : error;
+ 
Removed / Before Commit
- diff --git a/src/routes/net-exposure-bet.tsx b/src/routes/net-exposure-bet.tsx
- index 4c58b31..00a4a82 100644
- import { createFileRoute, useNavigate } from "@tanstack/react-router";
- import { useQuery } from "@tanstack/react-query";
- import { ArrowLeft, RefreshCw } from "lucide-react";
- import { Button } from "@/components/ui/button";
- import { cn } from "@/lib/utils";
- import { tenantApiClient } from "@/services/api/apiClient";
- liability: number;
- ipAddress: string;
- lastUpdated: string;
- }
- 
- interface BetsResponse {
- function NetExposureBetPage() {
- const { raceId, marketId, userId } = getExposureParams();
- const navigate = useNavigate();
- 
Added / After Commit
+ diff --git a/src/routes/net-exposure-bet.tsx b/src/routes/net-exposure-bet.tsx
+ index 4c58b31..00a4a82 100644
+ import { createFileRoute, useNavigate } from "@tanstack/react-router";
+ import { useQuery } from "@tanstack/react-query";
+ import { Fragment, useEffect, useState } from "react";
+ import { ArrowLeft, Eye, RefreshCw } from "lucide-react";
+ import { Button } from "@/components/ui/button";
+ import { cn } from "@/lib/utils";
+ import { tenantApiClient } from "@/services/api/apiClient";
+ liability: number;
+ ipAddress: string;
+ lastUpdated: string;
+   isMultiBet?: boolean;
+   multiBetType?: string | null;
+   totalLegs?: number;
+   combinedOdds?: number;
+   legs?: BetLeg[];
+ }
Removed / Before Commit
- diff --git a/src/routes/net-exposure-detail.tsx b/src/routes/net-exposure-detail.tsx
- index f81274a..6ebede2 100644
- import { createFileRoute, useNavigate } from "@tanstack/react-router";
- import { useQuery } from "@tanstack/react-query";
- import { useState } from "react";
- import type React from "react";
- import { ArrowLeft, RefreshCw, ChevronDown, Network } from "lucide-react";
- import { Button } from "@/components/ui/button";
- import { cn } from "@/lib/utils";
- import { tenantApiClient } from "@/services/api/apiClient";
- interface DetailRunner { runnerId: string; runnerName: string; exposure: number; exposureProfit: number; }
- interface DetailMarket { marketId: string; marketName: string; totalStake: number; runners: DetailRunner[]; worstBook: number; bestBook: number; }
- interface Race { raceId: string; raceName: string; raceNo: number; startTime: string; }
- interface Bet { userId: string; username: string; betId: string; event: string; market: string; marketId: string; selection: string; runnerId: string; type: string; oddsRequested: number; oddsMatched: number; matched: number; unmatched: number; profitLiability: number; ipAddress: string; placedAt: string; }
- interface DetailData { race: Race; market: DetailMarket; bets: Bet[]; }
- interface OddsRunner { runnerId: string; name: string; back_odd: number | null; lay_odd: number | null; runner: { horse_number: number }; }
- interface OddsMarket { marketId: string; marketName: string; odds: OddsRunner[]; }
- const { raceId, marketId, parentUserId } = getExposureParams();
Added / After Commit
+ diff --git a/src/routes/net-exposure-detail.tsx b/src/routes/net-exposure-detail.tsx
+ index f81274a..6ebede2 100644
+ import { createFileRoute, useNavigate } from "@tanstack/react-router";
+ import { useQuery } from "@tanstack/react-query";
+ import { Fragment, useEffect, useState } from "react";
+ import type React from "react";
+ import { ArrowLeft, RefreshCw, ChevronDown, Network, Eye } from "lucide-react";
+ import { Button } from "@/components/ui/button";
+ import { cn } from "@/lib/utils";
+ import { tenantApiClient } from "@/services/api/apiClient";
+ interface DetailRunner { runnerId: string; runnerName: string; exposure: number; exposureProfit: number; }
+ interface DetailMarket { marketId: string; marketName: string; totalStake: number; runners: DetailRunner[]; worstBook: number; bestBook: number; }
+ interface Race { raceId: string; raceName: string; raceNo: number; startTime: string; }
+ interface Bet { userId: string; username: string; betId: string; event: string; market: string; marketId: string; selection: string; runnerId: string; type: string; oddsRequested: number; oddsMatched: number; bet_amount: number; return_amount: number; liability_amount: number; ipAddress: string; placedAt: string; isMultiBet?: boolean; multiBetType?: string | null; totalLegs?: number; combinedOdds?: number; legs?: BetLeg[]; }
+ interface BetLeg { legId?: string; legNumber?: number; position?: number; raceId?: string; market?: string; marketId?: string; selection?: string; runnerId?: string; oddsRequested?: number; oddsMatched?: number; legStatus?: string; stakeAtLeg?: number; grossProfit?: number; deductionPercent?: number; deductionAmount?: number; netProfit?: number; }
+ interface DetailData { race: Race; market: DetailMarket; bets: Bet[]; }
+ interface OddsRunner { runnerId: string; name: string; back_odd: number | null; lay_odd: number | null; runner: { horse_number: number }; }
+ interface OddsMarket { marketId: string; marketName: string; odds: OddsRunner[]; }
Removed / Before Commit
- diff --git a/src/routes/statement.tsx b/src/routes/statement.tsx
- index 102d604..af8a97a 100644
- .trim()
- .toLowerCase();
- const isDebitAmount = amountType === "debit" || (!amountType && isRevoke);
- const amountColorClass = isDebitAmount
- ? "text-red-400"
- : amountType === "credit"
Added / After Commit
+ diff --git a/src/routes/statement.tsx b/src/routes/statement.tsx
+ index 102d604..af8a97a 100644
+ .trim()
+ .toLowerCase();
+ const isDebitAmount = amountType === "debit" || (!amountType && isRevoke);
+   
+ const amountColorClass = isDebitAmount
+ ? "text-red-400"
+ : amountType === "credit"
Removed / Before Commit
- diff --git a/src/routes/user-details.$userId.tsx b/src/routes/user-details.$userId.tsx
- index 6f56dde..c44f7aa 100644
- import { Badge } from "@/components/ui/badge";
- import TablePagination from "@/components/common/TablePagination";
- import DateRangePicker from "@/components/common/DateRangePicker";
- import { Fragment, useState, useMemo } from "react";
- import type { DateRange } from "react-day-picker";
- import {
- Table,
- type BetStatus = "matched" | "unmatched";
- type BetTimeFilter = "current" | "past";
- 
- type UserBetLeg = MultiBetLeg & {
- odds_request?: number | string;
- stake_at_leg?: number | string;
- function UserDetailsPage() {
- const { userId } = Route.useParams();
- const [activeTab, setActiveTab] = useState<TabType>("activity");
Added / After Commit
+ diff --git a/src/routes/user-details.$userId.tsx b/src/routes/user-details.$userId.tsx
+ index 6f56dde..c44f7aa 100644
+ import { Badge } from "@/components/ui/badge";
+ import TablePagination from "@/components/common/TablePagination";
+ import DateRangePicker from "@/components/common/DateRangePicker";
+ import { Fragment, useEffect, useState, useMemo } from "react";
+ import type { DateRange } from "react-day-picker";
+ import {
+ Table,
+ type BetStatus = "matched" | "unmatched";
+ type BetTimeFilter = "current" | "past";
+ 
+ function getDefaultStatementDateRange(): DateRange {
+   return {
+     from: new Date(),
+     to: new Date(),
+   };
+ }
Removed / Before Commit
- diff --git a/src/routes/virtual-report.tsx b/src/routes/virtual-report.tsx
- index 42c1006..480d1c9 100644
- import { Button } from "@/components/ui/button";
- import { useQuery } from "@tanstack/react-query";
- import { toast } from "sonner";
- import { internalServices } from "@/services/api/internalServices";
- import { Calendar as CalendarIcon, Download } from "lucide-react";
- import { Calendar } from "@/components/ui/calendar";
- import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
- };
- const [appliedFilters, setAppliedFilters] = useState(defaultFilters);
- 
-   const reportQuery = useQuery({
-     queryKey: ["virtual-report", appliedFilters],
-     queryFn: () => internalServices.horseRacingReports.globalProfitLoss(appliedFilters.fromDate, appliedFilters.toDate),
-     staleTime: 30_000,
-     retry: 1,
-   });
Added / After Commit
+ diff --git a/src/routes/virtual-report.tsx b/src/routes/virtual-report.tsx
+ index 42c1006..480d1c9 100644
+ import { Button } from "@/components/ui/button";
+ import { useQuery } from "@tanstack/react-query";
+ import { toast } from "sonner";
+ // import { internalServices } from "@/services/api/internalServices";
+ import { Calendar as CalendarIcon, Download } from "lucide-react";
+ import { Calendar } from "@/components/ui/calendar";
+ import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
+ };
+ const [appliedFilters, setAppliedFilters] = useState(defaultFilters);
+ 
+   // const reportQuery = useQuery({
+   //   queryKey: ["virtual-report", appliedFilters],
+   //   queryFn: () => internalServices.horseRacingReports.globalProfitLoss(appliedFilters.fromDate, appliedFilters.toDate),
+   //   staleTime: 30_000,
+   //   retry: 1,
+   // });
Removed / Before Commit
- diff --git a/src/services/api/internalServices.ts b/src/services/api/internalServices.ts
- index 9789069..748cb41 100644
- params?: {
- page?: number;
- limit?: number;
- },
- ) {
- const queryString = toQueryString({
- page: params?.page || 1,
- limit: params?.limit || 100,
- });
- return unwrapData<{
- user: {
- params?: {
- page?: number;
- limit?: number;
- },
- ) {
Added / After Commit
+ diff --git a/src/services/api/internalServices.ts b/src/services/api/internalServices.ts
+ index 9789069..748cb41 100644
+ params?: {
+ page?: number;
+ limit?: number;
+         fromDate?: string;
+         toDate?: string;
+ },
+ ) {
+ const queryString = toQueryString({
+ page: params?.page || 1,
+ limit: params?.limit || 100,
+         fromDate: params?.fromDate,
+         toDate: params?.toDate,
+ });
+ return unwrapData<{
+ user: {
+ params?: {