mirror of
https://github.com/usatiuk/ustk-todolist.git
synced 2025-10-28 23:57:49 +01:00
nice design
This commit is contained in:
@@ -15,7 +15,8 @@
|
||||
"allowTernary": true
|
||||
}
|
||||
],
|
||||
"max-len": "off"
|
||||
"max-len": "off",
|
||||
"react/forbid-prop-types": "off"
|
||||
},
|
||||
"env": {
|
||||
"browser": true
|
||||
|
||||
@@ -8,6 +8,7 @@ export const LOGOUT = 'LOGOUT';
|
||||
export const START_LOGIN = 'INVALIDATE_USER';
|
||||
export const REQUEST_USER = 'REQUEST_USER';
|
||||
export const VALIDATE_USER = 'VALIDATE_USER';
|
||||
export const RESET_USER = 'RESET_USER';
|
||||
|
||||
function startLogin() {
|
||||
return { type: START_LOGIN };
|
||||
@@ -72,8 +73,8 @@ function signupSuccess(user) {
|
||||
return { type: SIGNUP_SUCCESS, user };
|
||||
}
|
||||
|
||||
function signupFail(errors) {
|
||||
return { type: SIGNUP_FAIL, errors };
|
||||
function signupFail(error) {
|
||||
return { type: SIGNUP_FAIL, error };
|
||||
}
|
||||
|
||||
export function signup(user) {
|
||||
@@ -96,6 +97,10 @@ export function signup(user) {
|
||||
};
|
||||
}
|
||||
|
||||
export function reset() {
|
||||
return { type: RESET_USER };
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
localStorage.removeItem('jwt');
|
||||
return { type: LOGOUT };
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
body {
|
||||
background: white;
|
||||
color: black;
|
||||
font-family: "Trebuchet MS";
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#lists-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
|
||||
#lists {
|
||||
@@ -43,34 +37,21 @@ body {
|
||||
#listselector {
|
||||
margin-left: 0.2rem;
|
||||
align-self: center;
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
|
||||
#listselector select {
|
||||
color: black;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 500;
|
||||
font-weight: 400;
|
||||
outline: none;
|
||||
border: none;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#root {
|
||||
margin-top: 5rem;
|
||||
}
|
||||
|
||||
#container {
|
||||
overflow: hidden;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
max-width: 25rem;
|
||||
border: 1px solid #dddddd;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
|
||||
background-color: #fbfbfb;
|
||||
}
|
||||
|
||||
#inputs {
|
||||
transition: 0.4s ease-in-out;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 2px 7px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
height: 2.5rem;
|
||||
}
|
||||
@@ -78,7 +59,7 @@ body {
|
||||
#input {
|
||||
color: black;
|
||||
background: white;
|
||||
font-family: "Trebuchet MS";
|
||||
font-family: "Roboto";
|
||||
box-sizing: border-box;
|
||||
font-size: 1rem;
|
||||
flex-grow: 1;
|
||||
@@ -93,7 +74,7 @@ body {
|
||||
#add {
|
||||
color: black;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
font-weight: 500;
|
||||
flex-grow: 1;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -124,13 +105,13 @@ li button {
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
border: none;
|
||||
border-top: 1px solid #dddddd;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
background: none;
|
||||
width: 2rem;
|
||||
font-size: 1rem;
|
||||
transition: 0.4s ease-in-out;
|
||||
overflow: hidden;
|
||||
box-shadow: inset -3px 0 6px -3px rgba(0, 0, 0, 0.5);
|
||||
box-shadow: inset -3px 0 6px -3px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
li button.todo {
|
||||
@@ -169,8 +150,9 @@ li {
|
||||
word-wrap: break-word;
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
border-top: 1px solid #dddddd;
|
||||
font-weight: 500;
|
||||
padding-left: 1rem;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
font-weight: 400;
|
||||
flex-grow: 2;
|
||||
flex-shrink: 1;
|
||||
transition: 0.3s ease-in-out;
|
||||
@@ -202,34 +184,12 @@ li {
|
||||
color: #555555;
|
||||
border: none;
|
||||
background: none;
|
||||
transition: 0.3s ease-in-out;
|
||||
transition: 0.1s ease-in-out;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.filter--active {
|
||||
font-weight: 700;
|
||||
font-weight: 400;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#user-header {
|
||||
display: flex;
|
||||
height: 2rem;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
justify-content: flex-end;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.logout {
|
||||
height: 100%;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
margin: 0.2rem;
|
||||
padding: 0.2rem;
|
||||
color: #555555;
|
||||
border: none;
|
||||
background: none;
|
||||
transition: 0.3s ease-in-out;
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
@@ -3,7 +3,8 @@ import PropTypes from 'prop-types';
|
||||
import { BrowserRouter as Router, Route } from 'react-router-dom';
|
||||
|
||||
import 'normalize.css';
|
||||
import '../App.css';
|
||||
import './Container.css';
|
||||
import './App.css';
|
||||
|
||||
import TodosContainer from '../containers/TodosContainer';
|
||||
import LoginForm from '../components/user/LoginForm';
|
||||
|
||||
50
src/components/Container.css
Normal file
50
src/components/Container.css
Normal file
@@ -0,0 +1,50 @@
|
||||
@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500");
|
||||
|
||||
body {
|
||||
background: white;
|
||||
color: black;
|
||||
font-family: "Roboto";
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#root {
|
||||
margin-top: 5rem;
|
||||
}
|
||||
|
||||
#container {
|
||||
overflow: hidden;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
max-width: 25rem;
|
||||
border: 1px solid #dddddd;
|
||||
border-radius: 7px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
#user-header {
|
||||
display: flex;
|
||||
height: 2rem;
|
||||
position: relative;
|
||||
z-index: 20;
|
||||
box-shadow: 0 2px 7px rgba(0, 0, 0, 0.1);
|
||||
justify-content: flex-end;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
#user-header button {
|
||||
box-sizing: border-box;
|
||||
margin-right: 0.2rem;
|
||||
height: 100%;
|
||||
flex-grow: 0;
|
||||
flex-shrink: 1;
|
||||
color: #888888;
|
||||
border: none;
|
||||
background: none;
|
||||
transition: 0.1s ease-in-out;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
#user-header button:hover {
|
||||
color: #555555;
|
||||
}
|
||||
22
src/components/Form.css
Normal file
22
src/components/Form.css
Normal file
@@ -0,0 +1,22 @@
|
||||
#form {
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
|
||||
input {
|
||||
border: none;
|
||||
border-bottom: 1px solid #999999;
|
||||
margin-left: 1rem;
|
||||
height: 2rem;
|
||||
}
|
||||
|
||||
.error {
|
||||
margin: 1rem;
|
||||
color: red;
|
||||
}
|
||||
|
||||
form button {
|
||||
padding: 0.25rem 1rem;
|
||||
background: #f5f5f5;
|
||||
border: 1px solid #f0f0f0;
|
||||
box-shadow: 0 2px 7px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
@@ -6,17 +6,22 @@ import PropTypes from 'prop-types';
|
||||
export default function ListActions({
|
||||
addList, removeList, editList, list,
|
||||
}) {
|
||||
const editRemoveButtons = list
|
||||
? [
|
||||
<button onClick={() => removeList(list)}>
|
||||
<FontAwesomeIcon icon={faTrash} />
|
||||
</button>,
|
||||
<button onClick={() => editList(list, prompt('List name?'))}>
|
||||
<FontAwesomeIcon icon={faEdit} />
|
||||
</button>,
|
||||
]
|
||||
: null;
|
||||
return (
|
||||
<div id="listactions">
|
||||
<button onClick={() => addList(prompt('List name?'))}>
|
||||
<FontAwesomeIcon icon={faPlus} />
|
||||
</button>
|
||||
<button onClick={() => removeList(list)}>
|
||||
<FontAwesomeIcon icon={faTrash} />
|
||||
</button>
|
||||
<button onClick={() => editList(list, prompt('List name?'))}>
|
||||
<FontAwesomeIcon icon={faEdit} />
|
||||
</button>
|
||||
{editRemoveButtons}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -75,7 +75,11 @@ class Todo extends React.Component {
|
||||
);
|
||||
const buttons = this.state.editing
|
||||
? [
|
||||
<animated.button key="save" className="save" onClick={() => this.stopEdit(input.value)}>
|
||||
<animated.button
|
||||
key="save"
|
||||
className="save"
|
||||
onClick={() => this.stopEdit(input.value)}
|
||||
>
|
||||
<FontAwesomeIcon icon={faCheck} />
|
||||
</animated.button>,
|
||||
]
|
||||
@@ -87,7 +91,11 @@ class Todo extends React.Component {
|
||||
>
|
||||
<FontAwesomeIcon icon={faTrash} />
|
||||
</animated.button>,
|
||||
<animated.button key="edit" className={editClasses.join(' ')} onClick={this.startEdit}>
|
||||
<animated.button
|
||||
key="edit"
|
||||
className={editClasses.join(' ')}
|
||||
onClick={this.startEdit}
|
||||
>
|
||||
<FontAwesomeIcon icon={faEdit} />
|
||||
</animated.button>,
|
||||
];
|
||||
@@ -115,7 +123,7 @@ Todo.propTypes = {
|
||||
removeTodo: PropTypes.func.isRequired,
|
||||
toggleTodo: PropTypes.func.isRequired,
|
||||
editTodo: PropTypes.func.isRequired,
|
||||
style: PropTypes.shape({ maxHeight: PropTypes.number.isRequired }).isRequired,
|
||||
style: PropTypes.shape({ height: PropTypes.object.isRequired }).isRequired,
|
||||
};
|
||||
|
||||
export default Todo;
|
||||
|
||||
@@ -4,25 +4,30 @@ import { Transition } from 'react-spring';
|
||||
|
||||
import Todo from './Todo';
|
||||
|
||||
export default function TodosContainer(props) {
|
||||
export default function TodosContainer({
|
||||
todos,
|
||||
toggleTodo,
|
||||
removeTodo,
|
||||
editTodo,
|
||||
}) {
|
||||
return (
|
||||
<ul id="list">
|
||||
<Transition
|
||||
native
|
||||
items={props.todos}
|
||||
items={todos}
|
||||
keys={todo => todo.id}
|
||||
from={todo => ({ height: 0, borderColor: '#ffffff', opacity: 0.9 })}
|
||||
enter={todo => ({ height: 60, borderColor: '#dddddd', opacity: 1 })}
|
||||
leave={todo => ({ height: 0, borderColor: '#ffffff', opacity: 0.5 })}
|
||||
from={{ height: 0, borderColor: '#f0f0f0', opacity: 0.9 }}
|
||||
enter={{ height: 60, borderColor: '#f0f0f0', opacity: 1 }}
|
||||
leave={{ height: 0, borderColor: '#ffffff', opacity: 0.5 }}
|
||||
>
|
||||
{props.todos.map(todo => styles => (
|
||||
{todos.map(todo => styles => (
|
||||
<Todo
|
||||
key={todo.id}
|
||||
todo={todo}
|
||||
style={styles}
|
||||
toggleTodo={() => props.toggleTodo(todo.id)}
|
||||
removeTodo={() => props.removeTodo(todo.id)}
|
||||
editTodo={text => props.editTodo(todo.id, text)}
|
||||
toggleTodo={() => toggleTodo(todo.id)}
|
||||
removeTodo={() => removeTodo(todo.id)}
|
||||
editTodo={text => editTodo(todo.id, text)}
|
||||
/>
|
||||
))}
|
||||
</Transition>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Redirect } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import InputContainer from '../containers/InputContainer';
|
||||
import TodoListContainer from '../containers/TodoListContainer';
|
||||
@@ -22,3 +22,9 @@ export default function Todos({ user, loadLists, history }) {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Todos.propTypes = {
|
||||
loadLists: PropTypes.func.isRequired,
|
||||
history: PropTypes.object.isRequired,
|
||||
user: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
30
src/components/user/InputField.js
Normal file
30
src/components/user/InputField.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default function InputField({
|
||||
required,
|
||||
input,
|
||||
label,
|
||||
meta: { touched, error },
|
||||
type,
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<label htmlFor={input.name}>
|
||||
{label} <input required={required} {...input} type={type} />
|
||||
</label>
|
||||
{touched && error && <span className="error">{error}</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
InputField.propTypes = {
|
||||
required: PropTypes.bool.isRequired,
|
||||
input: PropTypes.any.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
meta: PropTypes.shape({
|
||||
touched: PropTypes.bool,
|
||||
error: PropTypes.string,
|
||||
}).isRequired,
|
||||
type: PropTypes.string.isRequired,
|
||||
};
|
||||
@@ -2,62 +2,70 @@ import React from 'react';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import InputField from './InputField';
|
||||
|
||||
import { login } from '../../actions/user';
|
||||
import '../Form.css';
|
||||
|
||||
function validate(values) {
|
||||
const errors = {};
|
||||
if (values.username === '') {
|
||||
errors.username = 'should have username';
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
const InputField = ({
|
||||
input, label, meta: { touched, error }, type,
|
||||
}) => (
|
||||
<div>
|
||||
<label htmlFor={input.name}>
|
||||
{label} <input {...input} type={type} />
|
||||
</label>
|
||||
{touched && error && <span className="error">{error}</span>}
|
||||
</div>
|
||||
);
|
||||
import { login, reset } from '../../actions/user';
|
||||
|
||||
function LoginForm({
|
||||
handleSubmit, login, user, history,
|
||||
handleSubmit, onLogin, user, history, resetUser,
|
||||
}) {
|
||||
let errors;
|
||||
if (user.errors) {
|
||||
if (user.errors.name === 'AuthenticationError') {
|
||||
errors = <div>Wrong username or password</div>;
|
||||
errors = <div className="error">Wrong username or password</div>;
|
||||
}
|
||||
}
|
||||
if (user.user) {
|
||||
history.push('/');
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="login--form">
|
||||
{errors}
|
||||
<form onSubmit={handleSubmit(login)}>
|
||||
<Field
|
||||
label="username"
|
||||
name="username"
|
||||
component={InputField}
|
||||
type="text"
|
||||
/>
|
||||
<Field
|
||||
label="password"
|
||||
name="password"
|
||||
component={InputField}
|
||||
type="password"
|
||||
/>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
<div>
|
||||
<div id="user-header">
|
||||
<button
|
||||
onClick={() => {
|
||||
resetUser();
|
||||
history.push('/signup');
|
||||
}}
|
||||
>
|
||||
signup
|
||||
</button>
|
||||
</div>
|
||||
<div id="form">
|
||||
{errors}
|
||||
<form onSubmit={handleSubmit(onLogin)}>
|
||||
<Field
|
||||
label="username"
|
||||
name="username"
|
||||
required
|
||||
component={InputField}
|
||||
type="text"
|
||||
/>
|
||||
<Field
|
||||
label="password"
|
||||
name="password"
|
||||
required
|
||||
component={InputField}
|
||||
type="password"
|
||||
/>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
LoginForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
onLogin: PropTypes.func.isRequired,
|
||||
user: PropTypes.object.isRequired,
|
||||
history: PropTypes.any.isRequired,
|
||||
resetUser: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
user: state.user,
|
||||
@@ -66,7 +74,9 @@ function mapStateToProps(state) {
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
login: ({ username, password }) => dispatch(login({ username, password })),
|
||||
resetUser: () => dispatch(reset()),
|
||||
onLogin: ({ username, password }) =>
|
||||
dispatch(login({ username, password })),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -76,5 +86,4 @@ export default reduxForm({
|
||||
username: '',
|
||||
password: '',
|
||||
},
|
||||
validate,
|
||||
})(withRouter(connect(mapStateToProps, mapDispatchToProps)(LoginForm)));
|
||||
|
||||
@@ -2,71 +2,92 @@ import React from 'react';
|
||||
import { Field, reduxForm } from 'redux-form';
|
||||
import { connect } from 'react-redux';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import { signup } from '../../actions/user';
|
||||
import InputField from './InputField';
|
||||
|
||||
import '../Form.css';
|
||||
|
||||
import { signup, reset } from '../../actions/user';
|
||||
|
||||
function validate(values) {
|
||||
const errors = {};
|
||||
if (values.username === '') {
|
||||
errors.username = 'should have username';
|
||||
}
|
||||
if (values.password !== values.passwordRepeat) {
|
||||
errors.passwordRepeat = 'Invalid';
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
const InputField = ({
|
||||
input, label, meta: { touched, error }, type,
|
||||
}) => (
|
||||
<div>
|
||||
<label htmlFor={input.name}>
|
||||
{label} <input {...input} type={type} />
|
||||
</label>
|
||||
{touched && error && <span className="error">{error}</span>}
|
||||
</div>
|
||||
);
|
||||
|
||||
function SignupForm({
|
||||
handleSubmit, signup, user, history,
|
||||
handleSubmit, onSignup, user, history, resetUser,
|
||||
}) {
|
||||
let errors;
|
||||
if (user.errors) {
|
||||
if (user.errors.name === 'AuthenticationError') {
|
||||
errors = <div>Wrong username or password</div>;
|
||||
errors = <div className="error">Wrong username or password</div>;
|
||||
}
|
||||
if (user.errors.name === 'ValidationError') {
|
||||
if (user.errors.message.split(' ').includes('unique.')) {
|
||||
errors = <div className="error">User already exists</div>;
|
||||
} else {
|
||||
errors = <div className="error">Validation error</div>;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (user.user) {
|
||||
history.push('/');
|
||||
}
|
||||
return (
|
||||
<div id="signup--form">
|
||||
{errors}
|
||||
<form onSubmit={handleSubmit(signup)}>
|
||||
<Field
|
||||
label="username"
|
||||
name="username"
|
||||
component={InputField}
|
||||
type="text"
|
||||
/>
|
||||
<Field
|
||||
label="password"
|
||||
name="password"
|
||||
component={InputField}
|
||||
type="password"
|
||||
/>
|
||||
<Field
|
||||
label="repeat pasword"
|
||||
name="passwordRepeat"
|
||||
component={InputField}
|
||||
type="password"
|
||||
/>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
<div>
|
||||
<div id="user-header">
|
||||
<button
|
||||
onClick={() => {
|
||||
resetUser();
|
||||
history.push('/login');
|
||||
}}
|
||||
>
|
||||
login
|
||||
</button>
|
||||
</div>
|
||||
<div id="form">
|
||||
{errors}
|
||||
<form onSubmit={handleSubmit(onSignup)}>
|
||||
<Field
|
||||
label="username"
|
||||
name="username"
|
||||
required
|
||||
component={InputField}
|
||||
type="text"
|
||||
/>
|
||||
<Field
|
||||
label="password"
|
||||
name="password"
|
||||
required
|
||||
component={InputField}
|
||||
type="password"
|
||||
/>
|
||||
<Field
|
||||
label="repeat pasword"
|
||||
name="passwordRepeat"
|
||||
required
|
||||
component={InputField}
|
||||
type="password"
|
||||
/>
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
SignupForm.propTypes = {
|
||||
handleSubmit: PropTypes.func.isRequired,
|
||||
onSignup: PropTypes.func.isRequired,
|
||||
user: PropTypes.object.isRequired,
|
||||
history: PropTypes.any.isRequired,
|
||||
resetUser: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
user: state.user,
|
||||
@@ -75,7 +96,8 @@ function mapStateToProps(state) {
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
signup: ({ username, password }) =>
|
||||
resetUser: () => dispatch(reset()),
|
||||
onSignup: ({ username, password }) =>
|
||||
dispatch(signup({ username, password })),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
SIGNUP_FAIL,
|
||||
SIGNUP_SUCCESS,
|
||||
VALIDATE_USER,
|
||||
RESET_USER,
|
||||
} from '../actions/user';
|
||||
|
||||
export default function user(
|
||||
@@ -33,6 +34,7 @@ export default function user(
|
||||
return {
|
||||
...state,
|
||||
user: action.user,
|
||||
errors: null,
|
||||
dirty: false,
|
||||
fetching: false,
|
||||
};
|
||||
@@ -40,10 +42,18 @@ export default function user(
|
||||
case LOGIN_FAIL:
|
||||
return {
|
||||
...state,
|
||||
user: null,
|
||||
errors: action.error,
|
||||
dirty: false,
|
||||
fetching: false,
|
||||
};
|
||||
case RESET_USER:
|
||||
return {
|
||||
...state,
|
||||
fetching: false,
|
||||
user: null,
|
||||
errors: null,
|
||||
};
|
||||
case LOGOUT:
|
||||
return {
|
||||
...state,
|
||||
|
||||
Reference in New Issue
Block a user