├── .gitattributes ├── src ├── react-app-env.d.ts ├── store │ ├── constant.ts │ ├── reducers │ │ ├── persistReducer.tsx │ │ ├── index.ts │ │ ├── menu.ts │ │ ├── sports.ts │ │ ├── snackbar.ts │ │ └── auth.ts │ └── index.ts ├── assets │ ├── images │ │ ├── games │ │ │ ├── boom.png │ │ │ ├── fire.png │ │ │ ├── limbo1.png │ │ │ ├── limbo2.png │ │ │ ├── rocket.png │ │ │ ├── darkPanel.png │ │ │ ├── mountain.png │ │ │ ├── chip.svg │ │ │ └── back.svg │ │ ├── icons │ │ │ ├── SOL.png │ │ │ ├── phantom-logo.png │ │ │ ├── coinbase.svg │ │ │ └── wallet.svg │ │ ├── logo │ │ │ ├── logo.png │ │ │ └── 200xlogo.png │ │ ├── payments │ │ │ ├── 1.png │ │ │ └── 2.png │ │ ├── sports │ │ │ └── trophy.png │ │ ├── users │ │ │ └── avatar.png │ │ ├── landing │ │ │ ├── header-bg.jpg │ │ │ └── img-contact-mail.svg │ │ └── maintenance │ │ │ ├── img-error-text.svg │ │ │ ├── img-error-purple.svg │ │ │ ├── img-error-bg.svg │ │ │ └── img-error-bg-dark.svg │ ├── fonts │ │ ├── Unlock-Regular.ttf │ │ ├── fa-solid-900.woff2 │ │ ├── sportsicons.woff2 │ │ ├── Silkscreen-Bold.ttf │ │ ├── Silkscreen-Regular.ttf │ │ └── OFL.txt │ └── scss │ │ ├── fontawesome.scss │ │ ├── sportsicon.scss │ │ └── _themes-vars.module.scss ├── types │ ├── menu.ts │ ├── overrides │ │ ├── Alert.d.ts │ │ ├── createTheme.d.ts │ │ ├── createPalette.d.ts │ │ └── createTypography.d.ts │ ├── snackbar.ts │ ├── config.ts │ ├── payment.ts │ ├── index.ts │ ├── auth.ts │ ├── sports.ts │ └── default-theme.ts ├── hooks │ ├── useConfig.ts │ ├── useApi.ts │ ├── useScriptRef.ts │ └── useLocalStorage.ts ├── navigation │ ├── index.tsx │ ├── pages.tsx │ └── main.tsx ├── ui-component │ ├── Logo.tsx │ ├── Loader.tsx │ ├── Loadable.tsx │ ├── Locales.tsx │ ├── extended │ │ ├── Avatar.tsx │ │ ├── AnimateButton.tsx │ │ ├── Transitions.tsx │ │ └── Snackbar.tsx │ └── cards │ │ ├── SubCard.tsx │ │ └── MainCard.tsx ├── views │ ├── mybets │ │ └── history │ │ │ └── index.tsx │ ├── casino │ │ └── Blackjack │ │ │ ├── Card.tsx │ │ │ ├── Deal.tsx │ │ │ └── Model.tsx │ ├── auth │ │ ├── Login.tsx │ │ ├── ResetPassword.tsx │ │ ├── ForgotPassword.tsx │ │ ├── auth-forms │ │ │ └── AuthLogin.tsx │ │ └── Register.tsx │ ├── sports │ │ └── component │ │ │ ├── OddNum.tsx │ │ │ └── Betslip │ │ │ └── index.tsx │ ├── profile │ │ └── Wallet │ │ │ ├── index.tsx │ │ │ └── DepositCoinpayment.tsx │ └── pages │ │ └── Error.tsx ├── layout │ ├── CasinoLayout │ │ └── index.tsx │ ├── MainLayout │ │ ├── LogoSection │ │ │ └── index.tsx │ │ ├── Sidebar │ │ │ └── MenuList │ │ │ │ ├── index.tsx │ │ │ │ └── NavGroup │ │ │ │ └── index.tsx │ │ ├── Advertisement │ │ │ └── index.tsx │ │ ├── Header │ │ │ ├── BetslipSection │ │ │ │ └── index.tsx │ │ │ └── SearchSection │ │ │ │ └── index.tsx │ │ ├── MobileMenu │ │ │ └── index.tsx │ │ └── index.tsx │ ├── NavigationScroll.tsx │ ├── AuthLayout │ │ └── index.tsx │ ├── UserLayout │ │ ├── index.tsx │ │ └── NavItem.tsx │ ├── MinimalLayout │ │ └── index.tsx │ ├── MyBetsLayout │ │ └── index.tsx │ └── Footer.tsx ├── utils │ ├── getlibrary.ts │ ├── snackbar.ts │ ├── AuthGuard.tsx │ ├── number.tsx │ ├── games.ts │ ├── Icons.tsx │ ├── password-strength.ts │ ├── axios.ts │ └── connectors.ts ├── reportWebVitals.ts ├── routes │ ├── index.tsx │ ├── AuthenticationRoutes.tsx │ ├── MyBetsRoutes.tsx │ ├── ProfileRoutes.tsx │ ├── MainRoutes.tsx │ └── CasinoRoutes.tsx ├── config.ts ├── themes │ ├── shadows.tsx │ ├── index.tsx │ ├── typography.tsx │ └── palette.tsx ├── contexts │ └── ConfigContext.tsx ├── index.tsx └── serviceWorker.tsx ├── public ├── logo.png ├── favicon.ico └── index.html ├── .prettierrc ├── .eslintrc.js ├── tsconfig.json ├── config-overrides.js └── .gitignore /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | declare module 'oddslib'; 3 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /src/store/constant.ts: -------------------------------------------------------------------------------- 1 | export const gridSpacing = 3; 2 | export const drawerWidth = 280; 3 | export const appDrawerWidth = 320; 4 | -------------------------------------------------------------------------------- /src/assets/images/games/boom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/games/boom.png -------------------------------------------------------------------------------- /src/assets/images/games/fire.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/games/fire.png -------------------------------------------------------------------------------- /src/assets/images/icons/SOL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/icons/SOL.png -------------------------------------------------------------------------------- /src/assets/images/logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/logo/logo.png -------------------------------------------------------------------------------- /src/assets/images/payments/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/payments/1.png -------------------------------------------------------------------------------- /src/assets/images/payments/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/payments/2.png -------------------------------------------------------------------------------- /src/types/menu.ts: -------------------------------------------------------------------------------- 1 | export type MenuProps = { 2 | selectedItem: string[]; 3 | drawerOpen: boolean; 4 | page: string; 5 | }; 6 | -------------------------------------------------------------------------------- /src/assets/fonts/Unlock-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/fonts/Unlock-Regular.ttf -------------------------------------------------------------------------------- /src/assets/fonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/fonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /src/assets/fonts/sportsicons.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/fonts/sportsicons.woff2 -------------------------------------------------------------------------------- /src/assets/images/games/limbo1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/games/limbo1.png -------------------------------------------------------------------------------- /src/assets/images/games/limbo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/games/limbo2.png -------------------------------------------------------------------------------- /src/assets/images/games/rocket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/games/rocket.png -------------------------------------------------------------------------------- /src/assets/images/logo/200xlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/logo/200xlogo.png -------------------------------------------------------------------------------- /src/assets/images/sports/trophy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/sports/trophy.png -------------------------------------------------------------------------------- /src/assets/images/users/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/users/avatar.png -------------------------------------------------------------------------------- /src/assets/fonts/Silkscreen-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/fonts/Silkscreen-Bold.ttf -------------------------------------------------------------------------------- /src/assets/images/games/darkPanel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/games/darkPanel.png -------------------------------------------------------------------------------- /src/assets/images/games/mountain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/games/mountain.png -------------------------------------------------------------------------------- /src/assets/fonts/Silkscreen-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/fonts/Silkscreen-Regular.ttf -------------------------------------------------------------------------------- /src/assets/images/icons/phantom-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/icons/phantom-logo.png -------------------------------------------------------------------------------- /src/assets/images/landing/header-bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fairrustana/Sports-Betting-Sportsbook/HEAD/src/assets/images/landing/header-bg.jpg -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSpacing": true, 3 | "printWidth": 140, 4 | "singleQuote": true, 5 | "trailingComma": "none", 6 | "tabWidth": 4, 7 | "useTabs": false 8 | } 9 | -------------------------------------------------------------------------------- /src/hooks/useConfig.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { ConfigContext } from 'contexts/ConfigContext'; 3 | 4 | const useConfig = () => useContext(ConfigContext); 5 | 6 | export default useConfig; 7 | -------------------------------------------------------------------------------- /src/navigation/index.tsx: -------------------------------------------------------------------------------- 1 | import main from './main'; 2 | import { NavItemType } from 'types'; 3 | 4 | const menuItems: { items: NavItemType[] } = { 5 | items: [main] 6 | }; 7 | 8 | export default menuItems; 9 | -------------------------------------------------------------------------------- /src/types/overrides/Alert.d.ts: -------------------------------------------------------------------------------- 1 | import * as Alert from '@mui/material/Alert'; 2 | 3 | declare module '@mui/material/Alert' { 4 | interface AlertPropsColorOverrides { 5 | primary; 6 | secondary; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/ui-component/Logo.tsx: -------------------------------------------------------------------------------- 1 | import LogoImg from 'assets/images/logo/logo.png'; 2 | 3 | const Logo = () => ; 4 | 5 | export default Logo; 6 | -------------------------------------------------------------------------------- /src/views/mybets/history/index.tsx: -------------------------------------------------------------------------------- 1 | import { Grid } from "@mui/material"; 2 | 3 | const SportsBetsList = () => { 4 | return ( 5 | 6 | 7 | ); 8 | }; 9 | 10 | export default SportsBetsList; 11 | -------------------------------------------------------------------------------- /src/layout/CasinoLayout/index.tsx: -------------------------------------------------------------------------------- 1 | import { Outlet } from 'react-router-dom'; 2 | import History from 'views/casino/History'; 3 | 4 | const CasinoLayout = () => ( 5 | <> 6 | 7 | 8 | 9 | ); 10 | 11 | export default CasinoLayout; 12 | -------------------------------------------------------------------------------- /src/layout/MainLayout/LogoSection/index.tsx: -------------------------------------------------------------------------------- 1 | import { HOME_PATH } from 'config'; 2 | import Logo from 'ui-component/Logo'; 3 | 4 | const LogoSection = () => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default LogoSection; 11 | -------------------------------------------------------------------------------- /src/ui-component/Loader.tsx: -------------------------------------------------------------------------------- 1 | import LinearProgress from '@mui/material/LinearProgress'; 2 | import { LoaderWrapper } from 'ui-component'; 3 | 4 | const Loader = () => ( 5 | 6 | 7 | 8 | ); 9 | 10 | export default Loader; 11 | -------------------------------------------------------------------------------- /src/utils/getlibrary.ts: -------------------------------------------------------------------------------- 1 | import { Web3Provider, JsonRpcFetchFunc } from '@ethersproject/providers'; 2 | 3 | const getLibrary = (provider: JsonRpcFetchFunc) => { 4 | const library = new Web3Provider(provider, 'any'); 5 | library.pollingInterval = 15000; 6 | return library; 7 | }; 8 | 9 | export default getLibrary; 10 | -------------------------------------------------------------------------------- /src/hooks/useApi.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import APIContext from 'contexts/ApiContext'; 3 | 4 | const useApi = () => { 5 | const context = useContext(APIContext); 6 | 7 | if (!context) throw new Error('context must be use inside provider'); 8 | 9 | return context; 10 | }; 11 | 12 | export default useApi; 13 | -------------------------------------------------------------------------------- /src/hooks/useScriptRef.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | 3 | const useScriptRef = () => { 4 | const scripted = useRef(true); 5 | 6 | useEffect( 7 | () => () => { 8 | scripted.current = false; 9 | }, 10 | [] 11 | ); 12 | 13 | return scripted; 14 | }; 15 | 16 | export default useScriptRef; 17 | -------------------------------------------------------------------------------- /src/store/reducers/persistReducer.tsx: -------------------------------------------------------------------------------- 1 | import { persistReducer } from 'redux-persist'; 2 | import storage from 'redux-persist/lib/storage'; 3 | 4 | const persistConfig = { 5 | key: 'boi-book-v1', 6 | storage, 7 | whitelist: ['auth'] 8 | }; 9 | 10 | const persist = (reducers: any) => persistReducer(persistConfig, reducers); 11 | 12 | export default persist; 13 | -------------------------------------------------------------------------------- /src/types/snackbar.ts: -------------------------------------------------------------------------------- 1 | import { AlertProps, SnackbarOrigin } from '@mui/material'; 2 | 3 | export interface SnackbarProps { 4 | action: boolean; 5 | open: boolean; 6 | message: string; 7 | anchorOrigin: SnackbarOrigin; 8 | variant: string; 9 | alert: AlertProps; 10 | transition: string; 11 | close: boolean; 12 | actionButton: boolean; 13 | } 14 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | node: true, 4 | es6: true, 5 | browser: true 6 | }, 7 | parserOptions: { 8 | ecmaVersion: 6, 9 | sourceType: 'module', 10 | ecmaFeatures: { 11 | jsx: true, 12 | modules: true, 13 | experimentalObjectRestSpread: true 14 | } 15 | }, 16 | rules: { 17 | } 18 | } -------------------------------------------------------------------------------- /src/store/reducers/index.ts: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | 3 | import authReducer from './auth'; 4 | import menuReducer from './menu'; 5 | import sportsReducer from './sports'; 6 | import snackbarReducer from './snackbar'; 7 | 8 | const reducer = combineReducers({ 9 | auth: authReducer, 10 | menu: menuReducer, 11 | sports: sportsReducer, 12 | snackbar: snackbarReducer 13 | }); 14 | 15 | export default reducer; 16 | -------------------------------------------------------------------------------- /src/utils/snackbar.ts: -------------------------------------------------------------------------------- 1 | import { store } from 'store'; 2 | import { openSnackbar } from 'store/reducers/snackbar'; 3 | 4 | const snackbar = (message: any, color: string = 'success') => { 5 | store.dispatch( 6 | openSnackbar({ 7 | open: true, 8 | message, 9 | variant: 'alert', 10 | transition: 'SlideLeft', 11 | alert: { color }, 12 | anchorOrigin: { vertical: 'top', horizontal: 'right' } 13 | }) 14 | ); 15 | }; 16 | 17 | export default snackbar; 18 | -------------------------------------------------------------------------------- /src/layout/NavigationScroll.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, ReactElement } from 'react'; 2 | import { useLocation } from 'react-router-dom'; 3 | 4 | const NavigationScroll = ({ children }: { children: ReactElement | null }) => { 5 | const { pathname } = useLocation(); 6 | 7 | useEffect(() => { 8 | window.scrollTo({ 9 | top: 0, 10 | left: 0, 11 | behavior: 'smooth' 12 | }); 13 | }, [pathname]); 14 | 15 | return children || null; 16 | }; 17 | 18 | export default NavigationScroll; 19 | -------------------------------------------------------------------------------- /src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /src/ui-component/Loadable.tsx: -------------------------------------------------------------------------------- 1 | import { Suspense, LazyExoticComponent, ComponentType } from 'react'; 2 | 3 | import { LinearProgressProps } from '@mui/material'; 4 | 5 | import Loader from './Loader'; 6 | 7 | interface LoaderProps extends LinearProgressProps {} 8 | 9 | const Loadable = (Component: LazyExoticComponent<() => JSX.Element> | ComponentType | any) => (props: LoaderProps) => 10 | ( 11 | }> 12 | 13 | 14 | ); 15 | 16 | export default Loadable; 17 | -------------------------------------------------------------------------------- /src/utils/AuthGuard.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { useNavigate } from 'react-router-dom'; 3 | import { GuardProps } from 'types'; 4 | import { HOME_PATH } from 'config'; 5 | import { useSelector } from 'store'; 6 | 7 | const AuthGuard = ({ children }: GuardProps) => { 8 | const navigate = useNavigate(); 9 | const { isLoggedIn } = useSelector((state) => state.auth); 10 | 11 | useEffect(() => { 12 | if (!isLoggedIn) { 13 | navigate(HOME_PATH, { replace: true }); 14 | } 15 | }, [isLoggedIn, navigate]); 16 | 17 | return children; 18 | }; 19 | 20 | export default AuthGuard; 21 | -------------------------------------------------------------------------------- /src/routes/index.tsx: -------------------------------------------------------------------------------- 1 | import { useRoutes } from 'react-router-dom'; 2 | 3 | import MainRoutes from './MainRoutes'; 4 | import MyBetsRoutes from './MyBetsRoutes'; 5 | // import CasinoRoutes from './CasinoRoutes'; 6 | import ProfileRoutes from './ProfileRoutes'; 7 | import AuthenticationRoutes from './AuthenticationRoutes'; 8 | import Error from 'views/pages/Error'; 9 | 10 | export default function ThemeRoutes() { 11 | return useRoutes([ 12 | MainRoutes, 13 | // CasinoRoutes, 14 | ProfileRoutes, 15 | MyBetsRoutes, 16 | AuthenticationRoutes, 17 | { path: '*', element: } 18 | ]); 19 | } 20 | -------------------------------------------------------------------------------- /src/types/overrides/createTheme.d.ts: -------------------------------------------------------------------------------- 1 | import * as createTheme from '@mui/material/styles'; 2 | import { customShadows } from 'themes/shadows'; 3 | 4 | declare module '@mui/material/styles' { 5 | export interface ThemeOptions { 6 | customShadows?: customShadows; 7 | customization?: TypographyOptions | ((palette: Palette) => TypographyOptions); 8 | darkTextSecondary?: string; 9 | textDark?: string; 10 | darkTextPrimary?: string; 11 | grey500?: string; 12 | } 13 | interface Theme { 14 | customShadows: customShadows; 15 | customization: Typography; 16 | darkTextSecondary: string; 17 | textDark: string; 18 | grey500: string; 19 | darkTextPrimary: string; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/utils/number.tsx: -------------------------------------------------------------------------------- 1 | import NumberFormat from 'react-number-format'; 2 | 3 | export const toNumber = (number: number | undefined, fixed = 5, status = false) => { 4 | if (!number || isNaN(number)) { 5 | if (status) { 6 | return Number(0).toFixed(fixed); 7 | } 8 | return '0.00'; 9 | } 10 | if (status) { 11 | return Number(number).toFixed(fixed).toLocaleString(); 12 | } 13 | return Number(Number(number).toFixed(fixed)).toLocaleString(); 14 | }; 15 | 16 | export const toNumberTag = (number = 0, fixed = 5) => { 17 | if (!number || isNaN(number)) { 18 | return '0.00'; 19 | } 20 | return ; 21 | }; 22 | -------------------------------------------------------------------------------- /src/layout/AuthLayout/index.tsx: -------------------------------------------------------------------------------- 1 | import { useSelector } from 'store'; 2 | 3 | import Login from 'views/auth/Login'; 4 | import Register from 'views/auth/Register'; 5 | import Forgot from 'views/auth/ForgotPassword'; 6 | import ResetPassword from 'views/auth/ResetPassword'; 7 | import Bets from 'views/mybets/bets'; 8 | 9 | const AuthLayout = () => { 10 | const { page } = useSelector((state) => state.menu); 11 | return ( 12 | <> 13 | {page === 'login' && } 14 | {page === 'register' && } 15 | {page === 'forgot' && } 16 | {page === 'reset-password' && } 17 | {page === 'bets' && } 18 | 19 | ); 20 | }; 21 | 22 | export default AuthLayout; 23 | -------------------------------------------------------------------------------- /src/assets/images/icons/coinbase.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/store/reducers/menu.ts: -------------------------------------------------------------------------------- 1 | import { MenuProps } from 'types/menu'; 2 | import { createSlice } from '@reduxjs/toolkit'; 3 | 4 | const initialState: MenuProps = { 5 | selectedItem: ['dashboard'], 6 | drawerOpen: false, 7 | page: '' 8 | }; 9 | 10 | const menu = createSlice({ 11 | name: 'menu', 12 | initialState, 13 | reducers: { 14 | activeItem(state, action) { 15 | state.selectedItem = action.payload; 16 | }, 17 | 18 | openDrawer(state, action) { 19 | state.drawerOpen = action.payload; 20 | }, 21 | 22 | ChangePage(state, action: any) { 23 | state.page = action.payload; 24 | } 25 | } 26 | }); 27 | 28 | export default menu.reducer; 29 | 30 | export const { activeItem, openDrawer, ChangePage } = menu.actions; 31 | -------------------------------------------------------------------------------- /src/types/overrides/createPalette.d.ts: -------------------------------------------------------------------------------- 1 | import * as createPalette from '@mui/material/styles/createPalette'; 2 | 3 | declare module '@mui/material/styles/createPalette' { 4 | interface PaletteColor { 5 | 100: string; 6 | 200: string; 7 | 300: string; 8 | 400: string; 9 | 500: string; 10 | 600: string; 11 | 700: string; 12 | 800: string; 13 | 900: string; 14 | } 15 | 16 | export interface TypeText { 17 | dark: string; 18 | hint: string; 19 | } 20 | 21 | interface PaletteOptions { 22 | orange?: PaletteColorOptions; 23 | dark?: PaletteColorOptions; 24 | icon?: IconPaletteColorOptions; 25 | } 26 | interface Palette { 27 | orange: PaletteColor; 28 | dark: PaletteColor; 29 | icon: IconPaletteColor; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/views/casino/Blackjack/Card.tsx: -------------------------------------------------------------------------------- 1 | import { CardProp } from './Model'; 2 | 3 | class Card { 4 | card: CardProp; 5 | 6 | constructor(card: CardProp) { 7 | this.card = card; 8 | } 9 | 10 | getIndex() { 11 | return this.card.index; 12 | } 13 | 14 | getType() { 15 | return this.card.type; 16 | } 17 | 18 | getRank() { 19 | return this.card.rank; 20 | } 21 | 22 | getSuit() { 23 | return this.card.suit; 24 | } 25 | 26 | getValue() { 27 | switch (this.getRank()) { 28 | case 'A': 29 | return 11; 30 | case 'K': 31 | case 'Q': 32 | case 'J': 33 | return 10; 34 | default: 35 | return Math.floor(Number(this.getRank())); 36 | } 37 | } 38 | } 39 | 40 | export default Card; 41 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Sidebar/MenuList/index.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from 'react'; 2 | 3 | import { Typography } from '@mui/material'; 4 | 5 | import { FormattedMessage } from 'react-intl'; 6 | 7 | import menuItem from 'navigation'; 8 | import NavGroup from './NavGroup'; 9 | 10 | const MenuList = () => { 11 | const navItems = menuItem.items.map((item) => { 12 | switch (item.type) { 13 | case 'group': 14 | return ; 15 | default: 16 | return ( 17 | 18 | 19 | 20 | ); 21 | } 22 | }); 23 | 24 | return <>{navItems}; 25 | }; 26 | 27 | export default memo(MenuList); 28 | -------------------------------------------------------------------------------- /src/views/auth/Login.tsx: -------------------------------------------------------------------------------- 1 | import Dialog from '@mui/material/Dialog'; 2 | import DialogContent from '@mui/material/DialogContent'; 3 | 4 | import { useDispatch } from 'store'; 5 | import { ChangePage } from 'store/reducers/menu'; 6 | 7 | import AuthMetamask from './auth-forms/AuthMetamask'; 8 | 9 | const Login = () => { 10 | const dispatch = useDispatch(); 11 | 12 | return ( 13 | dispatch(ChangePage(''))} 16 | aria-labelledby="alert-dialog-title" 17 | aria-describedby="alert-dialog-description" 18 | sx={{ zIndex: '999 !important' }} 19 | > 20 | 21 | 22 | 23 | 24 | ); 25 | }; 26 | 27 | export default Login; 28 | -------------------------------------------------------------------------------- /src/assets/images/games/chip.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "jsx": "react-jsx", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "lib": ["dom", "dom.iterable", "esnext"], 11 | "allowJs": true, 12 | "noUnusedLocals": false, 13 | "allowSyntheticDefaultImports": true, 14 | "noFallthroughCasesInSwitch": true, 15 | "moduleResolution": "node", 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "noEmit": true, 19 | "noImplicitAny": true, 20 | "noImplicitThis": true, 21 | "strictNullChecks": true, 22 | "types": ["node", "webpack-env"], 23 | "typeRoots": ["./types"], 24 | "baseUrl": "src" 25 | }, 26 | "include": ["src"] 27 | } 28 | -------------------------------------------------------------------------------- /src/routes/AuthenticationRoutes.tsx: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | 3 | import Loadable from 'ui-component/Loadable'; 4 | import MinimalLayout from 'layout/MinimalLayout'; 5 | 6 | const PagesTerms = Loadable(lazy(() => import('views/pages/Terms'))); 7 | const PagesContactUS = Loadable(lazy(() => import('views/pages/contact-us'))); 8 | const PagesPrivacyPolicy = Loadable(lazy(() => import('views/pages/PrivacyPolicy'))); 9 | 10 | const AuthenticationRoutes = { 11 | path: '/pages', 12 | element: , 13 | children: [ 14 | { 15 | path: '/pages/terms', 16 | element: 17 | }, 18 | { 19 | path: '/pages/contact-us', 20 | element: 21 | }, 22 | { 23 | path: '/pages/privacy-policy', 24 | element: 25 | } 26 | ] 27 | }; 28 | 29 | export default AuthenticationRoutes; 30 | -------------------------------------------------------------------------------- /src/store/index.ts: -------------------------------------------------------------------------------- 1 | import { persistStore } from 'redux-persist'; 2 | import { configureStore } from '@reduxjs/toolkit'; 3 | import { useDispatch as useAppDispatch, useSelector as useAppSelector, TypedUseSelectorHook } from 'react-redux'; 4 | 5 | import rootReducer from './reducers'; 6 | import persistReducer from './reducers/persistReducer'; 7 | 8 | const store = configureStore({ 9 | reducer: persistReducer(rootReducer), 10 | middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false, immutableCheck: false }) 11 | }); 12 | 13 | const persister = persistStore(store); 14 | 15 | export type RootState = ReturnType; 16 | 17 | export type AppDispatch = typeof store.dispatch; 18 | 19 | const { dispatch } = store; 20 | 21 | const useDispatch = () => useAppDispatch(); 22 | const useSelector: TypedUseSelectorHook = useAppSelector; 23 | 24 | export { store, persister, dispatch, useSelector, useDispatch }; 25 | -------------------------------------------------------------------------------- /src/config.ts: -------------------------------------------------------------------------------- 1 | import { ConfigProps } from 'types/config'; 2 | 3 | export const BASE_URL = process.env.REACT_APP_API_URL || 'http://localhost:2020'; 4 | export const BASE_PATH = ''; 5 | export const HOME_PATH = '/sports'; 6 | 7 | const config: ConfigProps = { 8 | fontFamily: `'Roboto', sans-serif`, 9 | borderRadius: 8, 10 | boxShadow: 'rgba(0, 0, 0, 0.2) 0px 1px 3px 0px, rgba(0, 0, 0, 0.12) 0px 1px 2px 0px, rgba(255, 255, 255, 0.04) 0px 1px 0px 0px inset', 11 | outlinedFilled: true, 12 | navType: 'dark', 13 | presetColor: 'default', 14 | dark1: '#191919', 15 | dark2: '#272727', 16 | dark3: '#1c1c1c', 17 | grey2: '#8c8c8c', 18 | locale: 'en', 19 | rtlLayout: false, 20 | timer1: 5000, 21 | timer2: 900000, 22 | RECAPTCHA_SITE_KEY: '6LeRhsIeAAAAADY6KUkpQaIqPTKsXy2sa7u4JBAb', 23 | adminSolanaWallet: '8Myhky6nWVJFeNkcBH3FE9i29KqV4qsD8reook3AUqYk', 24 | adminMetamaskWallet: '0x9FbCF8e7a61c734869FC3d00e17c4c616EDBbd98' 25 | }; 26 | 27 | export default config; 28 | -------------------------------------------------------------------------------- /src/types/config.ts: -------------------------------------------------------------------------------- 1 | import { PaletteMode } from '@mui/material'; 2 | 3 | export type ConfigProps = { 4 | fontFamily: string; 5 | borderRadius: number; 6 | outlinedFilled: boolean; 7 | navType: PaletteMode; 8 | presetColor: string; 9 | grey2: string; 10 | dark1: string; 11 | dark2: string; 12 | dark3: string; 13 | boxShadow: string; 14 | locale: string; 15 | rtlLayout: boolean; 16 | timer1: number; 17 | timer2: number; 18 | RECAPTCHA_SITE_KEY: string; 19 | adminSolanaWallet: string; 20 | adminMetamaskWallet: string; 21 | }; 22 | 23 | export type CustomizationProps = { 24 | fontFamily: string; 25 | borderRadius: number; 26 | outlinedFilled: boolean; 27 | navType: PaletteMode; 28 | presetColor: string; 29 | boxShadow: string; 30 | locale: string; 31 | rtlLayout: boolean; 32 | onChangeLocale: (locale: string) => void; 33 | }; 34 | 35 | export enum ModeTypes { 36 | pro = 'pro', 37 | _dev = '_dev', 38 | dev = 'dev' 39 | } 40 | -------------------------------------------------------------------------------- /src/views/sports/component/OddNum.tsx: -------------------------------------------------------------------------------- 1 | import { Typography } from '@mui/material'; 2 | import * as oddslib from 'oddslib'; 3 | import { useSelector } from 'store'; 4 | 5 | const OddNum = ({ odd, color }: { odd: number; color?: string }) => { 6 | const { user } = useSelector((state) => state.auth); 7 | 8 | const oddFormat = (params: number) => { 9 | if (user?.oddsformat === undefined || user?.oddsformat === 'decimal') { 10 | return Number(params).toFixed(2); 11 | } 12 | try { 13 | const number = oddslib.from('decimal', params).to(user.oddsformat); 14 | if (user.oddsformat === 'moneyline') { 15 | return Math.floor(number); 16 | } 17 | return Number(number).toFixed(2); 18 | } catch (error) { 19 | return 0; 20 | } 21 | }; 22 | 23 | return ( 24 | 25 | {oddFormat(odd)} 26 | 27 | ); 28 | }; 29 | 30 | export default OddNum; 31 | -------------------------------------------------------------------------------- /src/routes/MyBetsRoutes.tsx: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | import MainLayout from 'layout/MainLayout'; 3 | import MyBetsLayout from 'layout/MyBetsLayout'; 4 | import Loadable from 'ui-component/Loadable'; 5 | import AuthGuard from 'utils/AuthGuard'; 6 | 7 | const MybetsActive = Loadable(lazy(() => import('views/mybets'))); 8 | const MybetsSettled = Loadable(lazy(() => import('views/mybets/settled'))); 9 | const MybetsHistory = Loadable(lazy(() => import('views/mybets/history/'))); 10 | 11 | const ProfileRoutes = { 12 | path: '/my-bets', 13 | element: ( 14 | 15 | 16 | 17 | 18 | 19 | ), 20 | children: [ 21 | { 22 | path: '/my-bets', 23 | element: 24 | }, 25 | { 26 | path: '/my-bets/settled', 27 | element: 28 | }, 29 | { 30 | path: '/my-bets/history', 31 | element: 32 | } 33 | ] 34 | }; 35 | 36 | export default ProfileRoutes; 37 | -------------------------------------------------------------------------------- /src/assets/scss/fontawesome.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Font Awesome 5 Pro'; 3 | font-style: normal; 4 | font-weight: 900; 5 | font-display: block; 6 | src: url(../fonts/fa-solid-900.woff2) format('woff2'); 7 | } 8 | 9 | .fas { 10 | font-family: 'Font Awesome 5 Pro'; 11 | font-weight: 900; 12 | -moz-osx-font-smoothing: grayscale; 13 | -webkit-font-smoothing: antialiased; 14 | display: inline-block; 15 | font-style: normal; 16 | font-variant: normal; 17 | text-rendering: auto; 18 | line-height: 1; 19 | } 20 | 21 | .fa-spade:before { 22 | content: '\f2f4'; 23 | } 24 | 25 | .fa-heart:before { 26 | content: '\f004'; 27 | } 28 | 29 | .fa-club:before { 30 | content: '\f327'; 31 | } 32 | 33 | .fa-diamond:before { 34 | content: '\f219'; 35 | } 36 | 37 | .fa-gem:before { 38 | content: '\f3a5'; 39 | } 40 | 41 | .fa-square:before { 42 | content: '\f0c8'; 43 | } 44 | 45 | .fa-coin:before { 46 | content: '\f85c'; 47 | } 48 | 49 | .fa-bullseye:before { 50 | content: '\f140'; 51 | } 52 | 53 | .fa-dice-d20:before { 54 | content: '\f6cf'; 55 | } 56 | 57 | .fa-rocket:before { 58 | content: '\f135'; 59 | } 60 | -------------------------------------------------------------------------------- /src/hooks/useLocalStorage.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from 'react'; 2 | 3 | export default function useLocalStorage(key: string, defaultValue: ValueType) { 4 | const [value, setValue] = useState(() => { 5 | const storedValue = localStorage.getItem(key); 6 | return storedValue === null ? defaultValue : JSON.parse(storedValue); 7 | }); 8 | 9 | useEffect(() => { 10 | const listener = (e: StorageEvent) => { 11 | if (e.storageArea === localStorage && e.key === key) { 12 | setValue(e.newValue ? JSON.parse(e.newValue) : e.newValue); 13 | } 14 | }; 15 | window.addEventListener('storage', listener); 16 | 17 | return () => { 18 | window.removeEventListener('storage', listener); 19 | }; 20 | }, [key, defaultValue]); 21 | 22 | const setValueInLocalStorage = (newValue: ValueType) => { 23 | setValue((currentValue: any) => { 24 | const result = typeof newValue === 'function' ? newValue(currentValue) : newValue; 25 | localStorage.setItem(key, JSON.stringify(result)); 26 | return result; 27 | }); 28 | }; 29 | 30 | return [value, setValueInLocalStorage]; 31 | } 32 | -------------------------------------------------------------------------------- /src/types/payment.ts: -------------------------------------------------------------------------------- 1 | export interface CurrencyProps { 2 | _id: string; 3 | symbol: string; 4 | name?: string; 5 | betLimit?: number; 6 | maxBet?: number; 7 | minBet?: number; 8 | minDeposit?: number; 9 | minWithdraw?: number; 10 | icon?: string; 11 | status?: boolean; 12 | deposit?: boolean; 13 | withdrawal?: boolean; 14 | network?: string; 15 | tokenMintAccount?: string; 16 | } 17 | 18 | export interface BalanceProps { 19 | _id: string; 20 | balance: number; 21 | currency: CurrencyProps; 22 | disabled: boolean; 23 | status: boolean; 24 | userId: string; 25 | } 26 | 27 | export interface TransactionsProps { 28 | _id: string; 29 | amount: number; 30 | currencyId: CurrencyProps; 31 | ipn_type: string; 32 | status_text: string; 33 | status: number; 34 | createdAt: Date; 35 | updatedAt: Date; 36 | } 37 | 38 | export interface GameProps { 39 | icon: string; 40 | name: string; 41 | } 42 | 43 | export interface HistoryProps { 44 | _id: string; 45 | amount: number; 46 | currency: string; 47 | game: GameProps; 48 | profit: number; 49 | status: string; 50 | username: string; 51 | createdAt: Date; 52 | } 53 | -------------------------------------------------------------------------------- /src/utils/games.ts: -------------------------------------------------------------------------------- 1 | import $ from 'jquery'; 2 | import { toNumber } from './number'; 3 | 4 | export const resultPopup = (game: any) => { 5 | const status = game.status.toLowerCase(); 6 | const popup = $(`
7 |
${Number(game.odds).toFixed(2)}x
8 |
9 |
${game.profit === 0 ? '0.00' : toNumber(game.profit)}
10 |
11 | `); 12 | $('.game-content').append(popup); 13 | popup.hide().fadeIn('fast'); 14 | setTimeout(() => { 15 | // eslint-disable-next-line 16 | popup.fadeOut('fast', function () { 17 | $(this).remove(); 18 | }); 19 | }, 2000); 20 | }; 21 | 22 | export const Random = (min: number, max: number, floor = true) => { 23 | const r = Math.random() * max + min; 24 | return floor ? Math.floor(r) : r; 25 | }; 26 | 27 | export const chain = (times: number, ms: number, cb: Function) => { 28 | let i = 0; 29 | const next = () => { 30 | if (i < times) { 31 | setTimeout(() => { 32 | cb(i); 33 | next(); 34 | }, ms); 35 | i += 1; 36 | } 37 | }; 38 | next(); 39 | }; 40 | -------------------------------------------------------------------------------- /src/utils/Icons.tsx: -------------------------------------------------------------------------------- 1 | import { IconContext } from 'react-icons'; 2 | import { IoIosFootball, IoIosBaseball } from 'react-icons/io'; 3 | import { GiAmericanFootballBall, GiAmericanFootballHelmet, GiBasketballBall, GiDeathStar } from 'react-icons/gi'; 4 | import { RiBoxingFill } from 'react-icons/ri'; 5 | 6 | const UseIcons = (icon: string) => { 7 | if (icon) { 8 | return ( 9 | 10 | {icon === 'football' ? : null} 11 | {icon === 'icehockey' ? : null} 12 | {icon === 'basketball' ? : null} 13 | {icon === 'americanfootball' ? : null} 14 | {icon === 'boxing' ? : null} 15 | {icon === 'baseball' ? : null} 16 | 17 | ); 18 | } 19 | return ( 20 | 21 |
22 | 23 |
24 |
25 | ); 26 | }; 27 | 28 | export default UseIcons; 29 | -------------------------------------------------------------------------------- /src/routes/ProfileRoutes.tsx: -------------------------------------------------------------------------------- 1 | import { lazy } from 'react'; 2 | import MainLayout from 'layout/MainLayout'; 3 | import UserLayout from 'layout/UserLayout'; 4 | import Loadable from 'ui-component/Loadable'; 5 | import AuthGuard from 'utils/AuthGuard'; 6 | 7 | const Wallet = Loadable(lazy(() => import('views/profile/Wallet'))); 8 | const Account = Loadable(lazy(() => import('views/profile/Account'))); 9 | const Referral = Loadable(lazy(() => import('views/profile/Referral'))); 10 | const Preferences = Loadable(lazy(() => import('views/profile/Preferences'))); 11 | 12 | const ProfileRoutes = { 13 | path: '/user', 14 | element: ( 15 | 16 | 17 | 18 | 19 | 20 | ), 21 | children: [ 22 | { 23 | path: '/user/wallet', 24 | element: 25 | }, 26 | { 27 | path: '/user/account', 28 | element: 29 | }, 30 | { 31 | path: '/user/referral', 32 | element: 33 | }, 34 | { 35 | path: '/user/preferences', 36 | element: 37 | } 38 | ] 39 | }; 40 | 41 | export default ProfileRoutes; 42 | -------------------------------------------------------------------------------- /src/layout/UserLayout/index.tsx: -------------------------------------------------------------------------------- 1 | import { Outlet } from 'react-router-dom'; 2 | 3 | import { CardContent, Grid, useTheme } from '@mui/material'; 4 | 5 | import { gridSpacing } from 'store/constant'; 6 | import MainCard from 'ui-component/cards/MainCard'; 7 | import NavItem from './NavItem'; 8 | 9 | const UserLayout = () => { 10 | const theme = useTheme(); 11 | 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 28 | 29 | 30 | 31 | 32 | 33 | ); 34 | }; 35 | 36 | export default UserLayout; 37 | -------------------------------------------------------------------------------- /src/themes/shadows.tsx: -------------------------------------------------------------------------------- 1 | import { alpha, Theme } from '@mui/material'; 2 | 3 | const createCustomShadow = (theme: Theme, color: string) => { 4 | const transparent = alpha(color, 0.24); 5 | return { 6 | z1: `0 1px 2px 0 ${transparent}`, 7 | z8: `0 8px 16px 0 ${transparent}`, 8 | z12: `0 12px 24px 0 ${transparent} 0 10px 20px 0 ${transparent}`, 9 | z16: `0 0 3px 0 ${transparent} 0 14px 28px -5px ${transparent}`, 10 | z20: `0 0 3px 0 ${transparent} 0 18px 36px -5px ${transparent}`, 11 | z24: `0 0 6px 0 ${transparent} 0 21px 44px 0 ${transparent}`, 12 | 13 | primary: `0px 12px 14px 0px ${alpha(theme.palette.primary.main, 0.3)}`, 14 | secondary: `0px 12px 14px 0px ${alpha(theme.palette.secondary.main, 0.3)}`, 15 | orange: `0px 12px 14px 0px ${alpha(theme.palette.orange.main, 0.3)}`, 16 | success: `0px 12px 14px 0px ${alpha(theme.palette.success.main, 0.3)}`, 17 | warning: `0px 12px 14px 0px ${alpha(theme.palette.warning.main, 0.3)}`, 18 | error: `0px 12px 14px 0px ${alpha(theme.palette.error.main, 0.3)}` 19 | }; 20 | }; 21 | 22 | export default function customShadows(navType: string, theme: Theme) { 23 | return navType === 'dark' ? createCustomShadow(theme, theme.palette.dark.main) : createCustomShadow(theme, theme.palette.grey[600]); 24 | } 25 | -------------------------------------------------------------------------------- /src/utils/password-strength.ts: -------------------------------------------------------------------------------- 1 | import { NumbColorFunc, StringBoolFunc, StringNumFunc } from 'types'; 2 | import value from 'assets/scss/_themes-vars.module.scss'; 3 | 4 | const hasNumber: StringBoolFunc = (number) => new RegExp(/[0-9]/).test(number); 5 | 6 | const hasMixed: StringBoolFunc = (number) => new RegExp(/[a-z]/).test(number) && new RegExp(/[A-Z]/).test(number); 7 | 8 | const hasSpecial: StringBoolFunc = (number) => new RegExp(/[!#@$%^&*)(+=._-]/).test(number); 9 | 10 | export const strengthColor: NumbColorFunc = (count) => { 11 | if (count < 2) return { label: 'Poor', color: value.errorMain }; 12 | if (count < 3) return { label: 'Weak', color: value.warningDark }; 13 | if (count < 4) return { label: 'Normal', color: value.orangeMain }; 14 | if (count < 5) return { label: 'Good', color: value.successMain }; 15 | if (count < 6) return { label: 'Strong', color: value.successDark }; 16 | return { label: 'Poor', color: value.errorMain }; 17 | }; 18 | 19 | export const strengthIndicator: StringNumFunc = (number) => { 20 | let strengths = 0; 21 | if (number.length > 5) strengths += 1; 22 | if (number.length > 7) strengths += 1; 23 | if (hasNumber(number)) strengths += 1; 24 | if (hasSpecial(number)) strengths += 1; 25 | if (hasMixed(number)) strengths += 1; 26 | return strengths; 27 | }; 28 | -------------------------------------------------------------------------------- /src/ui-component/Locales.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | 3 | import { IntlProvider, MessageFormatElement } from 'react-intl'; 4 | import useConfig from 'hooks/useConfig'; 5 | import Axios from 'utils/axios'; 6 | import Loader from './Loader'; 7 | 8 | interface LocalsProps { 9 | children: React.ReactNode; 10 | } 11 | 12 | const Locales = ({ children }: LocalsProps) => { 13 | const { locale } = useConfig(); 14 | const [loading, setLoading] = useState(true); 15 | const [messages, setMessages] = useState | Record | undefined>(); 16 | 17 | useEffect(() => { 18 | setLoading(true); 19 | Axios.post('api/v1/languages/word/', { id: locale || 'es' }) 20 | .then(({ data }) => { 21 | setMessages(data); 22 | setLoading(false); 23 | }) 24 | .catch(() => { 25 | setLoading(false); 26 | }); 27 | }, [locale]); 28 | 29 | if (loading) return ; 30 | return ( 31 | <> 32 | {messages && ( 33 | {}}> 34 | {children} 35 | 36 | )} 37 | 38 | ); 39 | }; 40 | 41 | export default Locales; 42 | -------------------------------------------------------------------------------- /src/utils/axios.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { BASE_URL } from 'config'; 3 | import { store } from 'store'; 4 | import { Logout } from 'store/reducers/auth'; 5 | import snackbar from './snackbar'; 6 | 7 | const axiosServices = axios.create(); 8 | 9 | axiosServices.interceptors.request.use( 10 | (config: any) => { 11 | config.baseURL = BASE_URL; 12 | const state = store.getState() as any; 13 | const accessToken = state.auth.token; 14 | if (accessToken) { 15 | config.headers.authorization = accessToken; 16 | } 17 | return config; 18 | }, 19 | (error) => Promise.reject(error) 20 | ); 21 | 22 | axiosServices.interceptors.response.use( 23 | (response) => response, 24 | (error) => { 25 | const { response } = error; 26 | if (response && response.status === 400) { 27 | snackbar(response.data, 'error'); 28 | } else if (response && response.status === 401) { 29 | store.dispatch(Logout({})); 30 | } else if (response && response.status === 413) { 31 | snackbar(response.data, 'error'); 32 | } else if (response && response.status === 429) { 33 | snackbar(response.data, 'error'); 34 | } else { 35 | console.log(response); 36 | } 37 | return Promise.reject(error); 38 | } 39 | ); 40 | 41 | export default axiosServices; 42 | -------------------------------------------------------------------------------- /src/layout/MainLayout/Sidebar/MenuList/NavGroup/index.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | 3 | import { Typography } from '@mui/material'; 4 | 5 | import { FormattedMessage } from 'react-intl'; 6 | 7 | import { GenericCardProps } from 'types'; 8 | 9 | import NavItem from '../NavItem'; 10 | import NavCollapse from '../NavCollapse'; 11 | 12 | export interface NavGroupProps { 13 | item: { 14 | id?: string; 15 | type?: string; 16 | icon?: GenericCardProps['iconPrimary']; 17 | children?: NavGroupProps['item'][]; 18 | title?: ReactNode | string; 19 | caption?: ReactNode | string; 20 | color?: 'primary' | 'secondary' | 'default' | undefined; 21 | }; 22 | } 23 | 24 | const NavGroup = ({ item }: NavGroupProps) => { 25 | const items = item.children?.map((menu) => { 26 | switch (menu.type) { 27 | case 'collapse': 28 | return ; 29 | case 'item': 30 | return ; 31 | default: 32 | return ( 33 | 34 | 35 | 36 | ); 37 | } 38 | }); 39 | 40 | return <>{items}; 41 | }; 42 | 43 | export default NavGroup; 44 | -------------------------------------------------------------------------------- /src/contexts/ConfigContext.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, ReactNode } from 'react'; 2 | 3 | import defaultConfig from 'config'; 4 | import useLocalStorage from 'hooks/useLocalStorage'; 5 | 6 | import { CustomizationProps } from 'types/config'; 7 | 8 | const initialState: CustomizationProps = { 9 | ...defaultConfig, 10 | onChangeLocale: () => {} 11 | }; 12 | 13 | const ConfigContext = createContext(initialState); 14 | 15 | type ConfigProviderProps = { 16 | children: ReactNode; 17 | }; 18 | 19 | function ConfigProvider({ children }: ConfigProviderProps) { 20 | const [config, setConfig] = useLocalStorage('berry-config', { 21 | fontFamily: initialState.fontFamily, 22 | borderRadius: initialState.borderRadius, 23 | outlinedFilled: initialState.outlinedFilled, 24 | navType: initialState.navType, 25 | boxShadow: initialState.boxShadow, 26 | presetColor: initialState.presetColor, 27 | locale: initialState.locale, 28 | rtlLayout: initialState.rtlLayout 29 | }); 30 | 31 | const onChangeLocale = (locale: string) => { 32 | setConfig({ 33 | ...config, 34 | locale 35 | }); 36 | }; 37 | 38 | return ( 39 | 45 | {children} 46 | 47 | ); 48 | } 49 | 50 | export { ConfigProvider, ConfigContext }; 51 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import ReactDOM from 'react-dom'; 2 | import { BrowserRouter } from 'react-router-dom'; 3 | import { Provider } from 'react-redux'; 4 | import { PersistGate } from 'redux-persist/integration/react'; 5 | 6 | import { Web3ReactProvider } from '@web3-react/core'; 7 | import * as serviceWorker from 'serviceWorker'; 8 | import reportWebVitals from 'reportWebVitals'; 9 | 10 | import App from 'App'; 11 | import { BASE_PATH } from 'config'; 12 | import { store, persister } from 'store'; 13 | import getLibrary from 'utils/getlibrary'; 14 | import { ConfigProvider } from 'contexts/ConfigContext'; 15 | 16 | import 'assets/scss/style.scss'; 17 | 18 | import 'moment/locale/ja'; 19 | import 'moment/locale/es'; 20 | import 'moment/locale/pt'; 21 | import 'moment/locale/tr'; 22 | import 'moment/locale/th'; 23 | import 'moment/locale/de'; 24 | import 'moment/locale/fr'; 25 | import 'moment/locale/vi'; 26 | import 'moment/locale/zh-cn'; 27 | 28 | ReactDOM.render( 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | , 40 | document.getElementById('root') 41 | ); 42 | 43 | serviceWorker.unregister(); 44 | reportWebVitals(); 45 | -------------------------------------------------------------------------------- /src/assets/images/icons/wallet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/layout/MinimalLayout/index.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from 'react'; 2 | import { Outlet } from 'react-router-dom'; 3 | import { AppBar, Box, Container, Toolbar } from '@mui/material'; 4 | 5 | import PerfectScrollbar from 'react-perfect-scrollbar'; 6 | 7 | import useConfig from 'hooks/useConfig'; 8 | 9 | import Footer from 'layout/Footer'; 10 | import Header from 'layout/MainLayout/Header'; 11 | 12 | import Auth from '../AuthLayout'; 13 | 14 | const MinimalLayout = () => { 15 | const { navType } = useConfig(); 16 | 17 | const header = useMemo( 18 | () => ( 19 | 20 |
21 | 22 | ), 23 | [] 24 | ); 25 | return ( 26 | 27 | 28 | 38 | {header} 39 | 40 | 41 | 42 | 43 |