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

Review Result ?

solutionbowl/crm-dashbaord · 773393a4
This commit integrates settle and position APIs into the horse race detail page and navigation components. It adds role-based menu items for the OWNER role, protects OwnerRoute based on user roles, and implements detailed position handling functions for race horses. It facilitates position normalization, validation, and selection with proper UI feedback like spinners and toasts.
Quality ?
85%
Security ?
80%
Business Value ?
90%
Maintainability ?
83%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Getpositionlabel Returns Position As A Str...
Where src/modules/horse/pages/Race/RaceDetail.tsx:56
Issue / Evidence getPositionLabel returns position as a string without ordinal suffixes (e.g., '1st', '2nd')
Suggested Fix add proper ordinal suffixes to improve UX and clarity
Normalizepositiondisplay Uses Many Positio...
Where src/modules/horse/pages/Race/RaceDetail.tsx:86
Issue / Evidence normalizePositionDisplay uses many position property variants, which can lead to inconsistent data
Suggested Fix unify backend data shape to reduce complexity and prevent bugs
Getsettlementcandidate Returns The First S...
Where src/modules/horse/pages/Race/RaceDetail.tsx:131
Issue / Evidence getSettlementCandidate returns the first sorted candidate by position, but does not handle ties or invalid positions explicitly
Suggested Fix add explicit error handling and manage tie cases to reduce potential bugs
Missing Validation
Where src/modules/horse/pages/Race/RaceDetail.tsx:486
Issue / Evidence handlePositionSelect does not sanitize or validate input beyond numeric check
Suggested Fix add robust input sanitization to mitigate injection or UI bugs
Ownerroute Only Checks Userrole === 'Owner...
Where src/components/OwnerRoute.tsx:26
Issue / Evidence OwnerRoute only checks userRole === 'OWNER'
Suggested Fix consider supporting multiple roles or more granular permission checks to enhance flexibility and security
Message Is Brief And Not Descriptive
Where commit message
Issue / Evidence message is brief and not descriptive
Suggested Fix improve commit message to describe specific integrations and changes for better traceability
Code Change Preview · src/components/OwnerRoute.tsx ?
Removed / Before Commit
- diff --git a/src/components/OwnerRoute.tsx b/src/components/OwnerRoute.tsx
- new file mode 100644
- index 0000000..dc8c7a2
Added / After Commit
+ diff --git a/src/components/OwnerRoute.tsx b/src/components/OwnerRoute.tsx
+ new file mode 100644
+ index 0000000..dc8c7a2
+ import React from "react";
+ import { Navigate } from "react-router-dom";
+ import { useAuth } from "../hooks/useAuth";
+ 
+ interface OwnerRouteProps {
+   children: React.ReactNode;
+   redirectTo?: string;
+ }
+ 
+ const OwnerRoute: React.FC<OwnerRouteProps> = ({
+   children,
+   redirectTo = "/dashboard",
+ }) => {
+   const { userRole, loading } = useAuth();
+ 
Removed / Before Commit
- diff --git a/src/components/sidebar/nav.tsx b/src/components/sidebar/nav.tsx
- index 332243b..ffc6a15 100644
- 
- const Usersicon = <svg xmlns="http://www.w3.org/2000/svg" className="side-menu__icon" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><circle cx="128" cy="96" r="64" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><path d="M30.989,215.99064a112.03731,112.03731,0,0,1,194.02311.002" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/></svg>
- 
- const Bannersicon = <svg xmlns="http://www.w3.org/2000/svg" className="side-menu__icon" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><rect x="32" y="48" width="192" height="160" rx="8" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><line x1="32" y1="112" x2="224" y2="112" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><circle cx="68" cy="80" r="12"/><circle cx="108" cy="80" r="12"/></svg>
- 
- const Racesicon = <svg xmlns="http://www.w3.org/2000/svg" className="side-menu__icon" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M48 184h160" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><path d="M72 184V88l56-32 56 32v96" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><path d="M100 184v-40h56v40" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/></svg>
- 
- const Punchingicon = <svg xmlns="http://www.w3.org/2000/svg" className="side-menu__icon" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><rect x="32" y="48" width="192" height="160" rx="8" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><line x1="96" y1="48" x2="96" y2="208" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><line x1="32" y1="128" x2="96" y2="128" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/></svg>
- 
- const link = (path: string, title: string) => ({
- path: `${import.meta.env.BASE_URL}${path}`,
- 
- const punchingItem = linkIcon("punching", "Punching", Punchingicon);
- 
- export const getMenuItemsByRole = (userRole: string | null, permissions: string[] = []): any[] => {
- 
Added / After Commit
+ diff --git a/src/components/sidebar/nav.tsx b/src/components/sidebar/nav.tsx
+ index 332243b..ffc6a15 100644
+ 
+ const Usersicon = <svg xmlns="http://www.w3.org/2000/svg" className="side-menu__icon" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><circle cx="128" cy="96" r="64" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><path d="M30.989,215.99064a112.03731,112.03731,0,0,1,194.02311.002" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/></svg>
+ 
+ const Bannersicon = <svg xmlns="http://www.w3.org/2000/svg" className="side-menu__icon" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><rect x="32" y="48" width="192" height="160" rx="8" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><line x1="32" y1="112" x2="224" y2="112" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><circle cx="68" cy="80" r="12"/><circle cx="108" cy="80" r="12"/></svg>
+ 
+ const Racesicon = <svg xmlns="http://www.w3.org/2000/svg" className="side-menu__icon" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><path d="M48 184h160" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><path d="M72 184V88l56-32 56 32v96" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><path d="M100 184v-40h56v40" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/></svg>
+ 
+ const Punchingicon = <svg xmlns="http://www.w3.org/2000/svg" className="side-menu__icon" viewBox="0 0 256 256"><rect width="256" height="256" fill="none"/><rect x="32" y="48" width="192" height="160" rx="8" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><line x1="96" y1="48" x2="96" y2="208" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/><line x1="32" y1="128" x2="96" y2="128" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="16"/></svg>
+ 
+ const link = (path: string, title: string) => ({
+ path: `${import.meta.env.BASE_URL}${path}`,
+ 
+ const punchingItem = linkIcon("punching", "Punching", Punchingicon);
+ 
+ export const getMenuItemsByRole = (userRole: string | null, permissions: string[] = []): any[] => {
+ 
Removed / Before Commit
- diff --git a/src/main.tsx b/src/main.tsx
- index 15d3268..1eecd60 100644
- const CreateUser        = lazy(() => import('./pages/Users/CreateUser.tsx'));
- const Userdetail        = lazy(() => import('./pages/Users/Userdetail.tsx'));
- const AllBanners        = lazy(() => import('./pages/Banners/AllBanners.tsx'));
- 
- const CreateBanner      = lazy(() => import('./pages/Banners/CreateBanner.tsx'));
- const MainAllRaces      = lazy(() => import('./pages/Races/AllRaces.tsx'));
- <Route path={`${import.meta.env.BASE_URL}users/create`} element={<CreateUser />} />
- <Route path={`${import.meta.env.BASE_URL}users/detail/:id`} element={<Userdetail />} />
- <Route path={`${import.meta.env.BASE_URL}banners`} element={<AllBanners />} />
- <Route path={`${import.meta.env.BASE_URL}banners/create`} element={<CreateBanner />} />
- <Route path={`${import.meta.env.BASE_URL}banners/edit/:id`} element={<CreateBanner />} />
- <Route path={`${import.meta.env.BASE_URL}races`} element={<MainAllRaces />} />
- <Route path={`${import.meta.env.BASE_URL}races/stats/:id`} element={<MainRaceStats />} />
- <Route path={`${import.meta.env.BASE_URL}platform-users`} element={<AllPlatformUsers />} />
- <Route path={`${import.meta.env.BASE_URL}platform-users/create`} element={<CreatePlatformUser />} />
Added / After Commit
+ diff --git a/src/main.tsx b/src/main.tsx
+ index 15d3268..1eecd60 100644
+ const CreateUser        = lazy(() => import('./pages/Users/CreateUser.tsx'));
+ const Userdetail        = lazy(() => import('./pages/Users/Userdetail.tsx'));
+ const AllBanners        = lazy(() => import('./pages/Banners/AllBanners.tsx'));
+ const AllSport          = lazy(() => import('./pages/Sports/AllSport.tsx'));
+ 
+ const CreateBanner      = lazy(() => import('./pages/Banners/CreateBanner.tsx'));
+ const MainAllRaces      = lazy(() => import('./pages/Races/AllRaces.tsx'));
+ <Route path={`${import.meta.env.BASE_URL}users/create`} element={<CreateUser />} />
+ <Route path={`${import.meta.env.BASE_URL}users/detail/:id`} element={<Userdetail />} />
+ <Route path={`${import.meta.env.BASE_URL}banners`} element={<AllBanners />} />
+               
+ <Route path={`${import.meta.env.BASE_URL}banners/create`} element={<CreateBanner />} />
+ <Route path={`${import.meta.env.BASE_URL}banners/edit/:id`} element={<CreateBanner />} />
+ <Route path={`${import.meta.env.BASE_URL}races`} element={<MainAllRaces />} />
+               <Route path={`${import.meta.env.BASE_URL}sports`} element={<AllSport />} />
+ <Route path={`${import.meta.env.BASE_URL}races/stats/:id`} element={<MainRaceStats />} />
Removed / Before Commit
- diff --git a/src/modules/horse/pages/Race/RaceDetail.tsx b/src/modules/horse/pages/Race/RaceDetail.tsx
- index 55c59a7..a12abef 100644
- import React, { Fragment, useState, useEffect } from "react";
- import { Card, Col, Row, Spinner, Badge, Modal, Form, Button } from "react-bootstrap";
- import Pageheader from "../../components/pageheader/pageheader";
- import { useNavigate, useParams, useLocation } from "react-router-dom";
- import { toast } from "react-toastify";
- jockey: string;
- trainer: string;
- status: boolean;
- odds: {
- back_odds: number;
- lay_odds: number;
- }>;
- }
- 
- const runnerTableHeadCell: React.CSSProperties = {
- textAlign: "center",
Added / After Commit
+ diff --git a/src/modules/horse/pages/Race/RaceDetail.tsx b/src/modules/horse/pages/Race/RaceDetail.tsx
+ index 55c59a7..a12abef 100644
+ import React, { Fragment, useState, useEffect } from "react";
+ import { Card, Col, Row, Spinner, Badge, Modal, Form, Button, Dropdown } from "react-bootstrap";
+ import Pageheader from "../../components/pageheader/pageheader";
+ import { useNavigate, useParams, useLocation } from "react-router-dom";
+ import { toast } from "react-toastify";
+ jockey: string;
+ trainer: string;
+ status: boolean;
+     position?: string;
+     position_value?: string | number;
+     saved_position?: string | number;
+     horse_position?: string | number;
+     finishing_position?: string | number;
+     finishingPosition?: string | number;
+     finish_position?: string | number;
+     result_position?: string | number;
Removed / Before Commit
- diff --git a/src/pages/Sports/AllSport.tsx b/src/pages/Sports/AllSport.tsx
- new file mode 100644
- index 0000000..d60329a
Added / After Commit
+ diff --git a/src/pages/Sports/AllSport.tsx b/src/pages/Sports/AllSport.tsx
+ new file mode 100644
+ index 0000000..d60329a
+ import { Fragment, useState } from "react";
+ import { Card, Col, Row, Badge, Spinner, Button, Form, Modal } from "react-bootstrap";
+ import Pageheader from "../../components/pageheader/pageheader";
+ import DataTable from "react-data-table-component";
+ 
+ type Sport = {
+   sportsId: number;
+   sportsName: string;
+   eventName: string;
+   status: string;
+   createdAt: string;
+ };
+ 
+ const data: Sport[] = [
+   { sportsId: 1, sportsName: "Cricket",  eventName: "IPL 2026",       status: "ACTIVE",   createdAt: "2026-04-01" },