Explorar el Código

Merge branch 'feature/1736_implemented_registration' of Neca/HRCenter into FE_dev

pull/97/head
safet.purkovic hace 3 años
padre
commit
45c6f3c762

+ 1
- 1
src/assets/styles/components/_button.scss Ver fichero

@@ -250,5 +250,5 @@
text-align: left;
}
.w-289.f {
margin-top: 35px !important;
margin-top: 25px !important;
}

+ 63
- 10
src/components/Registration/FirstStepForm.js Ver fichero

@@ -7,19 +7,21 @@ import {
IconButton,
InputAdornment,
TextField,
Typography,
// Typography,
} from "@mui/material";
import Button from "../Button/Button";
import { useState } from "react";
import googleLogo from "../../assets/images/google1.png";
// import googleLogo from "../../assets/images/google1.png";
import DiligLogo from "../../assets/images/logo_horizontal_black.png";
import { Box } from "@mui/system";
import { FormContext } from "../../context/FormContext";
import { useLocation } from "react-router-dom";

function FirstStepForm() {
const { activeStepIndex, setActiveStepIndex, formData, setFormData } =
useContext(FormContext);
const { search } = useLocation();

const { t } = useTranslation();

const [showPassword, setShowPassword] = useState(false);
@@ -27,22 +29,48 @@ function FirstStepForm() {
const handleMouseDownPassword = () => setShowPassword(!showPassword);

const submitHandler = (values) => {
const data = { ...formData, ...values };
const data = {
...formData,
...values,
token: search.split("&")[0].split("=")[1],
};
setFormData(data);
setActiveStepIndex(activeStepIndex + 1);
};

const formik = useFormik({
initialValues: {
email: "",
email: search.split("&")[1].split("=")[1],
password: "",
confirm: "",
},
validationSchema: yup.object().shape({
email: yup
.string()
.required(t("login.emailRequired"))
.matches(/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/, t("login.invalidEmail")),
password: yup.string().required(t("login.passwordRequired")),
password: yup
.string()
.required(t("login.passwordRequired"))
.matches(
// eslint-disable-next-line
/[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]+/,
"Paswword must contain atleast one special character"
)
.matches(/[0-9]/g, "Paswword must contain atleast one number")
.matches(
/[a-z]/g,
"Paswword must contain at least one lowercase character"
)
.matches(
/[A-Z]/g,
"Paswword must contain at least one uppercase character"
)
.min(8, "Password must contain at least 8 characters"),
confirm: yup
.string()
.required("Please retype your password.")
.oneOf([yup.ref("password")], "Your passwords do not match."),
}),
onSubmit: submitHandler,
validateOnBlur: true,
@@ -62,9 +90,11 @@ function FirstStepForm() {
<>
<TextField
name="email"
label={"E-mail"}
// label={"E-mail"}
margin="normal"
disabled
fullWidth
value={formik.values.email}
onChange={formik.handleChange}
error={formik.touched.email && Boolean(formik.errors.email)}
helperText={formik.touched.email && formik.errors.email}
@@ -92,17 +122,40 @@ function FirstStepForm() {
),
}}
/>
<TextField
className="rounded-input"
name="confirm"
label={"Potvrda šifre"}
margin="normal"
type={showPassword ? "text" : "password"}
fullWidth
onChange={formik.handleChange}
error={formik.touched.confirm && Boolean(formik.errors.confirm)}
helperText={formik.touched.confirm && formik.errors.confirm}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<IconButton
onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword}
>
{showPassword ? <Visibility /> : <VisibilityOff />}
</IconButton>
</InputAdornment>
),
}}
/>
</>
<Button
variant="contained"
sx={{ mt: 3, mb: 2 }}
sx={{ mt: 2, mb: 2 }}
fullWidth
className="c-btn c-btn--primary w-289 f"
type="submit"
>
Nastavi
</Button>
<div className="flex-center">
{/* <div className="flex-center">
<div className="hr hr-s"></div>
<div className="hr-mid">{t("common.or")}</div>
<div className="hr hr-e"></div>
@@ -119,7 +172,7 @@ function FirstStepForm() {
</Typography>
</Button>
<div id="signInDiv"></div>
</div>
</div> */}
<div className="flex-center">
<img src={DiligLogo} style={{ margin: "50px auto 30px auto" }} />
</div>

