| DialogTitle, | DialogTitle, | ||||
| DialogActions, | DialogActions, | ||||
| Button, | Button, | ||||
| useMediaQuery, | |||||
| useTheme, | |||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| const DialogComponent = ({ title, content, onClose, open }) => { | |||||
| const DialogComponent = ({ | |||||
| title, | |||||
| content, | |||||
| onClose, | |||||
| open, | |||||
| maxWidth, | |||||
| fullWidth, | |||||
| responsive, | |||||
| }) => { | |||||
| const theme = useTheme(); | |||||
| const fullScreen = useMediaQuery(theme.breakpoints.down('md')); | |||||
| const handleClose = () => { | const handleClose = () => { | ||||
| onClose(); | onClose(); | ||||
| }; | }; | ||||
| return ( | return ( | ||||
| <Dialog onClose={handleClose} open={open}> | |||||
| <Dialog | |||||
| maxWidth={maxWidth} | |||||
| fullWidth={fullWidth} | |||||
| fullScreen={responsive && fullScreen} | |||||
| onClose={handleClose} | |||||
| open={open} | |||||
| > | |||||
| <DialogTitle>{title}</DialogTitle> | <DialogTitle>{title}</DialogTitle> | ||||
| {content && <DialogContent>{content}</DialogContent>} | {content && <DialogContent>{content}</DialogContent>} | ||||
| <DialogActions> | <DialogActions> | ||||
| DialogComponent.propTypes = { | DialogComponent.propTypes = { | ||||
| title: PropTypes.string, | title: PropTypes.string, | ||||
| open: PropTypes.bool.isRequired, | |||||
| content: PropTypes.any, | content: PropTypes.any, | ||||
| onClose: PropTypes.func.isRequired, | onClose: PropTypes.func.isRequired, | ||||
| open: PropTypes.bool.isRequired, | |||||
| selectedValue: PropTypes.string.isRequired, | |||||
| maxWidth: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']), | |||||
| fullWidth: PropTypes.bool, | |||||
| responsive: PropTypes.bool, | |||||
| }; | }; | ||||
| export default DialogComponent; | export default DialogComponent; |
| import React from 'react'; | import React from 'react'; | ||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||
| import { | |||||
| Drawer, | |||||
| List, | |||||
| ListItem, | |||||
| ListItemButton, | |||||
| ListItemIcon, | |||||
| ListItemText, | |||||
| } from '@mui/material'; | |||||
| import { Drawer } from '@mui/material'; | |||||
| const DrawerComponent = ({ open, toggleOpen }) => ( | |||||
| <Drawer anchor="right" open={open} onClose={toggleOpen}> | |||||
| <List> | |||||
| <ListItemButton divider onClick={toggleOpen}> | |||||
| <ListItemIcon> | |||||
| <ListItemText>Link 1</ListItemText> | |||||
| </ListItemIcon> | |||||
| </ListItemButton> | |||||
| <ListItem divider onClick={toggleOpen}> | |||||
| <ListItemIcon> | |||||
| <ListItemText>Link 2</ListItemText> | |||||
| </ListItemIcon> | |||||
| </ListItem> | |||||
| <ListItem divider onClick={toggleOpen}> | |||||
| <ListItemText>Link 3</ListItemText> | |||||
| </ListItem> | |||||
| </List> | |||||
| const DrawerComponent = ({ open, toggleOpen, content, anchor = 'right' }) => ( | |||||
| <Drawer | |||||
| sx={{ | |||||
| minWidth: 250, | |||||
| '& .MuiDrawer-paper': { | |||||
| minWidth: 250, | |||||
| }, | |||||
| }} | |||||
| anchor={anchor} | |||||
| open={open} | |||||
| onClose={toggleOpen} | |||||
| > | |||||
| {content ? content : null} | |||||
| </Drawer> | </Drawer> | ||||
| ); | ); | ||||
| DrawerComponent.propTypes = { | DrawerComponent.propTypes = { | ||||
| open: PropTypes.bool, | open: PropTypes.bool, | ||||
| toggleOpen: PropTypes.func, | toggleOpen: PropTypes.func, | ||||
| content: PropTypes.any, | |||||
| anchor: PropTypes.oneOf(['top', 'right', 'left', 'bottom']), | |||||
| }; | }; | ||||
| export default DrawerComponent; | export default DrawerComponent; |
| import React, { useState } from 'react'; | |||||
| import React, { useState, useMemo } from 'react'; | |||||
| import { | import { | ||||
| AppBar, | AppBar, | ||||
| Badge, | Badge, | ||||
| IconButton, | IconButton, | ||||
| Toolbar, | Toolbar, | ||||
| Typography, | Typography, | ||||
| List, | |||||
| ListItem, | |||||
| ListItemButton, | |||||
| ListItemIcon, | |||||
| ListItemText, | |||||
| useMediaQuery, | useMediaQuery, | ||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import { useTheme } from '@mui/system'; | import { useTheme } from '@mui/system'; | ||||
| setOpenDrawer(!openDrawer); | setOpenDrawer(!openDrawer); | ||||
| }; | }; | ||||
| const drawerContent = useMemo(() => ( | |||||
| <List> | |||||
| <ListItemButton divider onClick={handleToggleDrawer}> | |||||
| <ListItemIcon> | |||||
| <ListItemText>Link 1</ListItemText> | |||||
| </ListItemIcon> | |||||
| </ListItemButton> | |||||
| <ListItem divider onClick={handleToggleDrawer}> | |||||
| <ListItemIcon> | |||||
| <ListItemText>Link 2</ListItemText> | |||||
| </ListItemIcon> | |||||
| </ListItem> | |||||
| <ListItem divider onClick={handleToggleDrawer}> | |||||
| <ListItemText>Link 3</ListItemText> | |||||
| </ListItem> | |||||
| </List> | |||||
| ), [handleToggleDrawer]); | |||||
| return ( | return ( | ||||
| <AppBar elevation={2} sx={{ backgroundColor: 'background.default', position: 'relative' }}> | |||||
| <AppBar | |||||
| elevation={2} | |||||
| sx={{ backgroundColor: 'background.default', position: 'relative' }} | |||||
| > | |||||
| <Toolbar> | <Toolbar> | ||||
| <Box | <Box | ||||
| component='div' | |||||
| component="div" | |||||
| sx={{ | sx={{ | ||||
| display: 'flex', | display: 'flex', | ||||
| justifyContent: 'space-between', | justifyContent: 'space-between', | ||||
| }} | }} | ||||
| > | > | ||||
| {matches ? ( | {matches ? ( | ||||
| <Drawer open={openDrawer} toggleOpen={handleToggleDrawer} /> | |||||
| <Drawer | |||||
| open={openDrawer} | |||||
| toggleOpen={handleToggleDrawer} | |||||
| content={drawerContent} | |||||
| /> | |||||
| ) : ( | ) : ( | ||||
| <Box sx={{ display: 'flex' }}> | <Box sx={{ display: 'flex' }}> | ||||
| <Typography | <Typography | ||||
| variant='h6' | |||||
| variant="h6" | |||||
| sx={{ | sx={{ | ||||
| marginRight: 3, | marginRight: 3, | ||||
| cursor: 'pointer', | cursor: 'pointer', | ||||
| Link 1 | Link 1 | ||||
| </Typography> | </Typography> | ||||
| <Typography | <Typography | ||||
| variant='body1' | |||||
| variant="body1" | |||||
| sx={{ | sx={{ | ||||
| marginRight: 3, | marginRight: 3, | ||||
| cursor: 'pointer', | cursor: 'pointer', | ||||
| Link 2 | Link 2 | ||||
| </Typography> | </Typography> | ||||
| <Typography | <Typography | ||||
| variant='subtitle1' | |||||
| variant="subtitle1" | |||||
| sx={{ | sx={{ | ||||
| marginRight: 3, | marginRight: 3, | ||||
| cursor: 'pointer', | cursor: 'pointer', | ||||
| </Box> | </Box> | ||||
| ) : ( | ) : ( | ||||
| <IconButton> | <IconButton> | ||||
| <Badge badgeContent={3} color='primary'> | |||||
| <ShoppingBasketIcon color='action' /> | |||||
| <Badge badgeContent={3} color="primary"> | |||||
| <ShoppingBasketIcon color="action" /> | |||||
| </Badge> | </Badge> | ||||
| </IconButton> | </IconButton> | ||||
| )} | )} |
| import React from 'react'; | |||||
| import PropTypes from 'prop-types'; | |||||
| import { Box, Popover } from '@mui/material'; | |||||
| const PopoverComponent = ({ open, anchorEl, onClose, content }) => { | |||||
| const handleClose = () => { | |||||
| onClose(); | |||||
| }; | |||||
| return ( | |||||
| <Box component="div"> | |||||
| <Popover | |||||
| sx={{ p: 5 }} | |||||
| open={open} | |||||
| anchorEl={anchorEl} | |||||
| onClose={handleClose} | |||||
| anchorOrigin={{ | |||||
| vertical: 'bottom', | |||||
| horizontal: 'left', | |||||
| }} | |||||
| > | |||||
| {content} | |||||
| </Popover> | |||||
| </Box> | |||||
| ); | |||||
| }; | |||||
| PopoverComponent.propTypes = { | |||||
| anchorEl: PropTypes.element, | |||||
| open: PropTypes.bool.isRequired, | |||||
| onClose: PropTypes.func.isRequired, | |||||
| content: PropTypes.any, | |||||
| }; | |||||
| export default PopoverComponent; |
| i18n.use(initReactI18next).init({ | i18n.use(initReactI18next).init({ | ||||
| lng: 'en', | lng: 'en', | ||||
| fallbackLng: 'en', | fallbackLng: 'en', | ||||
| debug: true, | |||||
| debug: false, | |||||
| supportedLngs: ['en'], | supportedLngs: ['en'], | ||||
| resources: { | resources: { | ||||
| en: { | en: { |
| import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
| import { Box, Button, Typography } from '@mui/material'; | |||||
| import { Box, Button, Paper, Typography } from '@mui/material'; | |||||
| import DialogComponent from '../../components/MUI/DialogComponent'; | import DialogComponent from '../../components/MUI/DialogComponent'; | ||||
| import DrawerComponent from '../../components/MUI/DrawerComponent'; | |||||
| import Navbar from '../../components/MUI/Navbar'; | import Navbar from '../../components/MUI/Navbar'; | ||||
| import PopoverComponent from '../../components/MUI/PopoverComponent'; | |||||
| const HomePage = () => { | const HomePage = () => { | ||||
| const [dialogOpen, setDialogOpen] = useState(false); | const [dialogOpen, setDialogOpen] = useState(false); | ||||
| const [drawerOpen, setDrawerOpen] = useState(false); | |||||
| const [popoverOpen, setPopoverOpen] = useState(false); | |||||
| const [anchorEl, setAnchorEl] = useState(null); | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <Navbar /> | <Navbar /> | ||||
| <Box component="div"> | |||||
| <Button onClick={() => setDialogOpen(true)}>Open Dialog</Button> | |||||
| <DialogComponent | |||||
| title="Dialog Title" | |||||
| content={<Typography>Dialog Content</Typography>} | |||||
| open={dialogOpen} | |||||
| onClose={() => setDialogOpen(false)} | |||||
| /> | |||||
| <Box | |||||
| sx={{ | |||||
| mt: 4, | |||||
| ml: 4, | |||||
| display: 'flex', | |||||
| flexGrow: 1, | |||||
| }} | |||||
| > | |||||
| <Paper | |||||
| sx={{ | |||||
| p: 4, | |||||
| display: 'flex', | |||||
| flexDirection: 'column', | |||||
| }} | |||||
| > | |||||
| <Button onClick={() => setDialogOpen(true)}>Open Dialog</Button> | |||||
| <Button onClick={() => setDrawerOpen(true)}>Open Drawer</Button> | |||||
| <Button | |||||
| onClick={(e) => { | |||||
| setPopoverOpen(true); | |||||
| setAnchorEl(e.currentTarget); | |||||
| }} | |||||
| > | |||||
| Open Popover | |||||
| </Button> | |||||
| </Paper> | |||||
| <DialogComponent | |||||
| title="Dialog Title" | |||||
| content={<Typography>Dialog Content</Typography>} | |||||
| open={dialogOpen} | |||||
| onClose={() => setDialogOpen(false)} | |||||
| maxWidth="md" | |||||
| fullWidth | |||||
| responsive | |||||
| /> | |||||
| <DrawerComponent | |||||
| anchor="left" | |||||
| content={<Typography sx={{ p: 2 }}>Drawer Content</Typography>} | |||||
| open={drawerOpen} | |||||
| toggleOpen={() => setDrawerOpen(!drawerOpen)} | |||||
| /> | |||||
| <PopoverComponent | |||||
| anchorEl={anchorEl} | |||||
| open={popoverOpen} | |||||
| onClose={() => { | |||||
| setPopoverOpen(false); | |||||
| setAnchorEl(null); | |||||
| }} | |||||
| content={<Typography sx={{ p: 2 }}>Popover Content</Typography>} | |||||
| /> | |||||
| </Box> | </Box> | ||||
| </> | </> | ||||
| ); | ); |
| import { selectIsLoadingByActionType } from '../../store/selectors/loadingSelectors'; | import { selectIsLoadingByActionType } from '../../store/selectors/loadingSelectors'; | ||||
| import { LOGIN_USER_LOADING } from '../../store/actions/login/loginActionConstants'; | import { LOGIN_USER_LOADING } from '../../store/actions/login/loginActionConstants'; | ||||
| const LoginValidationSchema = Yup.object().shape({ | |||||
| username: Yup.string().required(i18next.t('login.usernameRequired')), | |||||
| password: Yup.string().required(i18next.t('login.passwordRequired')), | |||||
| }); | |||||
| const LoginPage = ({ history }) => { | const LoginPage = ({ history }) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| username: '', | username: '', | ||||
| password: '', | password: '', | ||||
| }, | }, | ||||
| validationSchema: LoginValidationSchema, | |||||
| validationSchema: Yup.object().shape({ | |||||
| username: Yup.string().required(t('login.usernameRequired')), | |||||
| password: Yup.string().required(t('login.passwordRequired')), | |||||
| }), | |||||
| onSubmit: handleSubmit, | onSubmit: handleSubmit, | ||||
| validateOnBlur: true, | validateOnBlur: true, | ||||
| enableReinitialize: true, | enableReinitialize: true, |