Showing AI reviews for crm-dashbaord
Project AI Score ?
73%
Quality Avg ?
74%
Security Avg ?
74%
Reviews ?
130

Review Result ?

solutionbowl/crm-dashbaord · 6301f3af
The commit adds a custom hook useBets for fetching bet data and many utility functions and state management for a horse race admin page. It improves feature completeness with data handling and UI toggles but could be improved with better type usage, error handling, and documentation. The security posture is decent due to controlled API usage and error toast notifications. Low bug risk overall, though mutable states and dependency handling could be better. Fake work risk is low given meaningful feature additions.
Quality ?
85%
Security ?
80%
Business Value ?
80%
Maintainability ?
80%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Generic Error Typed As 'Any', Use A More S...
Where src/modules/horse/hooks/useBets.ts:27
Issue / Evidence generic error typed as 'any', use a more specific error type or error handling utility to improve bug risk and quality
Suggested Fix Review and simplify this section.
Long Function
Where src/modules/horse/hooks/useBets.ts:10
Issue / Evidence early return condition using 'isOwner' alongside api params could cause premature skips; clarify or decouple conditions for better correctness
Suggested Fix Review and simplify this section.
Long Function
Where src/modules/horse/pages/Race/AdminRacepage.tsx:114
Issue / Evidence complex isSameRunner function could be simplified or documented for maintainability and reduced bug risk
Suggested Fix Review and simplify this section.
Logic Assumes Missing Gateno Means Runners...
Where src/modules/horse/pages/Race/AdminRacepage.tsx:131
Issue / Evidence logic assumes missing gateNo means runners match; verify to avoid false positives (bug risk)
Suggested Fix Review and simplify this section.
Multiple Nullable Fields On Odds And Runne...
Where src/modules/horse/pages/Race/AdminRacepage.tsx:61-66
Issue / Evidence multiple nullable fields on odds and runner data should have clearer typing instead of multiple optional nullables for better code quality
Suggested Fix Review and simplify this section.
Long Function
Where src/modules/horse/pages/Race/AdminRacepage.tsx:629-632
Issue / Evidence setRunnerPercentDrafts and markets updates dependent on complex keys; add comments/documentation to improve maintainability
Suggested Fix Review and simplify this section.
Long Function
Where src/modules/horse/pages/Race/AdminRacepage.tsx:635-665
Issue / Evidence applyRunnerPercent has nested, complex logic with toast notifications for error; consider extracting smaller functions for clarity and testing
Suggested Fix Review and simplify this section.
Too Generic And Low Detail
Where commit message
Issue / Evidence too generic and low detail
Suggested Fix improve commit message to include a concise summary of main changes and rationale for better traceability and business value
Code Change Preview · src/modules/horse/hooks/useBets.ts ?
Removed / Before Commit
- diff --git a/src/modules/horse/hooks/useBets.ts b/src/modules/horse/hooks/useBets.ts
- new file mode 100644
- index 0000000..2d2e3bc
- \ No newline at end of file
Added / After Commit
+ diff --git a/src/modules/horse/hooks/useBets.ts b/src/modules/horse/hooks/useBets.ts
+ new file mode 100644
+ index 0000000..2d2e3bc
+ import { useEffect, useState } from "react";
+ import { toast } from "react-toastify";
+ import { tenantServiceInstance as axiosInstance } from "../../../services/api/axiosConfig";
+ 
+ export const useBets = (raceId: string | undefined, marketType: string | undefined, isOwner: boolean) => {
+   const [betRows, setBetRows] = useState<any[]>([]);
+   const [loading, setLoading] = useState(false);
+ 
+   const fetchBets = async () => {
+     if (!raceId || !marketType || !isOwner) {
+       setBetRows([]);
+       return;
+     }
+ 
+     try {
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/AdminRacepage.tsx b/src/modules/horse/pages/Race/AdminRacepage.tsx
- index e0b62c8..3ec68f0 100644
- runnerId?: string;
- name?: string;
- exposure?: number | null;
-   runner:             {
- runnerId?: string;
- name?: string;
- horse_number: number;
- 
- type GlobalState = { active: boolean; suspended: boolean; inactive: boolean };
- type StatusField = keyof GlobalState;
- 
- type UpdateOddsPayload = {
- marketsData: Array<{
- lay_static_volume: number | null;
- back_volume: number | null;
- lay_volume: number | null;
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/AdminRacepage.tsx b/src/modules/horse/pages/Race/AdminRacepage.tsx
+ index e0b62c8..3ec68f0 100644
+ runnerId?: string;
+ name?: string;
+ exposure?: number | null;
+   exposureProfit?: number | null;
+   back_percent?: number | null;
+   lay_percent?: number | null;
+   runner:{
+ runnerId?: string;
+ name?: string;
+ horse_number: number;
+ 
+ type GlobalState = { active: boolean; suspended: boolean; inactive: boolean };
+ type StatusField = keyof GlobalState;
+ type OddsField = keyof Pick<OddsRow, "back_odd" | "lay_odd">;
+ 
+ type UpdateOddsPayload = {
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/stats.module.css b/src/modules/horse/pages/Race/stats.module.css
- new file mode 100644
- index 0000000..982b42d
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/stats.module.css b/src/modules/horse/pages/Race/stats.module.css
+ new file mode 100644
+ index 0000000..982b42d
+ /* Stats Page Styles */
+ 
+ .page {
+   background: #ffffff;
+   border: 1px solid #e5e7eb;
+   border-radius: 18px;
+   box-shadow: 0 12px 32px rgba(15, 23, 42, 0.08);
+   overflow: hidden;
+ }
+ 
+ .panel {
+   background: #ffffff;
+   border: 1px solid #e5e7eb;
+   border-radius: 14px;
+   color: #111827;
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/stats.tsx b/src/modules/horse/pages/Race/stats.tsx
- index 6ccf770..f56e556 100644
- import Pageheader from "../../components/pageheader/pageheader";
- import { tenantServiceInstance as axiosInstance } from "../../../../services/api/axiosConfig";
- import useRaceOddsSocket from "../../hooks/useRaceOddsSocket";
- 
- type Runner = {
- runnerId?: string;
- runnerId?: string;
- runner: Runner;
- exposure: number;
- back_static_volume: number | null;
- lay_static_volume:  number | null;
- back_volume:        number | null;
- oddsRow?.stack ??
- oddsRow?.pnl
- ) ?? 0,
- back_static_volume: toNullableNumber(oddsRow?.back_static_volume),
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/stats.tsx b/src/modules/horse/pages/Race/stats.tsx
+ index 6ccf770..f56e556 100644
+ import Pageheader from "../../components/pageheader/pageheader";
+ import { tenantServiceInstance as axiosInstance } from "../../../../services/api/axiosConfig";
+ import useRaceOddsSocket from "../../hooks/useRaceOddsSocket";
+ import { adjustOdd } from "../../utils/odds";
+ import { useBets } from "../../hooks/useBets";
+ import styles from "./stats.module.css";
+ 
+ type Runner = {
+ runnerId?: string;
+ runnerId?: string;
+ runner: Runner;
+ exposure: number;
+   exposureProfit: number;
+ back_static_volume: number | null;
+ lay_static_volume:  number | null;
+ back_volume:        number | null;
Removed / Before Commit
- diff --git a/src/modules/horse/utils/odds.tsx b/src/modules/horse/utils/odds.tsx
- new file mode 100644
- index 0000000..c2a155c
- \ No newline at end of file
Added / After Commit
+ diff --git a/src/modules/horse/utils/odds.tsx b/src/modules/horse/utils/odds.tsx
+ new file mode 100644
+ index 0000000..c2a155c
+ export const adjustOdd = (value: number | null | undefined) => {
+   if (value === null || value === undefined) return value;
+   return value + 1;
+ };
+ \ No newline at end of file
Removed / Before Commit
- diff --git a/src/pages/Auth/Login.tsx b/src/pages/Auth/Login.tsx
- index 110034a..efdc949 100644
- // Show success message
- toast.success("Login successful!");
- 
-       // Redirect to dashboard
-       navigate("/dashboard");
- } catch (error: any) {
- console.error("Login error:", error);
- 
- };
- 
- // Quick login with predefined credentials
-   const handleQuickLogin = async (username: string, password: string, role: string) => {
-     setFormData({ username, password });
-     
-     try {
-       setLoading(true);
Added / After Commit
+ diff --git a/src/pages/Auth/Login.tsx b/src/pages/Auth/Login.tsx
+ index 110034a..efdc949 100644
+ // Show success message
+ toast.success("Login successful!");
+ 
+       // Get user data to check permissions
+       const user = authService.getCurrentUser();
+       
+       
+       const permissions: string[] = Array.isArray(user?.permissions)
+         ? user.permissions
+         : [];
+ 
+       const lowerPermissions = permissions.map((p: string) => p.toLowerCase());
+ 
+       const hasOnlyHorseAccess =
+         lowerPermissions.length === 1 &&
+         lowerPermissions.includes("access_horses");
Removed / Before Commit
- diff --git a/src/pages/Platforms/AdminMarketPage.tsx b/src/pages/Platforms/AdminMarketPage.tsx
- index 25cd5f9..0d37d7a 100644
- runnerId?: string;
- name?: string;
- exposure?: number | null;
-   runner:             {
- runnerId?: string;
- name?: string;
- horse_number: number;
- 
- type GlobalState = { active: boolean; suspended: boolean; inactive: boolean };
- type StatusField = keyof GlobalState;
- 
- type UpdateOddsPayload = {
- marketsData: Array<{
- lay_static_volume: number | null;
- back_volume: number | null;
- lay_volume: number | null;
Added / After Commit
+ diff --git a/src/pages/Platforms/AdminMarketPage.tsx b/src/pages/Platforms/AdminMarketPage.tsx
+ index 25cd5f9..0d37d7a 100644
+ runnerId?: string;
+ name?: string;
+ exposure?: number | null;
+   exposureProfit?: number | null;
+   back_percent?: number | null;
+   lay_percent?: number | null;
+   runner:{
+ runnerId?: string;
+ name?: string;
+ horse_number: number;
+ 
+ type GlobalState = { active: boolean; suspended: boolean; inactive: boolean };
+ type StatusField = keyof GlobalState;
+ type OddsField = keyof Pick<OddsRow, "back_odd" | "lay_odd">;
+ 
+ type UpdateOddsPayload = {
Removed / Before Commit
- diff --git a/src/pages/Races/stats.css b/src/pages/Races/stats.css
- new file mode 100644
- index 0000000..d5d4cf6
Added / After Commit
+ diff --git a/src/pages/Races/stats.css b/src/pages/Races/stats.css
+ new file mode 100644
+ index 0000000..d5d4cf6
+ .stats-page {
+   background: #ffffff;
+   border: 1px solid #e5e7eb;
+   border-radius: 18px;
+   box-shadow: 0 12px 32px rgba(15, 23, 42, 0.08);
+   overflow: hidden;
+ }
+ 
+ .stats-header {
+   border-bottom: 1px solid #e5e7eb;
+ }
+ 
+ .stats-heading {
+   color: #111827;
+ }
Removed / Before Commit
- diff --git a/src/pages/Races/stats.tsx b/src/pages/Races/stats.tsx
- index a3cc8b0..f715624 100644
- import { authService } from "../../services/api/authService";
- import { tenantServiceInstance as axiosInstance } from "../../services/api/axiosConfig";
- import useRaceOddsSocket from "../../modules/horse/hooks/useRaceOddsSocket";
- 
- type Runner = {
- runnerId?: string;
- runnerId?: string;
- runner: Runner;
- exposure: number;
- back_static_volume: number | null;
- lay_static_volume: number | null;
- back_volume: number | null;
- username?: string;
- phone?: string | number;
- market_name?: string;
- odds_type?: string;
Added / After Commit
+ diff --git a/src/pages/Races/stats.tsx b/src/pages/Races/stats.tsx
+ index a3cc8b0..f715624 100644
+ import { authService } from "../../services/api/authService";
+ import { tenantServiceInstance as axiosInstance } from "../../services/api/axiosConfig";
+ import useRaceOddsSocket from "../../modules/horse/hooks/useRaceOddsSocket";
+ import "./stats.css";
+ 
+ type Runner = {
+ runnerId?: string;
+ runnerId?: string;
+ runner: Runner;
+ exposure: number;
+   exposureProfit: number;
+ back_static_volume: number | null;
+ lay_static_volume: number | null;
+ back_volume: number | null;
+ username?: string;
+ phone?: string | number;