Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .eslintcache
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"D:\\WEB\\pixelteh\\src\\index.js":"1","D:\\WEB\\pixelteh\\src\\App.js":"2","D:\\WEB\\pixelteh\\src\\reportWebVitals.js":"3","D:\\WEB\\pixelteh\\src\\components\\LoginContainer.js":"4","D:\\WEB\\pixelteh\\src\\components\\Login.js":"5","D:\\WEB\\pixelteh\\src\\redux\\store.js":"6","D:\\WEB\\pixelteh\\src\\redux\\reducers\\index.js":"7","D:\\WEB\\pixelteh\\src\\redux\\reducers\\authReducer.js":"8","D:\\WEB\\pixelteh\\src\\redux\\actions\\authActions.js":"9","D:\\WEB\\pixelteh\\src\\sagas\\rootSaga.js":"10","D:\\WEB\\pixelteh\\src\\sagas\\userSaga.js":"11"},{"size":750,"mtime":1608653016664,"results":"12","hashOfConfig":"13"},{"size":834,"mtime":1608720258845,"results":"14","hashOfConfig":"13"},{"size":362,"mtime":499162500000,"results":"15","hashOfConfig":"13"},{"size":1489,"mtime":1608720143345,"results":"16","hashOfConfig":"13"},{"size":3060,"mtime":1608712915791,"results":"17","hashOfConfig":"13"},{"size":385,"mtime":1608716090779,"results":"18","hashOfConfig":"13"},{"size":183,"mtime":1608630649201,"results":"19","hashOfConfig":"13"},{"size":1379,"mtime":1608717726728,"results":"20","hashOfConfig":"13"},{"size":830,"mtime":1608717726804,"results":"21","hashOfConfig":"13"},{"size":182,"mtime":1608716131851,"results":"22","hashOfConfig":"13"},{"size":799,"mtime":1608717726877,"results":"23","hashOfConfig":"13"},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},"164dkoh",{"filePath":"27","messages":"28","errorCount":0,"warningCount":1,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"29","messages":"30","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"31","messages":"32","errorCount":0,"warningCount":2,"fixableErrorCount":0,"fixableWarningCount":0,"source":"33","usedDeprecatedRules":"26"},{"filePath":"34","messages":"35","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"36","messages":"37","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"38","messages":"39","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"40","messages":"41","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"42","messages":"43","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"44","messages":"45","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},{"filePath":"46","messages":"47","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"26"},"D:\\WEB\\pixelteh\\src\\index.js",[],["48","49"],"D:\\WEB\\pixelteh\\src\\App.js",["50"],"D:\\WEB\\pixelteh\\src\\reportWebVitals.js",[],"D:\\WEB\\pixelteh\\src\\components\\LoginContainer.js",["51","52"],"import React from \"react\";\r\nimport * as Yup from 'yup';\r\nimport Login from \"./Login\";\r\nimport {useDispatch, useSelector} from \"react-redux\";\r\nimport {loginFailed, loginSuccess, setLogin} from \"../redux/actions/authActions\";\r\n\r\nconst LoginContainer = () => {\r\n\r\n const SignupSchema = Yup.object().shape({\r\n email: Yup.string()\r\n .email('Invalid email')\r\n .required('Required'),\r\n password: Yup.string()\r\n .min(8, 'Too Short!')\r\n .matches(\r\n /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[a-zA-Z\\d]{8,}$/,\r\n 'Must Contain 8 Characters, One Uppercase, One Lowercase and one Number'\r\n )\r\n .required('Required'),\r\n });\r\n\r\n const dispatch = useDispatch();\r\n\r\n const { authData, isAuth, errorMessage } = useSelector(({ auth }) => auth);\r\n\r\n const submitAuth = (authData) => { debugger\r\n dispatch(setLogin(authData));\r\n localStorage.getItem(\"user\");\r\n if (localStorage.user !== 0) {\r\n dispatch(loginSuccess());\r\n } else {\r\n dispatch(loginFailed());\r\n console.log(errorMessage);\r\n }\r\n }\r\n\r\n return (\r\n <Login initialValues={{\r\n email: \"\",\r\n password: \"\"\r\n }}\r\n submitButtonText={\"Login\"}\r\n onSubmit={submitAuth}\r\n validationSchema={SignupSchema}\r\n />\r\n )\r\n};\r\n\r\nexport default LoginContainer;","D:\\WEB\\pixelteh\\src\\components\\Login.js",[],"D:\\WEB\\pixelteh\\src\\redux\\store.js",[],"D:\\WEB\\pixelteh\\src\\redux\\reducers\\index.js",[],"D:\\WEB\\pixelteh\\src\\redux\\reducers\\authReducer.js",[],"D:\\WEB\\pixelteh\\src\\redux\\actions\\authActions.js",[],"D:\\WEB\\pixelteh\\src\\sagas\\rootSaga.js",[],"D:\\WEB\\pixelteh\\src\\sagas\\userSaga.js",[],{"ruleId":"53","replacedBy":"54"},{"ruleId":"55","replacedBy":"56"},{"ruleId":"57","severity":1,"message":"58","line":14,"column":11,"nodeType":"59","messageId":"60","endLine":14,"endColumn":23},{"ruleId":"57","severity":1,"message":"61","line":24,"column":13,"nodeType":"59","messageId":"60","endLine":24,"endColumn":21},{"ruleId":"57","severity":1,"message":"62","line":24,"column":23,"nodeType":"59","messageId":"60","endLine":24,"endColumn":29},"no-native-reassign",["63"],"no-negated-in-lhs",["64"],"no-unused-vars","'submitLogout' is assigned a value but never used.","Identifier","unusedVar","'authData' is assigned a value but never used.","'isAuth' is assigned a value but never used.","no-global-assign","no-unsafe-negation"]
[{"D:\\WEB\\pixelteh\\src\\index.js":"1","D:\\WEB\\pixelteh\\src\\App.js":"2","D:\\WEB\\pixelteh\\src\\reportWebVitals.js":"3","D:\\WEB\\pixelteh\\src\\redux\\store.js":"4","D:\\WEB\\pixelteh\\src\\components\\HomePage.js":"5","D:\\WEB\\pixelteh\\src\\components\\Routes\\PrivateRoute.js":"6","D:\\WEB\\pixelteh\\src\\components\\Login\\LoginContainer.js":"7","D:\\WEB\\pixelteh\\src\\components\\Routes\\PublicRoute.js":"8","D:\\WEB\\pixelteh\\src\\sagas\\rootSaga.js":"9","D:\\WEB\\pixelteh\\src\\redux\\reducers\\index.js":"10","D:\\WEB\\pixelteh\\src\\components\\Login\\LogoutButton.js":"11","D:\\WEB\\pixelteh\\src\\components\\Login\\useAuth.js":"12","D:\\WEB\\pixelteh\\src\\components\\Login\\Login.js":"13","D:\\WEB\\pixelteh\\src\\sagas\\userSaga.js":"14","D:\\WEB\\pixelteh\\src\\redux\\reducers\\authReducer.js":"15","D:\\WEB\\pixelteh\\src\\redux\\actions\\authActions.js":"16"},{"size":750,"mtime":1608820263391,"results":"17","hashOfConfig":"18"},{"size":1017,"mtime":1608890440427,"results":"19","hashOfConfig":"18"},{"size":362,"mtime":499162500000,"results":"20","hashOfConfig":"18"},{"size":385,"mtime":1608716090779,"results":"21","hashOfConfig":"18"},{"size":242,"mtime":1608887470844,"results":"22","hashOfConfig":"18"},{"size":545,"mtime":1608832631102,"results":"23","hashOfConfig":"18"},{"size":1167,"mtime":1608896743518,"results":"24","hashOfConfig":"18"},{"size":552,"mtime":1608832631102,"results":"25","hashOfConfig":"18"},{"size":182,"mtime":1608716131851,"results":"26","hashOfConfig":"18"},{"size":183,"mtime":1608887470844,"results":"27","hashOfConfig":"18"},{"size":285,"mtime":1608832631101,"results":"28","hashOfConfig":"18"},{"size":768,"mtime":1608889040932,"results":"29","hashOfConfig":"18"},{"size":3058,"mtime":1608897094117,"results":"30","hashOfConfig":"18"},{"size":822,"mtime":1608888416348,"results":"31","hashOfConfig":"18"},{"size":1449,"mtime":1608832631104,"results":"32","hashOfConfig":"18"},{"size":804,"mtime":1608887607116,"results":"33","hashOfConfig":"18"},{"filePath":"34","messages":"35","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},"164dkoh",{"filePath":"37","messages":"38","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"39","messages":"40","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"41","messages":"42","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"43","messages":"44","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"45","messages":"46","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"47","messages":"48","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"49","messages":"50","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"51","messages":"52","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"53","messages":"54","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"55","messages":"56","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"57","messages":"58","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"59","messages":"60","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"61","messages":"62","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"63","messages":"64","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},{"filePath":"65","messages":"66","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"36"},"D:\\WEB\\pixelteh\\src\\index.js",[],["67","68"],"D:\\WEB\\pixelteh\\src\\App.js",[],"D:\\WEB\\pixelteh\\src\\reportWebVitals.js",[],"D:\\WEB\\pixelteh\\src\\redux\\store.js",[],"D:\\WEB\\pixelteh\\src\\components\\HomePage.js",[],"D:\\WEB\\pixelteh\\src\\components\\Routes\\PrivateRoute.js",[],"D:\\WEB\\pixelteh\\src\\components\\Login\\LoginContainer.js",[],"D:\\WEB\\pixelteh\\src\\components\\Routes\\PublicRoute.js",[],"D:\\WEB\\pixelteh\\src\\sagas\\rootSaga.js",[],"D:\\WEB\\pixelteh\\src\\redux\\reducers\\index.js",[],"D:\\WEB\\pixelteh\\src\\components\\Login\\LogoutButton.js",[],"D:\\WEB\\pixelteh\\src\\components\\Login\\useAuth.js",[],"D:\\WEB\\pixelteh\\src\\components\\Login\\Login.js",[],"D:\\WEB\\pixelteh\\src\\sagas\\userSaga.js",[],"D:\\WEB\\pixelteh\\src\\redux\\reducers\\authReducer.js",[],"D:\\WEB\\pixelteh\\src\\redux\\actions\\authActions.js",[],{"ruleId":"69","replacedBy":"70"},{"ruleId":"71","replacedBy":"72"},"no-native-reassign",["73"],"no-negated-in-lhs",["74"],"no-global-assign","no-unsafe-negation"]
48 changes: 29 additions & 19 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,42 @@
import React from "react";
import LoginContainer from "./components/LoginContainer";
import {useDispatch, useSelector} from "react-redux";
import React, {useEffect} from "react";
import LoginContainer from "./components/Login/LoginContainer";
import "bootstrap/dist/css/bootstrap.min.css";
import {logoutFailed, logoutSuccess, setLogout} from "./redux/actions/authActions";
import {Switch, Redirect} from "react-router-dom";
import HomePage from "./components/HomePage";
import PrivateRoute from "./components/Routes/PrivateRoute";
import PublicRoute from "./components/Routes/PublicRoute";
import {useAuth} from "./components/Login/useAuth";

