From 1ea29fbdfe1a704a5557d1861450d9a30d7ed242 Mon Sep 17 00:00:00 2001 From: Ayoub Agoumi Date: Thu, 28 Dec 2023 16:29:46 +0100 Subject: [PATCH 1/9] refactor: app configuration and routing (#181) * refactor: app configuration and routing * feat: add loading indicator to when the networks are loading or on network change --- src/components/Navbar/NetworkSwitcher.tsx | 14 ++- src/hooks/useNetwork.ts | 21 ++-- src/index.css | 65 +++++++++- src/layout/MainLayout.tsx | 145 +++++++++++++++++----- src/layout/RenderApp.tsx | 8 +- src/layout/RoutesSuite.tsx | 18 +-- src/layout/index.tsx | 4 +- src/redux/slices/network.ts | 12 +- src/views/create/Create.tsx | 20 ++- 9 files changed, 229 insertions(+), 78 deletions(-) diff --git a/src/components/Navbar/NetworkSwitcher.tsx b/src/components/Navbar/NetworkSwitcher.tsx index 7acd7a91..116fbec7 100644 --- a/src/components/Navbar/NetworkSwitcher.tsx +++ b/src/components/Navbar/NetworkSwitcher.tsx @@ -1,9 +1,8 @@ -import { mdiDeleteOutline, mdiPencilOutline, mdiPlus } from '@mdi/js' -import Icon from '@mdi/react' import { Box, Button, Chip, + CircularProgress, DialogTitle, MenuItem, MenuList, @@ -12,13 +11,16 @@ import { Typography, useTheme, } from '@mui/material' -import React from 'react' -import useNetwork from '../../hooks/useNetwork' +import { mdiDeleteOutline, mdiPencilOutline, mdiPlus } from '@mdi/js' import { networkStatusColor, networkStatusName } from '../../utils/networkUtils' -import MHidden from '../@material-extend/MHidden' -import DialogAnimate from '../Animate/DialogAnimate' + 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' interface NetworkSwitcherProps { handleCloseSidebar?: () => void diff --git a/src/hooks/useNetwork.ts b/src/hooks/useNetwork.ts index 323e4743..832f2f59 100644 --- a/src/hooks/useNetwork.ts +++ b/src/hooks/useNetwork.ts @@ -1,18 +1,20 @@ import { addNetworks, changeActiveNetwork, + changeLoading, changeNetworkStatus, getActiveNetwork, getNetworks, selectNetworkStatus, } from '@/redux/slices/network' -import { useStore } from 'Explorer/useStore' +import { updateApps, updateNotificationStatus, updateShowButton } from '../redux/slices/app-config' +import { useAppDispatch, useAppSelector } from './reduxHooks' import { useEffect, useState } from 'react' + import { AvaNetwork } from 'wallet/AvaNetwork' -import store from 'wallet/store' import { Status } from '../@types' -import { updateApps, updateNotificationStatus, updateShowButton } from '../redux/slices/app-config' -import { useAppDispatch, useAppSelector } from './reduxHooks' +import store from 'wallet/store' +import { useStore } from 'Explorer/useStore' const useNetwork = (): { handleChangeNetwork: (arg: string) => void @@ -22,6 +24,7 @@ const useNetwork = (): { handleCloseModal: () => void switchNetwork: (network: AvaNetwork) => Promise status: Status + loading: boolean networks: AvaNetwork[] open: boolean edit: boolean @@ -39,18 +42,19 @@ const useNetwork = (): { const networks: AvaNetwork[] = useAppSelector(getNetworks) const activeNetwork = useAppSelector(getActiveNetwork) const status: Status = useAppSelector(selectNetworkStatus) + const loading = useAppSelector(state => state.network.loading) const { changeNetworkExplorer } = useStore() useEffect(() => { - if (selectedNetwork) { - handleChangeEvent() - } + if (selectedNetwork) handleChangeEvent() + // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedNetwork]) const switchNetwork = async (network: AvaNetwork) => { try { + dispatch(changeLoading(true)) dispatch(changeNetworkStatus(Status.LOADING)) if (store.state.activeWallet?.type === 'multisig') { await store.dispatch('activateWallet', store.state.wallets[0]) @@ -74,12 +78,14 @@ const useNetwork = (): { dispatch(updateNotificationStatus({ message: 'Disconnected', severity: 'error' })) store.state.Network.status = 'disconnected' dispatch(changeNetworkStatus(Status.FAILED)) + dispatch(changeLoading(false)) } finally { let newSelectedNetwork = store.state.Network.selectedNetwork ? store.state.Network.selectedNetwork : network dispatch(changeActiveNetwork(newSelectedNetwork)) changeNetworkExplorer(newSelectedNetwork) + dispatch(changeLoading(false)) } } const handleChangeNetwork = (selected: string) => { @@ -146,6 +152,7 @@ const useNetwork = (): { handleCloseModal, switchNetwork, status, + loading, networks, open, edit, diff --git a/src/index.css b/src/index.css index 77162045..1e4649bf 100644 --- a/src/index.css +++ b/src/index.css @@ -1,12 +1,37 @@ :root { --border-radius-lg: 12px; - --border-radius-sm: 7px; + --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%); + --tailwind-slate-slate-200: #e2e7f0; + --tailwind-slate-slate-300: #cbd4e2; + --tailwind-slate-slate-600: #475569; + --tailwind-slate-slate-900: #0f182a; + --tailwind-slate-white: #fff; + --spacing-space-sm: 8px; + --spacing-space-md: 12px; + --spacing-space-base: 16px; + --spacing-space-lg: 24px; } html[data-theme='day'] { @@ -24,7 +49,7 @@ html[data-theme='day'] { --info: #2c7490; --info-1: 44, 116, 144; --bg-wallet: #f5f6fa; - --warning: #f19d38; + --warning: #e5a21f; --bg-wallet-light: #ffffff; --primary-border-color: rgba(203, 213, 225, 0.12); --secondary-border-color: #e2e8f0; @@ -35,6 +60,19 @@ html[data-theme='day'] { --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='night'] { @@ -63,6 +101,27 @@ html[data-theme='night'] { --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: auto; + font-size: 16px !important; } #app { @@ -76,4 +135,4 @@ html[data-theme='night'] { font-family: 'Rubik', sans-serif; transition-duration: 0.2s; width: 100%; -} +} \ No newline at end of file diff --git a/src/layout/MainLayout.tsx b/src/layout/MainLayout.tsx index 58b007bf..de57b591 100644 --- a/src/layout/MainLayout.tsx +++ b/src/layout/MainLayout.tsx @@ -1,25 +1,36 @@ +import { Backdrop, CircularProgress, Paper, Typography } from '@mui/material' +import { Box, Toolbar, useTheme } from '@mui/material' import React, { useState } from 'react' -import Navbar from '../components/Navbar' +import { + addNetworks, + changeActiveNetwork, + changeLoading, + changeNetworkStatus, +} from '../redux/slices/network' + import Footer from '../components/Footer' -import store from 'wallet/store' +import Navbar from '../components/Navbar' +import Notifications from '../components/Notification' import { Status } from '../@types' -import { useAppDispatch } from '../hooks/reduxHooks' -import { addNetworks, changeActiveNetwork, changeNetworkStatus } from '../redux/slices/network' +import { changeActiveApp } from '../redux/slices/app-config' import { matchNetworkStatus } from '../utils/componentsUtils' -import { Box, Toolbar, useTheme } from '@mui/material' +import store from 'wallet/store' +import { useAppDispatch } from '../hooks/reduxHooks' +import { useEffect } from 'react' +import { useEffectOnce } from '../hooks/useEffectOnce' import { useLocation } from 'react-router-dom' -import { changeActiveApp } from '../redux/slices/app-config' +import useNetwork from '../hooks/useNetwork' import { useStore } from 'Explorer/useStore' -import Notifications from '../components/Notification' -import { useEffectOnce } from '../hooks/useEffectOnce' const MainLayout = ({ children }) => { const [loadNetworks, setLoadNetworks] = useState(true) const theme = useTheme() const dispatch = useAppDispatch() const { updateNetworks, changeNetworkExplorer } = useStore() + const { loading } = useNetwork() const location = useLocation() const init = async () => { + dispatch(changeLoading(true)) if (location.pathname.split('/')[1] === 'wallet') dispatch(changeActiveApp('Wallet')) else if (location.pathname.split('/')[1] === 'explorer') dispatch(changeActiveApp('Explorer')) @@ -39,36 +50,106 @@ const MainLayout = ({ children }) => { updateNetworks(networks) changeNetworkExplorer(selectedNetwork) setLoadNetworks(false) + dispatch(changeLoading(false)) } useEffectOnce(() => { init() }) + + useEffect(() => { + const html = document.documentElement + if (loading || loadNetworks) html.style.overflow = 'hidden' + else html.style.overflow = 'auto' + }, [loading, loadNetworks]) + return ( - - - - - - {!loadNetworks && <>{children}} + <> + + + + + + {!loadNetworks && <>{children}} + +