Просмотр исходного кода

Merged with feature 633

feature/646
Djordje Mitrovic 3 лет назад
Родитель
Сommit
a4489664b2

+ 2
- 0
.gitignore Просмотреть файл

npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*

/.idea

+ 6
- 0
src/AppRoutes.js Просмотреть файл



import { import {
LOGIN_PAGE, LOGIN_PAGE,
ADMIN_LOGIN_PAGE,
HOME_PAGE, HOME_PAGE,
NOT_FOUND_PAGE, NOT_FOUND_PAGE,
ERROR_PAGE, ERROR_PAGE,
MY_OFFERS_PAGE, MY_OFFERS_PAGE,
// PRICES_PAGE, // PRICES_PAGE,
ABOUT_PAGE, ABOUT_PAGE,
ADMIN_HOME_PAGE,
// POLICY_PRIVACY_PAGE, // POLICY_PRIVACY_PAGE,
} from "./constants/pages"; } from "./constants/pages";
import LoginPage from "./pages/LoginPage/LoginPage"; import LoginPage from "./pages/LoginPage/LoginPage";
import AdminLoginPage from "./pages/AdminLoginPage/AdminLoginPage";
import HomePage from "./pages/HomePage/HomePageMUI"; 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 PricesPage from "./pages/Prices/PricesPage"; // import PricesPage from "./pages/Prices/PricesPage";
import AboutPage from "./pages/About/AboutPage"; import AboutPage from "./pages/About/AboutPage";
import AuthRoute from "./components/Router/AuthRoute"; import AuthRoute from "./components/Router/AuthRoute";
import AdminHomePage from "./pages/AdminHomePage/AdminHomePage";
// import PrivacyPolicyPage from "./pages/PrivacyPolicy/PrivacyPolicyPage"; // import PrivacyPolicyPage from "./pages/PrivacyPolicy/PrivacyPolicyPage";


const AppRoutes = () => { const AppRoutes = () => {
<Switch> <Switch>
<Route exact path={BASE_PAGE} component={HomePage} /> <Route exact path={BASE_PAGE} component={HomePage} />
<AuthRoute exact path={LOGIN_PAGE} component={LoginPage} /> <AuthRoute exact path={LOGIN_PAGE} component={LoginPage} />
<AuthRoute exact path={ADMIN_LOGIN_PAGE} component={AdminLoginPage} />
<Route path={ADMIN_HOME_PAGE} component={AdminHomePage} />
<Route path={NOT_FOUND_PAGE} component={NotFoundPage} /> <Route path={NOT_FOUND_PAGE} component={NotFoundPage} />
<Route path={ERROR_PAGE} component={ErrorPage} /> <Route path={ERROR_PAGE} component={ErrorPage} />
<AuthRoute path={REGISTER_SUCCESSFUL_PAGE} component={RegisterSuccessful} /> <AuthRoute path={REGISTER_SUCCESSFUL_PAGE} component={RegisterSuccessful} />

+ 7
- 0
src/assets/images/svg/logo-vertical-admin.svg
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 3
- 2
src/components/Login/Description/LoginDescription.js Просмотреть файл

import { LoginDescription as Description } from "./LoginDescription.styled"; import { LoginDescription as Description } from "./LoginDescription.styled";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";


const LoginDescription = () => {
const LoginDescription = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Description component="h1" variant="h6"> <Description component="h1" variant="h6">
{t("login.welcomeText")}
{props.isAdmin?t("admin.login.welcomeText"):t("login.welcomeText")}
</Description> </Description>
); );
}; };


LoginDescription.propTypes = { LoginDescription.propTypes = {
children: PropTypes.node, children: PropTypes.node,
isAdmin: PropTypes.bool
}; };


export default LoginDescription; export default LoginDescription;

+ 18
- 7
src/components/Login/Login.js Просмотреть файл