function App() {

const dispatch = useDispatch();
const {onLoginSuccess} = useAuth();

const { errorMessage } = useSelector(({ auth }) => auth);

//will be passed to the home page
const submitLogout = () => {
dispatch(setLogout());
localStorage.getItem("user");
if (localStorage.user === 0) {
dispatch(logoutSuccess());
} else {
dispatch(logoutFailed());
console.log(errorMessage);
}
};
useEffect(() => {
if (localStorage.user){
onLoginSuccess();
} // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

return (
<div className="App">
<LoginContainer />
<Switch>
<PublicRoute path="/login" component={LoginContainer} />
<PrivateRoute path="/notes" component={HomePage} />
<Redirect from='*' to="/notes"/>
</Switch>
</div>
);
}

export default App;











13 changes: 13 additions & 0 deletions src/components/HomePage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";
import LogoutButton from "./Login/LogoutButton";

function HomePage() {
return (
<>
<div>Home Page</div>
<LogoutButton />
</>
)
}

export default HomePage;
1 change: 0 additions & 1 deletion src/components/Login.js → src/components/Login/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import Row from "react-bootstrap/Row";
import Col from "react-bootstrap/Col";

const Login = ({initialValues, validationSchema, submitButtonText, onSubmit}) => {

return (
<>
<Formik
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from "react";
import * as Yup from 'yup';
import Login from "./Login";
import {useDispatch, useSelector} from "react-redux";
import {loginFailed, loginSuccess, setLogin} from "../redux/actions/authActions";
import {useAuth} from "./useAuth";
import {Redirect} from "react-router-dom";

const LoginContainer = () => {

Expand All @@ -14,24 +14,19 @@ const LoginContainer = () => {
.min(8, 'Too Short!')
.matches(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/,
'Must Contain 8 Characters, One Uppercase, One Lowercase and one Number'
'Must contain 8 Characters, 1 Uppercase, 1 Lowercase, 1 Number'
)
.required('Required'),
});

const dispatch = useDispatch();
const {onLogin, isAuth} = useAuth();

const { authData, isAuth, errorMessage } = useSelector(({ auth }) => auth);
const submitAuth = (authData) => {
onLogin(authData);
}

const submitAuth = (authData) => { debugger
dispatch(setLogin(authData));
localStorage.getItem("user");
if (localStorage.user !== 0) {
dispatch(loginSuccess());
} else {
dispatch(loginFailed());
console.log(errorMessage);
}
if (isAuth) {
return <Redirect to="/notes"/>;
}

return (
Expand Down
13 changes: 13 additions & 0 deletions src/components/Login/LogoutButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";
import {useAuth} from "./useAuth";

const LogoutButton = () => {
const {onLogout, isAuth} = useAuth();
return isAuth ? (
<button onClick={onLogout}>
Logout
</button>
) : null
}

export default LogoutButton;
22 changes: 22 additions & 0 deletions src/components/Login/useAuth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {useCallback} from "react";
import {useDispatch, useSelector} from "react-redux";
import {loginRequest, loginSuccess, logoutRequest} from "../../redux/actions/authActions";

export function useAuth() {
const dispatch = useDispatch();
const { authData, isAuth, isLoading, errorMessage } = useSelector(({ auth }) => auth);

const onLogin = useCallback((authData) => dispatch(loginRequest(authData)), [dispatch]);
const onLogout = useCallback(() => dispatch(logoutRequest()), [dispatch]);
const onLoginSuccess = useCallback(() => dispatch(loginSuccess()), [dispatch]);

return {
authData,
isAuth,
isLoading,
errorMessage,
onLogout,
onLogin,
onLoginSuccess
}
}
22 changes: 22 additions & 0 deletions src/components/Routes/PrivateRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";
import { Route, Redirect } from "react-router-dom";
import {useAuth} from "../Login/useAuth";

function PrivateRoute({ component: Component, ...rest }) {

const { isAuth } = useAuth();
return (
<Route {...rest}
render={props =>
isAuth
? (
<Component {...props} />
) : (
<Redirect to="/login" />
)
}
/>
);
}

export default PrivateRoute;
22 changes: 22 additions & 0 deletions src/components/Routes/PublicRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";
import {Route, Redirect} from "react-router-dom";
import {useAuth} from "../Login/useAuth";

function PublicRoute({component: Component, ...rest}) {

const {isAuth} = useAuth();
return (
<Route {...rest}
render={props =>
!isAuth
? (
<Component {...props} />
) : (
<Redirect to="/notes"/>
)
}
/>
);
}

export default PublicRoute;
24 changes: 22 additions & 2 deletions src/index.sass
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@ code
text-align: center
box-shadow: 0px 17px 24px 0px rgba(48, 63, 159, 0.2)

@media only screen and (max-width : 992px)
.App
min-width: 320px
min-height: 350px
margin: 100px

.row
margin: 0

.col
margin: 0
@media only screen and (max-width : 576px)
.App
margin: 0
padding: 0
height: 100%

.form
margin-top: 10%

Expand All @@ -28,15 +45,18 @@ code

&__field
margin-bottom: 25px
position: relative


&_input
width: 80%
position: relative

&__error
position: absolute
top: 30px
left: 25px
left: 15%
font-size: 11px
max-width: 320px
white-space: nowrap
overflow: hidden
text-overflow: ellipsis
27 changes: 13 additions & 14 deletions src/redux/actions/authActions.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,35 @@
export const SET_LOGIN = "SET_LOGIN";
export const SET_LOGOUT = "SET_LOGOUT";
export const LOGIN_REQUEST = "LOGIN_REQUEST";
export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
export const LOGIN_FAILED = "LOGIN_FAILED";

export const LOGOUT_REQUEST = "LOGOUT_REQUEST";
export const LOGOUT_SUCCESS = "LOGOUT_SUCCESS";
export const LOGOUT_FAILED = "LOGOUT_FAILED";

export const setLogin = (authData) => ({
type: SET_LOGIN,
export const loginRequest = (authData) => ({
type: LOGIN_REQUEST,
payload: authData,
});

export const setLogout = () => ({
type: SET_LOGOUT,
payload: null,
});

export const loginSuccess = () => ({
type: LOGIN_SUCCESS,
payload: true,
type: LOGIN_SUCCESS
});


export const loginFailed = () => ({
type: LOGIN_FAILED,
payload: "login failed"
});

export const logoutRequest = () => ({
type: LOGOUT_REQUEST
});

export const logoutSuccess = () => ({
type: LOGIN_SUCCESS,
payload: false,
type: LOGOUT_SUCCESS
});

export const logoutFailed = () => ({
type: LOGIN_FAILED,
type: LOGOUT_FAILED,
payload: "logout failed"
});
Loading