diff --git a/src/@fuse/core/FuseLayout/FuseLayout.js b/src/@fuse/core/FuseLayout/FuseLayout.js index 6ef588f..febcc93 100644 --- a/src/@fuse/core/FuseLayout/FuseLayout.js +++ b/src/@fuse/core/FuseLayout/FuseLayout.js @@ -11,7 +11,6 @@ import { memo, useCallback, useContext, useMemo, useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { matchRoutes, useLocation } from 'react-router-dom'; import GlobalStyles from '@mui/material/GlobalStyles'; -import { alpha } from '@mui/material/styles'; const inputGlobalStyles = ( , + }, + ], +}; + +export default ForgotPasswordConfig; diff --git a/src/app/main/authPages/forgot-password/ForgotPasswordPage.js b/src/app/main/authPages/forgot-password/ForgotPasswordPage.js new file mode 100644 index 0000000..550507c --- /dev/null +++ b/src/app/main/authPages/forgot-password/ForgotPasswordPage.js @@ -0,0 +1,105 @@ +import { yupResolver } from '@hookform/resolvers/yup'; +import _ from '@lodash'; +import Button from '@mui/material/Button'; +import Paper from '@mui/material/Paper'; +import TextField from '@mui/material/TextField'; +import Typography from '@mui/material/Typography'; +import { Controller, useForm } from 'react-hook-form'; +import { withTranslation } from 'react-i18next'; +import { Link } from 'react-router-dom'; +import * as yup from 'yup'; +import LeftSideCanvas from '../shared-components/LeftSideCanvas'; + +const defaultValues = { + email: '', +}; + +function ForgotPasswordPage({ t }) { + const schema = yup.object().shape({ + email: yup.string().email(t('email_error')).required(t('email_error')), + }); + + const { control, formState, handleSubmit, reset } = useForm({ + mode: 'onChange', + defaultValues, + resolver: yupResolver(schema), + }); + + const { isValid, dirtyFields, errors } = formState; + + function onSubmit() { + reset(defaultValues); + } + + return ( +
+ + + theme.palette.background?.authPaper }} + > +
+ + {t('forgot_password')} + +
+ {t('suggestion')} +
+ +
+ ( + theme.palette.background.paper, + }, + }} + /> + )} + /> + +
+ +
+ + + {t('return')} + + {t('sign_in')} + + + +
+
+
+ ); +} + +export default withTranslation('forgotPasswordPage')(ForgotPasswordPage); diff --git a/src/app/main/authPages/forgot-password/i18n/en.js b/src/app/main/authPages/forgot-password/i18n/en.js new file mode 100644 index 0000000..ab790b9 --- /dev/null +++ b/src/app/main/authPages/forgot-password/i18n/en.js @@ -0,0 +1,16 @@ +const locale = { + title: 'Lorem ipsum dolor sit amet!', + subtitle: + 'Lorem ipsum dolor sit amet consectetur. Scelerisque blandit sit sagittis justo viverra. Morbi accumsaniam elementum enim commodo sed mauris vel. Scelerisque rhoncus in metus non arcu cursus non rhoncus.', + text: 'Lorem ipsum dolor sit amet consectetur. Scelerisque blandit sit.', + forgot_password: 'Forgot password?', + suggestion: 'Fill the form to reset your password', + email: 'Email', + email_error: + 'Lorem ipsum dolor sit amet consectetur. Eget pellentesque id consequat consectetur eu quis.', + forgot_password_btn: 'send reset link', + return: 'Return to', + sign_in: 'Sign in', +}; + +export default locale; diff --git a/src/app/main/authPages/shared-components/AdditionalSignWays.js b/src/app/main/authPages/shared-components/AdditionalSignWays.js new file mode 100644 index 0000000..c0ed8ff --- /dev/null +++ b/src/app/main/authPages/shared-components/AdditionalSignWays.js @@ -0,0 +1,40 @@ +import FuseSvgIcon from '@fuse/core/FuseSvgIcon/FuseSvgIcon'; +import { Typography } from '@mui/material'; +import Button from '@mui/material/Button'; +import { memo } from 'react'; + +function AdditionalSignWays({ divider, text }) { + return ( + <> + {divider && ( +
+
+ + {text} + +
+
+ )} + +
+ + + +
+ + ); +} + +export default memo(AdditionalSignWays); diff --git a/src/app/main/authPages/shared-components/LeftSideCanvas.js b/src/app/main/authPages/shared-components/LeftSideCanvas.js new file mode 100644 index 0000000..bd30a88 --- /dev/null +++ b/src/app/main/authPages/shared-components/LeftSideCanvas.js @@ -0,0 +1,58 @@ +import Avatar from '@mui/material/Avatar'; +import AvatarGroup from '@mui/material/AvatarGroup'; +import Box from '@mui/material/Box'; + +function LeftSideCanvas({ title, subtitle, text }) { + return ( + + + + + + + + +
+ {title &&
{title}
} + {subtitle && ( +
{subtitle}
+ )} +
+ + + + + + + + {text &&
{text}
} +
+
+
+ ); +} + +export default LeftSideCanvas; diff --git a/src/app/main/authPages/sign-in/SignInPage.js b/src/app/main/authPages/sign-in/SignInPage.js index 09eb949..b46fe8b 100644 --- a/src/app/main/authPages/sign-in/SignInPage.js +++ b/src/app/main/authPages/sign-in/SignInPage.js @@ -1,32 +1,18 @@ import { yupResolver } from '@hookform/resolvers/yup'; -import { Controller, useForm } from 'react-hook-form'; +import _ from '@lodash'; import Button from '@mui/material/Button'; import Checkbox from '@mui/material/Checkbox'; import FormControl from '@mui/material/FormControl'; import FormControlLabel from '@mui/material/FormControlLabel'; +import Paper from '@mui/material/Paper'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; +import { Controller, useForm } from 'react-hook-form'; +import { withTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; import * as yup from 'yup'; -import _ from '@lodash'; -import FuseSvgIcon from '@fuse/core/FuseSvgIcon'; -import AvatarGroup from '@mui/material/AvatarGroup'; -import Avatar from '@mui/material/Avatar'; -import Box from '@mui/material/Box'; -import Paper from '@mui/material/Paper'; -import { useEffect } from 'react'; -import jwtService from '../../../auth/services/jwtService'; - -/** - * Form Validation Schema - */ -const schema = yup.object().shape({ - email: yup.string().email('You must enter a valid email').required('You must enter a email'), - password: yup - .string() - .required('Please enter your password.') - .min(4, 'Password is too short - must be at least 4 chars.'), -}); +import AdditionalSignWays from '../shared-components/AdditionalSignWays'; +import LeftSideCanvas from '../shared-components/LeftSideCanvas'; const defaultValues = { email: '', @@ -34,8 +20,13 @@ const defaultValues = { remember: true, }; -function SignInPage() { - const { control, formState, handleSubmit, setError, setValue } = useForm({ +function SignInPage({ t }) { + const schema = yup.object().shape({ + email: yup.string().email(t('email_error')).required(t('email_error')), + password: yup.string().required(t('password_error')).min(8, t('password_error')), + }); + + const { control, formState, handleSubmit, reset } = useForm({ mode: 'onChange', defaultValues, resolver: yupResolver(schema), @@ -43,47 +34,33 @@ function SignInPage() { const { isValid, dirtyFields, errors } = formState; - useEffect(() => { - setValue('email', 'admin@fusetheme.com', { shouldDirty: true, shouldValidate: true }); - setValue('password', 'admin', { shouldDirty: true, shouldValidate: true }); - }, [setValue]); - - function onSubmit({ email, password }) { - jwtService - .signInWithEmailAndPassword(email, password) - .then((user) => { - // No need to do anything, user data will be set at app/auth/AuthContext - }) - .catch((_errors) => { - _errors.forEach((error) => { - setError(error.type, { - type: 'manual', - message: error.message, - }); - }); - }); + function onSubmit() { + reset(defaultValues); } return ( -
- -
- logo +
+ - + theme.palette.background?.authPaper }} + > +
+ Sign in -
- Don't have an account? - - Sign up +
+ {t('have_account')} + + {t('sign_up')}
( theme.palette.background.paper, + }, + }} /> )} /> @@ -111,14 +93,19 @@ function SignInPage() { render={({ field }) => ( theme.palette.background.paper, + }, + }} /> )} /> @@ -130,138 +117,43 @@ function SignInPage() { render={({ field }) => ( } + label={t('remember')} + control={ + theme.palette.border.light }} + /> + } /> )} /> - - Forgot password? + + {t('forgot_password')}
- - -
-
- - Or continue with - -
-
- -
- - -
+ +
- - - - - - - - - - - - - - - - - -
-
-
Welcome to
-
our community
-
-
- Fuse helps developers to build organized and well coded dashboards full of beautiful and - rich modules. Join us and start building your application today. -
-
- - - - - - - -
- More than 17k people joined us, it's your turn -
-
-
-
); } -export default SignInPage; +export default withTranslation('signInPage')(SignInPage); diff --git a/src/app/main/authPages/sign-in/i18n/en.js b/src/app/main/authPages/sign-in/i18n/en.js index 2d905d1..18285a6 100644 --- a/src/app/main/authPages/sign-in/i18n/en.js +++ b/src/app/main/authPages/sign-in/i18n/en.js @@ -1,3 +1,24 @@ -const locale = {}; +const locale = { + title: 'Lorem ipsum dolor sit amet!', + subtitle: + 'Lorem ipsum dolor sit amet consectetur. Scelerisque blandit sit sagittis justo viverra. Morbi accumsaniam elementum enim commodo sed mauris vel. Scelerisque rhoncus in metus non arcu cursus non rhoncus.', + text: 'Lorem ipsum dolor sit amet consectetur. Scelerisque blandit sit.', + sign_in: 'Sign In', + have_account: 'Don`t have an account?', + sign_up: 'Sign up', + name: 'Name', + name_error: + 'Lorem ipsum dolor sit amet consectetur. Eget pellentesque id consequat consectetur eu quis.', + email: 'Email', + email_error: + 'Lorem ipsum dolor sit amet consectetur. Eget pellentesque id consequat consectetur eu quis.', + password: 'Password', + password_error: + 'Lorem ipsum dolor sit amet consectetur. Eget pellentesque id consequat consectetur eu quis.', + remember: 'Remember me', + forgot_password: 'Forgot password?', + sign_in_btn: 'sign in', + additional_ways: 'Or continue with', +}; export default locale; diff --git a/src/app/main/authPages/sign-up/SignUpPage.js b/src/app/main/authPages/sign-up/SignUpPage.js index 9985f73..02fe2d6 100644 --- a/src/app/main/authPages/sign-up/SignUpPage.js +++ b/src/app/main/authPages/sign-up/SignUpPage.js @@ -1,109 +1,94 @@ import { yupResolver } from '@hookform/resolvers/yup'; -import { Controller, useForm } from 'react-hook-form'; +import _ from '@lodash'; import Button from '@mui/material/Button'; import Checkbox from '@mui/material/Checkbox'; import FormControl from '@mui/material/FormControl'; import FormControlLabel from '@mui/material/FormControlLabel'; +import FormHelperText from '@mui/material/FormHelperText'; +import Paper from '@mui/material/Paper'; import TextField from '@mui/material/TextField'; import Typography from '@mui/material/Typography'; +import { Controller, useForm } from 'react-hook-form'; +import { withTranslation } from 'react-i18next'; import { Link } from 'react-router-dom'; import * as yup from 'yup'; -import _ from '@lodash'; -import AvatarGroup from '@mui/material/AvatarGroup'; -import Avatar from '@mui/material/Avatar'; -import Box from '@mui/material/Box'; -import Paper from '@mui/material/Paper'; -import FormHelperText from '@mui/material/FormHelperText'; -import jwtService from '../../../auth/services/jwtService'; - -/** - * Form Validation Schema - */ -const schema = yup.object().shape({ - displayName: yup.string().required('You must enter display name'), - email: yup.string().email('You must enter a valid email').required('You must enter a email'), - password: yup - .string() - .required('Please enter your password.') - .min(8, 'Password is too short - should be 8 chars minimum.'), - passwordConfirm: yup.string().oneOf([yup.ref('password'), null], 'Passwords must match'), - acceptTermsConditions: yup.boolean().oneOf([true], 'The terms and conditions must be accepted.'), -}); +import AdditionalSignWays from '../shared-components/AdditionalSignWays'; +import LeftSideCanvas from '../shared-components/LeftSideCanvas'; const defaultValues = { - displayName: '', + name: '', email: '', password: '', passwordConfirm: '', acceptTermsConditions: false, }; -function SignUpPage() { +function SignUpPage({ t }) { + const schema = yup.object().shape({ + name: yup.string().required(t('name_error')), + email: yup.string().email(t('email_error')).required(t('email_error')), + password: yup.string().required(t('password_error')).min(8, t('password_error')), + passwordConfirm: yup.string().oneOf([yup.ref('password'), null], t('password_confirm_error')), + acceptTermsConditions: yup.boolean().oneOf([true], t('accept_terms_error')), + }); + const { control, formState, handleSubmit, reset } = useForm({ mode: 'onChange', defaultValues, resolver: yupResolver(schema), }); - const { isValid, dirtyFields, errors, setError } = formState; + const { isValid, dirtyFields, errors } = formState; - function onSubmit({ displayName, password, email }) { - jwtService - .createUser({ - displayName, - password, - email, - }) - .then((user) => { - // No need to do anything, registered user data will be set at app/auth/AuthContext - }) - .catch((_errors) => { - _errors.forEach((error) => { - setError(error.type, { - type: 'manual', - message: error.message, - }); - }); - }); + function onSubmit() { + reset(defaultValues); } return ( -
- -
- logo +
+ - - Sign up + theme.palette.background?.authPaper }} + > +
+ + {t('sign_up')} -
- Already have an account? - - Sign in +
+ {t('have_account')} + + {t('sign_in')}
( theme.palette.background.paper, + }, + }} /> )} /> @@ -114,14 +99,19 @@ function SignUpPage() { render={({ field }) => ( theme.palette.background.paper, + }, + }} /> )} /> @@ -132,14 +122,19 @@ function SignUpPage() { render={({ field }) => ( theme.palette.background.paper, + }, + }} /> )} /> @@ -150,14 +145,19 @@ function SignUpPage() { render={({ field }) => ( theme.palette.background.paper, + }, + }} /> )} /> @@ -166,110 +166,38 @@ function SignUpPage() { name="acceptTermsConditions" control={control} render={({ field }) => ( - + } + label={t('accept_terms')} + control={ + theme.palette.border.light }} /> + } /> {errors?.acceptTermsConditions?.message} )} /> - +
+ +
+ +
- - - - - - - - - - - - - - - - - -
-
-
Welcome to
-
our community
-
-
- Fuse helps developers to build organized and well coded dashboards full of beautiful and - rich modules. Join us and start building your application today. -
-
- - - - - - - -
- More than 17k people joined us, it's your turn -
-
-
-
); } -export default SignUpPage; +export default withTranslation('signUpPage')(SignUpPage); diff --git a/src/app/main/authPages/sign-up/i18n/en.js b/src/app/main/authPages/sign-up/i18n/en.js index 2d905d1..235417b 100644 --- a/src/app/main/authPages/sign-up/i18n/en.js +++ b/src/app/main/authPages/sign-up/i18n/en.js @@ -1,3 +1,28 @@ -const locale = {}; +const locale = { + title: 'Lorem ipsum dolor sit amet!', + subtitle: + 'Lorem ipsum dolor sit amet consectetur. Scelerisque blandit sit sagittis justo viverra. Morbi accumsaniam elementum enim commodo sed mauris vel. Scelerisque rhoncus in metus non arcu cursus non rhoncus.', + text: 'Lorem ipsum dolor sit amet consectetur. Scelerisque blandit sit.', + sign_up: 'Sign Up', + have_account: 'Already have an account?', + sign_in: 'Sign in', + name: 'Name', + name_error: + 'Lorem ipsum dolor sit amet consectetur. Eget pellentesque id consequat consectetur eu quis.', + email: 'Email', + email_error: + 'Lorem ipsum dolor sit amet consectetur. Eget pellentesque id consequat consectetur eu quis.', + password: 'Password', + password_error: + 'Lorem ipsum dolor sit amet consectetur. Eget pellentesque id consequat consectetur eu quis.', + password_confirm: 'Password (Confirm)', + password_confirm_error: + 'Lorem ipsum dolor sit amet consectetur. Eget pellentesque id consequat consectetur eu quis.', + accept_terms: 'I agree to the Terms of Service and Privacy Policy', + accept_terms_error: + 'Lorem ipsum dolor sit amet consectetur. Eget pellentesque id consequat consectetur eu quis.', + sign_up_btn: 'create your account', + additional_ways: 'Or register with', +}; export default locale; diff --git a/src/app/main/navigationPages/dashboard/DashboardConfig.js b/src/app/main/navigationPages/dashboard/DashboardConfig.js index 27e9eb0..1912a20 100644 --- a/src/app/main/navigationPages/dashboard/DashboardConfig.js +++ b/src/app/main/navigationPages/dashboard/DashboardConfig.js @@ -1,5 +1,6 @@ import i18next from 'i18next'; +import { authRoles } from 'src/app/auth'; import Dashboard from './Dashboard'; import en from './i18n/en'; @@ -11,6 +12,7 @@ const DashboardConfig = { config: {}, }, }, + auth: authRoles.user, routes: [ { path: 'dashboard', diff --git a/src/app/main/navigationPages/favorites/FavoritesConfig.js b/src/app/main/navigationPages/favorites/FavoritesConfig.js index 3ed743d..f041d50 100644 --- a/src/app/main/navigationPages/favorites/FavoritesConfig.js +++ b/src/app/main/navigationPages/favorites/FavoritesConfig.js @@ -1,7 +1,8 @@ import i18next from 'i18next'; -import en from './i18n/en'; +import { authRoles } from 'src/app/auth'; import Favorites from './Favorites'; +import en from './i18n/en'; i18next.addResourceBundle('en', 'favoritesPage', en); @@ -11,6 +12,7 @@ const FavoritesConfig = { config: {}, }, }, + auth: authRoles.user, routes: [ { path: 'favorites', diff --git a/src/app/main/navigationPages/history/HistoryConfig.js b/src/app/main/navigationPages/history/HistoryConfig.js index f7e16fc..8b4943c 100644 --- a/src/app/main/navigationPages/history/HistoryConfig.js +++ b/src/app/main/navigationPages/history/HistoryConfig.js @@ -1,7 +1,8 @@ import i18next from 'i18next'; -import en from './i18n/en'; +import { authRoles } from 'src/app/auth'; import History from './History'; +import en from './i18n/en'; i18next.addResourceBundle('en', 'historyPage', en); @@ -11,6 +12,7 @@ const HistoryConfig = { config: {}, }, }, + auth: authRoles.user, routes: [ { path: 'history', diff --git a/src/app/main/navigationPages/profile/ProfileConfig.js b/src/app/main/navigationPages/profile/ProfileConfig.js index 80648cf..73ed73a 100644 --- a/src/app/main/navigationPages/profile/ProfileConfig.js +++ b/src/app/main/navigationPages/profile/ProfileConfig.js @@ -1,5 +1,6 @@ import i18next from 'i18next'; +import { authRoles } from 'src/app/auth'; import en from './i18n/en'; import Profile from './Profile'; @@ -11,6 +12,7 @@ const ProfileConfig = { config: {}, }, }, + auth: authRoles.user, routes: [ { path: 'profile', diff --git a/src/styles/app-base.css b/src/styles/app-base.css index f6a9ae2..8fab455 100644 --- a/src/styles/app-base.css +++ b/src/styles/app-base.css @@ -1,6 +1,4 @@ -@tailwind base; - /** * Custom base styles */