diff --git a/package.json b/package.json index dda2a017..d0119a77 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,9 @@ "name": "host-react", "version": "1.0.0", "scripts": { - "build": "PUBLIC_PATH=https://suite.camino.network/ EXPLORER_PATH=https://suite.camino.network/explorer/ WALLET_PATH=https://suite.camino.network/wallet/ webpack --config webpack.prod.js", - "build:dev": "PUBLIC_PATH=https://dev.suite.camino.network/ EXPLORER_PATH=https://dev.suite.camino.network/explorer/ WALLET_PATH=https://dev.suite.camino.network/wallet/ webpack --config webpack.dev.js", - "build:stage": "PUBLIC_PATH=https://stage.suite.camino.network/ EXPLORER_PATH=https://stage.suite.camino.network/explorer/ WALLET_PATH=https://stage.suite.camino.network/wallet/ webpack --config webpack.prod.js", + "build": "PUBLIC_PATH=https://suite.camino.network/ EXPLORER_PATH=https://suite.camino.network/explorer/ WALLET_PATH=https://suite.camino.network/wallet/ DAC_PATH=https://suite.camino.network/dac/ webpack --config webpack.prod.js", + "build:dev": "PUBLIC_PATH=https://dev.suite.camino.network/ EXPLORER_PATH=https://dev.suite.camino.network/explorer/ WALLET_PATH=https://dev.suite.camino.network/wallet/ DAC_PATH=https://suite.camino.network/dac/ webpack --config webpack.dev.js", + "build:stage": "PUBLIC_PATH=https://stage.suite.camino.network/ EXPLORER_PATH=https://stage.suite.camino.network/explorer/ WALLET_PATH=https://stage.suite.camino.network/wallet/ DAC_PATH=https://suite.camino.network/dac/ webpack --config webpack.prod.js", "build:start": "cd dist && PORT=5001 npx serve", "start": "webpack-dev-server --config webpack.local.js", "start:live": "webpack-dev-server --open --config webpack.local.js --live-reload", @@ -32,16 +32,16 @@ "@emotion/styled": "^11.10.5", "@mdi/js": "^7.0.96", "@mdi/react": "^1.6.1", + "@types/big.js": "^6.2.2", + "@types/ethereum-protocol": "^1.0.5", + "@reduxjs/toolkit": "^1.8.1", + "@testing-library/dom": "^8.19.0", "@mui/icons-material": "^5.15.11", "@mui/material": "^5.15.11", "@mui/system": "^5.15.11", - "@reduxjs/toolkit": "^1.8.1", - "@testing-library/dom": "^8.19.0", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.0.1", "@testing-library/user-event": "^14.1.1", - "@types/big.js": "^6.2.2", - "@types/ethereum-protocol": "^1.0.5", "@types/jest": "^27.4.1", "@types/lodash": "^4.14.189", "@types/node": "^17.0.25", @@ -83,10 +83,10 @@ "webpack-dev-server": "^4.3.1", "webpack-merge": "^5.8.0", "yup": "^0.32.11", - "ethers": "^6.13.2" + "ethers": "^6.13.2", + "big.js": "^6.2.1" }, "dependencies": { - "big.js": "^6.2.1", "react": "^18.2.0", "react-circle-flags": "^0.0.18", "react-dom": "^18.2.0" diff --git a/src/components/Animate/DialogAnimate.tsx b/src/components/Animate/DialogAnimate.tsx index f3f18a66..64b2dfe2 100644 --- a/src/components/Animate/DialogAnimate.tsx +++ b/src/components/Animate/DialogAnimate.tsx @@ -1,5 +1,5 @@ +import { Box, Dialog, DialogProps, Paper, useTheme } from '@mui/material' import React from 'react' -import { Dialog, Box, Paper, DialogProps, useTheme } from '@mui/material' interface DialogAnimateProps extends DialogProps { animate?: object diff --git a/src/components/Navbar/AddNewNetwork.tsx b/src/components/Navbar/AddNewNetwork.tsx index d6851237..2fe153aa 100644 --- a/src/components/Navbar/AddNewNetwork.tsx +++ b/src/components/Navbar/AddNewNetwork.tsx @@ -9,15 +9,15 @@ import { } from '@mui/material' import { Form, FormikProvider, useFormik } from 'formik' -import { AvaNetwork } from 'wallet/AvaNetwork' import { Button } from '@mui/material' -import { Network } from '../../@types/store' -import React from 'react' -import { addNetworks } from '../../redux/slices/network' +import { useStore } from 'Explorer/useStore' import axios from 'axios' +import React from 'react' +import { AvaNetwork } from 'wallet/AvaNetwork' import store from 'wallet/store' +import { Network } from '../../@types/store' import { useAppDispatch } from '../../hooks/reduxHooks' -import { useStore } from 'Explorer/useStore' +import { addNetworks } from '../../redux/slices/network' export default function AddNewNetwork({ networks, diff --git a/src/components/Navbar/NetworkSwitcher.tsx b/src/components/Navbar/NetworkSwitcher.tsx index ef2c575f..71c9b375 100644 --- a/src/components/Navbar/NetworkSwitcher.tsx +++ b/src/components/Navbar/NetworkSwitcher.tsx @@ -1,26 +1,25 @@ +import { mdiDeleteOutline, mdiPencilOutline, mdiPlus } from '@mdi/js' import { Box, Button, Chip, - CircularProgress, DialogTitle, MenuItem, MenuList, Select, Stack, Typography, - useTheme, + useTheme } from '@mui/material' -import { mdiDeleteOutline, mdiPencilOutline, mdiPlus } from '@mdi/js' import { networkStatusColor, networkStatusName } from '../../utils/networkUtils' -import AddNewNetwork from './AddNewNetwork' -import DialogAnimate from '../Animate/DialogAnimate' import Icon from '@mdi/react' -import MHidden from '../@material-extend/MHidden' import React from 'react' -import SelectedNetwork from './SelectNetwork' import useNetwork from '../../hooks/useNetwork' +import MHidden from '../@material-extend/MHidden' +import DialogAnimate from '../Animate/DialogAnimate' +import AddNewNetwork from './AddNewNetwork' +import SelectedNetwork from './SelectNetwork' interface NetworkSwitcherProps { handleCloseSidebar?: () => void diff --git a/src/components/Navbar/SelectNetwork.tsx b/src/components/Navbar/SelectNetwork.tsx index 3a1daa13..88484581 100644 --- a/src/components/Navbar/SelectNetwork.tsx +++ b/src/components/Navbar/SelectNetwork.tsx @@ -1,5 +1,5 @@ +import { Box, Chip, Typography } from '@mui/material' import React from 'react' -import { Box, Typography, Chip } from '@mui/material' import { useAppSelector } from '../../hooks/reduxHooks' import { NetworkID, getActiveNetwork, selectNetworkStatus } from '../../redux/slices/network' diff --git a/src/components/Navbar/index.tsx b/src/components/Navbar/index.tsx index 61aff4cc..a3838158 100644 --- a/src/components/Navbar/index.tsx +++ b/src/components/Navbar/index.tsx @@ -1,3 +1,4 @@ +import { mdiClose, mdiMenu, mdiWalletOutline } from '@mdi/js' import { AppBar, Box, @@ -8,26 +9,25 @@ import { Typography, useTheme, } from '@mui/material' -import { DRAWER_WIDTH, TIMEOUT_DURATION } from '../../constants/apps-consts' import React, { useState } from 'react' -import { mdiClose, mdiMenu, mdiWalletOutline } from '@mdi/js' +import { DRAWER_WIDTH, TIMEOUT_DURATION } from '../../constants/apps-consts' import { useAppDispatch, useAppSelector } from '../../hooks/reduxHooks' -import Account from './Account' import Icon from '@mdi/react' -import LoggedInAccount from './LoggedInAccount' +import { getActiveNetwork } from '../../redux/slices/network' import MHidden from '../@material-extend/MHidden' import MIconButton from '../@material-extend/MIconButton' -import NetworkSwitcher from './NetworkSwitcher' import PlatformSwitcher from '../PlatformSwitcher' +import Account from './Account' +import LoggedInAccount from './LoggedInAccount' +import NetworkSwitcher from './NetworkSwitcher' import ThemeSwitcher from './ThemeSwitcher' -import { getActiveNetwork } from '../../redux/slices/network' // @ts-ignore +import { useIdleTimer } from 'react-idle-timer' +import { useNavigate } from 'react-router-dom' import store from 'wallet/store' import { updateAccount } from '../../redux/slices/app-config' import { updateAuthStatus } from '../../redux/slices/utils' -import { useIdleTimer } from 'react-idle-timer' -import { useNavigate } from 'react-router-dom' export default function Navbar() { const theme = useTheme() diff --git a/src/components/PlatformSwitcher.tsx b/src/components/PlatformSwitcher.tsx index 5f45deb0..dc2919ac 100644 --- a/src/components/PlatformSwitcher.tsx +++ b/src/components/PlatformSwitcher.tsx @@ -1,10 +1,11 @@ import { mdiChevronRight } from '@mdi/js' import Icon from '@mdi/react' import { Box, MenuItem, Select, Typography, useTheme } from '@mui/material' -import React from 'react' +import React, { useEffect, useState } from 'react' import { useDispatch } from 'react-redux' import { useNavigate } from 'react-router-dom' import { useAppSelector } from '../hooks/reduxHooks' +import useWallet from '../hooks/useWallet' import useWidth from '../hooks/useWidth' import { changeActiveApp, @@ -12,9 +13,12 @@ import { getAllApps, getAuthStatus, } from '../redux/slices/app-config' +import { getActiveNetwork } from '../redux/slices/network' +import { isFeatureEnabled } from '../utils/featureFlags/featureFlagUtils' export default function PlatformSwitcher() { const theme = useTheme() + const activeNetwork = useAppSelector(getActiveNetwork) const navigate = useNavigate() const activeApp = useAppSelector(getActiveApp) const allApps = useAppSelector(getAllApps) @@ -22,6 +26,24 @@ export default function PlatformSwitcher() { const themeMode = theme.palette.mode === 'light' ? true : false const { isDesktop } = useWidth() const dispatch = useDispatch() + const { getUpgradePhases } = useWallet() + + const [featureEnabled, setFeatureEnabled] = useState(false) + + useEffect(() => { + checkFeature() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [activeNetwork]) + + const checkFeature = async () => { + try { + const phases = await getUpgradePhases() + const enabled = await isFeatureEnabled('DACFeature', activeNetwork?.url, phases) + setFeatureEnabled(enabled) + } catch (error) { + setFeatureEnabled(false) + } + } return ( {allApps?.map((app, index) => { - if (!app.hidden && (!app.private || isAuth)) - return ( - navigate(app.url)} - data-cy={`app-selector-${app.name}`} - > - - + if ( + !app.hidden && + (!app.private || isAuth) && + (app.name !== 'DAC' || featureEnabled) + ) + if ( + !app.hidden && + (!app.private || isAuth) && + (app.name !== 'DAC' || featureEnabled) + ) + return ( + navigate(app.url)} + data-cy={`app-selector-${app.name}`} + > + + + + {app.name} + + + - {app.name} + {app.subText} - - - {app.subText} - - - - ) + + ) })} diff --git a/src/constants/apps-consts.ts b/src/constants/apps-consts.ts index db6164c6..670cbe66 100644 --- a/src/constants/apps-consts.ts +++ b/src/constants/apps-consts.ts @@ -18,6 +18,12 @@ export const APPS_CONSTS = [ url: '/explorer', private: false, }, + { + name: 'DAC', + subText: 'Decentralized Autonomous Consortium', + url: '/dac', + private: false, + }, { name: 'Foundation', subText: 'Tools for foundation members.', diff --git a/src/constants/featureFlag-consts.ts b/src/constants/featureFlag-consts.ts new file mode 100644 index 00000000..62d50efe --- /dev/null +++ b/src/constants/featureFlag-consts.ts @@ -0,0 +1,13 @@ +// config/featureFlags.ts +import { FeatureFlag } from '../utils/types/featureFlag-type'; + +const featureFlags: { [key: string]: FeatureFlag } = { + DACFeature: { + enabled: true, + nodeVersion: '>=1.1.0', + requiredUpgradePhase: 'BerlinPhase', // Add the required phase name here + }, + // Add more feature flags as needed +}; + +export default featureFlags; diff --git a/src/hooks/useWallet.ts b/src/hooks/useWallet.ts index 6ff9779e..d208530c 100644 --- a/src/hooks/useWallet.ts +++ b/src/hooks/useWallet.ts @@ -29,7 +29,12 @@ const useWallet = () => { ) } } - return { updateStore, getRegisteredNode, getAddress } + + async function getUpgradePhases(): Promise { + return await caminoClient.PChain().getUpgradePhases() + } + + return { updateStore, getRegisteredNode, getAddress , getUpgradePhases} } export default useWallet diff --git a/src/index.css b/src/index.css index e329eba2..654b45d5 100644 --- a/src/index.css +++ b/src/index.css @@ -1,168 +1,168 @@ :root { - --border-radius-lg: 12px; - --border-radius-sm: 6px; - --spacing-space-md: 12px; - --spacing-space-base: 16px; - --primary-btn-border-color: #149ded; - --secondary-color: #149ded; - --primary-border: solid 1px var(--primary-border-color); - --secondary-border: solid 1px var(--secondary-border-color); - --box-shadow: rgb(0 0 0 / 10%) 0px 0px 5px; - --tooltip-bg: rgba(51, 65, 85, 0.92); - --slate-600: #475569; - --negative-background: #e5431f; - --white: #fff; - --camino-slate-slate-300: #cbd4e2; - --camino-slate-slate-600: #475569; - --camino-slate-slate-700: #334155; - --camino-slate-slate-800: #1e293b; - --camino-slate-slate-950: #020617; - --camino-brand-too-blue-to-be-true: #0085ff; - --camino-brand-too-blue-to-be-true-100: rgba(0, 133, 255, 0.25); - --camino-brand-error: #e5431f; - --camino-brand-error-100: rgba(229, 67, 31, 0.25); - --primary-font: 'Inter', sans-serif; - --camino-brand-primary: linear-gradient(90deg, #0085ff 0%, #b440fc 100%); - --spacing-space-sm: 8px; - --spacing-space-md: 12px; - --spacing-space-base: 16px; - --spacing-space-lg: 24px; + --border-radius-lg: 12px; + --border-radius-sm: 6px; + --spacing-space-md: 12px; + --spacing-space-base: 16px; + --primary-btn-border-color: #149ded; + --secondary-color: #149ded; + --primary-border: solid 1px var(--primary-border-color); + --secondary-border: solid 1px var(--secondary-border-color); + --box-shadow: rgb(0 0 0 / 10%) 0px 0px 5px; + --tooltip-bg: rgba(51, 65, 85, 0.92); + --slate-600: #475569; + --negative-background: #e5431f; + --white: #fff; + --camino-slate-slate-300: #cbd4e2; + --camino-slate-slate-600: #475569; + --camino-slate-slate-700: #334155; + --camino-slate-slate-800: #1e293b; + --camino-slate-slate-950: #020617; + --camino-brand-too-blue-to-be-true: #0085ff; + --camino-brand-too-blue-to-be-true-100: rgba(0, 133, 255, 0.25); + --camino-brand-error: #e5431f; + --camino-brand-error-100: rgba(229, 67, 31, 0.25); + --primary-font: 'Inter', sans-serif; + --camino-brand-primary: linear-gradient(90deg, #0085ff 0%, #b440fc 100%); + --spacing-space-sm: 8px; + --spacing-space-md: 12px; + --spacing-space-base: 16px; + --spacing-space-lg: 24px; - --tailwind-slate-white: #FFFFFF; - --tailwind-slate-slate-50: #F8FAFC; - --tailwind-slate-slate-100: #F1F5F9; - --tailwind-slate-slate-200: #E2E7F0; - --tailwind-slate-slate-300: #CBD4E2; - --tailwind-slate-slate-400: #94A2B8; - --tailwind-slate-slate-500: #64748B; - --tailwind-slate-slate-600: #475569; - --tailwind-slate-slate-700: #334155; - --tailwind-slate-slate-800: #1E293B; - --tailwind-slate-slate-900: #0F182A; - --tailwind-slate-slate-950: #020617; + --tailwind-slate-white: #FFFFFF; + --tailwind-slate-slate-50: #F8FAFC; + --tailwind-slate-slate-100: #F1F5F9; + --tailwind-slate-slate-200: #E2E7F0; + --tailwind-slate-slate-300: #CBD4E2; + --tailwind-slate-slate-400: #94A2B8; + --tailwind-slate-slate-500: #64748B; + --tailwind-slate-slate-600: #475569; + --tailwind-slate-slate-700: #334155; + --tailwind-slate-slate-800: #1E293B; + --tailwind-slate-slate-900: #0F182A; + --tailwind-slate-slate-950: #020617; - --camino-too-blue-to-be-true: #0085FF; - --camino-magento: #B440FC; - --camino-aphrodite-teal: #35E9AD; - --camino-aphrodite-aqua: #B5E3FD; - --camino-muted-blue: #317CA5; + --camino-too-blue-to-be-true: #0085FF; + --camino-magento: #B440FC; + --camino-aphrodite-teal: #35E9AD; + --camino-aphrodite-aqua: #B5E3FD; + --camino-muted-blue: #317CA5; - --camino-gradient-1: linear-gradient(90deg, #0085FF 0%, #B440FC 100%); - --camino-gradient-2: linear-gradient(90deg, #B440FC 0%, #35E9AD 100%); - --camino-gradient-3: linear-gradient(90deg, #35E9AD 0%, #0085FF 100%); - --camino-gradient-4: linear-gradient(90deg, #B440FC 0%, #0F182A 100%); + --camino-gradient-1: linear-gradient(90deg, #0085FF 0%, #B440FC 100%); + --camino-gradient-2: linear-gradient(90deg, #B440FC 0%, #35E9AD 100%); + --camino-gradient-3: linear-gradient(90deg, #35E9AD 0%, #0085FF 100%); + --camino-gradient-4: linear-gradient(90deg, #B440FC 0%, #0F182A 100%); - --camino-primary-light: #B3DAFF; - --camino-primary-dark: #012C5D; - --camino-secondary-light: #E9C6FE; - --camino-secondary-dark: #37175C; - --camino-success-light: #18B728; - --camino-success-dark: #09DE6B; - --camino-warning-light: #E5A21F; - --camino-warning-dark: #E5A21F; - --camino-error-light: #E5431F; - --camino-error-dark: #E5431F; + --camino-primary-light: #B3DAFF; + --camino-primary-dark: #012C5D; + --camino-secondary-light: #E9C6FE; + --camino-secondary-dark: #37175C; + --camino-success-light: #18B728; + --camino-success-dark: #09DE6B; + --camino-warning-light: #E5A21F; + --camino-warning-dark: #E5A21F; + --camino-error-light: #E5431F; + --camino-error-dark: #E5431F; } html[data-theme='light'] { - --bg: #f1f5f9; - --bg-1: 255, 255, 255; - --bg-light: #e2e8f0; - --bg-light-1: 245, 246, 250; - --bg-light-2: #e2e8f0; - --primary-color: #0f172a; - --primary-color-light: #757575; - --selection-color: #6a91d8; - --link-secondary: #6e7479; - --error: #c23f38; - --success: #6bc688; - --info: #2c7490; - --info-1: 44, 116, 144; - --bg-wallet: #f5f6fa; - --warning: #e5a21f; - --bg-wallet-light: #ffffff; - --primary-border-color: rgba(203, 213, 225, 0.12); - --secondary-border-color: #e2e8f0; - --disabled-color: #e2e8f0; - --primary-contrast-text: #0f172a; - --secondary-contrast-text: #ffffff; - --sidebar-links: #64748b; - --sidebar-background: #fff; - --icon-color: #0f172a; - --icon-color-light: #334155; - --camino-slate-slate-white: #ffffff; - --camino-info-border: rgba(0, 133, 255, 0.5); - --camino-info-background: rgba(0, 133, 255, 0.05); - --camino-positive-border: rgba(9, 222, 107, 0.5); - --camino-positive-background: rgba(9, 222, 107, 0.05); - --camino-warning-border: rgba(229, 162, 31, 0.5); - --camino-warning-background: rgba(229, 162, 31, 0.05); - --camino-negative-border: rgba(229, 67, 31, 0.5); - --camino-negative-background: rgba(229, 67, 31, 0.05); - --camino-warning-color: #334155; - --camino-alert-color: #334155; - --camino-success-color: rgba(24, 183, 40, 1); - --camino-error-color: rgba(229, 67, 31, 1); + --bg: #f1f5f9; + --bg-1: 255, 255, 255; + --bg-light: #e2e8f0; + --bg-light-1: 245, 246, 250; + --bg-light-2: #e2e8f0; + --primary-color: #0f172a; + --primary-color-light: #757575; + --selection-color: #6a91d8; + --link-secondary: #6e7479; + --error: #c23f38; + --success: #6bc688; + --info: #2c7490; + --info-1: 44, 116, 144; + --bg-wallet: #f5f6fa; + --warning: #e5a21f; + --bg-wallet-light: #ffffff; + --primary-border-color: rgba(203, 213, 225, 0.12); + --secondary-border-color: #e2e8f0; + --disabled-color: #e2e8f0; + --primary-contrast-text: #0f172a; + --secondary-contrast-text: #ffffff; + --sidebar-links: #64748b; + --sidebar-background: #fff; + --icon-color: #0f172a; + --icon-color-light: #334155; + --camino-slate-slate-white: #ffffff; + --camino-info-border: rgba(0, 133, 255, 0.5); + --camino-info-background: rgba(0, 133, 255, 0.05); + --camino-positive-border: rgba(9, 222, 107, 0.5); + --camino-positive-background: rgba(9, 222, 107, 0.05); + --camino-warning-border: rgba(229, 162, 31, 0.5); + --camino-warning-background: rgba(229, 162, 31, 0.05); + --camino-negative-border: rgba(229, 67, 31, 0.5); + --camino-negative-background: rgba(229, 67, 31, 0.05); + --camino-warning-color: #334155; + --camino-alert-color: #334155; + --camino-success-color: rgba(24, 183, 40, 1); + --camino-error-color: rgba(229, 67, 31, 1); } html[data-theme='dark'] { - --bg: #020617; - --bg-1: 36, 39, 41; - --bg-light: #1e293b; - --bg-light-1: 46, 50, 52; - --bg-light-2: #334155; - --primary-color: #f5f5f5; - --primary-color-light: #6e7479; - --selection-color: #6a91d8; - --link-secondary: #6e7479; - --error: #c23f38; - --success: #6bc688; - --info: #4c8caf; - --info-1: 76, 140, 175; - --bg-wallet: #334155; - --warning: #f19d38; - --bg-wallet-light: #0f172a; - --primary-border-color: rgba(255, 255, 255, 0.12); - --secondary-border-color: rgba(255, 255, 255, 0.12); - --disabled-color: rgba(255, 255, 255, 0.12); - --primary-contrast-text: #ffffff; - --secondary-contrast-text: #0f172a; - --sidebar-links: #64748b; - --sidebar-background: #1e293b; - --icon-color: #ffffff; - --icon-color--light: #ffffff; - --camino-brand-too-blue-to-be-true: #0085ff; - --camino-info-border: rgba(0, 133, 255, 0.3); - --camino-info-background: rgba(0, 133, 255, 0.05); - --camino-positive-border: rgba(9, 222, 107, 0.3); - --camino-positive-background: rgba(9, 222, 107, 0.05); - --camino-warning-border: rgba(229, 162, 31, 0.3); - --camino-warning-background: rgba(229, 162, 31, 0.05); - --camino-negative-border: rgba(229, 67, 31, 0.3); - --camino-negative-background: rgba(229, 67, 31, 0.05); - --camino-warning-color: #cbd4e2; - --camino-alert-color: #cbd4e2; - --camino-success-color: rgba(9, 222, 107, 1); - --camino-error-color: rgba(229, 67, 31, 1); - --camino-slate-slate-950: #020617; - --camino-slate-slate-600: #475569; + --bg: #020617; + --bg-1: 36, 39, 41; + --bg-light: #1e293b; + --bg-light-1: 46, 50, 52; + --bg-light-2: #334155; + --primary-color: #f5f5f5; + --primary-color-light: #6e7479; + --selection-color: #6a91d8; + --link-secondary: #6e7479; + --error: #c23f38; + --success: #6bc688; + --info: #4c8caf; + --info-1: 76, 140, 175; + --bg-wallet: #334155; + --warning: #f19d38; + --bg-wallet-light: #0f172a; + --primary-border-color: rgba(255, 255, 255, 0.12); + --secondary-border-color: rgba(255, 255, 255, 0.12); + --disabled-color: rgba(255, 255, 255, 0.12); + --primary-contrast-text: #ffffff; + --secondary-contrast-text: #0f172a; + --sidebar-links: #64748b; + --sidebar-background: #1e293b; + --icon-color: #ffffff; + --icon-color--light: #ffffff; + --camino-brand-too-blue-to-be-true: #0085ff; + --camino-info-border: rgba(0, 133, 255, 0.3); + --camino-info-background: rgba(0, 133, 255, 0.05); + --camino-positive-border: rgba(9, 222, 107, 0.3); + --camino-positive-background: rgba(9, 222, 107, 0.05); + --camino-warning-border: rgba(229, 162, 31, 0.3); + --camino-warning-background: rgba(229, 162, 31, 0.05); + --camino-negative-border: rgba(229, 67, 31, 0.3); + --camino-negative-background: rgba(229, 67, 31, 0.05); + --camino-warning-color: #cbd4e2; + --camino-alert-color: #cbd4e2; + --camino-success-color: rgba(9, 222, 107, 1); + --camino-error-color: rgba(229, 67, 31, 1); + --camino-slate-slate-950: #020617; + --camino-slate-slate-600: #475569; } body { - overflow: auto; - background-color: var(--bg) !important; - height: 100%; - font-size: 16px !important; - padding-right: 0 !important; + overflow: auto; + background-color: var(--bg) !important; + height: 100%; + font-size: 16px !important; + padding-right: 0 !important; } #app { - display: flex; - min-height: 100%; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - text-align: left; - color: var(--primary-color); - font-family: 'Rubik', sans-serif; - transition-duration: 0.2s; - width: 100%; + display: flex; + min-height: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-align: left; + color: var(--primary-color); + font-family: 'Rubik', sans-serif; + transition-duration: 0.2s; + width: 100%; } \ No newline at end of file diff --git a/src/layout/Protected.tsx b/src/layout/Protected.tsx index b9e30a8d..953bdb70 100644 --- a/src/layout/Protected.tsx +++ b/src/layout/Protected.tsx @@ -1,8 +1,8 @@ import React, { useState } from 'react' import { Navigate, Outlet } from 'react-router-dom' +import store from 'wallet/store' import { updateAssets } from '../helpers/walletStore' import { useEffectOnce } from '../hooks/useEffectOnce' -import store from 'wallet/store' const OutletWrraper = () => { const [fetch, setFetch] = useState(false) diff --git a/src/layout/RenderApp.tsx b/src/layout/RenderApp.tsx index d4078264..eeb00b3d 100644 --- a/src/layout/RenderApp.tsx +++ b/src/layout/RenderApp.tsx @@ -1,13 +1,15 @@ -import ExplorerApp from './ExplorerApp' import React from 'react' +import { useAppSelector } from '../hooks/reduxHooks' import { RootState } from '../redux/store' +import VoteApp from '../views/vote/VoteApp' +import ExplorerApp from './ExplorerApp' import Wallet from './WalletApp' -import { useAppSelector } from '../hooks/reduxHooks' const RenderApp = () => { const activeApp = useAppSelector((state: RootState) => state.appConfig.activeApp) if (activeApp === 'Explorer') return else if (activeApp === 'Wallet') return + else if (activeApp === 'DAC') return return
Not Yet Implemented
} diff --git a/src/layout/RoutesSuite.tsx b/src/layout/RoutesSuite.tsx index 783f2391..bd23de82 100644 --- a/src/layout/RoutesSuite.tsx +++ b/src/layout/RoutesSuite.tsx @@ -4,8 +4,10 @@ import { Navigate, Route, Routes, useNavigate } from 'react-router-dom' import { useDispatch } from 'react-redux' import { useLocation } from 'react-router-dom' import { useAppSelector } from '../hooks/reduxHooks' +import useWallet from '../hooks/useWallet' import { changeActiveApp } from '../redux/slices/app-config' import { getActiveNetwork } from '../redux/slices/network' +import { isFeatureEnabled } from '../utils/featureFlags/featureFlagUtils' import AccessLayout from '../views/access' import MountAccessComponent from '../views/access/MountAccessComponent' import Create from '../views/create/Create' @@ -24,6 +26,7 @@ import UpgradeCMAccount from '../views/partners/UpgradeCMAccount' import MultisigWallet from '../views/settings/MultisigWallet' import VerifyWallet from '../views/settings/VerifyWallet' import Settings from '../views/settings/index' +import VoteApp from '../views/vote/VoteApp' import Wallet from '../views/wallet/WalletApp' import CreateDepositsLayout from './CreateDepositLayout' import PartnersLayout from './PartnersLayout' @@ -35,9 +38,11 @@ export default function RoutesSuite() { const navigate = useNavigate() const activeNetwork = useAppSelector(getActiveNetwork) const location = useLocation() + const { getUpgradePhases } = useWallet() const [lastUrlWithNewNetwork, setLastUrlWithNewNetwork] = useState('') const [networkAliasToUrl, setNetworkAliasToUrl] = useState('camino') + const [featureEnabled, setFeatureEnabled] = useState(false) useEffect(() => { if (activeNetwork) { @@ -75,6 +80,20 @@ export default function RoutesSuite() { // eslint-disable-next-line react-hooks/exhaustive-deps }, [location]) + useEffect(() => { + checkFeature() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [activeNetwork]) + + const checkFeature = async () => { + try { + const phases = await getUpgradePhases() + const enabled = await isFeatureEnabled('DACFeature', activeNetwork?.url, phases) + setFeatureEnabled(enabled) + } catch (error) { + setFeatureEnabled(false) + } + } return ( <> @@ -97,6 +116,13 @@ export default function RoutesSuite() { path="/explorer" element={} /> + + {featureEnabled && ( + <> + } /> + } /> + + )} ) : null} }> diff --git a/src/layout/index.tsx b/src/layout/index.tsx index cf23ec75..14336d02 100644 --- a/src/layout/index.tsx +++ b/src/layout/index.tsx @@ -1,8 +1,8 @@ +import { default as React } from 'react' import { BrowserRouter } from 'react-router-dom' +import ScrollToTop from '../components/ScrollToTop' import MainLayout from './MainLayout' -import React from 'react' import RoutesSuite from './RoutesSuite' -import ScrollToTop from '../components/ScrollToTop' export default function Layout() { return ( diff --git a/src/redux/slices/network.ts b/src/redux/slices/network.ts index bd313afe..bba70cab 100644 --- a/src/redux/slices/network.ts +++ b/src/redux/slices/network.ts @@ -1,6 +1,6 @@ -import { RootState } from '../store' -import { Status } from '../../@types' import { createSlice } from '@reduxjs/toolkit' +import { Status } from '../../@types' +import { RootState } from '../store' export enum NetworkID { MAINNET = 1000, diff --git a/src/theme/breakpoints.ts b/src/theme/breakpoints.ts index a0d97c08..75430988 100644 --- a/src/theme/breakpoints.ts +++ b/src/theme/breakpoints.ts @@ -1,12 +1,13 @@ const breakpoints = { - values: { - xs: 0, - sm: 640, - md: 768, - lg: 1024, - xl: 1280, - xxl: 1536, - }, -} - -export default breakpoints + values: { + xs: 0, + sm: 640, + md: 768, + lg: 1024, + xl: 1280, + xxl: 1536, + }, + } + + export default breakpoints + \ No newline at end of file diff --git a/src/theme/globalStyles.tsx b/src/theme/globalStyles.tsx index 90170fa8..4b0a6fed 100644 --- a/src/theme/globalStyles.tsx +++ b/src/theme/globalStyles.tsx @@ -1,5 +1,6 @@ -import { useTheme } from '@mui/material/styles' import { GlobalStyles as GlobalThemeStyles } from '@mui/material' +import { useTheme } from '@mui/material/styles' +import * as React from 'react' export default function GlobalStyles() { const theme = useTheme() diff --git a/src/theme/overrides/AccordionDetails.ts b/src/theme/overrides/AccordionDetails.ts new file mode 100644 index 00000000..4eeb5188 --- /dev/null +++ b/src/theme/overrides/AccordionDetails.ts @@ -0,0 +1,13 @@ +import { Theme } from '@mui/material/styles' + +export default function AccordionDetails(theme: Theme) { + return { + MuiAccordionDetails: { + styleOverrides: { + root: { + border: '0px', + }, + }, + }, + } +} diff --git a/src/theme/overrides/Tab.ts b/src/theme/overrides/Tab.ts index aab28c1a..88a6395c 100644 --- a/src/theme/overrides/Tab.ts +++ b/src/theme/overrides/Tab.ts @@ -1,5 +1,6 @@ import { Theme } from '@mui/material/styles' +//TODO need to be fixed the theme is not used there export default function Tab(theme: Theme) { return { MuiTab: { @@ -26,6 +27,9 @@ export default function Tab(theme: Theme) { borderRadius: '4px 4px 0px 0px', background: '#0085FF', }, + '&.Mui-selected': { + color: '#fff', + }, }, }, }, diff --git a/src/theme/overrides/index.ts b/src/theme/overrides/index.ts index 08756752..2a5c6aac 100644 --- a/src/theme/overrides/index.ts +++ b/src/theme/overrides/index.ts @@ -1,18 +1,18 @@ -import { merge } from 'lodash' import { Theme } from '@mui/material/styles' +import { merge } from 'lodash' import AppBar from './AppBar' -import Select from './Select' -import MenuList from './MenuList' -import Toolbar from './Toolbar' import Button from './Button' -import Modal from './Modal' -import TextField from './TextField' import CssBaseline from './CssBaseline' -import Paper from './Paper' +import DialogActions from './DialogActions' import Drawer from './Drawer' import Input from './Input' -import DialogActions from './DialogActions' +import MenuList from './MenuList' +import Modal from './Modal' +import Paper from './Paper' +import Select from './Select' import Tab from './Tab' +import TextField from './TextField' +import Toolbar from './Toolbar' export default function ComponentsOverrides(theme: Theme) { return merge( diff --git a/src/utils/featureFlags/featureFlagUtils.ts b/src/utils/featureFlags/featureFlagUtils.ts new file mode 100644 index 00000000..7667866d --- /dev/null +++ b/src/utils/featureFlags/featureFlagUtils.ts @@ -0,0 +1,64 @@ +// src/utils/featureFlagUtils.ts +import axios from 'axios' +import semver from 'semver' +import featureFlags from '../../constants/featureFlag-consts' + +export async function getNodeVersion(url: string, credential = false): Promise { + try { + const response = await axios.post( + `${url}/ext/info`, + { jsonrpc: '2.0', id: 1, method: 'info.getNodeVersion' }, + { withCredentials: credential, timeout: 60000 }, + ) + + const versionString = response.data.result.version + const versionMatch = versionString.match(/\/(\d+\.\d+\.\d+)/) + + return versionMatch ? versionMatch[1] : null + } catch (error) { + if (axios.isAxiosError(error) && error.code === 'ECONNABORTED') { + return 'timeout' + } + return null + } +} + +export async function isFeatureEnabled( + featureName: string, + url: string, + phases?: Record, +): Promise { + const feature = featureFlags[featureName] + + if (!feature) { + console.warn(`Feature flag "${featureName}" does not exist.`) + return false + } + + const nodeVersion = await getNodeVersion(url) + + if (typeof nodeVersion !== 'string') { + console.error('Failed to get node version:', nodeVersion) + return false + } + + const isNodeVersionValid = semver.satisfies(nodeVersion, feature.nodeVersion) + + if (!isNodeVersionValid) { + return false + } + + if (feature.requiredUpgradePhase && phases) { + if (phases?.length < 1) { + return false + } + + const requiredPhaseValue = phases[feature.requiredUpgradePhase] + + if (isNaN(requiredPhaseValue) || requiredPhaseValue === 0) { + return false + } + } + + return feature.enabled +} diff --git a/src/utils/types/featureFlag-type.ts b/src/utils/types/featureFlag-type.ts new file mode 100644 index 00000000..6343b461 --- /dev/null +++ b/src/utils/types/featureFlag-type.ts @@ -0,0 +1,6 @@ +// src/utils/types/featureFlag-type.ts +export interface FeatureFlag { + enabled: boolean; + nodeVersion: string; + requiredUpgradePhase?: string; // Optional property for the upgrade phase +} diff --git a/src/views/create/Create.tsx b/src/views/create/Create.tsx index f05ab708..1ac03c39 100644 --- a/src/views/create/Create.tsx +++ b/src/views/create/Create.tsx @@ -1,11 +1,10 @@ import React, { useEffect, useRef, useState } from 'react' -import { changeActiveApp } from '../../redux/slices/app-config' +import { useNavigate } from 'react-router-dom' import { mountCreateWallet } from 'wallet/mountCreate' -import { updateAuthStatus } from '../../redux/slices/utils' -import { updateValues } from '../../redux/slices/app-config' import { useAppDispatch } from '../../hooks/reduxHooks' -import { useNavigate } from 'react-router-dom' +import { changeActiveApp, updateValues } from '../../redux/slices/app-config' +import { updateAuthStatus } from '../../redux/slices/utils' const CreateWallet = () => { const ref = useRef(null) diff --git a/src/views/landing/LandingPage.tsx b/src/views/landing/LandingPage.tsx index 7550b8c2..18c2b7b2 100644 --- a/src/views/landing/LandingPage.tsx +++ b/src/views/landing/LandingPage.tsx @@ -1,11 +1,13 @@ import { Box, Grid, Typography } from '@mui/material' import { changeActiveApp, getAllApps } from '../../redux/slices/app-config' -import React from 'react' +import React, { useEffect, useState } from 'react' import { useDispatch } from 'react-redux' import { useNavigate } from 'react-router' import { useAppSelector } from '../../hooks/reduxHooks' +import useWallet from '../../hooks/useWallet' import { getActiveNetwork } from '../../redux/slices/network' +import { isFeatureEnabled } from '../../utils/featureFlags/featureFlagUtils' import LandingPageAppWidget from './LandingPageAppWidget' export default function LandingPage() { @@ -14,6 +16,24 @@ export default function LandingPage() { const navigate = useNavigate() const allApps = useAppSelector(getAllApps) const isAuth = useAppSelector(state => state.appConfig.isAuth) + const [featureEnabled, setFeatureEnabled] = useState(false) + const { getUpgradePhases } = useWallet() + + useEffect(() => { + checkFeature() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [activeNetwork]) + + const checkFeature = async () => { + try { + const phases = await getUpgradePhases() + const enabled = await isFeatureEnabled('DACFeature', activeNetwork?.url, phases) + setFeatureEnabled(enabled) + } catch (error) { + setFeatureEnabled(false) + } + } + const handleWidgetClick = app => { dispatch(changeActiveApp(app?.name)) @@ -31,8 +51,8 @@ export default function LandingPage() { Camino Suite - The Camino Suite unifies all network wide applications of the Camino - Network + The Camino Suite unifies all network wide applications of the Camino Network The + Camino Suite unifies all network wide applications of the Camino Network @@ -41,7 +61,8 @@ export default function LandingPage() { {allApps?.map((app, index) => { if ( !app.hidden && - (app.private === false || (app.name === 'Foundation' && isAuth)) + (app.private === false || (app.name === 'Foundation' && isAuth)) && + (app.name !== 'DAC' || featureEnabled) ) return ( diff --git a/src/views/vote/VoteApp.tsx b/src/views/vote/VoteApp.tsx new file mode 100644 index 00000000..f42569cc --- /dev/null +++ b/src/views/vote/VoteApp.tsx @@ -0,0 +1,16 @@ +import { useTheme } from '@mui/system' +import React from 'react' +import useNetwork from '../../hooks/useNetwork' +const Vote = React.lazy(() => import('DAC/dac')) + +const VoteApp = () => { + const { activeNetwork } = useNetwork() + const theme = useTheme() + return ( + Loading...}> + + + ) +} + +export default VoteApp diff --git a/webpack.dev.js b/webpack.dev.js index 8384ced6..af3defd1 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -6,6 +6,7 @@ const deps = require('./package.json').dependencies const publicPath = process.env.PUBLIC_PATH const explorerPath = process.env.EXPLORER_PATH const walletPath = process.env.WALLET_PATH +const dacPath = process.env.DAC_PATH module.exports = merge(common, { mode: 'development', @@ -24,6 +25,7 @@ module.exports = merge(common, { remotes: { Explorer: 'Explorer@' + explorerPath + 'remoteEntry.js', wallet: 'wallet@' + walletPath + 'remoteEntry.js', + DAC: 'dac@' + dacPath + 'remoteEntry.js', }, exposes: {}, shared: { diff --git a/webpack.local.js b/webpack.local.js index a667f50f..36c3a220 100644 --- a/webpack.local.js +++ b/webpack.local.js @@ -24,6 +24,7 @@ module.exports = merge(common, { remotes: { Explorer: 'Explorer@http://localhost:5002/remoteEntry.js', wallet: 'wallet@http://localhost:5003/remoteEntry.js', + DAC: 'dac@http://localhost:5005/remoteEntry.js', }, exposes: {}, shared: { diff --git a/webpack.prod.js b/webpack.prod.js index c19dc31b..19890f64 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -6,6 +6,7 @@ const deps = require('./package.json').dependencies const publicPath = process.env.PUBLIC_PATH const explorerPath = process.env.EXPLORER_PATH const walletPath = process.env.WALLET_PATH +const dacPath = process.env.DAC_PATH module.exports = merge(common, { mode: 'production', @@ -23,6 +24,7 @@ module.exports = merge(common, { remotes: { Explorer: 'Explorer@' + explorerPath + 'remoteEntry.js', wallet: 'wallet@' + walletPath + 'remoteEntry.js', + DAC: 'dac@' + dacPath + 'remoteEntry.js', }, exposes: {}, shared: { diff --git a/yarn.lock b/yarn.lock index 0923b1b4..fb3df1a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1113,17 +1113,24 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.23.9", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.25.6" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.6.tgz#9afc3289f7184d8d7f98b099884c26317b9264d2" - integrity sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ== +"@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.22.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.3.tgz#0a7fce51d43adbf0f7b517a71f4c3aaca92ebcbb" + integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ== dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.24.7", "@babel/template@^7.25.0", "@babel/template@^7.3.3": +"@babel/runtime@^7.23.9": version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" - integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" + integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== + dependencies: + regenerator-runtime "^0.14.0" + +"@babel/template@^7.18.10", "@babel/template@^7.20.7", "@babel/template@^7.21.9", "@babel/template@^7.3.3": + version "7.21.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.21.9.tgz#bf8dad2859130ae46088a99c1f265394877446fb" + integrity sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ== dependencies: "@babel/code-frame" "^7.24.7" "@babel/parser" "^7.25.0" @@ -1159,7 +1166,7 @@ "@c4tplatform/camino-wallet-sdk@file:camino-wallet-sdk": version "0.0.2" dependencies: - "@c4tplatform/caminojs" "file:../../../Library/Caches/Yarn/v6/npm-@c4tplatform-camino-wallet-sdk-0.0.2-a8baa879-41ba-402a-8932-cca31b30a2f0-1726562987441/node_modules/@c4tplatform/camino-wallet-sdk/caminojs" + "@c4tplatform/caminojs" "file:../../../Library/Caches/Yarn/v6/npm-@c4tplatform-camino-wallet-sdk-0.0.2-1fadaec2-3f62-4796-8990-317e53bafe4c-1722126943544/node_modules/@c4tplatform/camino-wallet-sdk/caminojs" "@ethereumjs/tx" "3.4.0" "@ledgerhq/hw-app-eth" "6.12.2" "@ledgerhq/hw-transport" "^6.19.0" @@ -1421,10 +1428,10 @@ dependencies: "@emotion/memoize" "0.7.4" -"@emotion/is-prop-valid@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz#bd84ba972195e8a2d42462387581560ef780e4e2" - integrity sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ== +"@emotion/is-prop-valid@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== dependencies: "@emotion/memoize" "^0.9.0" @@ -2611,28 +2618,28 @@ hey-listen "^1.0.8" tslib "^2.3.1" -"@mui/core-downloads-tracker@^5.16.7": - version "5.16.7" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz#182a325a520f7ebd75de051fceabfc0314cfd004" - integrity sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ== +"@mui/core-downloads-tracker@^5.16.5": + version "5.16.5" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.5.tgz#396c7e133a0705c8d04c8ef36edad7ad94cb4981" + integrity sha512-ziFn1oPm6VjvHQcdGcAO+fXvOQEgieIj0BuSqcltFU+JXIxjPdVYNTdn2HU7/Ak5Gabk6k2u7+9PV7oZ6JT5sA== "@mui/icons-material@^5.15.11": - version "5.16.7" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.16.7.tgz#e27f901af792065efc9f3d75d74a66af7529a10a" - integrity sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q== + version "5.16.5" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.16.5.tgz#53cdd03132315c8daff2200d146035f34c913470" + integrity sha512-bn88xxU/J9UV0s6+eutq7o3TTOrOlbCX+KshFb8kxgIxJZZfYz3JbAXVMivvoMF4Md6jCVUzM9HEkf4Ajab4tw== dependencies: "@babel/runtime" "^7.23.9" "@mui/material@^5.15.11": - version "5.16.7" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.16.7.tgz#6e814e2eefdaf065a769cecf549c3569e107a50b" - integrity sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg== + version "5.16.5" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.16.5.tgz#7989b088073f88c2d19501cc947899d811556089" + integrity sha512-eQrjjg4JeczXvh/+8yvJkxWIiKNHVptB/AqpsKfZBWp5mUD5U3VsjODMuUl1K2BSq0omV3CiO/mQmWSSMKSmaA== dependencies: "@babel/runtime" "^7.23.9" - "@mui/core-downloads-tracker" "^5.16.7" - "@mui/system" "^5.16.7" + "@mui/core-downloads-tracker" "^5.16.5" + "@mui/system" "^5.16.5" "@mui/types" "^7.2.15" - "@mui/utils" "^5.16.6" + "@mui/utils" "^5.16.5" "@popperjs/core" "^2.11.8" "@types/react-transition-group" "^4.4.10" clsx "^2.1.0" @@ -2641,48 +2648,48 @@ react-is "^18.3.1" react-transition-group "^4.4.5" -"@mui/private-theming@^5.16.6": - version "5.16.6" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.16.6.tgz#547671e7ae3f86b68d1289a0b90af04dfcc1c8c9" - integrity sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw== +"@mui/private-theming@^5.16.5": + version "5.16.5" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.16.5.tgz#b90afcfa76ea50778453c633656ff59cb1b5494d" + integrity sha512-CSLg0YkpDqg0aXOxtjo3oTMd3XWMxvNb5d0v4AYVqwOltU8q6GvnZjhWyCLjGSCrcgfwm6/VDjaKLPlR14wxIA== dependencies: "@babel/runtime" "^7.23.9" - "@mui/utils" "^5.16.6" + "@mui/utils" "^5.16.5" prop-types "^15.8.1" -"@mui/styled-engine@^5.16.6": - version "5.16.6" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.16.6.tgz#60110c106dd482dfdb7e2aa94fd6490a0a3f8852" - integrity sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g== +"@mui/styled-engine@^5.16.4": + version "5.16.4" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.16.4.tgz#a7a8c9079c307bab91ccd65ed5dd1496ddf2a3ab" + integrity sha512-0+mnkf+UiAmTVB8PZFqOhqf729Yh0Cxq29/5cA3VAyDVTRIUUQ8FXQhiAhUIbijFmM72rY80ahFPXIm4WDbzcA== dependencies: "@babel/runtime" "^7.23.9" "@emotion/cache" "^11.11.0" csstype "^3.1.3" prop-types "^15.8.1" -"@mui/system@^5.15.11", "@mui/system@^5.16.7": - version "5.16.7" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.16.7.tgz#4583ca5bf3b38942e02c15a1e622ba869ac51393" - integrity sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA== +"@mui/system@^5.15.11", "@mui/system@^5.16.5": + version "5.16.5" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.16.5.tgz#a90239e1467f7fce960167939dde9f44f6869484" + integrity sha512-uzIUGdrWddUx1HPxW4+B2o4vpgKyRxGe/8BxbfXVDPNPHX75c782TseoCnR/VyfnZJfqX87GcxDmnZEE1c031g== dependencies: "@babel/runtime" "^7.23.9" - "@mui/private-theming" "^5.16.6" - "@mui/styled-engine" "^5.16.6" + "@mui/private-theming" "^5.16.5" + "@mui/styled-engine" "^5.16.4" "@mui/types" "^7.2.15" - "@mui/utils" "^5.16.6" + "@mui/utils" "^5.16.5" clsx "^2.1.0" csstype "^3.1.3" prop-types "^15.8.1" "@mui/types@^7.2.15": - version "7.2.16" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.16.tgz#66710c691b51cd4fca95322100cd74ec230cfe30" - integrity sha512-qI8TV3M7ShITEEc8Ih15A2vLzZGLhD+/UPNwck/hcls2gwg7dyRjNGXcQYHKLB5Q7PuTRfrTkAoPa2VV1s67Ag== + version "7.2.15" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.15.tgz#dadd232fe9a70be0d526630675dff3b110f30b53" + integrity sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q== -"@mui/utils@^5.16.6": - version "5.16.6" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.16.6.tgz#905875bbc58d3dcc24531c3314a6807aba22a711" - integrity sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA== +"@mui/utils@^5.16.5": + version "5.16.5" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.16.5.tgz#3a16877a80166a7f8b58c893d08e0993040fc49e" + integrity sha512-CwhcA9y44XwK7k2joL3Y29mRUnoBt+gOZZdGyw7YihbEwEErJYBtDwbZwVgH68zAljGe/b+Kd5bzfl63Gi3R2A== dependencies: "@babel/runtime" "^7.23.9" "@mui/types" "^7.2.15" @@ -3364,10 +3371,15 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== -"@types/prop-types@*", "@types/prop-types@^15.7.12": - version "15.7.13" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.13.tgz#2af91918ee12d9d32914feb13f5326658461b451" - integrity sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA== +"@types/prop-types@*": + version "15.7.5" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + +"@types/prop-types@^15.7.12": + version "15.7.12" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== "@types/q@^1.5.1": version "1.5.8" @@ -3406,16 +3418,16 @@ "@types/react" "*" "@types/react-transition-group@^4.4.10": - version "4.4.11" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.11.tgz#d963253a611d757de01ebb241143b1017d5d63d5" - integrity sha512-RM05tAniPZ5DZPzzNFP+DmrcOdD0efDUxMy3145oljWSl3x9ZV5vhme98gTxFrj2lhXvmGNnUiuDyJgY9IKkNA== + version "4.4.10" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac" + integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q== dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.0.28": - version "18.3.6" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.6.tgz#1cb5895c5ea0d99d8bc7d659e42f72713cbd3942" - integrity sha512-CnGaRYNu2iZlkGXGrOYtdg5mLK8neySj0woZ4e2wF/eli2E6Sazmq5X+Nrj6OBrrFVQfJWTUFeqAzoRhWQXYvg== +"@types/react@*": + version "18.2.7" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.7.tgz#dfb4518042a3117a045b8c222316f83414a783b3" + integrity sha512-ojrXpSH2XFCmHm7Jy3q44nXDyN54+EYKP2lBhJ2bqfyPj6cIUW/FZW/Csdia34NQgq7KYcAlHi5184m4X88+yw== dependencies: "@types/prop-types" "*" csstype "^3.0.2" @@ -5788,7 +5800,12 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -csstype@^3.0.2, csstype@^3.1.3: +csstype@^3.0.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + +csstype@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== @@ -12323,7 +12340,12 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0, react-is@^18.3.1: +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +react-is@^18.3.1: version "18.3.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== @@ -12556,10 +12578,10 @@ regenerator-runtime@^0.14.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== -regenerator-transform@^0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" - integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== +regenerator-transform@^0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.1.tgz#f6c4e99fc1b4591f780db2586328e4d9a9d8dc56" + integrity sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg== dependencies: "@babel/runtime" "^7.8.4"