✨ feat: add dark mod
This commit is contained in:
parent
dd9b03e80e
commit
eb482990c1
8
web/berry/.prettierrc
Normal file
8
web/berry/.prettierrc
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"bracketSpacing": true,
|
||||
"printWidth": 140,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useEffect } from 'react';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
|
||||
import { ThemeProvider } from '@mui/material/styles';
|
||||
import { CssBaseline, StyledEngineProvider } from '@mui/material';
|
||||
|
||||
import { SET_THEME } from 'store/actions';
|
||||
// routing
|
||||
import Routes from 'routes';
|
||||
|
||||
@ -20,8 +21,16 @@ import { SnackbarProvider } from 'notistack';
|
||||
// ==============================|| APP ||============================== //
|
||||
|
||||
const App = () => {
|
||||
const dispatch = useDispatch();
|
||||
const customization = useSelector((state) => state.customization);
|
||||
|
||||
useEffect(() => {
|
||||
const storedTheme = localStorage.getItem('theme');
|
||||
if (storedTheme) {
|
||||
dispatch({ type: SET_THEME, theme: storedTheme });
|
||||
}
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<StyledEngineProvider injectFirst>
|
||||
<ThemeProvider theme={themes(customization)}>
|
||||
|
13
web/berry/src/assets/images/logo-white.svg
Normal file
13
web/berry/src/assets/images/logo-white.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<svg viewBox="0 0 590 360" xmlns="http://www.w3.org/2000/svg" version="1.1">
|
||||
<g>
|
||||
<ellipse transform="rotate(103.6 287.6 32.87)" id="svg_1" ry="28.14" rx="28.47" cy="32.87" cx="287.60001" fill="#fff"/>
|
||||
<path id="svg_2" d="m232.92,128.89c3.78,27.29 -1.81,55.44 -17.71,78.09a2.62,2.62 0 0 0 -0.06,2.92c1.24,1.92 2.96,5.05 5.56,4.94q5.25,-0.22 10.79,0.11a1.26,1.26 0 0 1 1.19,1.27l-0.4,42.53a1.31,1.31 0 0 1 -1.31,1.3q-16.77,-0.09 -36.53,0.01q-2.25,0.02 -3.71,-1.56q-16.02,-17.28 -31.98,-35.32c-5.13,-5.8 -10.18,-11.16 -14.86,-17.59a1.35,1.34 -31.1 0 1 0.5,-2q12.88,-6.32 22.13,-17.12q18.18,-21.23 15.08,-48.84q-2.66,-23.7 -22.4,-40.46q-23.43,-19.9 -54.88,-13.86c-4.1,0.79 -7.83,2.5 -11.72,4.12q-11.86,4.94 -20.59,14.64c-14.25,15.81 -20.07,36.4 -15.05,57.16q4.99,20.63 22.86,35.71c10.45,8.81 23.7,13.12 37.26,14.18q1.47,0.11 3.6,2.65c11.68,13.89 24.48,27.72 35.94,41.96a0.43,0.43 0 0 1 -0.21,0.68q-22.51,7.27 -47.37,5.37q-19.4,-1.47 -39.74,-11.22q-18.27,-8.75 -30.59,-21.28q-18.66,-18.98 -28.02,-43.57q-10.8,-28.4 -4.93,-58.67c1.59,-8.17 4.03,-17 7.42,-24.61q5.08,-11.38 11.61,-20.64q25.41,-36.03 68.45,-46.13q32.42,-7.61 64.23,3.92q25.31,9.17 43.2,27.31c16.85,17.09 28.91,40.01 32.24,64z" fill="#fff"/>
|
||||
<path id="svg_3" d="m499.47,180.61c6.45,13.53 16.44,21.75 31.96,22q11.94,0.19 22.17,-5.36q2.21,-1.2 3.93,0.69q12.56,13.78 24.89,28.47q1.21,1.44 1.44,3.13a0.95,0.95 0 0 1 -0.36,0.89c-1.62,1.23 -3.33,2.71 -5.03,3.69q-29.37,17.01 -62.47,11.31c-20.61,-3.55 -39.05,-15.24 -51.47,-32.51q-6.4,-8.89 -9.91,-17.08c-2.62,-6.12 -4.73,-13.3 -5.41,-20.08q-3.96,-39.88 22.94,-67.74c9.48,-9.81 21.15,-16.67 34.39,-19.49c16.54,-3.53 34.64,-1.83 48.77,7.1q13.92,8.79 21.13,20.4q11.07,17.84 10.48,38.92c-0.02,0.94 -0.21,1.81 -0.85,2.54q-7.73,8.77 -18.71,20.16c-1.28,1.32 -2.61,2.26 -4.51,2.23q-24.45,-0.37 -51.64,-0.41q-5.03,0 -10.84,-0.22a0.96,0.95 -11.7 0 0 -0.9,1.36zm1.12,-37.17q-0.55,1.19 -0.63,2.34q-0.08,1.01 0.94,1.03q19.01,0.25 36.98,0.01q0.5,0 0.94,-0.22q0.57,-0.28 0.44,-0.9q-2.34,-11.6 -14.11,-15.25q-3.59,-1.11 -6.44,-0.57q-13.07,2.5 -18.12,13.56z" fill="#fff"/>
|
||||
<path id="svg_4" d="m312.3,100.22a0.5,0.49 -22.1 0 0 0.84,0.35q2.76,-2.64 5.82,-4.31q8.45,-4.62 16.71,-6.57c15.81,-3.72 33.58,-3.2 48.2,3.95q24.49,11.98 35.05,35.76c4.66,10.5 5.44,22.96 5.5,35.35q0.21,49.99 -0.12,88q-0.03,3.06 -0.08,6.16a1.32,1.32 0 0 1 -1.33,1.3q-20.22,-0.18 -40.18,-0.23q-3.64,-0.01 -8.13,-0.44a1.06,1.05 -87.3 0 1 -0.95,-1.05q0.02,-45.49 -0.22,-92.99c-0.03,-6.25 -1.21,-13.88 -5.05,-18.95q-5.33,-7.03 -12.32,-10.18c-10.99,-4.93 -24.52,-1.84 -33.13,6.37q-10.01,9.53 -10.07,23.76q-0.11,25.46 -0.1,48.98c0,3.52 -0.06,8.31 -1.1,11.68c-4.37,14.04 -17.31,19.5 -31.04,16.77c-8.22,-1.64 -15.07,-7.75 -17.62,-15.62q-1.45,-4.49 -1.42,-10.2q0.3,-64.69 0.1,-129.86a0.47,0.47 0 0 1 0.47,-0.47l48.46,-0.35a1.56,1.55 89.4 0 1 1.56,1.54l0.15,11.25z" fill="#fff"/>
|
||||
<path id="svg_5" d="m265.63,344.43a2.02,2.01 76.7 0 0 -1.85,-1.15l-17.03,0.24a2.25,2.22 9.3 0 0 -2.06,1.46l-2.86,7.84a2.47,2.46 -79.1 0 1 -2.38,1.62l-6.23,-0.19q-1.19,-0.04 -0.88,-1.19q1.38,-5.23 2.81,-8.7c3.41,-8.3 6.48,-16.83 10.12,-25.35q2.96,-6.93 5.21,-14.24c0.46,-1.52 1.69,-2.64 3.37,-2.63c2.02,0 4.68,-0.78 5.7,1.58q7.68,17.74 18.16,44.75q0.96,2.46 1.48,5a0.67,0.66 84.3 0 1 -0.65,0.8l-6.05,-0.02q-2.16,-0.01 -3.1,-1.96l-3.76,-7.86zm-16.73,-10.31a0.34,0.34 0 0 0 0.32,0.47l12.85,-0.36a0.34,0.34 0 0 0 0.3,-0.48l-6.84,-14.7a0.34,0.34 0 0 0 -0.62,0.02l-6.01,15.05z" fill="#fff"/>
|
||||
<rect id="svg_6" rx="2.17" height="52.28" width="9.84" y="302.19" x="345.67" fill="#fff"/>
|
||||
<path id="svg_7" d="m303.07,338.46l-0.15,14.42q-0.01,1.55 -1.56,1.52l-5.84,-0.12q-1.79,-0.04 -1.81,-1.83c-0.24,-15.33 -0.25,-30.89 -0.27,-47.22q-0.01,-2.99 2.55,-3.06q12.47,-0.33 20.15,0.8q8.61,1.25 12.86,9.17c2.95,5.49 2.53,13.5 -1.5,18.65c-5.57,7.14 -14.88,6.62 -23.24,6.51a1.17,1.17 0 0 0 -1.19,1.16zm-0.15,-24.81l0.16,12.72a1.72,1.72 0 0 0 1.74,1.7l6.07,-0.08a10.01,7.98 -0.7 0 0 9.91,-8.1l0,-0.2a10.01,7.98 -0.7 0 0 -10.11,-7.86l-6.07,0.08a1.72,1.72 0 0 0 -1.7,1.74z" fill="#fff"/>
|
||||
<rect id="svg_8" rx="3.58" height="7.26" width="79.2" y="322.99" x="107" fill="#fff"/>
|
||||
<rect id="svg_9" rx="3.81" height="7.72" width="79.1" y="322.78" x="417.27" fill="#fff"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
@ -46,11 +46,16 @@ $grey600: #4b5565;
|
||||
$grey700: #364152;
|
||||
$grey900: #121926;
|
||||
|
||||
$tableBackground: #f4f6f8;
|
||||
$tableBorderBottom: #f1f3f4;
|
||||
|
||||
// ==============================|| DARK THEME VARIANTS ||============================== //
|
||||
|
||||
// paper & background
|
||||
$darkBackground: #1a223f; // level 3
|
||||
$darkPaper: #111936; // level 4
|
||||
$darkDivider: rgba(227, 232, 239, 0.2);
|
||||
$darkSelectedBack : rgba(124, 77, 255, 0.15);
|
||||
|
||||
// dark 800 & 900
|
||||
$darkLevel1: #29314f; // level 1
|
||||
@ -154,4 +159,9 @@ $darkTextSecondary: #8492c4;
|
||||
darkSecondaryDark: $darkSecondaryDark;
|
||||
darkSecondary200: $darkSecondary200;
|
||||
darkSecondary800: $darkSecondary800;
|
||||
|
||||
darkDivider: $darkDivider;
|
||||
darkSelectedBack: $darkSelectedBack;
|
||||
tableBackground: $tableBackground;
|
||||
tableBorderBottom: $tableBorderBottom;
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ const ProfileSection = () => {
|
||||
alignItems: 'center',
|
||||
borderRadius: '27px',
|
||||
transition: 'all .2s ease-in-out',
|
||||
borderColor: theme.palette.primary.light,
|
||||
backgroundColor: theme.palette.primary.light,
|
||||
borderColor: theme.typography.menuChip.background,
|
||||
backgroundColor: theme.typography.menuChip.background,
|
||||
'&[aria-controls="menu-list-grow"], &:hover': {
|
||||
borderColor: theme.palette.primary.main,
|
||||
background: `${theme.palette.primary.main}!important`,
|
||||
|
@ -7,6 +7,7 @@ import { Avatar, Box, ButtonBase } from '@mui/material';
|
||||
// project imports
|
||||
import LogoSection from '../LogoSection';
|
||||
import ProfileSection from './ProfileSection';
|
||||
import ThemeButton from 'ui-component/ThemeButton';
|
||||
|
||||
// assets
|
||||
import { IconMenu2 } from '@tabler/icons-react';
|
||||
@ -37,9 +38,8 @@ const Header = ({ handleLeftDrawerToggle }) => {
|
||||
sx={{
|
||||
...theme.typography.commonAvatar,
|
||||
...theme.typography.mediumAvatar,
|
||||
...theme.typography.menuButton,
|
||||
transition: 'all .2s ease-in-out',
|
||||
background: theme.palette.secondary.light,
|
||||
color: theme.palette.secondary.dark,
|
||||
'&:hover': {
|
||||
background: theme.palette.secondary.dark,
|
||||
color: theme.palette.secondary.light
|
||||
@ -55,7 +55,7 @@ const Header = ({ handleLeftDrawerToggle }) => {
|
||||
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
|
||||
<ThemeButton />
|
||||
<ProfileSection />
|
||||
</>
|
||||
);
|
||||
|
@ -36,7 +36,7 @@ import { useNavigate } from 'react-router-dom';
|
||||
// }));
|
||||
|
||||
const CardStyle = styled(Card)(({ theme }) => ({
|
||||
background: theme.palette.primary.light,
|
||||
background: theme.typography.menuChip.background,
|
||||
marginBottom: '22px',
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
@ -121,7 +121,6 @@ const MenuCard = () => {
|
||||
/>
|
||||
</ListItem>
|
||||
</List>
|
||||
{/* <LinearProgressWithLabel value={80} /> */}
|
||||
</CardContent>
|
||||
</CardStyle>
|
||||
);
|
||||
|
@ -39,7 +39,13 @@ const Sidebar = ({ drawerOpen, drawerToggle, window }) => {
|
||||
<MenuList />
|
||||
<MenuCard />
|
||||
<Stack direction="row" justifyContent="center" sx={{ mb: 2 }}>
|
||||
<Chip label={process.env.REACT_APP_VERSION} disabled chipcolor="secondary" size="small" sx={{ cursor: 'pointer' }} />
|
||||
<Chip
|
||||
label={process.env.REACT_APP_VERSION || '未知版本号'}
|
||||
disabled
|
||||
chipcolor="secondary"
|
||||
size="small"
|
||||
sx={{ cursor: 'pointer' }}
|
||||
/>
|
||||
</Stack>
|
||||
</PerfectScrollbar>
|
||||
</BrowserView>
|
||||
@ -48,7 +54,13 @@ const Sidebar = ({ drawerOpen, drawerToggle, window }) => {
|
||||
<MenuList />
|
||||
<MenuCard />
|
||||
<Stack direction="row" justifyContent="center" sx={{ mb: 2 }}>
|
||||
<Chip label={process.env.REACT_APP_VERSION} disabled chipcolor="secondary" size="small" sx={{ cursor: 'pointer' }} />
|
||||
<Chip
|
||||
label={process.env.REACT_APP_VERSION || '未知版本号'}
|
||||
disabled
|
||||
chipcolor="secondary"
|
||||
size="small"
|
||||
sx={{ cursor: 'pointer' }}
|
||||
/>
|
||||
</Stack>
|
||||
</Box>
|
||||
</MobileView>
|
||||
|
@ -1,10 +1,30 @@
|
||||
// material-ui
|
||||
import { useTheme } from "@mui/material/styles";
|
||||
import { Box, Button, Stack } from "@mui/material";
|
||||
import LogoSection from "layout/MainLayout/LogoSection";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useLocation } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useState } from 'react';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Stack,
|
||||
Popper,
|
||||
IconButton,
|
||||
List,
|
||||
ListItemButton,
|
||||
Paper,
|
||||
ListItemText,
|
||||
Typography,
|
||||
Divider,
|
||||
ClickAwayListener
|
||||
} from '@mui/material';
|
||||
import LogoSection from 'layout/MainLayout/LogoSection';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
import ThemeButton from 'ui-component/ThemeButton';
|
||||
import ProfileSection from 'layout/MainLayout/Header/ProfileSection';
|
||||
import { IconMenu2 } from '@tabler/icons-react';
|
||||
import Transitions from 'ui-component/extended/Transitions';
|
||||
import MainCard from 'ui-component/cards/MainCard';
|
||||
import { useMediaQuery } from '@mui/material';
|
||||
|
||||
// ==============================|| MAIN NAVBAR / HEADER ||============================== //
|
||||
|
||||
@ -12,16 +32,26 @@ const Header = () => {
|
||||
const theme = useTheme();
|
||||
const { pathname } = useLocation();
|
||||
const account = useSelector((state) => state.account);
|
||||
const [open, setOpen] = useState(null);
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||
|
||||
const handleOpenMenu = (event) => {
|
||||
setOpen(open ? null : event.currentTarget);
|
||||
};
|
||||
|
||||
const handleCloseMenu = () => {
|
||||
setOpen(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
sx={{
|
||||
width: 228,
|
||||
display: "flex",
|
||||
[theme.breakpoints.down("md")]: {
|
||||
width: "auto",
|
||||
},
|
||||
display: 'flex',
|
||||
[theme.breakpoints.down('md')]: {
|
||||
width: 'auto'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Box component="span" sx={{ flexGrow: 1 }}>
|
||||
@ -31,43 +61,99 @@ const Header = () => {
|
||||
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
<Stack spacing={2} direction="row">
|
||||
<Button
|
||||
component={Link}
|
||||
variant="text"
|
||||
to="/"
|
||||
color={pathname === "/" ? "primary" : "inherit"}
|
||||
>
|
||||
首页
|
||||
</Button>
|
||||
<Button
|
||||
component={Link}
|
||||
variant="text"
|
||||
to="/about"
|
||||
color={pathname === "/about" ? "primary" : "inherit"}
|
||||
>
|
||||
关于
|
||||
</Button>
|
||||
{account.user ? (
|
||||
<Button
|
||||
component={Link}
|
||||
variant="contained"
|
||||
to="/panel"
|
||||
color="primary"
|
||||
>
|
||||
控制台
|
||||
</Button>
|
||||
<Stack spacing={2} direction="row" justifyContent="center" alignItems="center">
|
||||
{isMobile ? (
|
||||
<>
|
||||
<ThemeButton />
|
||||
<IconButton onClick={handleOpenMenu}>
|
||||
<IconMenu2 />
|
||||
</IconButton>
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
component={Link}
|
||||
variant="contained"
|
||||
to="/login"
|
||||
color="primary"
|
||||
>
|
||||
登入
|
||||
</Button>
|
||||
<>
|
||||
<Button component={Link} variant="text" to="/" color={pathname === '/' ? 'primary' : 'inherit'}>
|
||||
首页
|
||||
</Button>
|
||||
<Button component={Link} variant="text" to="/about" color={pathname === '/about' ? 'primary' : 'inherit'}>
|
||||
关于
|
||||
</Button>
|
||||
<ThemeButton />
|
||||
{account.user ? (
|
||||
<>
|
||||
<Button component={Link} variant="contained" to="/panel" color="primary">
|
||||
控制台
|
||||
</Button>
|
||||
<ProfileSection />
|
||||
</>
|
||||
) : (
|
||||
<Button component={Link} variant="contained" to="/login" color="primary">
|
||||
登录
|
||||
</Button>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
<Popper
|
||||
open={!!open}
|
||||
anchorEl={open}
|
||||
transition
|
||||
disablePortal
|
||||
popperOptions={{
|
||||
modifiers: [
|
||||
{
|
||||
name: 'offset',
|
||||
options: {
|
||||
offset: [0, 14]
|
||||
}
|
||||
}
|
||||
]
|
||||
}}
|
||||
style={{ width: '100vw' }}
|
||||
>
|
||||
{({ TransitionProps }) => (
|
||||
<Transitions in={open} {...TransitionProps}>
|
||||
<ClickAwayListener onClickAway={handleCloseMenu}>
|
||||
<Paper style={{ width: '100%' }}>
|
||||
<MainCard border={false} elevation={16} content={false} boxShadow shadow={theme.shadows[16]}>
|
||||
<List
|
||||
component="nav"
|
||||
sx={{
|
||||
width: '100%',
|
||||
maxWidth: '100%',
|
||||
minWidth: '100%',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
|
||||
'& .MuiListItemButton-root': {
|
||||
mt: 0.5
|
||||
}
|
||||
}}
|
||||
onClick={handleCloseMenu}
|
||||
>
|
||||
<ListItemButton component={Link} variant="text" to="/">
|
||||
<ListItemText primary={<Typography variant="body2">首页</Typography>} />
|
||||
</ListItemButton>
|
||||
|
||||
<ListItemButton component={Link} variant="text" to="/about">
|
||||
<ListItemText primary={<Typography variant="body2">关于</Typography>} />
|
||||
</ListItemButton>
|
||||
<Divider />
|
||||
{account.user ? (
|
||||
<ListItemButton component={Link} variant="contained" to="/panel" color="primary">
|
||||
控制台
|
||||
</ListItemButton>
|
||||
) : (
|
||||
<ListItemButton component={Link} variant="contained" to="/login" color="primary">
|
||||
登录
|
||||
</ListItemButton>
|
||||
)}
|
||||
</List>
|
||||
</MainCard>
|
||||
</Paper>
|
||||
</ClickAwayListener>
|
||||
</Transitions>
|
||||
)}
|
||||
</Popper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { AppBar, Box, CssBaseline, Toolbar } from '@mui/material';
|
||||
import { AppBar, Box, CssBaseline, Toolbar, Container } from '@mui/material';
|
||||
import Header from './Header';
|
||||
import Footer from 'ui-component/Footer';
|
||||
|
||||
@ -22,9 +22,11 @@ const MinimalLayout = () => {
|
||||
flex: 'none'
|
||||
}}
|
||||
>
|
||||
<Toolbar>
|
||||
<Header />
|
||||
</Toolbar>
|
||||
<Container>
|
||||
<Toolbar>
|
||||
<Header />
|
||||
</Toolbar>
|
||||
</Container>
|
||||
</AppBar>
|
||||
<Box sx={{ flex: '1 1 auto', overflow: 'auto' }} marginTop={'80px'}>
|
||||
<Outlet />
|
||||
|
@ -7,3 +7,4 @@ export const SET_BORDER_RADIUS = '@customization/SET_BORDER_RADIUS';
|
||||
export const SET_SITE_INFO = '@siteInfo/SET_SITE_INFO';
|
||||
export const LOGIN = '@account/LOGIN';
|
||||
export const LOGOUT = '@account/LOGOUT';
|
||||
export const SET_THEME = '@customization/SET_THEME';
|
||||
|
@ -9,7 +9,8 @@ export const initialState = {
|
||||
defaultId: 'default',
|
||||
fontFamily: config.fontFamily,
|
||||
borderRadius: config.borderRadius,
|
||||
opened: true
|
||||
opened: true,
|
||||
theme: 'light'
|
||||
};
|
||||
|
||||
// ==============================|| CUSTOMIZATION REDUCER ||============================== //
|
||||
@ -38,6 +39,11 @@ const customizationReducer = (state = initialState, action) => {
|
||||
...state,
|
||||
borderRadius: action.borderRadius
|
||||
};
|
||||
case actionTypes.SET_THEME:
|
||||
return {
|
||||
...state,
|
||||
theme: action.theme
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
export default function componentStyleOverrides(theme) {
|
||||
const bgColor = theme.colors?.grey50;
|
||||
const bgColor = theme.mode === 'dark' ? theme.backgroundDefault : theme.colors?.grey50;
|
||||
return {
|
||||
MuiButton: {
|
||||
styleOverrides: {
|
||||
@ -12,15 +12,7 @@ export default function componentStyleOverrides(theme) {
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiMenuItem: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:hover': {
|
||||
backgroundColor: theme.colors?.grey100
|
||||
}
|
||||
}
|
||||
}
|
||||
}, //MuiAutocomplete-popper MuiPopover-root
|
||||
//MuiAutocomplete-popper MuiPopover-root
|
||||
MuiAutocomplete: {
|
||||
styleOverrides: {
|
||||
popper: {
|
||||
@ -226,12 +218,12 @@ export default function componentStyleOverrides(theme) {
|
||||
MuiTableCell: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
borderBottom: '1px solid rgb(241, 243, 244)',
|
||||
borderBottom: '1px solid ' + theme.tableBorderBottom,
|
||||
textAlign: 'center'
|
||||
},
|
||||
head: {
|
||||
color: theme.darkTextSecondary,
|
||||
backgroundColor: 'rgb(244, 246, 248)'
|
||||
backgroundColor: theme.headBackgroundColor
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -239,7 +231,7 @@ export default function componentStyleOverrides(theme) {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:hover': {
|
||||
backgroundColor: 'rgb(244, 246, 248)'
|
||||
backgroundColor: theme.headBackgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -247,10 +239,29 @@ export default function componentStyleOverrides(theme) {
|
||||
MuiTooltip: {
|
||||
styleOverrides: {
|
||||
tooltip: {
|
||||
color: theme.paper,
|
||||
color: theme.colors.paper,
|
||||
background: theme.colors?.grey700
|
||||
}
|
||||
}
|
||||
},
|
||||
MuiCssBaseline: {
|
||||
styleOverrides: `
|
||||
.apexcharts-title-text {
|
||||
fill: ${theme.textDark} !important
|
||||
}
|
||||
.apexcharts-text {
|
||||
fill: ${theme.textDark} !important
|
||||
}
|
||||
.apexcharts-legend-text {
|
||||
color: ${theme.textDark} !important
|
||||
}
|
||||
.apexcharts-menu {
|
||||
background: ${theme.backgroundDefault} !important
|
||||
}
|
||||
.apexcharts-gridline, .apexcharts-xaxistooltip-background, .apexcharts-yaxistooltip-background {
|
||||
stroke: ${theme.divider} !important;
|
||||
}
|
||||
`
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -15,19 +15,10 @@ import themeTypography from './typography';
|
||||
|
||||
export const theme = (customization) => {
|
||||
const color = colors;
|
||||
|
||||
const options = customization.theme === 'light' ? GetLightOption() : GetDarkOption();
|
||||
const themeOption = {
|
||||
colors: color,
|
||||
heading: color.grey900,
|
||||
paper: color.paper,
|
||||
backgroundDefault: color.paper,
|
||||
background: color.primaryLight,
|
||||
darkTextPrimary: color.grey700,
|
||||
darkTextSecondary: color.grey500,
|
||||
textDark: color.grey900,
|
||||
menuSelected: color.secondaryDark,
|
||||
menuSelectedBack: color.secondaryLight,
|
||||
divider: color.grey200,
|
||||
...options,
|
||||
customization
|
||||
};
|
||||
|
||||
@ -53,3 +44,49 @@ export const theme = (customization) => {
|
||||
};
|
||||
|
||||
export default theme;
|
||||
|
||||
function GetDarkOption() {
|
||||
const color = colors;
|
||||
return {
|
||||
mode: 'dark',
|
||||
heading: color.darkTextTitle,
|
||||
paper: color.darkLevel2,
|
||||
backgroundDefault: color.darkPaper,
|
||||
background: color.darkBackground,
|
||||
darkTextPrimary: color.darkTextPrimary,
|
||||
darkTextSecondary: color.darkTextSecondary,
|
||||
textDark: color.darkTextTitle,
|
||||
menuSelected: color.darkSecondaryMain,
|
||||
menuSelectedBack: color.darkSelectedBack,
|
||||
divider: color.darkDivider,
|
||||
borderColor: color.darkBorderColor,
|
||||
menuButton: color.darkLevel1,
|
||||
menuButtonColor: color.darkSecondaryMain,
|
||||
menuChip: color.darkLevel1,
|
||||
headBackgroundColor: color.darkBackground,
|
||||
tableBorderBottom: color.darkDivider
|
||||
};
|
||||
}
|
||||
|
||||
function GetLightOption() {
|
||||
const color = colors;
|
||||
return {
|
||||
mode: 'light',
|
||||
heading: color.grey900,
|
||||
paper: color.paper,
|
||||
backgroundDefault: color.paper,
|
||||
background: color.primaryLight,
|
||||
darkTextPrimary: color.grey700,
|
||||
darkTextSecondary: color.grey500,
|
||||
textDark: color.grey900,
|
||||
menuSelected: color.secondaryDark,
|
||||
menuSelectedBack: color.secondaryLight,
|
||||
divider: color.grey200,
|
||||
borderColor: color.grey300,
|
||||
menuButton: color.secondaryLight,
|
||||
menuButtonColor: color.secondaryDark,
|
||||
menuChip: color.primaryLight,
|
||||
headBackgroundColor: color.tableBackground,
|
||||
tableBorderBottom: color.tableBorderBottom
|
||||
};
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
export default function themePalette(theme) {
|
||||
return {
|
||||
mode: 'light',
|
||||
mode: theme.mode,
|
||||
common: {
|
||||
black: theme.colors?.darkPaper
|
||||
},
|
||||
|
@ -132,6 +132,19 @@ export default function themeTypography(theme) {
|
||||
width: '44px',
|
||||
height: '44px',
|
||||
fontSize: '1.5rem'
|
||||
},
|
||||
menuButton: {
|
||||
color: theme.menuButtonColor,
|
||||
background: theme.menuButton
|
||||
},
|
||||
menuChip: {
|
||||
background: theme.menuChip
|
||||
},
|
||||
CardWrapper: {
|
||||
backgroundColor: theme.mode === 'dark' ? theme.colors.darkLevel2 : theme.colors.primaryDark
|
||||
},
|
||||
SubCard: {
|
||||
border: theme.mode === 'dark' ? '1px solid rgba(227, 232, 239, 0.2)' : '1px solid rgb(227, 232, 239)'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
// material-ui
|
||||
import logo from 'assets/images/logo.svg';
|
||||
import logoLight from 'assets/images/logo.svg';
|
||||
import logoDark from 'assets/images/logo-white.svg';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
|
||||
/**
|
||||
* if you want to use image instead of <svg> uncomment following.
|
||||
@ -14,6 +16,8 @@ import { useSelector } from 'react-redux';
|
||||
|
||||
const Logo = () => {
|
||||
const siteInfo = useSelector((state) => state.siteInfo);
|
||||
const theme = useTheme();
|
||||
const logo = theme.palette.mode === 'light' ? logoLight : logoDark;
|
||||
|
||||
return <img src={siteInfo.logo || logo} alt={siteInfo.system_name} height="50" />;
|
||||
};
|
||||
|
50
web/berry/src/ui-component/ThemeButton.js
Normal file
50
web/berry/src/ui-component/ThemeButton.js
Normal file
@ -0,0 +1,50 @@
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { SET_THEME } from 'store/actions';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import { Avatar, Box, ButtonBase } from '@mui/material';
|
||||
import { IconSun, IconMoon } from '@tabler/icons-react';
|
||||
|
||||
export default function ThemeButton() {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const defaultTheme = useSelector((state) => state.customization.theme);
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
ml: 2,
|
||||
mr: 3,
|
||||
[theme.breakpoints.down('md')]: {
|
||||
mr: 2
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ButtonBase sx={{ borderRadius: '12px' }}>
|
||||
<Avatar
|
||||
variant="rounded"
|
||||
sx={{
|
||||
...theme.typography.commonAvatar,
|
||||
...theme.typography.mediumAvatar,
|
||||
transition: 'all .2s ease-in-out',
|
||||
borderColor: theme.typography.menuChip.background,
|
||||
backgroundColor: theme.typography.menuChip.background,
|
||||
'&[aria-controls="menu-list-grow"],&:hover': {
|
||||
background: theme.palette.secondary.dark,
|
||||
color: theme.palette.secondary.light
|
||||
}
|
||||
}}
|
||||
onClick={() => {
|
||||
let theme = defaultTheme === 'light' ? 'dark' : 'light';
|
||||
dispatch({ type: SET_THEME, theme: theme });
|
||||
localStorage.setItem('theme', theme);
|
||||
}}
|
||||
color="inherit"
|
||||
>
|
||||
{defaultTheme === 'light' ? <IconSun stroke={1.5} size="1.3rem" /> : <IconMoon stroke={1.5} size="1.3rem" />}
|
||||
</Avatar>
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
);
|
||||
}
|
@ -15,7 +15,7 @@ const headerSX = {
|
||||
const MainCard = forwardRef(
|
||||
(
|
||||
{
|
||||
border = true,
|
||||
border = false,
|
||||
boxShadow,
|
||||
children,
|
||||
content = true,
|
||||
|
@ -15,8 +15,7 @@ const SubCard = forwardRef(
|
||||
<Card
|
||||
ref={ref}
|
||||
sx={{
|
||||
border: '1px solid',
|
||||
borderColor: theme.palette.primary.light,
|
||||
border: theme.typography.SubCard.border,
|
||||
':hover': {
|
||||
boxShadow: '0 2px 14px 0 rgb(32 40 45 / 8%)'
|
||||
},
|
||||
@ -36,8 +35,8 @@ const SubCard = forwardRef(
|
||||
{title && (
|
||||
<Divider
|
||||
sx={{
|
||||
opacity: 1,
|
||||
borderColor: theme.palette.primary.light
|
||||
opacity: 1
|
||||
// borderColor: theme.palette.primary.light
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
@ -62,7 +61,8 @@ SubCard.propTypes = {
|
||||
secondary: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]),
|
||||
sx: PropTypes.object,
|
||||
contentSX: PropTypes.object,
|
||||
title: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object])
|
||||
title: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object]),
|
||||
subTitle: PropTypes.oneOfType([PropTypes.node, PropTypes.string, PropTypes.object])
|
||||
};
|
||||
|
||||
SubCard.defaultProps = {
|
||||
|
@ -40,7 +40,8 @@ export function generateChartOptions(data, unit) {
|
||||
chart: {
|
||||
sparkline: {
|
||||
enabled: true
|
||||
}
|
||||
},
|
||||
background: 'transparent'
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
|
@ -8,7 +8,7 @@ import { UserContext } from 'contexts/UserContext';
|
||||
// ==============================|| AUTHENTICATION 1 WRAPPER ||============================== //
|
||||
|
||||
const AuthStyle = styled('div')(({ theme }) => ({
|
||||
backgroundColor: theme.palette.primary.light
|
||||
backgroundColor: theme.palette.background.default
|
||||
}));
|
||||
|
||||
// eslint-disable-next-line
|
||||
|
@ -12,7 +12,7 @@ import MainCard from 'ui-component/cards/MainCard';
|
||||
import SkeletonTotalOrderCard from 'ui-component/cards/Skeleton/EarningCard';
|
||||
|
||||
const CardWrapper = styled(MainCard)(({ theme }) => ({
|
||||
backgroundColor: theme.palette.primary.dark,
|
||||
...theme.typography.CardWrapper,
|
||||
color: '#fff',
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
|
Loading…
Reference in New Issue
Block a user