AI Review Center
Commit Review Workspace ?
Select a commit on the left to inspect quality, security, business value, findings, and suggested code changes.
Project AI Score
?
71%
Quality Avg
?
72%
Security Avg
?
74%
Reviews
?
123
Review Result ?
solutionbowl/website · 1f7092ee
The commit merges a branch with various UI components and event listener additions, mostly focusing on layout and profile navigation elements along with some console logging for session expiration events. While the UI adjustments and modular components improve UX and maintainability, extensive use of console.log statements may impact production code quality. There is little evidence of backend functionality or critical bug fixes, and the security implications are minimal though the use of session expiry event handling and localStorage usage requires cautious review. The commit message is non-descriptive, reducing clarity and traceability.
Quality
?
70%
Security
?
30%
Business Value
?
40%
Maintainability
?
78%
Issues & Suggested Fixes
?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Poor Practice
Where
commit message
Issue / Evidence
poor practice
Suggested Fix
provide a more descriptive commit message explaining the purpose and main changes of this merge to improve business value and fake work confidence
Excessive Console Logging
Where
src/components/layout/Layout.tsx:32
Issue / Evidence
excessive console logging
Suggested Fix
remove or replace console.log statements with proper logging or instrumentation for production to improve quality and security
Excessive Console Logging
Where
src/components/layout/Layout.tsx:35
Issue / Evidence
excessive console logging
Suggested Fix
remove debug console logs related to session expiration modal event handling
Potentially Fragile Event Handling
Where
src/components/layout/Layout.tsx:37
Issue / Evidence
potentially fragile event handling
Suggested Fix
add error handling or verify event data to reduce bug risk
Add Cleanup For Event Listeners In Useeffe...
Where
src/components/layout/Layout.tsx:56
Issue / Evidence
add cleanup for event listeners in useEffect hooks to prevent potential memory leaks or unintended behaviors
Suggested Fix
Review and simplify this section.
Hardcoded Inline Styles And Color Codes
Where
src/components/transactions/TransactionCard.tsx:13
Issue / Evidence
hardcoded inline styles and color codes
Suggested Fix
move color codes to theme or constants for maintainability and consistency
Toggle State Handling
Where
src/components/transactions/TransactionCard.tsx:20
Issue / Evidence
toggle state handling
Suggested Fix
consider debounce or throttling if this handler triggers heavy re-renders or API calls
Potential Missing Accessibility
Where
src/components/profile/ProfileMenu.tsx:16
Issue / Evidence
potential missing accessibility
Suggested Fix
add keyboard navigation handlers and ARIA attributes for better accessibility
Hardcoded Styling Values
Where
src/components/layout/BottomNav.tsx:39
Issue / Evidence
hardcoded styling values
Suggested Fix
extract repeated CSS styles to classes or styled components for reusability and cleaner code
Code Change Preview · src/components/common/SingleTabModal.tsx
?
Removed / Before Commit
- diff --git a/src/components/common/SingleTabModal.tsx b/src/components/common/SingleTabModal.tsx - index b2630b7..0af6eb6 100644 - <div - className="w-[90%] max-w-[400px] rounded-[16px] p-[24px] shadow-2xl" - style={{ backgroundColor: "#1a1f2e" }} - >cancel - {/* Icon */} - <div className="flex justify-center mb-[16px]"> - <div
Added / After Commit
+ diff --git a/src/components/common/SingleTabModal.tsx b/src/components/common/SingleTabModal.tsx + index b2630b7..0af6eb6 100644 + <div + className="w-[90%] max-w-[400px] rounded-[16px] p-[24px] shadow-2xl" + style={{ backgroundColor: "#1a1f2e" }} + > + {/* Icon */} + <div className="flex justify-center mb-[16px]"> + <div
Removed / Before Commit
- diff --git a/src/components/layout/BottomNav.tsx b/src/components/layout/BottomNav.tsx - index e06d8cc..f645092 100644 - }, [sportsbookEnabled, casinoEnabled, racingEnabled]); - - return ( - <div style={{ backgroundColor: colors.secondary }} className="lg:hidden block fixed left-0 bottom-0 w-full z-[9] py-[15px] px-[30px] shadow-[0_-4px_10px_rgba(0,0,0,0.2)]"> - <div className="flex gap-2 items-center justify-between"> - {navItems.map((item) => ( - <Link - key={item.path} - style={{ - color: location.pathname === item.path ? colors.primary : colors.textPrimary - }} - className="text-[12px] flex flex-col gap-[5px] items-center bottom-nav-btn" - > - <i className={`fa-solid ${item.icon}`}></i> - {item.name} - </Link>
Added / After Commit
+ diff --git a/src/components/layout/BottomNav.tsx b/src/components/layout/BottomNav.tsx + index e06d8cc..f645092 100644 + }, [sportsbookEnabled, casinoEnabled, racingEnabled]); + + return ( + <div style={{ backgroundColor: colors.secondary }} className="lg:hidden block fixed left-0 bottom-0 w-full z-[9] py-[12px] px-[20px] shadow-[0_-4px_10px_rgba(0,0,0,0.2)]"> + <div className="flex gap-[10px] items-center justify-around max-w-[500px] mx-auto"> + {navItems.map((item) => ( + <Link + key={item.path} + style={{ + color: location.pathname === item.path ? colors.primary : colors.textPrimary + }} + className="text-[12px] flex flex-col gap-[5px] items-center bottom-nav-btn flex-1" + > + <i className={`fa-solid ${item.icon} text-[18px]`}></i> + <span className="text-[11px]">{item.name}</span> + </Link>
Removed / Before Commit
- diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx - index c32d457..3650f5e 100644 - const location = useLocation(); - - useEffect(() => { - console.log('🎭 [Layout] Setting up session expired modal listener'); - - const openSessionExpiredModal = () => { - console.log('🎭 [Layout] SESSION_EXPIRED_MODAL_EVENT received!'); - const message = consumeSessionExpiredModal() || SESSION_EXPIRED_MESSAGE; - console.log('🎭 [Layout] Message from sessionStorage:', message); - setSessionExpiredMessage(message); - console.log('🎭 [Layout] Modal state set to:', message); - }; - - const message = consumeSessionExpiredModal(); - console.log('🎭 [Layout] Initial check for queued message:', message); -
Added / After Commit
+ diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx + index c32d457..3650f5e 100644 + const location = useLocation(); + + useEffect(() => { + console.log("🎭 [Layout] Setting up session expired modal listener"); + + const openSessionExpiredModal = () => { + console.log("🎭 [Layout] SESSION_EXPIRED_MODAL_EVENT received!"); + + const message = + consumeSessionExpiredModal() || SESSION_EXPIRED_MESSAGE; + + console.log("🎭 [Layout] Message from sessionStorage:", message); + + setSessionExpiredMessage(message); + + console.log("🎭 [Layout] Modal state set to:", message);
Removed / Before Commit
- diff --git a/src/components/profile/ProfileDrawer.tsx b/src/components/profile/ProfileDrawer.tsx - index fe28187..52acaa2 100644 - {/* Content */} - <div className="px-[16px] py-[20px]"> - <ProfileInfo /> - <ProfileMenu /> - </div> - </div> - </>
Added / After Commit
+ diff --git a/src/components/profile/ProfileDrawer.tsx b/src/components/profile/ProfileDrawer.tsx + index fe28187..52acaa2 100644 + {/* Content */} + <div className="px-[16px] py-[20px]"> + <ProfileInfo /> + <ProfileMenu onClose={onClose} /> + </div> + </div> + </>
Removed / Before Commit
- diff --git a/src/components/profile/ProfileMenu.tsx b/src/components/profile/ProfileMenu.tsx - index 9421b5e..26fd7be 100644 - import ProfileMenuItem from "./ProfileMenuItem"; - import { useAuth } from "../../contexts/AuthContext"; - - const ProfileMenu: React.FC = () => { - const navigate = useNavigate(); - const { logout } = useAuth(); - - const handleLogout = async () => { - await logout({ redirectTo: "/" }); - }; - - const handleBetHistory = () => { - navigate("/transactions"); - }; - - return (
Added / After Commit
+ diff --git a/src/components/profile/ProfileMenu.tsx b/src/components/profile/ProfileMenu.tsx + index 9421b5e..26fd7be 100644 + import ProfileMenuItem from "./ProfileMenuItem"; + import { useAuth } from "../../contexts/AuthContext"; + + interface ProfileMenuProps { + onClose?: () => void; + } + + const ProfileMenu: React.FC<ProfileMenuProps> = ({ onClose }) => { + const navigate = useNavigate(); + const { logout } = useAuth(); + + const handleLogout = async () => { + await logout({ redirectTo: "/" }); + onClose?.(); + }; +
Removed / Before Commit
- diff --git a/src/components/transactions/TransactionCard.tsx b/src/components/transactions/TransactionCard.tsx - index 94b1e54..085c3da 100644 - import { formatDate, typeColor, typeIcon } from "./helpers"; - - export default function TransactionCard({ row, colors, historyType = "single" }: any) { - if (historyType === "multi") { - return ( - <div className="rounded-[12px] p-4" style={{ backgroundColor: colors.secondary }}> - <div className="flex items-center justify-between mb-3"> - <div className="flex flex-col gap-1"> - <span className="font-medium text-[15px]" style={{ color: colors.textPrimary }}> - {row.bet_id} - </span> - <span className={`text-[13px] font-medium ${typeColor(row.bet_status)}`}> - {typeIcon(row.bet_status)} {row.bet_status} - </span> - </div> - <span className="text-[12px]" style={{ color: colors.textSecondary }}>
Added / After Commit
+ diff --git a/src/components/transactions/TransactionCard.tsx b/src/components/transactions/TransactionCard.tsx + index 94b1e54..085c3da 100644 + import { useState } from "react"; + import { formatDate, typeColor } from "./helpers"; + import { ChevronDown, ChevronUp, Flag, User, Target, TrendingUp, Calendar, Hash, CheckCircle, Copy } from "lucide-react"; + + export default function TransactionCard({ row, colors, historyType = "single" }: any) { + const [isExpanded, setIsExpanded] = useState(false); + + if (historyType === "multi") { + return ( + <div + className="rounded-[12px] overflow-hidden border-l-4" + style={{ + backgroundColor: colors.secondary, + borderLeftColor: row.bet_status === "WON" ? "#4ade80" : row.bet_status === "LOST" ? "#f87171" : "#fbbf24" + }} + >
Removed / Before Commit
- diff --git a/src/components/transactions/TransactionTabs.tsx b/src/components/transactions/TransactionTabs.tsx - index 0a830a9..dc96947 100644 - import { useState } from "react"; - import type { TransactionFilters } from "./helpers"; - import { ChevronDown } from "lucide-react"; - // const TABS = ['Bet History', 'Deposit', 'Withdraw']; - const RETURN_OPTIONS: Array<{ value: TransactionFilters["returnFilter"]; label: string }> = [ - { value: 'all', label: 'All Returns' }, - { value: 'won', label: 'Won' }, - { value: 'lost', label: 'Lost' }, - { value: 'pending', label: 'Pending' }, - ]; - - export default function TransactionTabs({ - filters, - onFiltersChange, - onClearFilters, - totalCount,
Added / After Commit
+ diff --git a/src/components/transactions/TransactionTabs.tsx b/src/components/transactions/TransactionTabs.tsx + index 0a830a9..dc96947 100644 + import { useState } from "react"; + import type { TransactionFilters } from "./helpers"; + import { ChevronDown } from "lucide-react"; + + // const TABS = ['Bet History', 'Deposit', 'Withdraw']; + + const RETURN_OPTIONS: Array<{ + value: TransactionFilters["returnFilter"]; + label: string; + }> = [ + { value: "all", label: "All Returns" }, + { value: "won", label: "Won" }, + { value: "lost", label: "Lost" }, + { value: "pending", label: "Pending" }, + ]; +
Removed / Before Commit
- diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx - index c9c22e5..0cc0159 100644 - dispatchLogoutEvent(); - - window.location.href = - "/login"; - } - - // Handle login from another tab/device - force logout current tab if DIFFERENT user
Added / After Commit
+ diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx + index c9c22e5..0cc0159 100644 + dispatchLogoutEvent(); + + window.location.href = + "/"; + } + + // Handle login from another tab/device - force logout current tab if DIFFERENT user
Removed / Before Commit
- diff --git a/src/pages/HorseRacing.tsx b/src/pages/HorseRacing.tsx - index dfd963c..78d5aad 100644 - import BannerCarousel from "../components/banner/BannerCarousel" - import RaceAccordion from "../components/racing/ReaceAccordion" - import { useThemeColors } from "../hooks/useThemeColors" - - - const COUNTRY_FLAG_BASE_URL = - "https://whitelable-dev-bucket.s3.ap-south-1.amazonaws.com/countries/" - - const RacingPage = () => { - const colors = useThemeColors() - const [countries, setCountries] = useState<Country[]>([]) - const [activeCountry, setActiveCountry] = useState<string>("") - const [raceEvents, setRaceEvents] = useState<RaceEvent[]>([]) - const [loading, setLoading] = useState(true) - const selectedCountry = countries.find((country) => country._id === activeCountry) ?? null -
Added / After Commit
+ diff --git a/src/pages/HorseRacing.tsx b/src/pages/HorseRacing.tsx + index dfd963c..78d5aad 100644 + import BannerCarousel from "../components/banner/BannerCarousel" + import RaceAccordion from "../components/racing/ReaceAccordion" + import { useThemeColors } from "../hooks/useThemeColors" + import MultiRaceDetail from "./MultiRaceDetail" + + + const COUNTRY_FLAG_BASE_URL = + "https://whitelable-dev-bucket.s3.ap-south-1.amazonaws.com/countries/" + + type ViewMode = "allRaces" | "multibet" + + const RacingPage = () => { + const colors = useThemeColors() + const [countries, setCountries] = useState<Country[]>([]) + const [activeCountry, setActiveCountry] = useState<string>("") + const [raceEvents, setRaceEvents] = useState<RaceEvent[]>([])
Removed / Before Commit
- diff --git a/src/pages/HorseRacingDetails.tsx b/src/pages/HorseRacingDetails.tsx - index 7c442f0..a38491f 100644 - return textsByMarketId - }, {}) - } - - return marketTexts.reduce<Record<string, string>>((textsByMarketId, marketText) => { - const scrollingText = marketText.scrolling_text?.trim() - - - - return ( - <div className="pb-[80px] w-full max-w-[1240px] mx-auto"> - <RaceHeader - eventName={race.race_name} - onRefreshMarkets={refreshRaceMarkets} - /> - </div>
Added / After Commit
+ diff --git a/src/pages/HorseRacingDetails.tsx b/src/pages/HorseRacingDetails.tsx + index 7c442f0..a38491f 100644 + return textsByMarketId + }, {}) + } + + return marketTexts.reduce<Record<string, string>>((textsByMarketId, marketText) => { + const scrollingText = marketText.scrolling_text?.trim() + + + + return ( + <div className="w-full max-w-[1240px] mx-auto pb-[90px] ml-[3px] md:ml-0"> + <div className="pb-[80px] w-full max-w-[1240px] mx-auto"> + <RaceHeader + eventName={race.race_name} + onRefreshMarkets={refreshRaceMarkets} + />
Removed / Before Commit
- diff --git a/src/pages/MultiRaceDetail.tsx b/src/pages/MultiRaceDetail.tsx - index 2732321..fb4476c 100644 - import { formatRaceDateTime } from "../utils/dateFormat" - import { useAuth } from "../contexts/AuthContext" - import { emitBetPlaced } from "../utils/betEvents" - import toast from "react-hot-toast" - - type Runner = { - return numberValue === null ? "-" : numberValue.toFixed(2) - } - - const formatVolume = (volume: number | null | undefined) => { - const numberValue = toNullableNumber(volume) - return numberValue === null ? "" : numberValue.toLocaleString("en-IN") - if (!Number.isFinite(timestamp)) { - return "-" - } -
Added / After Commit
+ diff --git a/src/pages/MultiRaceDetail.tsx b/src/pages/MultiRaceDetail.tsx + index 2732321..fb4476c 100644 + import { formatRaceDateTime } from "../utils/dateFormat" + import { useAuth } from "../contexts/AuthContext" + import { emitBetPlaced } from "../utils/betEvents" + import { addExtraToOdd } from "../utils/oddsHelper" + import toast from "react-hot-toast" + + type Runner = { + return numberValue === null ? "-" : numberValue.toFixed(2) + } + + const formatDisplayedRunnerOdds = (odds: number | null | undefined) => { + const numberValue = toNullableNumber(odds) + const displayValue = addExtraToOdd(numberValue) + return displayValue === null ? "-" : displayValue.toFixed(2) + } +