create-responsive-navbar naar master 4 jaren geleden
| // import LoginPage from './pages/LoginPage/LoginPage'; | // import LoginPage from './pages/LoginPage/LoginPage'; | ||||
| import LoginPage from './pages/LoginPage/LoginPageMUI'; | import LoginPage from './pages/LoginPage/LoginPageMUI'; | ||||
| import HomePage from './pages/HomePage/HomePage'; | |||||
| // import HomePage from './pages/HomePage/HomePage'; | |||||
| import HomePage from './pages/HomePage/HomePageMUI'; | |||||
| import NotFoundPage from './pages/ErrorPages/NotFoundPage'; | import NotFoundPage from './pages/ErrorPages/NotFoundPage'; | ||||
| import ErrorPage from './pages/ErrorPages/ErrorPage'; | import ErrorPage from './pages/ErrorPages/ErrorPage'; | ||||
| import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPage'; | |||||
| // import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPage'; | |||||
| import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPageMUI'; | |||||
| import PrivateRoute from './components/Router/PrivateRoute'; | import PrivateRoute from './components/Router/PrivateRoute'; | ||||
| const AppRoutes = () => ( | const AppRoutes = () => ( |
| import React from 'react'; | |||||
| import PropTypes from 'prop-types'; | |||||
| import { Typography } from '@mui/material'; | |||||
| const CustomErrorMessage = ({ error }) => ( | |||||
| <Typography variant="body1" color="error" my={2}> | |||||
| {error} | |||||
| </Typography> | |||||
| ); | |||||
| CustomErrorMessage.propTypes = { | |||||
| error: PropTypes.string.isRequired, | |||||
| }; | |||||
| export default CustomErrorMessage; |
| import React from 'react'; | |||||
| import PropTypes from 'prop-types'; | |||||
| import { | |||||
| Drawer, | |||||
| List, | |||||
| ListItem, | |||||
| ListItemButton, | |||||
| ListItemIcon, | |||||
| ListItemText, | |||||
| } 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> | |||||
| </Drawer> | |||||
| ); | |||||
| DrawerComponent.propTypes = { | |||||
| open: PropTypes.bool, | |||||
| toggleOpen: PropTypes.func, | |||||
| }; | |||||
| export default DrawerComponent; |
| import React, { useState } from 'react'; | |||||
| import { Button, Menu, MenuItem } from '@mui/material'; | |||||
| const MenuList = () => { | |||||
| const [anchorEl, setAnchorEl] = useState(null); | |||||
| const open = Boolean(anchorEl); | |||||
| const handleClick = (event) => { | |||||
| setAnchorEl(event.currentTarget); | |||||
| }; | |||||
| const handleClose = () => { | |||||
| setAnchorEl(null); | |||||
| }; | |||||
| return ( | |||||
| <div> | |||||
| <Button onClick={handleClick}>Menu List</Button> | |||||
| <Menu id="menu-list" anchorEl={anchorEl} open={open} onClose={handleClose}> | |||||
| <MenuItem onClick={handleClose}>Menu Item 1</MenuItem> | |||||
| <MenuItem onClick={handleClose}>Menu Item 2</MenuItem> | |||||
| <MenuItem onClick={handleClose}>Menu Item 3</MenuItem> | |||||
| </Menu> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default MenuList; |
| import React, { useState } from 'react'; | |||||
| import { | |||||
| AppBar, | |||||
| Badge, | |||||
| Box, | |||||
| IconButton, | |||||
| Toolbar, | |||||
| Typography, | |||||
| useMediaQuery, | |||||
| } from '@mui/material'; | |||||
| import { useTheme } from '@mui/system'; | |||||
| import MenuOutlinedIcon from '@mui/icons-material/MenuOutlined'; | |||||
| import ShoppingBasketIcon from '@mui/icons-material/ShoppingBasket'; | |||||
| import MenuList from './MenuList'; | |||||
| import Drawer from './DrawerComponent'; | |||||
| const Navbar = () => { | |||||
| const [openDrawer, setOpenDrawer] = useState(false); | |||||
| const theme = useTheme(); | |||||
| const matches = useMediaQuery(theme.breakpoints.down('sm')); | |||||
| const handleToggleDrawer = () => { | |||||
| setOpenDrawer(!openDrawer); | |||||
| }; | |||||
| return ( | |||||
| <> | |||||
| <AppBar elevation={2} sx={{ backgroundColor: 'background.default' }}> | |||||
| <Toolbar> | |||||
| <Box | |||||
| component="div" | |||||
| sx={{ | |||||
| display: 'flex', | |||||
| justifyContent: 'space-between', | |||||
| alignItems: 'center', | |||||
| width: '100%', | |||||
| }} | |||||
| > | |||||
| {matches ? ( | |||||
| <Drawer open={openDrawer} toggleOpen={handleToggleDrawer} /> | |||||
| ) : ( | |||||
| <Box sx={{ display: 'flex' }}> | |||||
| <Typography | |||||
| variant="h6" | |||||
| sx={{ | |||||
| marginRight: 3, | |||||
| cursor: 'pointer', | |||||
| color: 'text.primary', | |||||
| }} | |||||
| > | |||||
| Link 1 | |||||
| </Typography> | |||||
| <Typography | |||||
| variant="body1" | |||||
| sx={{ | |||||
| marginRight: 3, | |||||
| cursor: 'pointer', | |||||
| color: 'text.primary', | |||||
| }} | |||||
| > | |||||
| Link 2 | |||||
| </Typography> | |||||
| <Typography | |||||
| variant="subtitle1" | |||||
| sx={{ | |||||
| marginRight: 3, | |||||
| cursor: 'pointer', | |||||
| color: 'text.primary', | |||||
| }} | |||||
| > | |||||
| Link 3 | |||||
| </Typography> | |||||
| </Box> | |||||
| )} | |||||
| <Box> | |||||
| <MenuList /> | |||||
| </Box> | |||||
| <Box | |||||
| sx={{ | |||||
| display: 'flex', | |||||
| justifyContent: 'center', | |||||
| alignItems: 'center', | |||||
| }} | |||||
| > | |||||
| {matches ? ( | |||||
| <Box> | |||||
| <IconButton onClick={handleToggleDrawer}> | |||||
| <MenuOutlinedIcon /> | |||||
| </IconButton> | |||||
| </Box> | |||||
| ) : ( | |||||
| <IconButton> | |||||
| <Badge badgeContent={3} color="primary"> | |||||
| <ShoppingBasketIcon color="action" /> | |||||
| </Badge> | |||||
| </IconButton> | |||||
| )} | |||||
| </Box> | |||||
| </Box> | |||||
| </Toolbar> | |||||
| </AppBar> | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| export default Navbar; |
| forgotPassword: { | forgotPassword: { | ||||
| title: 'Forgot Password', | title: 'Forgot Password', | ||||
| label: 'Send email', | label: 'Send email', | ||||
| emailRequired: 'An email is required.', | |||||
| emailFormat: 'Invalid email address format.', | |||||
| forgotPassword: { | forgotPassword: { | ||||
| title: 'Forgot Password', | title: 'Forgot Password', | ||||
| subtitle: | subtitle: | ||||
| logout: 'Logout', | logout: 'Logout', | ||||
| }, | }, | ||||
| apiErrors:{ | apiErrors:{ | ||||
| ClientIpAddressIsNullOrEmpty:"Client Ip address is null or empty" | |||||
| ClientIpAddressIsNullOrEmpty:"Client Ip address is null or empty", | |||||
| UsernameDoesNotExist: "Username does not exist" | |||||
| } | } | ||||
| }; | }; |
| import React from 'react'; | |||||
| import { useFormik } from 'formik'; | |||||
| import { useTranslation } from 'react-i18next'; | |||||
| import * as Yup from 'yup'; | |||||
| import i18next from 'i18next'; | |||||
| import { | |||||
| Box, | |||||
| Container, | |||||
| Typography, | |||||
| Button, | |||||
| TextField, | |||||
| Link, | |||||
| Grid, | |||||
| } from '@mui/material'; | |||||
| import Backdrop from '../../components/MUI/CustomBackdrop'; | |||||
| import { LOGIN_PAGE } from '../../constants/pages'; | |||||
| import { NavLink } from 'react-router-dom'; | |||||
| const forgotPasswordValidationSchema = Yup.object().shape({ | |||||
| email: Yup.string() | |||||
| .required(i18next.t('forgotPassword.emailRequired')) | |||||
| .email(i18next.t('forgotPassword.emailFormat')), | |||||
| }); | |||||
| const ForgotPasswordPage = () => { | |||||
| const { t } = useTranslation(); | |||||
| const handleSubmit = (values) => { | |||||
| console.log('Values', values); | |||||
| }; | |||||
| const formik = useFormik({ | |||||
| initialValues: { | |||||
| email: '', | |||||
| }, | |||||
| validationSchema: forgotPasswordValidationSchema, | |||||
| onSubmit: handleSubmit, | |||||
| validateOnBlur: true, | |||||
| enableReinitialize: true, | |||||
| }); | |||||
| return ( | |||||
| <Container component="main" maxWidth="md"> | |||||
| <Box | |||||
| sx={{ | |||||
| marginTop: 32, | |||||
| display: 'flex', | |||||
| flexDirection: 'column', | |||||
| alignItems: 'center', | |||||
| }} | |||||
| > | |||||
| <Typography component="h1" variant="h5"> | |||||
| {t('forgotPassword.title')} | |||||
| </Typography> | |||||
| <Box | |||||
| component="form" | |||||
| onSubmit={formik.handleSubmit} | |||||
| sx={{ position: 'relative', mt: 1, p: 1 }} | |||||
| > | |||||
| <Backdrop position="absolute" isLoading={false} /> | |||||
| <TextField | |||||
| name="email" | |||||
| label={t('login.forgotPasswordEmail')} | |||||
| margin="normal" | |||||
| value={formik.values.email} | |||||
| onChange={formik.handleChange} | |||||
| error={formik.touched.email && Boolean(formik.errors.email)} | |||||
| helperText={formik.touched.email && formik.errors.email} | |||||
| autoFocus | |||||
| fullWidth | |||||
| /> | |||||
| <Button | |||||
| type="submit" | |||||
| variant="contained" | |||||
| sx={{ mt: 3, mb: 2 }} | |||||
| fullWidth | |||||
| > | |||||
| {t('forgotPassword.label')} | |||||
| </Button> | |||||
| <Grid container justifyContent="center"> | |||||
| <Link | |||||
| to={LOGIN_PAGE} | |||||
| component={NavLink} | |||||
| variant="body2" | |||||
| underline="hover" | |||||
| > | |||||
| {t('common.back')} | |||||
| </Link> | |||||
| </Grid> | |||||
| </Box> | |||||
| </Box> | |||||
| </Container> | |||||
| ); | |||||
| }; | |||||
| export default ForgotPasswordPage; |
| import React from 'react'; | |||||
| import Navbar from '../../components/MUI/Navbar'; | |||||
| const HomePage = () => { | |||||
| return ( | |||||
| <Navbar /> | |||||
| ) | |||||
| }; | |||||
| export default HomePage; |
| /* eslint-disable */ | |||||
| import React, { useState } from 'react'; | import React, { useState } from 'react'; | ||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||
| import { useFormik } from 'formik'; | import { useFormik } from 'formik'; | ||||
| clearLoginErrors, | clearLoginErrors, | ||||
| fetchUser, | fetchUser, | ||||
| } from '../../store/actions/login/loginActions'; | } from '../../store/actions/login/loginActions'; | ||||
| // import { selectLoginError } from '../../store/selectors/loginSelectors'; | |||||
| import { selectLoginError } from '../../store/selectors/loginSelectors'; | |||||
| import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from '../../constants/pages'; | import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from '../../constants/pages'; | ||||
| import { | import { | ||||
| Box, | Box, | ||||
| } from '@mui/material'; | } from '@mui/material'; | ||||
| import { Visibility, VisibilityOff } from '@mui/icons-material'; | import { Visibility, VisibilityOff } from '@mui/icons-material'; | ||||
| import Backdrop from '../../components/MUI/CustomBackdrop'; | import Backdrop from '../../components/MUI/CustomBackdrop'; | ||||
| import ErrorMessage from '../../components/MUI/CustomErrorMessage'; | |||||
| 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 LoginPage = ({ history }) => { | const LoginPage = ({ history }) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| // const error = useSelector(selectLoginError); | |||||
| const error = useSelector(selectLoginError); | |||||
| const [showPassword, setShowPassword] = useState(false); | const [showPassword, setShowPassword] = useState(false); | ||||
| const handleClickShowPassword = () => setShowPassword(!showPassword); | const handleClickShowPassword = () => setShowPassword(!showPassword); | ||||
| ); | ); | ||||
| const handleApiResponseSuccess = () => { | const handleApiResponseSuccess = () => { | ||||
| history.push({ | |||||
| pathname: HOME_PAGE, | |||||
| state: { | |||||
| from: history.location.pathname, | |||||
| }, | |||||
| }); | |||||
| // history.push({ | |||||
| // pathname: HOME_PAGE, | |||||
| // state: { | |||||
| // from: history.location.pathname, | |||||
| // }, | |||||
| // }); | |||||
| }; | }; | ||||
| const handleSubmit = (values) => { | const handleSubmit = (values) => { | ||||
| <Typography component="h1" variant="h5"> | <Typography component="h1" variant="h5"> | ||||
| {t('login.logInTitle')} | {t('login.logInTitle')} | ||||
| </Typography> | </Typography> | ||||
| {error && <ErrorMessage error={error} />} | |||||
| <Box | <Box | ||||
| component="form" | component="form" | ||||
| onSubmit={formik.handleSubmit} | onSubmit={formik.handleSubmit} | ||||
| {t('login.logIn')} | {t('login.logIn')} | ||||
| </Button> | </Button> | ||||
| <Grid container> | <Grid container> | ||||
| <Grid item xs> | |||||
| <Grid | |||||
| item | |||||
| xs={12} | |||||
| md={6} | |||||
| sx={{ textAlign: { xs: 'center', md: 'left' } }} | |||||
| > | |||||
| <Link | <Link | ||||
| to={FORGOT_PASSWORD_PAGE} | to={FORGOT_PASSWORD_PAGE} | ||||
| component={NavLink} | component={NavLink} | ||||
| {t('login.forgotYourPassword')} | {t('login.forgotYourPassword')} | ||||
| </Link> | </Link> | ||||
| </Grid> | </Grid> | ||||
| <Grid item> | |||||
| <Grid | |||||
| item | |||||
| xs={12} | |||||
| md={6} | |||||
| sx={{ textAlign: { xs: 'center', md: 'right' } }} | |||||
| > | |||||
| <Link | <Link | ||||
| to="#" | to="#" | ||||
| component={NavLink} | component={NavLink} |
| if (payload.handleApiResponseSuccess) { | if (payload.handleApiResponseSuccess) { | ||||
| yield call(payload.handleApiResponseSuccess); | yield call(payload.handleApiResponseSuccess); | ||||
| } | } | ||||
| // const errorMessage = yield call(rejectErrorCodeHelper, e); | |||||
| // yield put(fetchUserError(errorMessage)); | |||||
| const errorMessage = yield call(rejectErrorCodeHelper, e); | |||||
| yield put(fetchUserError(errorMessage)); | |||||
| } | } | ||||
| } | } | ||||
| } | } |