fetchLogin, fetchLogin,
} from "../../store/actions/login/loginActions"; } from "../../store/actions/login/loginActions";
import { selectLoginError } from "../../store/selectors/loginSelectors"; import { selectLoginError } from "../../store/selectors/loginSelectors";
import { HOME_PAGE } from "../../constants/pages";
import { HOME_PAGE, ADMIN_HOME_PAGE } from "../../constants/pages";
import { ReactComponent as Logo } from "../../assets/images/svg/logo-vertical.svg"; import { ReactComponent as Logo } from "../../assets/images/svg/logo-vertical.svg";
import { ReactComponent as LogoAdmin } from "../../assets/images/svg/logo-vertical-admin.svg";
import { LoginPageContainer, LoginFormContainer } from "./Login.styled"; import { LoginPageContainer, LoginFormContainer } from "./Login.styled";
import loginValidation from "../../validations/loginValidation"; import loginValidation from "../../validations/loginValidation";
import loginInitialValues from "../../initialValues/loginInitialValues"; import loginInitialValues from "../../initialValues/loginInitialValues";
import LoginButton from "./LoginButton/LoginButton"; import LoginButton from "./LoginButton/LoginButton";
import RegisterLink from "./RegisterLink/RegisterLink"; import RegisterLink from "./RegisterLink/RegisterLink";


const Login = () => {
const Login = (props) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const error = useSelector(selectLoginError); const error = useSelector(selectLoginError);
const history = useHistory(); const history = useHistory();


// Api response callback function on success // Api response callback function on success
const handleApiResponseSuccess = () => { const handleApiResponseSuccess = () => {
props.isAdmin ? history.push({
pathname: ADMIN_HOME_PAGE,
state: {
from: history.location.pathname,
},
}) :
history.push({ history.push({
pathname: HOME_PAGE, pathname: HOME_PAGE,
state: { state: {
password, password,
handleApiResponseSuccess, handleApiResponseSuccess,
handleApiResponseError, handleApiResponseError,
isAdmin: props.isAdmin
}) })
); );
} }


return ( return (
<LoginPageContainer> <LoginPageContainer>
<Logo />
<LoginTitle />
<LoginDescription />
{
props.isAdmin ? <LogoAdmin/> : <Logo/>
}
<LoginTitle isAdmin={props.isAdmin} />
<LoginDescription isAdmin={props.isAdmin}/>
<LoginFormContainer component="form" onSubmit={handleSubmitForm}> <LoginFormContainer component="form" onSubmit={handleSubmitForm}>
<EmailField formik={formik} /> <EmailField formik={formik} />
<PasswordField formik={formik} ref={passwordRef} /> <PasswordField formik={formik} ref={passwordRef} />
<ErrorMessage formik={formik} /> <ErrorMessage formik={formik} />
<ForgotPasswordLink />
{!props.isAdmin ? <ForgotPasswordLink/>:<></>}
<LoginButton formik={formik} /> <LoginButton formik={formik} />
<RegisterLink />
{!props.isAdmin ? <RegisterLink/>:<></>}
</LoginFormContainer> </LoginFormContainer>
</LoginPageContainer> </LoginPageContainer>
); );
pathname: PropTypes.string, pathname: PropTypes.string,
}), }),
}), }),
isAdmin: PropTypes.bool
}; };
export default Login; export default Login;

+ 5
- 2
src/components/Login/Title/LoginTitle.js Просмотреть файл

import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { LoginTitle as Title } from "./LoginTitle.styled"; import { LoginTitle as Title } from "./LoginTitle.styled";


const LoginTitle = () => {
const LoginTitle = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Title component="h1" variant="h5"> <Title component="h1" variant="h5">
{t("login.logInTitle")}
{
props.isAdmin ? t("admin.login.logInTitle") : t("login.logInTitle")
}
</Title> </Title>
); );
}; };


LoginTitle.propTypes = { LoginTitle.propTypes = {
children: PropTypes.node, children: PropTypes.node,
isAdmin: PropTypes.bool
}; };


export default LoginTitle; export default LoginTitle;

+ 2
- 0
src/constants/pages.js Просмотреть файл