+ 33
- 21
src/components/Registration/SecondStepForm.js Ver fichero

@@ -1,27 +1,41 @@
import { useFormik } from "formik";
import React from "react";
import React, { useContext } from "react";
import * as yup from "yup";
import { useTranslation } from "react-i18next";
import {
TextField,
Typography,
} from "@mui/material";
import { TextField } from "@mui/material";
import Button from "../Button/Button";
import googleLogo from "../../assets/images/google1.png";
// import googleLogo from "../../assets/images/google1.png";
import DiligLogo from "../../assets/images/logo_horizontal_black.png";
import { Box } from "@mui/system";
import { FormContext } from "../../context/FormContext";
import { useDispatch } from "react-redux";
import { registerRequest } from "../../store/actions/register/registerActions";
import { BASE_PAGE } from "../../constants/pages";
import { useHistory } from "react-router-dom";

function SecondStepForm() {
// const { activeStepIndex, setActiveStepIndex, formData, setFormData } =
// useContext(FormContext);
const { formData } = useContext(FormContext);
const dispatch = useDispatch();
const { t } = useTranslation();
const history = useHistory();

const submitHandler = (values) => {
console.log(values)
// const data = { ...formData, ...values };
// setFormData(data);
// setActiveStepIndex(activeStepIndex + 1);
alert('Done')
const data = { ...formData, ...values };
dispatch(
registerRequest({
model: data,
handleApiResponseSuccess,
})
);
};

const handleApiResponseSuccess = () => {
history.push({
pathname: BASE_PAGE,
state: {
from: history.location.pathname,
},
});
};

const formik = useFormik({
@@ -31,11 +45,9 @@ function SecondStepForm() {
linkedin: "",
},
validationSchema: yup.object().shape({
phone: yup
.string()
.required('Required'),
position: yup.string().required('Required'),
linkedin: yup.string().required('Required'),
phone: yup.string().required("Required"),
position: yup.string().required("Required"),
linkedin: yup.string().required("Required"),
}),
onSubmit: submitHandler,
validateOnBlur: true,
@@ -90,7 +102,7 @@ function SecondStepForm() {
>
Registruj se
</Button>
<div className="flex-center">
{/* <div className="flex-center">
<div className="hr hr-s"></div>
<div className="hr-mid">{t("common.or")}</div>
<div className="hr hr-e"></div>
@@ -107,7 +119,7 @@ function SecondStepForm() {
</Typography>
</Button>
<div id="signInDiv"></div>
</div>
</div> */}
<div className="flex-center">
<img src={DiligLogo} style={{ margin: "50px auto 30px auto" }} />
</div>
@@ -115,4 +127,4 @@ function SecondStepForm() {
);
}

export default SecondStepForm;
export default SecondStepForm;

+ 48
- 27
src/pages/RegisterPage/RegisterPage.js Ver fichero

@@ -3,7 +3,7 @@ import React, { useEffect, useState, useContext } from "react";
import PropTypes from "prop-types";
import { useFormik } from "formik";
import { useDispatch, useSelector } from "react-redux";
import { NavLink } from "react-router-dom";
import { NavLink, useLocation } from "react-router-dom";
import * as Yup from "yup";
import { useTranslation } from "react-i18next";
import HrLogo from "../../assets/images/hrcenter.png";
@@ -14,7 +14,11 @@ import {
fetchGoogleUser,
} from "../../store/actions/login/loginActions";
import { selectLoginError } from "../../store/selectors/loginSelectors";
import { FORGOT_PASSWORD_PAGE, HOME_PAGE } from "../../constants/pages";
import {
ADS_PAGE,
FORGOT_PASSWORD_PAGE,
HOME_PAGE,
} from "../../constants/pages";
import {
Box,
Button,
@@ -38,11 +42,13 @@ import { authScopeStringGetHelper } from "../../util/helpers/authScopeHelpers";
import { JWT_TOKEN } from "../../constants/localStorage";
import Step from "../../components/Registration/Step";
import { FormContext, FormProvider } from "../../context/FormContext";
import { selectIsUserAuthenticated } from "../../store/selectors/userSelectors";

const RegisterPage = ({ history }) => {
// const dispatch = useDispatch();
const { t } = useTranslation();
// const error = useSelector(selectLoginError);
const { search } = useLocation();

const { activeStepIndex } = useContext(FormContext);

@@ -74,11 +80,17 @@ const RegisterPage = ({ history }) => {
selectIsLoadingByActionType(LOGIN_GOOGLE_USER_LOADING)
);

const isUserAuthenticated = useSelector(selectIsUserAuthenticated);

useEffect(() => {
if (isInit) {
setIsInit(false);
return;
}

if (!isUserAuthenticated) {
history.push({ pathname: ADS_PAGE });
}
}, [isInit]);

return (
@@ -102,31 +114,40 @@ const RegisterPage = ({ history }) => {
}}
>
<img src={HrLogo} className="login-logo" />
<Typography variant="h5" sx={{ m: 1, mt: 3 }}>
{t("login.welcome")}
</Typography>
<Typography variant="p" sx={{ mb: 2 }}>
Dva koraka do HR Centra.
</Typography>
<div className="steps-cont">
<div
className={`step ${activeStepIndex && activeStepIndex === 1 ? "done" : "current"}`}
>
1
</div>
<div className="line-btw"></div>
<div
className={`step ${
activeStepIndex && activeStepIndex === 1 ? "current" : "disallowed"
}`}
>
2
</div>
</div>
{/* {error && <ErrorMessage error={error} />} */}

{/* THIS SHOULD BE COPIED */}
<Step />
{search.split("&")[1]?.split("=")[1] ? (
<>
<Typography variant="h5" sx={{ m: 1, mt: 3 }}>
{t("login.welcome")}
</Typography>
<Typography variant="p" sx={{ mb: 2 }}>
Dva koraka do HR Centra.
</Typography>
<div className="steps-cont">
<div
className={`step ${
activeStepIndex && activeStepIndex === 1
? "done"
: "current"
}`}
>
1
</div>
<div className="line-btw"></div>
<div
className={`step ${
activeStepIndex && activeStepIndex === 1
? "current"
: "disallowed"
}`}
>
2
</div>
</div>
<Step />
</>
) : (
<h3 style={{ margin: "50px 0px" }}>There was a mistake...</h3>
)}
</Box>
</Container>
</>

+ 2
- 2
src/pages/UsersPage/UserDetails.js Ver fichero

@@ -257,8 +257,8 @@ const UserDetails = ({ history }) => {
<div className="flex-center" style={{ justifyContent: "flex-start" }}>
<p style={{ width: "85px" }}>LinkedIn:</p>
<p className="text-blue">
{user?.socialMedias
? user.socialMedias
{user?.linkedIn
? user.linkedIn
: "User takes not part in any social media."}
</p>
</div>

+ 1
- 1
src/pages/UsersPage/UsersPage.js Ver fichero

@@ -239,7 +239,7 @@ const UsersPage = () => {
)}
</td>
<td>{n.email}</td>
<td className='profession'>HR Specialist</td>
<td className='profession'>{n.position}</td>
{editEnable && (
<td>
<>

+ 1
- 0
src/request/apiEndpoints.js Ver fichero

@@ -8,6 +8,7 @@ export default {
logout: base + "/authentications/logout?userId={userId}",
forgetPassword: base + "/authentications/ForgotPassword",
resetPassword: base + "/authentications/RessetPassword",
register: base + "/authentications/register",
},
users: {
allUsers: base + "/users",

+ 5
- 0
src/request/registerRequest.js Ver fichero

@@ -0,0 +1,5 @@
import { postRequest } from ".";
import apiEndpoints from "./apiEndpoints";

export const register = (payload) =>
postRequest(apiEndpoints.authentications.register, payload);

+ 3
- 0
src/store/actions/register/registerActionConstants.js Ver fichero

@@ -0,0 +1,3 @@
export const REGISTER_REQUEST = 'REGISTER_REQUEST'
export const REGISTER_SUCCESS = 'REGISTER_SUCCESS'
export const REGISTER_ERROR = 'REGISTER_ERROR'

+ 20
- 0
src/store/actions/register/registerActions.js Ver fichero

@@ -0,0 +1,20 @@
import {
REGISTER_ERROR,
REGISTER_REQUEST,
REGISTER_SUCCESS,
} from "./registerActionConstants";

export const registerRequest = (payload) => ({
type: REGISTER_REQUEST,
payload,
});

export const registerError = (payload) => ({
type: REGISTER_ERROR,
payload,
});

export const registerSuccess = (payload) => ({
type: REGISTER_SUCCESS,
payload,
});

+ 3
- 1
src/store/reducers/index.js Ver fichero

@@ -25,6 +25,7 @@ import updatePatternReducer from "./pattern/updatePatternReducer";
import statsReducer from "./stats/statsReducer";
import scheduleReducer from "./schedule/scheduleReducer";
import archiveActiveAdReducer from "./ad/archiveActiveAdReducer";
import registerReducer from "./register/registerReducer";

export default combineReducers({
login: loginReducer,
@@ -52,5 +53,6 @@ export default combineReducers({
createPattern: createPatternReducer,
updatePattern: updatePatternReducer,
stats: statsReducer,
schedule:scheduleReducer
schedule:scheduleReducer,
register: registerReducer
});

+ 32
- 0
src/store/reducers/register/registerReducer.js Ver fichero

@@ -0,0 +1,32 @@
import createReducer from "../../utils/createReducer";
import {
REGISTER_ERROR,
REGISTER_SUCCESS,
} from "../../actions/register/registerActionConstants";

const initialState = {
isSuccess: false,
errorMessage: "",
};

export default createReducer(
{
[REGISTER_SUCCESS]: setSuccess,
[REGISTER_ERROR]: setError,
},
initialState
);

function setSuccess(state) {
return {
...state,
isSuccess: true,
};
}

function setError(state, action) {
return {
...state,
errorMessage: action.payload,
};
}

+ 3
- 1
src/store/saga/index.js Ver fichero

@@ -8,6 +8,7 @@ import processesSaga from "./processSaga";
import patternsSage from "./patternsSaga";
import statsSaga from "./statsSaga";
import scheduleSaga from "./scheduleSaga";
import registerSaga from "./registerSaga";

export default function* rootSaga() {
yield all([
@@ -19,6 +20,7 @@ export default function* rootSaga() {
processesSaga(),
patternsSage(),
statsSaga(),
scheduleSaga()
scheduleSaga(),
registerSaga(),
]);
}

+ 28
- 0
src/store/saga/registerSaga.js Ver fichero

@@ -0,0 +1,28 @@
import { all, call, put, takeEvery } from "redux-saga/effects";
import { register } from "../../request/registerRequest";
import { rejectErrorCodeHelper } from "../../util/helpers/rejectErrorCodeHelper";
import { REGISTER_REQUEST } from "../actions/register/registerActionConstants";
import { registerError, registerSuccess } from "../actions/register/registerActions";

export function* registerUser({payload}) {
try {
yield call(register, payload.model);
yield put(registerSuccess());
console.log('ovde 1')
if(payload.handleApiResponseSuccess){
console.log('ovde 2')
yield call(payload.handleApiResponseSuccess)
}
} catch (error) {
if (error.response && error.response.data) {
const errorMessage = yield call(rejectErrorCodeHelper, error);
yield put(registerError(errorMessage));
}
}
}
export default function* registerSaga() {
yield all([
takeEvery(REGISTER_REQUEST, registerUser),
]);
}

+ 0
- 1
src/store/saga/statsSaga.js Ver fichero

@@ -12,7 +12,6 @@ export function* getAppStats() {
const JwtToken = yield call(authScopeStringGetHelper, JWT_TOKEN);
yield call(addHeaderToken, JwtToken);
const result = yield call(getStats);
console.log(result)
yield put(getStatsSuccess(result.data));
} catch (error) {
if (error.response && error.response.data) {

Cargando…
Cancelar
Guardar