Commit 20cb9f30 authored by janithGamage's avatar janithGamage

feat : update

desc :
> user registration option UI updated
> user registration option API Connected
> user logic on frontend
parent e686976e
......@@ -3,7 +3,7 @@ GENERATE_SOURCEMAP = false
## Backend API URL
REACT_APP_API_URL_MOCK=https://mock-data-api-nextjs.vercel.app/
REACT_APP_API_URL=http://13.49.44.192/api/v1/
REACT_APP_API_URL=http://localhost:5000/
## Google Map Key
......
......@@ -12,7 +12,8 @@ import authReducer from 'store/reducers/auth';
import Loader from 'components/Loader';
import { AuthProps, JWTContextType } from 'types/auth';
import { KeyedObject } from 'types/root';
import { axiosServices_Mock as axios } from 'utils/axios';
import { axiosServices_Mock as axios, axiosServices } from 'utils/axios';
const chance = new Chance();
......@@ -123,20 +124,49 @@ export const JWTProvider = ({ children }: { children: React.ReactElement }) => {
window.localStorage.setItem('users', JSON.stringify(users));
};
const registerUser = async (email: string, password: string, firstName: string, lastName: string, contactNumber: string, confirmPassword: string) => {
// todo: this flow need to be recode as it not verified
const id = chance.bb_pin();
const response = await axiosServices.post('/rest_node/user/sign-up', {
firstName,
lastName,
email,
contactNumber,
password,
confirmPassword,
type: "member"
});
let users = response.data;
if (window.localStorage.getItem('users') !== undefined && window.localStorage.getItem('users') !== null) {
const localUsers = window.localStorage.getItem('users');
users = [
...JSON.parse(localUsers!),
{
id,
email,
password,
name: `${firstName} ${lastName}`
}
];
}
window.localStorage.setItem('users', JSON.stringify(users));
};
const logout = () => {
setSession(null);
dispatch({ type: LOGOUT });
};
const resetPassword = async (email: string) => {};
const resetPassword = async (email: string) => { };
const updateProfile = () => {};
const updateProfile = () => { };
if (state.isInitialized !== undefined && !state.isInitialized) {
return <Loader />;
}
return <JWTContext.Provider value={{ ...state, login, logout, register, resetPassword, updateProfile }}>{children}</JWTContext.Provider>;
return <JWTContext.Provider value={{ ...state, login, logout, register, registerUser, resetPassword, updateProfile }}>{children}</JWTContext.Provider>;
};
export default JWTContext;
......@@ -3,6 +3,7 @@ import { FormattedMessage } from 'react-intl';
// assets
import {
BookOutlined,
CarryOutOutlined,
CreditCardOutlined,
FileTextOutlined,
......@@ -25,7 +26,8 @@ const icons = {
CarryOutOutlined,
CreditCardOutlined,
LoginOutlined,
RocketOutlined
RocketOutlined,
BookOutlined
};
// ==============================|| MENU ITEMS - SUPPORT ||============================== //
......@@ -63,6 +65,44 @@ const application: NavItemType = {
}
]
},
{
id: 'learning-management',
title: <FormattedMessage id="learning-management" />,
type: 'collapse',
icon: icons.BookOutlined,
children: [
// {
// id: 'learning-list',
// title: <FormattedMessage id="learning-list" />,
// type: 'item',
// url: '/learning-management/list',
// },
{
id: 'learning-curriculums',
title: <FormattedMessage id="learning-curriculums" />,
type: 'item',
url: '/learning-management/curriculums',
},
{
id: 'learning-curriculums-subscribed',
title: <FormattedMessage id="learning-curriculums-subscribed" />,
type: 'item',
url: '/learning-management/curriculums-subscribed',
},
{
id: 'learning-lead-board',
title: <FormattedMessage id="learning-lead-board" />,
type: 'item',
url: '/learning-management/lead-board',
},
{
id: 'learning-feedback',
title: <FormattedMessage id="learning-feedback" />,
type: 'item',
url: '/learning-management/feedback',
}
]
},
// {
// id: 'authentication',
// title: <FormattedMessage id="authentication" />,
......
......@@ -6,7 +6,7 @@ import { Grid, Stack, Typography } from '@mui/material';
// project import
import useAuth from 'hooks/useAuth';
import AuthWrapper from 'sections/auth/AuthWrapper';
import FirebaseRegister from 'sections/auth/auth-forms/AuthRegister';
import AuthRegister from 'sections/auth/auth-forms/AuthRegister';
// ================================|| REGISTER ||================================ //
......@@ -31,7 +31,7 @@ const Register = () => {
</Stack>
</Grid>
<Grid item xs={12}>
<FirebaseRegister />
<AuthRegister />
</Grid>
</Grid>
</AuthWrapper>
......
// material-ui
// project import
// ==============================|| List ||============================== //
const List = () => (
<>
</>
);
export default List;
......@@ -29,6 +29,9 @@ const Dashboard = Loadable(lazy(() => import('pages/home/dashboard')));
// render - user management page
// const UserManagementList = Loadable(lazy(() => import('pages/user-management/list/list')));
// render - learning management page
// const LearningManagementList = Loadable(lazy(() => import('pages/learning-management/list/list')));
// render - parameter curriculum management page
const CurriculumManagementList = Loadable(lazy(() => import('pages/parameter/curriculum-management/list/list')));
......@@ -74,7 +77,16 @@ const MainRoutes = {
element: <MaintenanceUnderConstruction />
}
]
},
},
{
path: 'learning-management',
children: [
{
path: 'list',
element: <MaintenanceUnderConstruction />
}
]
},
],
},
{
......@@ -102,7 +114,7 @@ const MainRoutes = {
element: <TutorialManagementList />
}
]
},
},
],
},
{
......
import { useEffect, useState, SyntheticEvent } from 'react';
import { SyntheticEvent, useEffect, useState } from 'react';
import { Link as RouterLink, useNavigate } from 'react-router-dom';
// material-ui
......@@ -8,21 +8,21 @@ import {
FormControl,
FormHelperText,
Grid,
Link,
InputAdornment,
InputLabel,
Link,
OutlinedInput,
Stack,
Typography
} from '@mui/material';
// third party
import * as Yup from 'yup';
import { Formik } from 'formik';
import * as Yup from 'yup';
// project import
import IconButton from 'components/@extended/IconButton';
import AnimateButton from 'components/@extended/AnimateButton';
import IconButton from 'components/@extended/IconButton';
import useAuth from 'hooks/useAuth';
import useScriptRef from 'hooks/useScriptRef';
......@@ -34,25 +34,35 @@ import { strengthColor, strengthIndicator } from 'utils/password-strength';
import { StringColorProps } from 'types/password';
// assets
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons';
import { EyeInvisibleOutlined, EyeOutlined } from '@ant-design/icons';
// ============================|| JWT - REGISTER ||============================ //
const AuthRegister = () => {
const { register } = useAuth();
const { registerUser } = useAuth();
const scriptedRef = useScriptRef();
const navigate = useNavigate();
const [level, setLevel] = useState<StringColorProps>();
const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
const handleClickShowPassword = () => {
setShowPassword(!showPassword);
};
const handleClickShowConfirmPassword = () => {
setShowConfirmPassword(!showConfirmPassword);
};
const handleMouseDownPassword = (event: SyntheticEvent) => {
event.preventDefault();
};
const handleMouseDownConfirmPassword = (event: SyntheticEvent) => {
event.preventDefault();
};
const changePassword = (value: string) => {
const temp = strengthIndicator(value);
setLevel(strengthColor(temp));
......@@ -62,26 +72,36 @@ const AuthRegister = () => {
changePassword('');
}, []);
const contactNumberPattern = /^(?:\+?94|0)(?:[1-9]\d{8})$/; // Sri Lankan contact number pattern
return (
<>
<Formik
initialValues={{
firstname: '',
lastname: '',
firstName: '',
lastName: '',
email: '',
company: '',
contactNumber: '',
password: '',
confirmPassword: '',
submit: null
}}
validationSchema={Yup.object().shape({
firstname: Yup.string().max(255).required('First Name is required'),
lastname: Yup.string().max(255).required('Last Name is required'),
firstName: Yup.string().max(255).required('First Name is required'),
lastName: Yup.string().max(255).required('Last Name is required'),
email: Yup.string().email('Must be a valid email').max(255).required('Email is required'),
password: Yup.string().max(255).required('Password is required')
password: Yup.string().max(255).required('Password is required'),
confirmPassword: Yup.string()
.oneOf([Yup.ref('password'), undefined], 'Passwords must match')
.max(255)
.required('Confirm Password is required'),
contactNumber: Yup.string()
.matches(contactNumberPattern, 'Invalid Sri Lankan contact number')
.required('Contact Number is required')
})}
onSubmit={async (values, { setErrors, setStatus, setSubmitting }) => {
try {
await register(values.email, values.password, values.firstname, values.lastname);
await registerUser(values.email, values.password, values.firstName, values.lastName, values.contactNumber, values.confirmPassword);
if (scriptedRef.current) {
setStatus({ success: true });
setSubmitting(false);
......@@ -116,64 +136,64 @@ const AuthRegister = () => {
<Grid container spacing={3}>
<Grid item xs={12} md={6}>
<Stack spacing={1}>
<InputLabel htmlFor="firstname-signup">First Name*</InputLabel>
<InputLabel htmlFor="firstName-signup">First Name*</InputLabel>
<OutlinedInput
id="firstname-login"
type="firstname"
value={values.firstname}
name="firstname"
id="firstName-login"
type="firstName"
value={values.firstName}
name="firstName"
onBlur={handleBlur}
onChange={handleChange}
placeholder="John"
fullWidth
error={Boolean(touched.firstname && errors.firstname)}
error={Boolean(touched.firstName && errors.firstName)}
/>
{touched.firstname && errors.firstname && (
<FormHelperText error id="helper-text-firstname-signup">
{errors.firstname}
{touched.firstName && errors.firstName && (
<FormHelperText error id="helper-text-firstName-signup">
{errors.firstName}
</FormHelperText>
)}
</Stack>
</Grid>
<Grid item xs={12} md={6}>
<Stack spacing={1}>
<InputLabel htmlFor="lastname-signup">Last Name*</InputLabel>
<InputLabel htmlFor="lastName-signup">Last Name*</InputLabel>
<OutlinedInput
fullWidth
error={Boolean(touched.lastname && errors.lastname)}
id="lastname-signup"
type="lastname"
value={values.lastname}
name="lastname"
error={Boolean(touched.lastName && errors.lastName)}
id="lastName-signup"
type="lastName"
value={values.lastName}
name="lastName"
onBlur={handleBlur}
onChange={handleChange}
placeholder="Doe"
inputProps={{}}
/>
{touched.lastname && errors.lastname && (
<FormHelperText error id="helper-text-lastname-signup">
{errors.lastname}
{touched.lastName && errors.lastName && (
<FormHelperText error id="helper-text-lastName-signup">
{errors.lastName}
</FormHelperText>
)}
</Stack>
</Grid>
<Grid item xs={12}>
<Stack spacing={1}>
<InputLabel htmlFor="company-signup">Company</InputLabel>
<InputLabel htmlFor="contactNumber-signup">Contact Number</InputLabel>
<OutlinedInput
fullWidth
error={Boolean(touched.company && errors.company)}
id="company-signup"
value={values.company}
name="company"
error={Boolean(touched.contactNumber && errors.contactNumber)}
id="contactNumber-signup"
value={values.contactNumber}
name="contactNumber"
onBlur={handleBlur}
onChange={handleChange}
placeholder="Demo Inc."
placeholder="+94 000 000 000 / 0000000000"
inputProps={{}}
/>
{touched.company && errors.company && (
<FormHelperText error id="helper-text-company-signup">
{errors.company}
{touched.contactNumber && errors.contactNumber && (
<FormHelperText error id="helper-text-contactNumber-signup">
{errors.contactNumber}
</FormHelperText>
)}
</Stack>
......@@ -250,6 +270,43 @@ const AuthRegister = () => {
</Grid>
</FormControl>
</Grid>
<Grid item xs={12}>
<Stack spacing={1}>
<InputLabel htmlFor="confirmPassword-signup">Confirm Password</InputLabel>
<OutlinedInput
fullWidth
error={Boolean(touched.confirmPassword && errors.confirmPassword)}
id="confirmPassword-signup"
type={showConfirmPassword ? 'text' : 'password'}
value={values.confirmPassword}
name="confirmPassword"
onBlur={handleBlur}
onChange={(e) => {
handleChange(e);
}}
endAdornment={
<InputAdornment position="end">
<IconButton
aria-label="toggle confirm Password visibility"
onClick={handleClickShowConfirmPassword}
onMouseDown={handleMouseDownConfirmPassword}
edge="end"
color="secondary"
>
{showConfirmPassword ? <EyeOutlined /> : <EyeInvisibleOutlined />}
</IconButton>
</InputAdornment>
}
placeholder="******"
inputProps={{}}
/>
{touched.confirmPassword && errors.confirmPassword && (
<FormHelperText error id="helper-text-confirmPassword-signup">
{errors.confirmPassword}
</FormHelperText>
)}
</Stack>
</Grid>
<Grid item xs={12}>
<Typography variant="body2">
By Signing up, you agree to our &nbsp;
......
......@@ -75,6 +75,7 @@ export type JWTContextType = {
logout: () => void;
login: (email: string, password: string) => Promise<void>;
register: (email: string, password: string, firstName: string, lastName: string) => Promise<void>;
registerUser: (email: string, password: string, firstName: string, lastName: string, contactNumber: string, confirmPassword: string) => Promise<void>;
resetPassword: (email: string) => Promise<void>;
updateProfile: VoidFunction;
};
......
......@@ -2,7 +2,7 @@ import axios from 'axios';
const axiosServices_Mock = axios.create({ baseURL: process.env.REACT_APP_API_URL_MOCK || 'http://localhost:3010/' });
const axiosServices = axios.create({ baseURL: process.env.REACT_APP_API_URL || 'http://localhost:3010/' });
const axiosServices = axios.create({ baseURL: process.env.REACT_APP_API_URL || 'http://localhost:5000/' });
// ==============================|| AXIOS - FOR MOCK SERVICES ||============================== //
......
......@@ -154,5 +154,11 @@
"nutrition-list": "Nutrition List",
"parameter": "Parameter",
"tutorial-management": "Tutorial Management",
"curriculum-management": "Curriculum Management"
"curriculum-management": "Curriculum Management",
"learning-management": "Learning Management",
"learning-list": "Learning List",
"learning-curriculums": "Course",
"learning-curriculums-subscribed": "My Courses",
"learning-lead-board": "Lead Board",
"learning-feedback": "Feedback"
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment