Entony 6 vuotta sitten
vanhempi
commit
c2548c01e2

+ 34 - 0
src/Reducers/auth.js

@@ -0,0 +1,34 @@
+import * as types from "../constants/actionTypes";
+
+const initState = {
+	user: null,
+	isFetching: false,
+	error: null
+};
+
+export default (state = initState, { type, payload }) => {
+	switch (type) {
+		case types.AUTH: {
+			return {
+				...state,
+				isFetching: true
+			};
+		}
+		case types.AUTH_SUCCESS: {
+			console.log("AUTH_SUCCESS", payload);
+			return {
+				...state,
+				isFetching: false
+			};
+		}
+		case types.AUTH_FAIL: {
+			return {
+				...state,
+				isFetching: false
+			};
+		}
+
+		default:
+			return state;
+	}
+};

+ 3 - 1
src/Reducers/index.js

@@ -3,9 +3,11 @@ import { reducer as formReducer } from "redux-form";
 
 import todo from "./todo";
 import weather from "./weather";
+import auth from "./auth";
 
 export default combineReducers({
 	form: formReducer,
 	todo,
-	w: weather
+	w: weather,
+	auth
 });

+ 16 - 0
src/actions/auth.js

@@ -0,0 +1,16 @@
+import * as types from "../constants/actionTypes";
+
+export const auth = payload => ({
+	type: types.AUTH,
+	payload
+});
+
+export const authSuccess = payload => ({
+	type: types.AUTH_SUCCESS,
+	payload
+});
+
+export const authFail = payload => ({
+	type: types.AUTH_FAIL,
+	payload
+});

+ 32 - 0
src/components/auth-form/index.js

@@ -0,0 +1,32 @@
+import React, { Component } from "react";
+import { reduxForm, Field } from "redux-form";
+import PropTypes from "prop-types";
+
+import { renderField } from "../common/formFunc";
+import { authValidate } from "../../utils/validate";
+
+class Form extends Component {
+	static contextTypes = {
+		auth: PropTypes.func
+	};
+
+	submit = values => {
+		const { auth } = this.context;
+		auth(values);
+	};
+
+	render() {
+		const { handleSubmit } = this.props;
+		return (
+			<form className="auth__form" onSubmit={handleSubmit(this.submit)}>
+				<Field name="email" type="email" label="E-mail" component={renderField} />
+
+				<Field name="password" type="password" label="Password" component={renderField} />
+
+				<button className="auth__submit-button">Submit</button>
+			</form>
+		);
+	}
+}
+
+export default reduxForm({ form: "authForm", validate: authValidate })(Form);

+ 9 - 0
src/components/auth-page/index.js

@@ -0,0 +1,9 @@
+import React from "react";
+
+import Form from "../auth-form";
+
+export default props => (
+	<div className="auth__form-wrapper">
+		<Form />
+	</div>
+);

+ 11 - 0
src/components/common/formFunc.js

@@ -0,0 +1,11 @@
+import React from "react";
+
+export const renderField = ({ input, meta: { touched, error }, label, type }) => (
+	<div className="form__input-box">
+		<label className="form__input-lable" htmlFor="origin">
+			{label}
+			<input type={type} {...input} />
+		</label>
+		{touched && error && <span>{error}</span>}
+	</div>
+);

+ 1 - 9
src/components/loadForm/index.js

@@ -2,15 +2,7 @@ import React, { Component } from "react";
 import { connect } from "react-redux";
 import { reduxForm, Field, FieldArray } from "redux-form";
 
