dark theme added
This commit is contained in:
84
src/App.tsx
84
src/App.tsx
@@ -1,96 +1,22 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Routes, Route } from 'react-router-dom';
|
import { Routes, Route } from 'react-router-dom';
|
||||||
import { ThemeProvider, createTheme } from "@mui/material/styles";
|
import { createTheme } from "@mui/material/styles";
|
||||||
import { GlobalInfoProvider } from "./context/globalInfo";
|
import { GlobalInfoProvider } from "./context/globalInfo";
|
||||||
import { PageWrapper } from "./pages/PageWrappper";
|
import { PageWrapper } from "./pages/PageWrappper";
|
||||||
|
import ThemeModeProvider from './context/theme-provider';
|
||||||
|
|
||||||
|
|
||||||
const theme = createTheme({
|
|
||||||
palette: {
|
|
||||||
primary: {
|
|
||||||
main: "#ff00c3",
|
|
||||||
contrastText: "#ffffff",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
MuiButton: {
|
|
||||||
styleOverrides: {
|
|
||||||
root: {
|
|
||||||
// Default styles for all buttons (optional)
|
|
||||||
textTransform: "none",
|
|
||||||
},
|
|
||||||
containedPrimary: {
|
|
||||||
// Styles for 'contained' variant with 'primary' color
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: "#ff66d9",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
outlined: {
|
|
||||||
// Apply white background for all 'outlined' variant buttons
|
|
||||||
backgroundColor: "#ffffff",
|
|
||||||
'&:hover': {
|
|
||||||
backgroundColor: "#f0f0f0", // Optional lighter background on hover
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MuiLink: {
|
|
||||||
styleOverrides: {
|
|
||||||
root: {
|
|
||||||
'&:hover': {
|
|
||||||
color: "#ff00c3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MuiIconButton: {
|
|
||||||
styleOverrides: {
|
|
||||||
root: {
|
|
||||||
// '&:hover': {
|
|
||||||
// color: "#ff66d9",
|
|
||||||
// },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MuiTab: {
|
|
||||||
styleOverrides: {
|
|
||||||
root: {
|
|
||||||
textTransform: "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MuiAlert: {
|
|
||||||
styleOverrides: {
|
|
||||||
standardInfo: {
|
|
||||||
backgroundColor: "#fce1f4",
|
|
||||||
color: "#ff00c3",
|
|
||||||
'& .MuiAlert-icon': {
|
|
||||||
color: "#ff00c3",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
MuiAlertTitle: {
|
|
||||||
styleOverrides: {
|
|
||||||
root: {
|
|
||||||
'& .MuiAlert-icon': {
|
|
||||||
color: "#ffffff",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
return (
|
return (
|
||||||
<ThemeProvider theme={theme}>
|
<ThemeModeProvider>
|
||||||
<GlobalInfoProvider>
|
<GlobalInfoProvider>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/*" element={<PageWrapper />} />
|
<Route path="/*" element={<PageWrapper />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</GlobalInfoProvider>
|
</GlobalInfoProvider>
|
||||||
</ThemeProvider>
|
</ThemeModeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ import axios from 'axios';
|
|||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { stopRecording } from "../../api/recording";
|
import { stopRecording } from "../../api/recording";
|
||||||
import { useGlobalInfoStore } from "../../context/globalInfo";
|
import { useGlobalInfoStore } from "../../context/globalInfo";
|
||||||
import { IconButton, Menu, MenuItem, Typography, Avatar } from "@mui/material";
|
import { IconButton, Menu, MenuItem, Typography, Avatar, Tooltip } from "@mui/material";
|
||||||
import { AccountCircle, Logout, Clear } from "@mui/icons-material";
|
import { AccountCircle, Logout, Clear, Brightness4, Brightness7 } from "@mui/icons-material";
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { AuthContext } from '../../context/auth';
|
import { AuthContext } from '../../context/auth';
|
||||||
import { SaveRecording } from '../molecules/SaveRecording';
|
import { SaveRecording } from '../molecules/SaveRecording';
|
||||||
import DiscordIcon from '../atoms/DiscordIcon';
|
import DiscordIcon from '../atoms/DiscordIcon';
|
||||||
import { apiUrl } from '../../apiConfig';
|
import { apiUrl } from '../../apiConfig';
|
||||||
import MaxunLogo from "../../assets/maxunlogo.png";
|
import MaxunLogo from "../../assets/maxunlogo.png";
|
||||||
|
import { useThemeMode } from '../../context/theme-provider';
|
||||||
|
|
||||||
interface NavBarProps {
|
interface NavBarProps {
|
||||||
recordingName: string;
|
recordingName: string;
|
||||||
@@ -18,10 +19,11 @@ interface NavBarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const NavBar: React.FC<NavBarProps> = ({ recordingName, isRecording }) => {
|
export const NavBar: React.FC<NavBarProps> = ({ recordingName, isRecording }) => {
|
||||||
const { notify, browserId, setBrowserId, recordingUrl } = useGlobalInfoStore();
|
const { notify, browserId, setBrowserId } = useGlobalInfoStore();
|
||||||
const { state, dispatch } = useContext(AuthContext);
|
const { state, dispatch } = useContext(AuthContext);
|
||||||
const { user } = state;
|
const { user } = state;
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const { darkMode, toggleTheme } = useThemeMode();
|
||||||
|
|
||||||
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
|
||||||
|
|
||||||
@@ -51,20 +53,18 @@ export const NavBar: React.FC<NavBarProps> = ({ recordingName, isRecording }) =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavBarWrapper>
|
<NavBarWrapper mode={darkMode ? 'dark' : 'light'}>
|
||||||
<div style={{
|
<div style={{ display: 'flex', justifyContent: 'flex-start' }}>
|
||||||
display: 'flex',
|
|
||||||
justifyContent: 'flex-start',
|
|
||||||
}}>
|
|
||||||
<img src={MaxunLogo} width={45} height={40} style={{ borderRadius: '5px', margin: '5px 0px 5px 15px' }} />
|
<img src={MaxunLogo} width={45} height={40} style={{ borderRadius: '5px', margin: '5px 0px 5px 15px' }} />
|
||||||
<div style={{ padding: '11px' }}><ProjectName>Maxun</ProjectName></div>
|
<div style={{ padding: '11px' }}>
|
||||||
|
<ProjectName mode={darkMode ? 'dark' : 'light'}>Maxun</ProjectName>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{
|
{user ? (
|
||||||
user ? (
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
|
||||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end' }}>
|
{!isRecording ? (
|
||||||
{!isRecording ? (
|
<>
|
||||||
<>
|
<IconButton
|
||||||
<IconButton
|
|
||||||
component="a"
|
component="a"
|
||||||
href="https://discord.gg/NFhWDCdb"
|
href="https://discord.gg/NFhWDCdb"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -76,72 +76,71 @@ export const NavBar: React.FC<NavBarProps> = ({ recordingName, isRecording }) =>
|
|||||||
padding: '8px',
|
padding: '8px',
|
||||||
marginRight: '10px',
|
marginRight: '10px',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<DiscordIcon sx={{ marginRight: '5px' }} />
|
<DiscordIcon sx={{ marginRight: '5px' }} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<iframe src="https://ghbtns.com/github-btn.html?user=getmaxun&repo=maxun&type=star&count=true&size=large" frameBorder="0" scrolling="0" width="170" height="30" title="GitHub"></iframe>
|
<iframe src="https://ghbtns.com/github-btn.html?user=getmaxun&repo=maxun&type=star&count=true&size=large" frameBorder="0" scrolling="0" width="170" height="30" title="GitHub"></iframe>
|
||||||
<IconButton onClick={handleMenuOpen} sx={{
|
<IconButton onClick={handleMenuOpen} sx={{
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderRadius: '5px',
|
borderRadius: '5px',
|
||||||
padding: '8px',
|
padding: '8px',
|
||||||
marginRight: '10px',
|
marginRight: '10px',
|
||||||
'&:hover': { backgroundColor: 'white', color: '#ff00c3' }
|
'&:hover': { backgroundColor: 'white', color: '#ff00c3' }
|
||||||
}}>
|
}}>
|
||||||
<AccountCircle sx={{ marginRight: '5px' }} />
|
<AccountCircle sx={{ marginRight: '5px' }} />
|
||||||
<Typography variant="body1">{user.email}</Typography>
|
<Typography variant="body1">{user.email}</Typography>
|
||||||
|
</IconButton>
|
||||||
|
<Menu
|
||||||
|
anchorEl={anchorEl}
|
||||||
|
open={Boolean(anchorEl)}
|
||||||
|
onClose={handleMenuClose}
|
||||||
|
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
|
||||||
|
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
|
||||||
|
>
|
||||||
|
<MenuItem onClick={() => { handleMenuClose(); logout(); }}>
|
||||||
|
<Logout sx={{ marginRight: '5px' }} /> Logout
|
||||||
|
</MenuItem>
|
||||||
|
</Menu>
|
||||||
|
{/* Theme Toggle Button */}
|
||||||
|
<Tooltip title="Toggle light/dark theme">
|
||||||
|
<IconButton onClick={toggleTheme} color="inherit">
|
||||||
|
{darkMode ? <Brightness7 /> : <Brightness4 />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Menu
|
</Tooltip>
|
||||||
anchorEl={anchorEl}
|
</>
|
||||||
open={Boolean(anchorEl)}
|
) : (
|
||||||
onClose={handleMenuClose}
|
<>
|
||||||
anchorOrigin={{
|
<IconButton onClick={goToMainMenu} sx={{
|
||||||
vertical: 'bottom',
|
borderRadius: '5px',
|
||||||
horizontal: 'right',
|
padding: '8px',
|
||||||
}}
|
background: 'red',
|
||||||
transformOrigin={{
|
color: 'white',
|
||||||
vertical: 'top',
|
marginRight: '10px',
|
||||||
horizontal: 'right',
|
'&:hover': { color: 'white', backgroundColor: 'red' }
|
||||||
}}
|
}}>
|
||||||
>
|
<Clear sx={{ marginRight: '5px' }} />
|
||||||
<MenuItem onClick={() => { handleMenuClose(); logout(); }}>
|
Discard
|
||||||
<Logout sx={{ marginRight: '5px' }} /> Logout
|
</IconButton>
|
||||||
</MenuItem>
|
<SaveRecording fileName={recordingName} />
|
||||||
</Menu>
|
</>
|
||||||
</>
|
)}
|
||||||
) : (
|
</div>
|
||||||
<>
|
) : null}
|
||||||
<IconButton onClick={goToMainMenu} sx={{
|
|
||||||
borderRadius: '5px',
|
|
||||||
padding: '8px',
|
|
||||||
background: 'red',
|
|
||||||
color: 'white',
|
|
||||||
marginRight: '10px',
|
|
||||||
'&:hover': { color: 'white', backgroundColor: 'red' }
|
|
||||||
}}>
|
|
||||||
<Clear sx={{ marginRight: '5px' }} />
|
|
||||||
Discard
|
|
||||||
</IconButton>
|
|
||||||
<SaveRecording fileName={recordingName} />
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
) : ""
|
|
||||||
}
|
|
||||||
</NavBarWrapper>
|
</NavBarWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const NavBarWrapper = styled.div`
|
const NavBarWrapper = styled.div<{ mode: 'light' | 'dark' }>`
|
||||||
grid-area: navbar;
|
grid-area: navbar;
|
||||||
background-color: white;
|
background-color: ${({ mode }) => (mode === 'dark' ? '#1e2124' : '#ffffff')};
|
||||||
padding:5px;
|
padding: 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border-bottom: 1px solid #e0e0e0;
|
border-bottom: 1px solid ${({ mode }) => (mode === 'dark' ? '#333' : '#e0e0e0')};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ProjectName = styled.b`
|
const ProjectName = styled.b<{ mode: 'light' | 'dark' }>`
|
||||||
color: #3f4853;
|
color: ${({ mode }) => (mode === 'dark' ? 'white' : 'black')};
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import * as React from 'react';
|
import React from 'react';
|
||||||
import Tabs from '@mui/material/Tabs';
|
import Tabs from '@mui/material/Tabs';
|
||||||
import Tab from '@mui/material/Tab';
|
import Tab from '@mui/material/Tab';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import { Paper, Button } from "@mui/material";
|
import { Paper, Button, useTheme } from "@mui/material";
|
||||||
import { AutoAwesome, FormatListBulleted, VpnKey, Usb, Article, Link, CloudQueue } from "@mui/icons-material";
|
import { AutoAwesome, FormatListBulleted, VpnKey, Usb, Article, CloudQueue } from "@mui/icons-material";
|
||||||
import { apiUrl } from "../../apiConfig";
|
|
||||||
|
|
||||||
interface MainMenuProps {
|
interface MainMenuProps {
|
||||||
value: string;
|
value: string;
|
||||||
@@ -12,6 +11,7 @@ interface MainMenuProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenuProps) => {
|
export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenuProps) => {
|
||||||
|
const theme = useTheme();
|
||||||
|
|
||||||
const handleChange = (event: React.SyntheticEvent, newValue: string) => {
|
const handleChange = (event: React.SyntheticEvent, newValue: string) => {
|
||||||
handleChangeContent(newValue);
|
handleChangeContent(newValue);
|
||||||
@@ -22,16 +22,14 @@ export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenu
|
|||||||
sx={{
|
sx={{
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
width: '250px',
|
width: '250px',
|
||||||
backgroundColor: 'white',
|
backgroundColor: theme.palette.background.paper,
|
||||||
paddingTop: '0.5rem',
|
paddingTop: '0.5rem',
|
||||||
|
color: theme.palette.text.primary,
|
||||||
}}
|
}}
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
square
|
square
|
||||||
>
|
>
|
||||||
<Box sx={{
|
<Box sx={{ width: '100%', paddingBottom: '1rem' }}>
|
||||||
width: '100%',
|
|
||||||
paddingBottom: '1rem',
|
|
||||||
}}>
|
|
||||||
<Tabs
|
<Tabs
|
||||||
value={value}
|
value={value}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
@@ -41,44 +39,28 @@ export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenu
|
|||||||
sx={{ alignItems: 'flex-start' }}
|
sx={{ alignItems: 'flex-start' }}
|
||||||
>
|
>
|
||||||
<Tab
|
<Tab
|
||||||
sx={{
|
sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: 'medium', color: theme.palette.text.primary }}
|
||||||
justifyContent: 'flex-start',
|
|
||||||
textAlign: 'left',
|
|
||||||
fontSize: 'medium',
|
|
||||||
}}
|
|
||||||
value="recordings"
|
value="recordings"
|
||||||
label="Robots"
|
label="Robots"
|
||||||
icon={<AutoAwesome />}
|
icon={<AutoAwesome />}
|
||||||
iconPosition="start"
|
iconPosition="start"
|
||||||
/>
|
/>
|
||||||
<Tab
|
<Tab
|
||||||
sx={{
|
sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: 'medium', color: theme.palette.text.primary }}
|
||||||
justifyContent: 'flex-start',
|
|
||||||
textAlign: 'left',
|
|
||||||
fontSize: 'medium',
|
|
||||||
}}
|
|
||||||
value="runs"
|
value="runs"
|
||||||
label="Runs"
|
label="Runs"
|
||||||
icon={<FormatListBulleted />}
|
icon={<FormatListBulleted />}
|
||||||
iconPosition="start"
|
iconPosition="start"
|
||||||
/>
|
/>
|
||||||
<Tab
|
<Tab
|
||||||
sx={{
|
sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: 'medium', color: theme.palette.text.primary }}
|
||||||
justifyContent: 'flex-start',
|
|
||||||
textAlign: 'left',
|
|
||||||
fontSize: 'medium',
|
|
||||||
}}
|
|
||||||
value="proxy"
|
value="proxy"
|
||||||
label="Proxy"
|
label="Proxy"
|
||||||
icon={<Usb />}
|
icon={<Usb />}
|
||||||
iconPosition="start"
|
iconPosition="start"
|
||||||
/>
|
/>
|
||||||
<Tab
|
<Tab
|
||||||
sx={{
|
sx={{ justifyContent: 'flex-start', textAlign: 'left', fontSize: 'medium', color: theme.palette.text.primary }}
|
||||||
justifyContent: 'flex-start',
|
|
||||||
textAlign: 'left',
|
|
||||||
fontSize: 'medium',
|
|
||||||
}}
|
|
||||||
value="apikey"
|
value="apikey"
|
||||||
label="API Key"
|
label="API Key"
|
||||||
icon={<VpnKey />}
|
icon={<VpnKey />}
|
||||||
@@ -87,7 +69,7 @@ export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenu
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
<hr />
|
<hr />
|
||||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '1rem', textAlign: 'left' }}>
|
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '1rem', textAlign: 'left' }}>
|
||||||
<Button href={`${apiUrl}/api-docs/`} target="_blank" rel="noopener noreferrer" sx={buttonStyles} startIcon={<Article />}>
|
<Button href="/api-docs" target="_blank" rel="noopener noreferrer" sx={buttonStyles} startIcon={<Article />}>
|
||||||
API Docs
|
API Docs
|
||||||
</Button>
|
</Button>
|
||||||
<Button href="https://forms.gle/hXjgqDvkEhPcaBW76" target="_blank" rel="noopener noreferrer" sx={buttonStyles} startIcon={<CloudQueue />}>
|
<Button href="https://forms.gle/hXjgqDvkEhPcaBW76" target="_blank" rel="noopener noreferrer" sx={buttonStyles} startIcon={<CloudQueue />}>
|
||||||
@@ -97,17 +79,17 @@ export const MainMenu = ({ value = 'recordings', handleChangeContent }: MainMenu
|
|||||||
</Box>
|
</Box>
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
const buttonStyles = {
|
const buttonStyles = {
|
||||||
justifyContent: 'flex-start',
|
justifyContent: 'flex-start',
|
||||||
textAlign: 'left',
|
textAlign: 'left',
|
||||||
fontSize: 'medium',
|
fontSize: 'medium',
|
||||||
padding: '6px 16px 6px 22px',
|
padding: '6px 16px 6px 22px',
|
||||||
minHeight: '48px',
|
minHeight: '48px',
|
||||||
minWidth: '100%',
|
minWidth: '100%',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
textTransform: 'none',
|
textTransform: 'none',
|
||||||
color: '#6C6C6C !important',
|
color: 'inherit',
|
||||||
};
|
};
|
||||||
|
|||||||
64
src/context/theme-provider.tsx
Normal file
64
src/context/theme-provider.tsx
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import React, { createContext, useContext, useState } from 'react';
|
||||||
|
import { ThemeProvider, createTheme } from '@mui/material/styles';
|
||||||
|
import CssBaseline from '@mui/material/CssBaseline';
|
||||||
|
|
||||||
|
const lightTheme = createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: 'light',
|
||||||
|
primary: {
|
||||||
|
main: '#1e88e5',
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
default: '#ffffff',
|
||||||
|
paper: '#f5f5f5',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
primary: '#000000',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const darkTheme = createTheme({
|
||||||
|
palette: {
|
||||||
|
mode: 'dark',
|
||||||
|
primary: {
|
||||||
|
main: '#90caf9',
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
default: '#121212',
|
||||||
|
paper: '#1e2124',
|
||||||
|
},
|
||||||
|
text: {
|
||||||
|
primary: '#ffffff',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create context for theme mode with state for current mode
|
||||||
|
// In theme-provider.tsx
|
||||||
|
|
||||||
|
const ThemeModeContext = createContext({
|
||||||
|
toggleTheme: () => {},
|
||||||
|
darkMode: false, // Add darkMode to context
|
||||||
|
});
|
||||||
|
|
||||||
|
export const useThemeMode = () => useContext(ThemeModeContext);
|
||||||
|
|
||||||
|
const ThemeModeProvider = ({ children }: { children: React.ReactNode }) => {
|
||||||
|
const [darkMode, setDarkMode] = useState(false);
|
||||||
|
|
||||||
|
const toggleTheme = () => {
|
||||||
|
setDarkMode((prevMode) => !prevMode);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ThemeModeContext.Provider value={{ toggleTheme, darkMode }}> {/* Pass darkMode here */}
|
||||||
|
<ThemeProvider theme={darkMode ? darkTheme : lightTheme}>
|
||||||
|
<CssBaseline />
|
||||||
|
{children}
|
||||||
|
</ThemeProvider>
|
||||||
|
</ThemeModeContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ThemeModeProvider;
|
||||||
Reference in New Issue
Block a user