diff --git a/src/App.tsx b/src/App.tsx index d8ee2409..7381499d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,9 +1,8 @@ +import './theme/theme.css'; import { useEffect } from 'react'; import { invoke } from '@tauri-apps/api/tauri'; import { listen } from '@tauri-apps/api/event'; - import CssBaseline from '@mui/material/CssBaseline'; -import './theme/theme.css'; import { ThemeProvider } from '@mui/material/styles'; import { lightTheme } from './theme/themes'; import { ContainerInner, DashboardContainer } from './theme/styles'; @@ -12,10 +11,19 @@ import { Dashboard } from './containers/Dashboard'; import { TitleBar } from './containers/TitleBar'; import { AppBackground } from './containers/AppBackground'; import useAppStateStore from './store/appStateStore'; +import ErrorSnackbar from './containers/Error/ErrorSnackbar'; function App() { + const { view, background, setHashRate, setCpuUsage, setAppState, setError } = + useAppStateStore((state) => ({ + view: state.view, + background: state.background, + setHashRate: state.setHashRate, + setCpuUsage: state.setCpuUsage, + setAppState: state.setAppState, + setError: state.setError, + })); - const { view, background, setHashRate, setCpuUsage } = useAppStateStore(); useEffect(() => { const unlistenPromise = listen('message', (event) => { console.log('some kind of event', event.event, event.payload); @@ -23,11 +31,11 @@ function App() { const intervalId = setInterval(() => { invoke('status', {}) - .then((status : any) => { + .then((status: any) => { console.log('Status', status); - + setAppState(status); setCpuUsage(status.cpu?.cpu_usage); - setHashRate(status.cpu?.hash_rate); + setHashRate(status.cpu?.hash_rate); const logArea = document.getElementById('log-area'); if (logArea) { logArea.innerText = JSON.stringify(status, null, 2); @@ -35,6 +43,7 @@ function App() { }) .catch((e) => { console.error('Could not get status', e); + setError(e.toString()); }); }, 1000); return () => { @@ -55,6 +64,7 @@ function App() { + ); } diff --git a/src/assets/backgrounds/loser.jpg b/src/assets/backgrounds/loser.jpg index 217c1c0c..5e5d569e 100644 Binary files a/src/assets/backgrounds/loser.jpg and b/src/assets/backgrounds/loser.jpg differ diff --git a/src/assets/icons/eco-icon.svg b/src/assets/icons/eco-icon.svg new file mode 100644 index 00000000..bf18a40b --- /dev/null +++ b/src/assets/icons/eco-icon.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/assets/icons/select-arrows.svg b/src/assets/icons/select-arrows.svg new file mode 100644 index 00000000..fd86658c --- /dev/null +++ b/src/assets/icons/select-arrows.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/containers/AppBackground/AppBackground.tsx b/src/containers/AppBackground/AppBackground.tsx index 7f2b0f4b..d6b91144 100644 --- a/src/containers/AppBackground/AppBackground.tsx +++ b/src/containers/AppBackground/AppBackground.tsx @@ -1,7 +1,5 @@ import { useTheme } from '@mui/material/styles'; import clouds from '../../assets/backgrounds/clouds.png'; -import { styled } from '@mui/material/styles'; -import { Box } from '@mui/material'; import loading from '../../assets/backgrounds/loading.jpg'; import defaultbg from '../../assets/backgrounds/defaultbg.jpg'; import determining from '../../assets/backgrounds/determining.jpg'; @@ -9,35 +7,8 @@ import mining from '../../assets/backgrounds/mining.jpg'; import loser from '../../assets/backgrounds/loser.jpg'; import winner from '../../assets/backgrounds/winner.jpg'; import { backgroundType } from '../../store/types'; - -const AppContainer = styled(Box)( - ({ theme, status }: { theme: any; status: any }) => ({ - backgroundColor: theme.palette.background.default, - backgroundSize: 'cover', - backgroundImage: `url(${status})`, - backgroundPosition: 'center', - }) -); - -// const BackgroundImage = styled(Box)( -// ({ theme, status }: { theme: any; status: statusType }) => ({ -// position: 'absolute', -// bottom: 0, -// right: 0, -// height: '80%', -// width: `calc(100% - ${sidebarWidth} - ${theme.spacing(4)})`, -// backgroundImage: `url(${ -// status === 'mining' ? build1 : status === 'waiting' ? build3 : '' -// })`, -// backgroundPosition: 'bottom center', -// backgroundRepeat: 'no-repeat', -// backgroundSize: 'contain', -// zIndex: 0, -// borderRadius: '12px', -// overflow: 'hidden', -// border: '1px solid red', -// }) -// ); +import useAppStateStore from '../../store/appStateStore'; +import { AppContainer } from './styles'; function AppBackground({ children, @@ -46,6 +17,7 @@ function AppBackground({ children: React.ReactNode; status: backgroundType; }) { + const visualMode = useAppStateStore((state) => state.visualMode); const theme = useTheme(); let bg = defaultbg; @@ -77,10 +49,17 @@ function AppBackground({ break; } + if (!visualMode) { + return ( + + {children} + + ); + } + return ( {children} - {/* */} ); } diff --git a/src/containers/AppBackground/styles.ts b/src/containers/AppBackground/styles.ts new file mode 100644 index 00000000..3c9885ff --- /dev/null +++ b/src/containers/AppBackground/styles.ts @@ -0,0 +1,11 @@ +import { styled } from '@mui/material/styles'; +import { Box } from '@mui/material'; + +export const AppContainer = styled(Box)( + ({ theme, status }: { theme: any; status: any }) => ({ + backgroundColor: theme.palette.background.default, + backgroundSize: 'cover', + backgroundImage: `url(${status})`, + backgroundPosition: 'center', + }) +); diff --git a/src/containers/Dashboard/MiningView/MiningView.tsx b/src/containers/Dashboard/MiningView/MiningView.tsx index 80ad41aa..2e561976 100644 --- a/src/containers/Dashboard/MiningView/MiningView.tsx +++ b/src/containers/Dashboard/MiningView/MiningView.tsx @@ -1,11 +1,16 @@ import BlockInfo from './components/BlockInfo'; +import TopStatus from './components/TopStatus'; import VisualMode from '../components/VisualMode'; import MiningButton from './components/MiningButton'; +import { InfoContainer } from '../styles'; function MiningView() { return ( <> - + + + + diff --git a/src/containers/Dashboard/MiningView/components/BlockInfo.tsx b/src/containers/Dashboard/MiningView/components/BlockInfo.tsx index db6170a9..ff56ce4d 100644 --- a/src/containers/Dashboard/MiningView/components/BlockInfo.tsx +++ b/src/containers/Dashboard/MiningView/components/BlockInfo.tsx @@ -1,9 +1,8 @@ import { Stack, Typography, Divider } from '@mui/material'; -import { BlockInfoContainer } from '../../styles'; function BlockInfo() { return ( - + #24,475 Floor @@ -18,7 +17,7 @@ function BlockInfo() { 01:23:05 Current floor build time - + ); } diff --git a/src/containers/Dashboard/MiningView/components/MiningButton.tsx b/src/containers/Dashboard/MiningView/components/MiningButton.tsx index 21064ec2..665dd715 100644 --- a/src/containers/Dashboard/MiningView/components/MiningButton.tsx +++ b/src/containers/Dashboard/MiningView/components/MiningButton.tsx @@ -21,7 +21,13 @@ const StopStyle = { }; function MiningButton() { - const { startMining, stopMining, setBackground } = useAppStateStore(); + const { startMining, stopMining, setBackground } = useAppStateStore( + (state) => ({ + startMining: state.startMining, + stopMining: state.stopMining, + setBackground: state.setBackground, + }) + ); const [mining, setMining] = useState(false); const handleMining = () => { diff --git a/src/containers/Dashboard/MiningView/components/TopStatus.tsx b/src/containers/Dashboard/MiningView/components/TopStatus.tsx new file mode 100644 index 00000000..432e3c79 --- /dev/null +++ b/src/containers/Dashboard/MiningView/components/TopStatus.tsx @@ -0,0 +1,27 @@ +import { useEffect } from 'react'; +import { Typography } from '@mui/material'; +import useAppStateStore from '../../../../store/appStateStore'; + +function TopStatus() { + const { topStatus, setTopStatus, appState } = useAppStateStore((state) => ({ + topStatus: state.topStatus, + setTopStatus: state.setTopStatus, + appState: state.appState, + })); + + useEffect(() => { + if (appState?.cpu?.is_mining) { + setTopStatus('Mining'); + } else { + setTopStatus('Not mining'); + } + }, [appState?.cpu?.is_mining]); + + return ( + + {topStatus} + + ); +} + +export default TopStatus; diff --git a/src/containers/Dashboard/components/VisualMode.tsx b/src/containers/Dashboard/components/VisualMode.tsx index 0e576ce4..30385a5c 100644 --- a/src/containers/Dashboard/components/VisualMode.tsx +++ b/src/containers/Dashboard/components/VisualMode.tsx @@ -3,7 +3,10 @@ import { VisualModeContainer } from '../styles'; import useAppStateStore from '../../../store/appStateStore'; function VisualMode() { - const { visualMode, setVisualMode } = useAppStateStore(); + const { visualMode, setVisualMode } = useAppStateStore((state) => ({ + visualMode: state.visualMode, + setVisualMode: state.setVisualMode, + })); return ( Visual Mode diff --git a/src/containers/Dashboard/styles.ts b/src/containers/Dashboard/styles.ts index 42c36f6d..ef1e51b8 100644 --- a/src/containers/Dashboard/styles.ts +++ b/src/containers/Dashboard/styles.ts @@ -1,6 +1,6 @@ import { styled } from '@mui/material/styles'; import { LinearProgress, Box } from '@mui/material'; -import { headerHeight } from '../../theme/styles'; +import { headerHeight, sidebarWidth } from '../../theme/styles'; export const DashboardContainer = styled(Box)(() => ({ display: 'flex', @@ -38,12 +38,13 @@ export const VisualModeContainer = styled(Box)(({ theme }) => ({ right: theme.spacing(1), })); -export const BlockInfoContainer = styled(Box)(({ theme }) => ({ +export const InfoContainer = styled(Box)(({ theme }) => ({ position: 'absolute', top: `calc(${headerHeight} + ${theme.spacing(1)})`, right: theme.spacing(4), display: 'flex', - alignItems: 'center', - justifyContent: 'center', + alignItems: 'flex-start', + justifyContent: 'space-between', + width: `calc(100% - ${sidebarWidth} - ${theme.spacing(8)})`, gap: theme.spacing(2), })); diff --git a/src/containers/Error/ErrorSnackbar.tsx b/src/containers/Error/ErrorSnackbar.tsx new file mode 100644 index 00000000..80f37ea2 --- /dev/null +++ b/src/containers/Error/ErrorSnackbar.tsx @@ -0,0 +1,59 @@ +import { Box, Alert, IconButton, Snackbar } from '@mui/material'; +import { IoClose } from 'react-icons/io5'; +import useAppStateStore from '../../store/appStateStore'; + +function ErrorSnackbar() { + const { error, setError } = useAppStateStore((state) => ({ + error: state.error, + setError: state.setError, + })); + + const handleClose = ( + _event: React.SyntheticEvent | Event, + reason?: string + ) => { + if (reason === 'clickaway') { + return; + } + + setError(''); + }; + + return ( + + + + + } + > + + {error} + + + + ); +} + +export default ErrorSnackbar; diff --git a/src/containers/SideBar/ExpandableBox.tsx b/src/containers/SideBar/ExpandableBox.tsx deleted file mode 100644 index 76557c27..00000000 --- a/src/containers/SideBar/ExpandableBox.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React, { useState } from 'react'; -import { Box, Button } from '@mui/material'; -import { styled } from '@mui/system'; - -const ExpandableBoxContainer = styled(Box)(({ theme }) => ({ - position: 'absolute', - overflow: 'hidden', - transition: 'width 0.3s ease-in-out', - backgroundColor: theme.palette.background.paper, - borderRadius: theme.shape.borderRadius, - // justifySelf: 'stretch', - // alignSelf: 'stretch', -})); - -interface ExpandableBoxProps { - initialWidth: string; - expandedWidth: string; - children: React.ReactNode; -} - -const ExpandableBox: React.FC = ({ - initialWidth, - expandedWidth, - children, -}) => { - const [expanded, setExpanded] = useState(false); - - const handleToggle = () => { - setExpanded((prevExpanded) => !prevExpanded); - }; - - return ( - - - {children} - - - - ); -}; - -export default ExpandableBox; diff --git a/src/containers/SideBar/Miner/Miner.tsx b/src/containers/SideBar/Miner/Miner.tsx new file mode 100644 index 00000000..b9ecbcc6 --- /dev/null +++ b/src/containers/SideBar/Miner/Miner.tsx @@ -0,0 +1,31 @@ +import Tile from './components/Tile.tsx'; +import { MinerContainer, TileContainer } from './styles.ts'; +import AutoMiner from './components/AutoMiner.tsx'; +import Scheduler from './components/Scheduler.tsx'; +import useAppStateStore from '../../../store/appStateStore.ts'; +import ModeSelect from './components/ModeSelect.tsx'; + +function Miner() { + const { cpuUsage, hashRate } = useAppStateStore((state) => ({ + cpuUsage: state.cpuUsage, + hashRate: state.hashRate, + })); + + return ( + + + + + + + {/**/} + + + + + + + ); +} + +export default Miner; diff --git a/src/containers/SideBar/TariMiner/components/AutoMiner.tsx b/src/containers/SideBar/Miner/components/AutoMiner.tsx similarity index 67% rename from src/containers/SideBar/TariMiner/components/AutoMiner.tsx rename to src/containers/SideBar/Miner/components/AutoMiner.tsx index 7d459e4d..f13235fe 100644 --- a/src/containers/SideBar/TariMiner/components/AutoMiner.tsx +++ b/src/containers/SideBar/Miner/components/AutoMiner.tsx @@ -1,6 +1,5 @@ import { FormGroup, Switch, Stack, Typography } from '@mui/material'; -import { AutoMinerContainer, ScheduleButton } from '../styles'; -import { IoCalendar } from 'react-icons/io5'; +import { AutoMinerContainer } from '../styles'; function AutoMiner() { return ( @@ -8,7 +7,7 @@ function AutoMiner() { Auto Miner - + Auto miner will turn on your miner when your machine is idle @@ -16,9 +15,6 @@ function AutoMiner() { - }> - Setup scheduler - ); } diff --git a/src/containers/SideBar/Miner/components/ModeSelect.tsx b/src/containers/SideBar/Miner/components/ModeSelect.tsx new file mode 100644 index 00000000..a4d6f2da --- /dev/null +++ b/src/containers/SideBar/Miner/components/ModeSelect.tsx @@ -0,0 +1,58 @@ +import MenuItem from '@mui/material/MenuItem'; +import FormControl from '@mui/material/FormControl'; +import Select, { SelectChangeEvent } from '@mui/material/Select'; +import { styled } from '@mui/system'; +import { modeType } from '../../../../store/types'; +import { IoCode } from 'react-icons/io5'; +import { Typography } from '@mui/material'; +import { TileItem } from '../styles'; +import useAppStateStore from '../../../../store/appStateStore'; + +const CustomSelect = styled(Select)(({ theme }: any) => ({ + '& .MuiSelect-select': { + padding: 0, + textTransform: 'uppercase', + fontSize: theme.typography.h5.fontSize, + fontFamily: theme.typography.h5.fontFamily, + lineHeight: theme.typography.h5.lineHeight, + }, + '& .MuiOutlinedInput-notchedOutline': { + border: 'none', + }, +})); + +function ModeSelect() { + const { mode, setMode } = useAppStateStore((state) => ({ + mode: state.mode, + setMode: state.setMode, + })); + + const handleChange = (event: SelectChangeEvent) => { + setMode(event.target.value as modeType); + }; + + return ( + + Mode + + + Eco + Ludicrous + + + + ); +} + +export default ModeSelect; diff --git a/src/containers/SideBar/Miner/components/Scheduler.tsx b/src/containers/SideBar/Miner/components/Scheduler.tsx new file mode 100644 index 00000000..3db84336 --- /dev/null +++ b/src/containers/SideBar/Miner/components/Scheduler.tsx @@ -0,0 +1,81 @@ +import React, { useState } from 'react'; +import { + IconButton, + Dialog, + DialogContent, + DialogActions, + Button, + Stack, + Box, + Typography, + Divider, +} from '@mui/material'; +import { IoClose } from 'react-icons/io5'; +import { IoCalendar } from 'react-icons/io5'; +import { ScheduleButton } from '../styles'; + +function Scheduler() { + const [open, setOpen] = useState(false); + + const handleClickOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + const handleCancel = () => { + handleClose(); + }; + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + handleClose(); + }; + + return ( + <> + } + onClick={handleClickOpen} + > + Setup scheduler + + + + + Mining Schedules + + + + + + + + Schedule your mining activity + + + + + + + + + + + + ); +} + +export default Scheduler; diff --git a/src/containers/SideBar/TariMiner/components/Tile.tsx b/src/containers/SideBar/Miner/components/Tile.tsx similarity index 100% rename from src/containers/SideBar/TariMiner/components/Tile.tsx rename to src/containers/SideBar/Miner/components/Tile.tsx diff --git a/src/containers/SideBar/TariMiner/styles.ts b/src/containers/SideBar/Miner/styles.ts similarity index 94% rename from src/containers/SideBar/TariMiner/styles.ts rename to src/containers/SideBar/Miner/styles.ts index be9f3e7b..75740a9c 100644 --- a/src/containers/SideBar/TariMiner/styles.ts +++ b/src/containers/SideBar/Miner/styles.ts @@ -39,4 +39,7 @@ export const AutoMinerContainer = styled(Box)(({ theme }) => ({ export const ScheduleButton = styled(Button)(({ theme }) => ({ backgroundColor: `${theme.palette.background.default} !important`, color: theme.palette.text.secondary, + '&:hover': { + backgroundColor: `${theme.palette.divider} !important`, + }, })); diff --git a/src/containers/SideBar/SideBar.tsx b/src/containers/SideBar/SideBar.tsx index 411416bd..d3a8c704 100644 --- a/src/containers/SideBar/SideBar.tsx +++ b/src/containers/SideBar/SideBar.tsx @@ -1,28 +1,33 @@ -import React from 'react'; -// import ExpandableBox from './ExpandableBox'; -import TariMiner from './TariMiner/TariMiner'; -import Wallet from './Wallet/Wallet'; -import { SideBarContainer } from './styles'; +import Miner from './Miner/Miner'; +import Wallet from './components/Wallet'; +import Heading from './components/Heading'; +import { + SideBarContainer, + SideBarInner, + HeadingContainer, + BottomContainer, +} from './styles'; import TestButtons from './TestButtons'; +import { useTheme } from '@mui/material/styles'; +import useAppStateStore from '../../store/appStateStore'; -const App: React.FC = () => { +function SideBar() { + const theme = useTheme(); + const sidebarOpen = useAppStateStore((state) => state.sidebarOpen); return ( - - - - + + + + + + + + + + + ); -}; - -export default App; - -{ - /* - Expandable Box Content - - This content is inside the expandable box. When expanded, it overlays - the main content without affecting its layout. - - */ } + +export default SideBar; diff --git a/src/containers/SideBar/TariMiner/TariMiner.tsx b/src/containers/SideBar/TariMiner/TariMiner.tsx deleted file mode 100644 index b0f10c63..00000000 --- a/src/containers/SideBar/TariMiner/TariMiner.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import { Typography, Stack, IconButton } from '@mui/material'; -import Tile from './components/Tile'; -import { MinerContainer, TileContainer } from './styles'; -import { IoSettingsOutline, IoResize } from 'react-icons/io5'; -import AutoMiner from './components/AutoMiner'; -import useAppStateStore from "../../../store/appStateStore.ts"; - -function TariMiner() { - const { cpuUsage, hashRate } = useAppStateStore(); - - return ( - - - Tari Miner - - console.log('Open Settings')}> - - - console.log('Expand Sidebar')}> - - - - - - - - - {/**/} - - - - - - - - ); -} - -export default TariMiner; diff --git a/src/containers/SideBar/TestButtons.tsx b/src/containers/SideBar/TestButtons.tsx index 7ee73939..493db2b5 100644 --- a/src/containers/SideBar/TestButtons.tsx +++ b/src/containers/SideBar/TestButtons.tsx @@ -1,12 +1,16 @@ -import { Button, ButtonGroup, Stack, Divider, Typography } from '@mui/material'; +import { Button, ButtonGroup, Stack, Typography } from '@mui/material'; import useAppStateStore from '../../store/appStateStore'; -import { viewType, backgroundType } from '../../store/types'; +import { viewType } from '../../store/types'; import { useState } from 'react'; function TestButtons() { - const { view, setView, background, setBackground } = useAppStateStore(); + const { view, setView, setBackground } = useAppStateStore((state) => ({ + view: state.view, + setView: state.setView, + setBackground: state.setBackground, + })); const [selectedView, setSelectedView] = useState(view); - const [selectedBg, setSelectedBg] = useState(background); + // const [selectedBg, setSelectedBg] = useState(background); const handleSetView = (value: viewType) => { setView(value); @@ -19,10 +23,10 @@ function TestButtons() { } }; - const handleSetStatus = (value: backgroundType) => { - setBackground(value); - setSelectedBg(value); - }; + // const handleSetStatus = (value: backgroundType) => { + // setBackground(value); + // setSelectedBg(value); + // }; return ( @@ -47,7 +51,7 @@ function TestButtons() { Mining - + {/* Backgrounds: - + */} ); } diff --git a/src/containers/SideBar/Wallet/styles.ts b/src/containers/SideBar/Wallet/styles.ts deleted file mode 100644 index 546bd80b..00000000 --- a/src/containers/SideBar/Wallet/styles.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { styled } from '@mui/material/styles'; -import { Box } from '@mui/material'; - -export const WalletContainer = styled(Box)(({ theme }) => ({ - display: 'flex', - flexDirection: 'column', - gap: theme.spacing(0.5), - backgroundColor: theme.palette.background.default, - paddingTop: theme.spacing(1), - paddingBottom: theme.spacing(1), - paddingLeft: theme.spacing(1.5), - paddingRight: theme.spacing(1.5), - borderRadius: theme.shape.borderRadius, -})); diff --git a/src/containers/SideBar/components/Heading.tsx b/src/containers/SideBar/components/Heading.tsx new file mode 100644 index 00000000..0b82fa29 --- /dev/null +++ b/src/containers/SideBar/components/Heading.tsx @@ -0,0 +1,28 @@ +import { Stack, Typography, IconButton } from '@mui/material'; +import { CgArrowsExpandRight, CgCompressRight } from 'react-icons/cg'; +import SettingsDialog from './Settings'; +import useAppStateStore from '../../../store/appStateStore'; + +function Heading() { + const { sidebarOpen, setSidebarOpen } = useAppStateStore((state) => ({ + sidebarOpen: state.sidebarOpen, + setSidebarOpen: state.setSidebarOpen, + })); + return ( + + Tari Universe + + + setSidebarOpen(!sidebarOpen)}> + {sidebarOpen ? ( + + ) : ( + + )} + + + + ); +} + +export default Heading; diff --git a/src/containers/SideBar/components/Settings.tsx b/src/containers/SideBar/components/Settings.tsx new file mode 100644 index 00000000..68eeaad1 --- /dev/null +++ b/src/containers/SideBar/components/Settings.tsx @@ -0,0 +1,94 @@ +import React, { useState } from 'react'; +import { + IconButton, + Dialog, + DialogContent, + DialogActions, + Button, + TextField, + Stack, + Box, + Typography, + Divider, +} from '@mui/material'; +import { IoSettingsOutline, IoClose } from 'react-icons/io5'; + +const Settings: React.FC = () => { + const [open, setOpen] = useState(false); + const [formState, setFormState] = useState({ field1: '', field2: '' }); + + const handleClickOpen = () => setOpen(true); + const handleClose = () => setOpen(false); + + const handleChange = (event: React.ChangeEvent) => { + const { name, value } = event.target; + setFormState((prevState) => ({ ...prevState, [name]: value })); + }; + + const handleCancel = () => { + setFormState({ field1: '', field2: '' }); + handleClose(); + }; + + const handleSubmit = (event: React.FormEvent) => { + event.preventDefault(); + console.log(formState); + handleClose(); + }; + + return ( + <> + + + + + + + Settings + + + + + + + + + + + + + + + + + + + + ); +}; + +export default Settings; diff --git a/src/containers/SideBar/Wallet/Wallet.tsx b/src/containers/SideBar/components/Wallet.tsx similarity index 86% rename from src/containers/SideBar/Wallet/Wallet.tsx rename to src/containers/SideBar/components/Wallet.tsx index 0cf45b59..58960822 100644 --- a/src/containers/SideBar/Wallet/Wallet.tsx +++ b/src/containers/SideBar/components/Wallet.tsx @@ -1,11 +1,11 @@ import { Typography, Stack } from '@mui/material'; import { ThemeProvider } from '@mui/material/styles'; -import { WalletContainer } from './styles'; +import { WalletContainer } from '../styles'; import { darkTheme } from '../../../theme/themes'; import useAppStateStore from '../../../store/appStateStore'; function Wallet() { - const { wallet } = useAppStateStore(); + const wallet = useAppStateStore((state) => state.wallet); return ( diff --git a/src/containers/SideBar/styles.ts b/src/containers/SideBar/styles.ts index bd914e5b..a28e952e 100644 --- a/src/containers/SideBar/styles.ts +++ b/src/containers/SideBar/styles.ts @@ -1,15 +1,63 @@ import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; +import { headerHeight, sidebarWidth } from '../../theme/styles'; -export const SideBarContainer = styled(Box)(({ theme }) => ({ - display: 'flex', - flexDirection: 'column', - gap: theme.spacing(2), +interface SideBarContainerProps { + sidebaropen: boolean; +} + +export const SideBarContainer = styled(Box, { + shouldForwardProp: (prop) => prop !== 'sidebaropen', +})(({ theme, sidebaropen }) => ({ backgroundColor: theme.palette.background.paper, borderRadius: theme.shape.borderRadius, - padding: theme.spacing(2), marginLeft: theme.spacing(1), marginRight: theme.spacing(1), marginBottom: theme.spacing(1), marginTop: 0, + position: 'absolute', + top: headerHeight, + left: 0, + height: `calc(100vh - ${headerHeight} - ${theme.spacing(1)})`, + width: sidebaropen ? `calc(100% - ${theme.spacing(2)})` : sidebarWidth, + zIndex: 100, + transition: 'width 0.5s ease-in-out', + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(2), + justifyContent: 'flex-start', +})); + +export const SideBarInner = styled(Box)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(2), + height: '100%', + overflowY: 'auto', + paddingLeft: theme.spacing(2), + paddingRight: theme.spacing(2), +})); + +export const BottomContainer = styled(Box)(({ theme }) => ({ + paddingLeft: theme.spacing(2), + paddingRight: theme.spacing(2), + paddingBottom: theme.spacing(2), +})); + +export const HeadingContainer = styled(Box)(({ theme }) => ({ + paddingLeft: theme.spacing(2), + paddingRight: theme.spacing(2), + paddingTop: theme.spacing(2), +})); + +export const WalletContainer = styled(Box)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + gap: theme.spacing(0.5), + backgroundColor: theme.palette.background.default, + paddingTop: theme.spacing(1), + paddingBottom: theme.spacing(1), + paddingLeft: theme.spacing(1.5), + paddingRight: theme.spacing(1.5), + borderRadius: theme.shape.borderRadius, })); diff --git a/src/store/appStateStore.ts b/src/store/appStateStore.ts index 676d7fdb..f2b47094 100644 --- a/src/store/appStateStore.ts +++ b/src/store/appStateStore.ts @@ -1,8 +1,18 @@ import { create } from 'zustand'; import { invoke } from '@tauri-apps/api/tauri'; -import { viewType, backgroundType } from './types'; +import { viewType, backgroundType, modeType } from './types'; interface AppState { + appState: any; + setAppState: (value: any) => void; + error: string; + setError: (value: string) => void; + topStatus: string; + setTopStatus: (value: string) => void; + errorOpen: boolean; + setErrorOpen: (value: boolean) => void; + + // gui background: backgroundType; setBackground: (value: backgroundType) => void; view: viewType; @@ -13,17 +23,35 @@ interface AppState { balance: number; }; setWallet: (value: { balance: number }) => void; - isMining : boolean, + isMining: boolean; setIsMining: (value: boolean) => void; + sidebarOpen: boolean; + setSidebarOpen: (value: boolean) => void; + + // stats cpuUsage: number; setCpuUsage: (value: number) => void; + mode: modeType; + setMode: (value: modeType) => void; hashRate: number; setHashRate: (value: number) => void; + + // functions startMining: () => Promise; stopMining: () => Promise; } const useAppStateStore = create((set) => ({ + appState: {}, + setAppState: (value) => set({ appState: value }), + error: '', + setError: (value) => set({ error: value }), + topStatus: 'Not mining', + setTopStatus: (value) => set({ topStatus: value }), + errorOpen: false, + setErrorOpen: (value) => set({ errorOpen: value }), + + // gui background: 'idle', setBackground: (value) => set({ background: value }), view: 'mining', @@ -34,12 +62,20 @@ const useAppStateStore = create((set) => ({ balance: 0, }, setWallet: (value) => set({ wallet: value }), - isMining: false, - setIsMining: (value) => set({ isMining: value }), - cpuUsage: 0, - setCpuUsage: (value) => set({ cpuUsage: value }), - hashRate: 0, - setHashRate: (value) => set({ hashRate: value }), + isMining: false, + setIsMining: (value) => set({ isMining: value }), + sidebarOpen: false, + setSidebarOpen: (value) => set({ sidebarOpen: value }), + + // stats + cpuUsage: 0, + setCpuUsage: (value) => set({ cpuUsage: value }), + mode: 'eco', + setMode: (value) => set({ mode: value }), + hashRate: 0, + setHashRate: (value) => set({ hashRate: value }), + + // functions startMining: async () => { try { await invoke('start_mining', {}); diff --git a/src/store/types.ts b/src/store/types.ts index 92d67303..d70519a8 100644 --- a/src/store/types.ts +++ b/src/store/types.ts @@ -7,3 +7,4 @@ export type backgroundType = | 'mining' | 'loser' | 'winner'; +export type modeType = 'eco' | 'ludicrous'; diff --git a/src/theme/styles.ts b/src/theme/styles.ts index b5ea10bd..52a0ca64 100644 --- a/src/theme/styles.ts +++ b/src/theme/styles.ts @@ -8,14 +8,10 @@ export const ContainerInner = styled(Box)(({ theme }) => ({ display: 'flex', flexDirection: 'row', alignItems: 'stretch', + justifyContent: 'center', gap: theme.spacing(2), minHeight: `calc(100vh - ${headerHeight})`, - '& > :first-of-type': { - width: sidebarWidth, - }, - '& > :nth-child(2)': { - flexGrow: 1, - }, + paddingLeft: sidebarWidth, })); export const DashboardContainer = styled(Box)(() => ({ diff --git a/src/theme/tokens.ts b/src/theme/tokens.ts index 0f528ff0..4e7f45ea 100644 --- a/src/theme/tokens.ts +++ b/src/theme/tokens.ts @@ -30,8 +30,8 @@ import { error, brightGreen, } from './colors'; -// import gradients from '../styles/styles/gradients'; -// import typography from '../styles/styles/typography'; + +export const appBorderRadius = '12px'; export const componentSettings: ThemeOptions = { shape: { @@ -51,84 +51,42 @@ export const componentSettings: ThemeOptions = { }, h1: { fontSize: '30px', - lineHeight: '38px', + lineHeight: '42px', fontFamily: '"PoppinsSemiBold", sans-serif', letterSpacing: '-0.4px', }, h2: { fontSize: '26px', - lineHeight: '30px', + lineHeight: '36px', fontFamily: '"PoppinsSemiBold", sans-serif', letterSpacing: '-0.4px', }, h3: { fontSize: '24px', - lineHeight: '28px', + lineHeight: '32px', fontFamily: '"PoppinsSemiBold", sans-serif', letterSpacing: '-0.4px', }, h4: { fontSize: '20px', - lineHeight: '24px', - fontFamily: '"PoppinsSemiBold", sans-serif', + lineHeight: '28px', + fontFamily: '"PoppinsMedium", sans-serif', letterSpacing: '-0.4px', }, h5: { fontSize: '16px', - lineHeight: '20px', - fontFamily: '"PoppinsSemiBold", sans-serif', + lineHeight: '26px', + fontFamily: '"PoppinsMedium", sans-serif', letterSpacing: '-0.4px', }, h6: { fontSize: '14px', - lineHeight: '18px', - fontFamily: '"PoppinsSemiBold", sans-serif', + lineHeight: '20px', + fontFamily: '"PoppinsMedium", sans-serif', letterSpacing: '-0.4px', }, }, - transitions: { - duration: { - enteringScreen: 500, - leavingScreen: 500, - }, - }, components: { - MuiTab: { - defaultProps: { - disableRipple: true, - sx: { - textTransform: 'none', - fontSize: 14, - lineHeight: '15px', - border: 'none', - boxShadow: 'none', - borderRadius: '50px', - padding: '12px 20px', - minHeight: '40px', - color: (theme) => theme.palette.text.secondary, - '&.Mui-selected': { - color: (theme) => theme.palette.text.primary, - background: (theme) => theme.palette.divider, - }, - '&:hover': { - color: (theme) => theme.palette.text.primary, - }, - '&:focus': { - backgroundColor: (theme) => theme.palette.action.hover, - }, - }, - }, - }, - MuiTabs: { - defaultProps: { - TabIndicatorProps: { - style: { - borderRadius: 4, - display: 'none', - }, - }, - }, - }, MuiTypography: { defaultProps: { sx: { @@ -151,13 +109,6 @@ export const componentSettings: ThemeOptions = { }, }, }, - MuiTableCell: { - defaultProps: { - sx: { - borderBottom: (theme) => `1px solid ${theme.palette.divider}`, - }, - }, - }, MuiDivider: { defaultProps: { sx: { @@ -165,46 +116,6 @@ export const componentSettings: ThemeOptions = { }, }, }, - MuiList: { - defaultProps: { - sx: { - listStyleType: 'disc', - pl: 2, - pt: 0, - '& .MuiListItem-root': { - display: 'list-item', - pb: 0.5, - pt: 0.5, - }, - }, - }, - }, - MuiFormControlLabel: { - defaultProps: { - sx: { - '& .MuiTypography-root': { - fontSize: '14px', - lineHeight: '1.8rem', - color: (theme) => theme.palette.text.primary, - }, - }, - }, - }, - MuiCircularProgress: { - defaultProps: { - thickness: 4, - sx: { - color: (theme) => theme.palette.primary.main, - }, - }, - }, - MuiDialogActions: { - defaultProps: { - sx: { - padding: 2, - }, - }, - }, MuiIconButton: { defaultProps: { sx: { @@ -228,44 +139,11 @@ export const componentSettings: ThemeOptions = { }, }, }, - MuiTextField: { - defaultProps: { - variant: 'outlined', - fullWidth: true, - // margin: 'normal', - size: 'small', - sx: { - boxShadow: 'none', - '& .MuiOutlinedInput-root': { - '& fieldset': { - borderColor: (theme) => theme.palette.divider, - }, - '&:hover fieldset': { - borderColor: (theme) => theme.palette.primary.main, - }, - }, - '&:hover fieldset': { - borderColor: (theme) => theme.palette.divider, - }, - }, - - InputProps: { - style: { - color: grey[500], - fontSize: '14px', - padding: '4px', - }, - }, - }, - }, MuiDialog: { defaultProps: { sx: { - padding: 0, - '& .MuiDialogContent-root': { padding: 0 }, - '& .MuiDialog-paper': { - border: (theme) => `1px solid ${theme.palette.divider}`, - boxShadow: '0 0 40px #00000011', + '& .MuiBackdrop-root': { + borderRadius: appBorderRadius, }, }, }, @@ -315,8 +193,7 @@ export const componentSettings: ThemeOptions = { }, '& .MuiSwitch-track': { borderRadius: 20 / 2, - backgroundColor: (theme) => - theme.palette.mode === 'light' ? '#E9E9EA' : '#39393D', + backgroundColor: 'black', opacity: 1, transition: (theme) => theme.transitions.create(['background-color'], { @@ -326,72 +203,6 @@ export const componentSettings: ThemeOptions = { }, }, }, - MuiChip: { - defaultProps: { - sx: { - fontSize: 12, - height: 26, - '& strong': { - fontFamily: '"PoppinsMedium", sans-serif', - }, - }, - }, - variants: [ - { - props: { color: 'success' }, - style: ({ theme }) => ({ - background: - theme.palette.mode === 'light' - ? theme.palette.success.light - : 'rgba(255,255,255, 0.08)', - color: - theme.palette.mode === 'light' - ? theme.palette.success.contrastText - : theme.palette.success.main, - }), - }, - { - props: { color: 'warning' }, - style: ({ theme }) => ({ - background: - theme.palette.mode === 'light' - ? theme.palette.warning.light - : 'rgba(255,255,255, 0.08)', - color: theme.palette.warning.main, - }), - }, - { - props: { color: 'error' }, - style: ({ theme }) => ({ - background: - theme.palette.mode === 'light' - ? theme.palette.error.light - : 'rgba(255,255,255, 0.08)', - color: theme.palette.error.main, - }), - }, - { - props: { color: 'info' }, - style: ({ theme }) => ({ - background: - theme.palette.mode === 'light' - ? theme.palette.info.light - : 'rgba(255,255,255, 0.08)', - color: theme.palette.info.main, - }), - }, - { - props: { color: 'primary' }, - style: ({ theme }) => ({ - background: - theme.palette.mode === 'light' - ? theme.palette.info.light - : 'rgba(255,255,255, 0.08)', - color: theme.palette.primary.main, - }), - }, - ], - }, }, };