| npm-debug.log* | npm-debug.log* | ||||
| yarn-debug.log* | yarn-debug.log* | ||||
| yarn-error.log* | yarn-error.log* | ||||
| /.idea |
| 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} /> |
| 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; |
| 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; |
| 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; |
| 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"; |
| 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", | |||||
| } | |||||
| } | |||||
| }; | }; |
| 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 |
| 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 |
| const LoginPage = () => { | const LoginPage = () => { | ||||
| return ( | return ( | ||||
| <Login /> | |||||
| <Login isAdmin={false}/> | |||||
| ) | ) | ||||
| } | } | ||||
| 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); |
| import { | import { | ||||
| ADMIN_LOGIN_PAGE, | |||||
| FORGOT_PASSWORD_MAIL_SENT, | FORGOT_PASSWORD_MAIL_SENT, | ||||
| FORGOT_PASSWORD_PAGE, | FORGOT_PASSWORD_PAGE, | ||||
| LOGIN_PAGE, | LOGIN_PAGE, |