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

Review Result ?

solutionbowl/crm-dashbaord · 4b855e58
This commit adds new routing and UI elements to integrate Tote race page as well as race type selection functionality. The ToteRacepage component is structured well with types defined and many helper functions helping maintain code clarity. However, the code could be improved with better naming consistency and more comments for maintainability. The commit message is vague and does not fully describe changes. Basic security considerations appear addressed, but error handling and validation are unclear, raising moderate bug risk.
Quality ?
80%
Security ?
70%
Business Value ?
85%
Maintainability ?
78%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Issue
Where commit message
Issue / Evidence issue
Suggested Fix Improve commit message clarity to better describe the business value and key changes made.
Code Comment
Where src/main.tsx:17
Issue / Evidence code comment
Suggested Fix Remove unused import comment if the ToteRacepage is now lazily loaded to reduce confusion.
Function Helper
Where src/modules/horse/pages/Race/ToteRacepage.tsx:68
Issue / Evidence function helper
Suggested Fix Add JSDoc comments and type info on utility helpers like hasOwn for clarity.
Edge Cases
Where src/modules/horse/pages/Race/ToteRacepage.tsx:82
Issue / Evidence edge cases
Suggested Fix Add input validation or error handling in toNullableNumber to prevent silent failures.
Naming & Code Reuse
Where src/modules/horse/pages/Race/ToteRacepage.tsx:131
Issue / Evidence naming & code reuse
Suggested Fix Inline comments and unify naming (left/right) or extract repeated logic from isSameRunner to improve readability and maintainability.
Ui Ux
Where src/modules/horse/pages/Race/CreateRaces.tsx:359 to 367
Issue / Evidence UI UX
Suggested Fix Add validation or user feedback if raceType is required and currently selected value is empty.
Accessibility
Where src/modules/horse/pages/Race/CreateRaces.tsx:391
Issue / Evidence accessibility
Suggested Fix Ensure switch input for race status is properly labeled and accessible.
Code Change Preview · src/main.tsx ?
Removed / Before Commit
- diff --git a/src/main.tsx b/src/main.tsx
- index 99c6728..45ff543 100644
- import AgentReport from './modules/horse/pages/Report/AgentReport.tsx';
- import BetButton from './modules/horse/pages/Report/BetButton.tsx';
- import BetButtonMarket from "./modules/horse/pages/Report/BetButtonMarket.tsx"
- authService.initializeAuth();
- 
- const Loader            = lazy(() => import('./components/loader/loader.tsx'));
- const HorseAllPlatforms = lazy(() => import('./modules/horse/pages/Platform/AllPlatforms.tsx'));
- const UpdateCountry     = lazy(() => import('./modules/horse/pages/Platform/UpdateCountry.tsx'));
- const AdminRacePage     = lazy(() => import('./modules/horse/pages/Race/AdminRacepage.tsx'));
- 
- createRoot(document.getElementById('root')!).render(
- <Fragment>
- <Route path="races/edit/:id" element={<CreateRace />} />
- <Route path="races/detail/:id" element={<RaceDetail />} />
- <Route path="races/admin/:raceId" element={<AdminRacePage />} />
- <Route path="races/stats/:id" element={<RaceStats />} />
Added / After Commit
+ diff --git a/src/main.tsx b/src/main.tsx
+ index 99c6728..45ff543 100644
+ import AgentReport from './modules/horse/pages/Report/AgentReport.tsx';
+ import BetButton from './modules/horse/pages/Report/BetButton.tsx';
+ import BetButtonMarket from "./modules/horse/pages/Report/BetButtonMarket.tsx"
+ // import ToteRacePage from './modules/horse/pages/Race/ToteRacepage.tsx';
+ authService.initializeAuth();
+ 
+ const Loader            = lazy(() => import('./components/loader/loader.tsx'));
+ const HorseAllPlatforms = lazy(() => import('./modules/horse/pages/Platform/AllPlatforms.tsx'));
+ const UpdateCountry     = lazy(() => import('./modules/horse/pages/Platform/UpdateCountry.tsx'));
+ const AdminRacePage     = lazy(() => import('./modules/horse/pages/Race/AdminRacepage.tsx'));
+ const ToteRacepage     = lazy(()=> import('./modules/horse/pages/Race/ToteRacepage.tsx'))
+ 
+ createRoot(document.getElementById('root')!).render(
+ <Fragment>
+ <Route path="races/edit/:id" element={<CreateRace />} />
+ <Route path="races/detail/:id" element={<RaceDetail />} />
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/AdminRacepage.tsx b/src/modules/horse/pages/Race/AdminRacepage.tsx
- index 281b3d0..3978f6a 100644
- import useRaceOddsSocket from "../../hooks/useRaceOddsSocket";
- 
- /* ── Types ───────────────────────────────────────────────────── */
- type OddsRow = {
- runnerId?: string;
- name?: string;
-   exposure?: number | null;
-   exposureProfit?: number | null;
- back_percent?: number | null;
- lay_percent?: number | null;
- runner:{
- back_volume: number | null;
- lay_volume: number | null;
- odds: Array<OddsRow & {
-       exposure?: number | null;
-       exposureProfit?: number | null;
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/AdminRacepage.tsx b/src/modules/horse/pages/Race/AdminRacepage.tsx
+ index 281b3d0..3978f6a 100644
+ import useRaceOddsSocket from "../../hooks/useRaceOddsSocket";
+ 
+ /* ── Types ───────────────────────────────────────────────────── */
+ 
+ type OddsRow = {
+ runnerId?: string;
+ name?: string;
+ back_percent?: number | null;
+ lay_percent?: number | null;
+ runner:{
+ back_volume: number | null;
+ lay_volume: number | null;
+ odds: Array<OddsRow & {
+ back_percent?: number | null;
+ lay_percent?: number | null;
+ }>;
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/AllRaces.tsx b/src/modules/horse/pages/Race/AllRaces.tsx
- index f63a5e8..56cd83e 100644
- const [searchTerm, setSearchTerm] = useState<string>("");
- const [events, setEvents] = useState<{ [key: string]: string }>({});
- 
-   // Load events for mapping
- const fetchEvents = async () => {
- try {
- const response = await eventService.getAllEvents(1, 100, "");
- setEvents(eventMap);
- }
- } catch (error) {
-       // Silently fail - events are optional for display
- }
- };
- 
-   // Fetch races data from API
- const fetchRaces = async () => {
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/AllRaces.tsx b/src/modules/horse/pages/Race/AllRaces.tsx
+ index f63a5e8..56cd83e 100644
+ const [searchTerm, setSearchTerm] = useState<string>("");
+ const [events, setEvents] = useState<{ [key: string]: string }>({});
+ 
+ const fetchEvents = async () => {
+ try {
+ const response = await eventService.getAllEvents(1, 100, "");
+ setEvents(eventMap);
+ }
+ } catch (error) {
+ 
+ }
+ };
+ 
+ const fetchRaces = async () => {
+ try {
+ setLoading(true);
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/CreateRaces.tsx b/src/modules/horse/pages/Race/CreateRaces.tsx
- index e04ff98..6aa88a0 100644
- race_name: string;
- distance: string;
- start_time: string;
- status: boolean;
- liveUrl: string;
- }
- race_name: "",
- distance: "",
- start_time: "",
- status: true,
- liveUrl: ""
- });
- race_name: race.race_name,
- distance: race.distance,
- start_time: formattedStartTime,
- status: race.status,
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/CreateRaces.tsx b/src/modules/horse/pages/Race/CreateRaces.tsx
+ index e04ff98..6aa88a0 100644
+ race_name: string;
+ distance: string;
+ start_time: string;
+   raceType: string;
+ status: boolean;
+ liveUrl: string;
+ }
+ race_name: "",
+ distance: "",
+ start_time: "",
+     raceType: "",
+ status: true,
+ liveUrl: ""
+ });
+ race_name: race.race_name,
+ distance: race.distance,
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/RaceDetail.tsx b/src/modules/horse/pages/Race/RaceDetail.tsx
- index 4caeff5..f4e0d7f 100644
- interface RaceDetailData {
- race: {
- _id: string;
- race_no: number;
- race_name: string;
- distance: string;
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/RaceDetail.tsx b/src/modules/horse/pages/Race/RaceDetail.tsx
+ index 4caeff5..f4e0d7f 100644
+ interface RaceDetailData {
+ race: {
+ _id: string;
+     
+ race_no: number;
+ race_name: string;
+ distance: string;
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/stats.tsx b/src/modules/horse/pages/Race/stats.tsx
- index 2a5b056..b4f9464 100644
- type OddsRow = {
- runnerId?: string;
- runner: Runner;
-   exposure: number;
-   exposureProfit: number;
- back_static_volume: number | null;
- lay_static_volume:  number | null;
- back_volume:        number | null;
- odds: OddsRow[];
- };
- 
- const toNullableNumber = (value: string | number | null | undefined): number | null => {
- if (value === "" || value === null || value === undefined) return null;
- const parsed = typeof value === "number" ? value : Number(value);
- 
- const getRunnerGateNo = (runner?: Runner) =>
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/stats.tsx b/src/modules/horse/pages/Race/stats.tsx
+ index 2a5b056..b4f9464 100644
+ type OddsRow = {
+ runnerId?: string;
+ runner: Runner;
+   exposure?: number;
+   exposureProfit?: number;
+ back_static_volume: number | null;
+ lay_static_volume:  number | null;
+ back_volume:        number | null;
+ odds: OddsRow[];
+ };
+ 
+ type ExposureRow = {
+   marketId?: string | number;
+   market_id?: string | number;
+   runnerId?: string | number;
+   runner_id?: string | number;
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/ToteRacepage.tsx b/src/modules/horse/pages/Race/ToteRacepage.tsx
- new file mode 100644
- index 0000000..86f44bc
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/ToteRacepage.tsx b/src/modules/horse/pages/Race/ToteRacepage.tsx
+ new file mode 100644
+ index 0000000..86f44bc
+ import React, { useState, useEffect, Fragment, useCallback, useMemo } from "react";
+ import { toast } from "react-toastify";
+ import { useParams } from "react-router-dom";
+ import Pageheader from "../../components/pageheader/pageheader";
+ 
+ import { tenantServiceInstance as axiosInstance } from "../../../../services/api/axiosConfig";
+ import useRaceOddsSocket from "../../hooks/useRaceOddsSocket";
+ 
+ 
+ /* ── Types ───────────────────────────────────────────────────── */
+ type OddsRow = {
+   runnerId?: string;
+   name?: string;
+   back_percent?: number | null;
+   lay_percent?: number | null;
Removed / Before Commit
- diff --git a/src/pages/Platforms/AdminMarketPage.tsx b/src/pages/Platforms/AdminMarketPage.tsx
- index 535986a..ab0b2d2 100644
- type OddsRow = {
- runnerId?: string;
- name?: string;
-   exposure?: number | null;
-   exposureProfit?: number | null;
- back_percent?: number | null;
- lay_percent?: number | null;
- runner:{
- back_volume: number | null;
- lay_volume: number | null;
- odds: Array<OddsRow & {
-       exposure?: number | null;
-       exposureProfit?: number | null;
- back_percent?: number | null;
- lay_percent?: number | null;
- }>;
Added / After Commit
+ diff --git a/src/pages/Platforms/AdminMarketPage.tsx b/src/pages/Platforms/AdminMarketPage.tsx
+ index 535986a..ab0b2d2 100644
+ type OddsRow = {
+ runnerId?: string;
+ name?: string;
+ back_percent?: number | null;
+ lay_percent?: number | null;
+ runner:{
+ back_volume: number | null;
+ lay_volume: number | null;
+ odds: Array<OddsRow & {
+ back_percent?: number | null;
+ lay_percent?: number | null;
+ }>;
+ ""
+ ) || undefined,
+ runner: normalizeRunner(oddsRow?.runner),
+ back_percent:
Removed / Before Commit
- diff --git a/src/pages/Races/stats.tsx b/src/pages/Races/stats.tsx
- index 8540f94..3d3f4f2 100644
- type OddsRow = {
- runnerId?: string;
- runner: Runner;
-   exposure: number;
-   exposureProfit: number;
- back_static_volume: number | null;
- lay_static_volume: number | null;
- back_volume: number | null;
- odds: OddsRow[];
- };
- 
- type BetApiRow = {
- _id?: string;
- username?: string;
- ...oddsRow,
- runnerId: String(oddsRow?.runnerId ?? oddsRow?.runner?.runnerId ?? oddsRow?.selection?.runnerId ?? "") || undefined,
Added / After Commit
+ diff --git a/src/pages/Races/stats.tsx b/src/pages/Races/stats.tsx
+ index 8540f94..3d3f4f2 100644
+ type OddsRow = {
+ runnerId?: string;
+ runner: Runner;
+   exposure?: number;
+   exposureProfit?: number;
+ back_static_volume: number | null;
+ lay_static_volume: number | null;
+ back_volume: number | null;
+ odds: OddsRow[];
+ };
+ 
+ type ExposureRow = {
+   marketId?: string | number;
+   market_id?: string | number;
+   runnerId?: string | number;
+   runner_id?: string | number;
Removed / Before Commit
- diff --git a/src/services/api/raceService.ts b/src/services/api/raceService.ts
- index 2df6a4e..0fbecef 100644
- race_name: string;
- distance: string;
- start_time: string;
- status: boolean;
- liveUrl?: string;
- createdAt: string;
- race_name: string;
- distance: string;
- start_time: string;
- status: boolean;
- liveUrl?: string;
- }): Promise<RaceResponse> {
- race_name: string;
- distance: string;
- start_time: string;
- status: boolean;
Added / After Commit
+ diff --git a/src/services/api/raceService.ts b/src/services/api/raceService.ts
+ index 2df6a4e..0fbecef 100644
+ race_name: string;
+ distance: string;
+ start_time: string;
+   raceType?: string;
+ status: boolean;
+ liveUrl?: string;
+ createdAt: string;
+ race_name: string;
+ distance: string;
+ start_time: string;
+     raceType?: string;
+ status: boolean;
+ liveUrl?: string;
+ }): Promise<RaceResponse> {
+ race_name: string;
+ distance: string;