export const BASE_PAGE = '/'; export const BASE_PAGE = '/';
export const LOGIN_PAGE = '/login'; export const LOGIN_PAGE = '/login';
export const FORGOT_PASSWORD_PAGE = '/forgot-password'; export const FORGOT_PASSWORD_PAGE = '/forgot-password';
export const ADMIN_LOGIN_PAGE = '/admin/login';
export const HOME_PAGE = '/home'; export const HOME_PAGE = '/home';
export const ERROR_PAGE = '/error-page'; export const ERROR_PAGE = '/error-page';
export const NOT_FOUND_PAGE = '/not-found'; export const NOT_FOUND_PAGE = '/not-found';
export const ABOUT_PAGE = "/about"; export const ABOUT_PAGE = "/about";
export const PRICES_PAGE = "/prices"; export const PRICES_PAGE = "/prices";
export const POLICY_PRIVACY_PAGE = "/policy"; export const POLICY_PRIVACY_PAGE = "/policy";
export const ADMIN_HOME_PAGE = "/admin/home";

+ 18
- 0
src/i18n/resources/rs.js Просмотреть файл

imagesReview: "Pregled fotografija", imagesReview: "Pregled fotografija",
offer: "Proizvod:", offer: "Proizvod:",
}, },
admin: {
login:{
welcome: "React template",
welcomeText: "Trampa sa kolegama na dohvat ruke",
emailFormat: "Nevalidan format email adrese!",
emailRequired: "Email adresa je obavezna!",
noUsers: "Ne postoji korisnik sa zadatom email adresom.",
passwordStrength: "Your password is {{strength}}.",
passwordLength: "Lozinka mora imati najmanje 8 karaktera!",
email: "Unesite email adresu kako biste se prijavili",
logInTitle: "Uloguj se",
logIn: "Uloguj se",
usernameRequired: "Username je obavezan!",
passwordRequired: "Lozinka je obavezna!",
wrongCredentials: "Pogrešan mail ili lozinka!",
headerTitle: "Ulogujte se",
}
}
}; };

+ 14
- 0
src/pages/AdminHomePage/AdminHomePage.js Просмотреть файл

import React from 'react'
import PropTypes from 'prop-types'

const AdminHomePage = () => {
return (
<div>Admin home page brateee</div>
)
}

AdminHomePage.propTypes = {
children: PropTypes.node,
}

export default AdminHomePage

+ 15
- 0
src/pages/AdminLoginPage/AdminLoginPage.js Просмотреть файл

import React from 'react'
import PropTypes from 'prop-types'
import Login from '../../components/Login/Login'

const LoginPage = () => {
return (
<Login isAdmin/>
)
}

LoginPage.propTypes = {
children: PropTypes.node,
}

export default LoginPage

+ 1
- 1
src/pages/LoginPage/LoginPage.js Просмотреть файл



const LoginPage = () => { const LoginPage = () => {
return ( return (
<Login />
<Login isAdmin={false}/>
) )
} }



+ 8
- 0
src/store/saga/loginSaga.js Просмотреть файл



function* fetchLogin({ payload }) { function* fetchLogin({ payload }) {
try { try {
const isAdmin = payload.isAdmin;
// delete payload.isAdmin
const { data } = yield call(attemptLogin, payload); const { data } = yield call(attemptLogin, payload);
if (data.token) { if (data.token) {
const token = data.token; const token = data.token;
const refresh = data.refresh; const refresh = data.refresh;
const tokenDecoded = jwt.decode(token); const tokenDecoded = jwt.decode(token);
const refreshDecoded = jwt.decode(refresh); const refreshDecoded = jwt.decode(refresh);
if(isAdmin && !tokenDecoded.roles.includes("Admin")){
throw Error("Not an admin login on /login");
}
const accessToken = { const accessToken = {
token: token, token: token,
exp: tokenDecoded.exp, exp: tokenDecoded.exp,
} }
} }
} catch (e) { } catch (e) {
if(e.message){
yield put(fetchUserError(e.message));
}
if (e.response && e.response.data) { if (e.response && e.response.data) {
if (payload.handleApiResponseError) { if (payload.handleApiResponseError) {
yield call(payload.handleApiResponseError, e.response.status); yield call(payload.handleApiResponseError, e.response.status);

+ 1
- 0
src/util/helpers/routeHelpers.js Просмотреть файл

import { import {
ADMIN_LOGIN_PAGE,
FORGOT_PASSWORD_MAIL_SENT, FORGOT_PASSWORD_MAIL_SENT,
FORGOT_PASSWORD_PAGE, FORGOT_PASSWORD_PAGE,
LOGIN_PAGE, LOGIN_PAGE,

Загрузка…
Отмена
Сохранить