-const renderField = ({ input, meta: { touched, error }, label, type }) => (
-	<div className="form__input-box">
-		<label className="form__input-lable" htmlFor="origin">
-			{label}
-			<input type={type} {...input} />
-		</label>
-		{touched && error && <span>{error}</span>}
-	</div>
-);
+import { renderField } from "../common/formFunc";
 
 const ololo = values => {
 	const { origin, destination } = values;

+ 9 - 0
src/constants/actionTypes.js

@@ -20,3 +20,12 @@ export const POST_LOADS_FAIL = "POST_LOADS_FAIL";
 export const EDIT_LOADS_REQUEST = "EDIT_LOADS_REQUEST";
 export const EDIT_LOADS_REQUEST_SUCCESS = "EDIT_LOADS_REQUEST_SUCCESS";
 export const EDIT_LOADS_REQUEST_FAIL = "EDIT_LOADS_REQUEST_FAIL";
+
+export const AUTH = "AUTH";
+export const AUTH_SUCCESS = "AUTH_SUCCESS";
+export const AUTH_FAIL = "AUTH_FAIL";
+
+export const USER = {
+	email: "test@test.com",
+	password: "qwerty"
+};

+ 40 - 0
src/container/Auth.js

@@ -0,0 +1,40 @@
+import React, { Component } from "react";
+import PropTypes from "prop-types";
+import { bindActionCreators } from "redux";
+import { connect } from "react-redux";
+
+import * as actions from "../actions/auth";
+import SomeDirt from "../components/auth-page";
+
+class Auth extends Component {
+	static childContextTypes = {
+		auth: PropTypes.func
+	};
+
+	getChildContext() {
+		const { auth } = this.props;
+		return {
+			auth
+		};
+	}
+
+	render() {
+		console.log("this", this);
+		return (
+			<div className="auth">
+				<SomeDirt />
+			</div>
+		);
+	}
+}
+
+const mapStateToProps = state => ({
+	authForm: state.form.authForm
+});
+
+const mapDispatchToProps = dispatch => bindActionCreators({ ...actions }, dispatch);
+
+export default connect(
+	mapStateToProps,
+	mapDispatchToProps
+)(Auth);

+ 18 - 0
src/privateRouter.js

@@ -0,0 +1,18 @@
+import React from "react";
+import { Route, Redirect } from "react-router-dom";
+
+const PrivateRoute = ({ component: Component, ...rest }) => (
+	<Route
+		{...rest}
+		render={props => {
+			const user = JSON.parse(localStorage.getItem("user"));
+			if (!user) {
+				return <Redirect to="/auth" />;
+			} else {
+				return <Component {...props} />;
+			}
+		}}
+	/>
+);
+
+export default PrivateRoute;

+ 5 - 1
src/router.js

@@ -2,14 +2,18 @@ import React from "react";
 import { Switch, Route } from "react-router-dom";
 import App from "./container/App";
 import FetchPage from "./container/fetchPage";
+import Auth from "./container/Auth";
 
 import Header from "./components/header";
 
+import PrivateRoute from "./privateRouter";
+
 export default () => (
 	<div className="container">
 		<Header />
 		<Switch>
-			<Route path="/" exact component={App} />
+			<PrivateRoute path="/" exact component={App} />
+			<Route path="/auth" render={props => <Auth name="Tony" {...props} />} />
 			<Route exact path="/fetch" component={FetchPage} />
 		</Switch>
 	</div>

+ 21 - 0
src/saga/auth/auth.js

@@ -0,0 +1,21 @@
+import { delay } from "redux-saga";
+import { call, put } from "redux-saga/effects";
+import * as actions from "../../actions/auth";
+import { USER } from "../../constants/actionTypes";
+
+import comprassion from "../../utils/comrassion";
+
+export default function* auth({ payload }) {
+	try {
+		const res = yield call(comprassion, payload, USER);
+
+		if (res) {
+			localStorage.setItem("user", JSON.stringify(payload));
+		}
+
+		yield call(delay, 5000);
+		yield put(actions.authSuccess(res));
+	} catch (e) {
+		yield put(actions.authFail(e.response));
+	}
+}

+ 10 - 0
src/saga/auth/index.js

@@ -0,0 +1,10 @@
+import { takeEvery } from "redux-saga/effects";
+import * as Types from "../../constants/actionTypes";
+
+import auth from "./auth";
+
+function* authRequest() {
+	yield takeEvery(Types.AUTH, auth);
+}
+
+export default authRequest;

+ 2 - 0
src/saga/index.js

@@ -1,7 +1,9 @@
 import { fork } from "redux-saga/effects";
 
 import loads from "./loads";
+import authRequest from "./auth";
 
 export default function*() {
 	yield fork(loads);
+	yield fork(authRequest);
 }

+ 2 - 0
src/style/index.scss

@@ -11,3 +11,5 @@
 @import "components/list";
 @import "components/header";
 @import "components/form";
+
+@import "page/auth";

+ 30 - 0
src/style/page/_auth.scss

@@ -0,0 +1,30 @@
+.auth {
+	margin: 0 auto;
+	margin-top: 10rem;
+	width: 40%;
+
+	background-color: $color-white;
+	border-radius: 3px;
+
+	&__form-wrapper {
+		padding: 2rem;
+	}
+
+	&__form {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	&__submit-button {
+		padding: 0 2rem;
+		background-color: $color-blue;
+		color: $color-white;
+		border-radius: 3px;
+
+		&:focus {
+			outline: 0;
+		}
+	}
+}

+ 6 - 0
src/utils/comrassion.js

@@ -0,0 +1,6 @@
+export default (values, trueValues) => {
+	const result = Object.keys(values)
+		.map(el => (values[el] === trueValues[el] ? true : false))
+		.filter(el => !el);
+	return result.length === 0 ? true : false;
+};

+ 14 - 0
src/utils/validate.js

@@ -0,0 +1,14 @@
+export const authValidate = values => {
+	const { email, password } = values;
+	const error = {};
+
+	if (!email) {
+		error.email = "Required";
+	}
+
+	if (!password) {
+		error.password = "Required";
+	}
+
+	return error;
+};