Use redux hooks on user components

This commit is contained in:
Grégoire Delattre 2020-04-03 00:44:45 +02:00
parent ac0d746cc9
commit 27f0b742a4
7 changed files with 98 additions and 164 deletions

View File

@ -1,19 +1,18 @@
import React from "react"; import React from "react";
import PropTypes from "prop-types"; import { useSelector } from "react-redux";
import { connect } from "react-redux";
import { Redirect, Link } from "react-router-dom"; import { Redirect, Link } from "react-router-dom";
const mapStateToProps = (state) => ({ const UserActivation = () => {
isActivated: state.userStore.get("isActivated"), const isLogged = useSelector((state) => state.userStore.get("isLogged"));
isLogged: state.userStore.get("isLogged"), const isActivated = useSelector((state) =>
}); state.userStore.get("isActivated")
);
const UserActivation = (props) => { if (!isLogged) {
if (!props.isLogged) {
return <Redirect to="/users/login" />; return <Redirect to="/users/login" />;
} }
if (props.isActivated) { if (isActivated) {
return <Redirect to="/" />; return <Redirect to="/" />;
} }
@ -31,9 +30,4 @@ const UserActivation = (props) => {
</div> </div>
); );
}; };
UserActivation.propTypes = { export default UserActivation;
isActivated: PropTypes.bool.isRequired,
isLogged: PropTypes.bool.isRequired,
};
export default connect(mapStateToProps)(UserActivation);

View File

@ -1,44 +1,30 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import PropTypes from "prop-types"; import { useDispatch, useSelector } from "react-redux";
import { connect } from "react-redux";
import Loader from "../loader/loader"; import Loader from "../loader/loader";
import { List } from "immutable";
import { getUserInfos, updateUser } from "../../actions/users"; import { getUserInfos, updateUser } from "../../actions/users";
import { getPolochons } from "../../actions/polochon"; import { getPolochons } from "../../actions/polochon";
import { PolochonSelect } from "../polochons/select"; import { PolochonSelect } from "../polochons/select";
const mapStateToProps = (state) => ({ export const UserEdit = () => {
loading: state.userStore.get("loading"), const dispatch = useDispatch();
publicPolochons: state.polochon.get("public"),
polochonId: state.userStore.get("polochonId"),
polochonActivated: state.userStore.get("polochonActivated"),
});
const mapDispatchToProps = {
updateUser,
getPolochons,
getUserInfos,
};
const UserEditConnect = ({
loading,
polochonId,
polochonActivated,
updateUser,
getPolochons,
getUserInfos,
publicPolochons,
}) => {
const [id, setId] = useState(polochonId); const [id, setId] = useState(polochonId);
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [passwordConfirm, setPasswordConfirm] = useState(""); const [passwordConfirm, setPasswordConfirm] = useState("");
const loading = useSelector((state) => state.userStore.get("loading"));
const publicPolochons = useSelector((state) => state.polochon.get("public"));
const polochonId = useSelector((state) => state.userStore.get("polochonId"));
const polochonActivated = useSelector((state) =>
state.userStore.get("polochonActivated")
);
useEffect(() => { useEffect(() => {
getPolochons(); dispatch(getPolochons());
getUserInfos(); dispatch(getUserInfos());
}, [getPolochons, getUserInfos]); }, [dispatch]);
useEffect(() => { useEffect(() => {
setId(polochonId); setId(polochonId);
@ -46,11 +32,13 @@ const UserEditConnect = ({
const handleSubmit = (ev) => { const handleSubmit = (ev) => {
ev.preventDefault(); ev.preventDefault();
dispatch(
updateUser({ updateUser({
password: password, password: password,
password_confirm: passwordConfirm, // eslint-disable-line camelcase password_confirm: passwordConfirm, // eslint-disable-line camelcase
polochon_id: id, // eslint-disable-line camelcase polochon_id: id, // eslint-disable-line camelcase
}); })
);
}; };
if (loading) { if (loading) {
@ -115,17 +103,3 @@ const UserEditConnect = ({
</div> </div>
); );
}; };
UserEditConnect.propTypes = {
loading: PropTypes.bool.isRequired,
polochonId: PropTypes.string,
polochonActivated: PropTypes.bool,
updateUser: PropTypes.func,
getPolochons: PropTypes.func,
getUserInfos: PropTypes.func,
publicPolochons: PropTypes.instanceOf(List),
};
export const UserEdit = connect(
mapStateToProps,
mapDispatchToProps
)(UserEditConnect);

View File

@ -1,29 +1,28 @@
import React, { useState } from "react"; import React, { useState } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { connect } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { Redirect, Link } from "react-router-dom"; import { Redirect, Link } from "react-router-dom";
import { loginUser } from "../../actions/users"; import { loginUser } from "../../actions/users";
const mapStateToProps = (state) => ({ const UserLoginForm = () => {
isLogged: state.userStore.get("isLogged"), const dispatch = useDispatch();
isLoading: state.userStore.get("loading"),
error: state.userStore.get("error"), const isLogged = useSelector((state) => state.userStore.get("isLogged"));
}); const isLoading = useSelector((state) => state.userStore.get("loading"));
const mapDispatchToProps = { loginUser }; const error = useSelector((state) => state.userStore.get("error"));
const UserLoginForm = (props) => {
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const handleSubmit = (e) => { const handleSubmit = (e) => {
e.preventDefault(); e.preventDefault();
if (!props.isLoading) { if (!isLoading) {
props.loginUser(username, password); dispatch(loginUser(username, password));
} }
}; };
if (props.isLogged) { if (isLogged) {
return <Redirect to="/" />; return <Redirect to="/" />;
} }
@ -32,8 +31,8 @@ const UserLoginForm = (props) => {
<div className="col-10 offset-1 col-md-6 offset-md-3"> <div className="col-10 offset-1 col-md-6 offset-md-3">
<h2>Log in</h2> <h2>Log in</h2>
<hr /> <hr />
{props.error && props.error !== "" && ( {error && error !== "" && (
<div className="alert alert-danger">{props.error}</div> <div className="alert alert-danger">{error}</div>
)} )}
<form className="form-horizontal" onSubmit={(e) => handleSubmit(e)}> <form className="form-horizontal" onSubmit={(e) => handleSubmit(e)}>
<div> <div>
@ -66,12 +65,12 @@ const UserLoginForm = (props) => {
No account yet ? <Link to="/users/signup">Create one</Link> No account yet ? <Link to="/users/signup">Create one</Link>
</small> </small>
</span> </span>
{props.isLoading && ( {isLoading && (
<button className="btn btn-primary pull-right"> <button className="btn btn-primary pull-right">
<i className="fa fa-spinner fa-spin"></i> <i className="fa fa-spinner fa-spin"></i>
</button> </button>
)} )}
{props.isLoading || ( {isLoading || (
<span className="spaced-icons"> <span className="spaced-icons">
<input <input
className="btn btn-primary pull-right" className="btn btn-primary pull-right"
@ -87,11 +86,5 @@ const UserLoginForm = (props) => {
</div> </div>
); );
}; };
UserLoginForm.propTypes = {
loginUser: PropTypes.func.isRequired,
isLoading: PropTypes.bool.isRequired,
isLogged: PropTypes.bool.isRequired,
error: PropTypes.string,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserLoginForm); export default UserLoginForm;

View File

@ -1,26 +1,18 @@
import React from "react"; import React from "react";
import PropTypes from "prop-types"; import { useDispatch, useSelector } from "react-redux";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom"; import { Redirect } from "react-router-dom";
import { userLogout } from "../../actions/users"; import { userLogout } from "../../actions/users";
const mapStateToProps = (state) => ({ const UserLogout = () => {
isLogged: state.userStore.get("isLogged"), const dispatch = useDispatch();
}); const isLogged = useSelector((state) => state.userStore.get("isLogged"));
const mapDispatchToProps = { userLogout };
const UserLogout = (props) => { if (isLogged) {
if (props.isLogged) { dispatch(userLogout());
props.userLogout();
} }
return <Redirect to="/users/login" />; return <Redirect to="/users/login" />;
}; };
UserLogout.propTypes = {
isLogged: PropTypes.bool.isRequired,
userLogout: PropTypes.func.isRequired,
history: PropTypes.object,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserLogout); export default UserLogout;

View File

@ -1,7 +1,5 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import PropTypes from "prop-types"; import { useDispatch, useSelector } from "react-redux";
import { connect } from "react-redux";
import { Map } from "immutable";
import { PolochonList } from "../polochons/list"; import { PolochonList } from "../polochons/list";
import { UserEdit } from "./edit"; import { UserEdit } from "./edit";
@ -9,17 +7,16 @@ import { UserEdit } from "./edit";
import { getUserModules } from "../../actions/users"; import { getUserModules } from "../../actions/users";
import Modules from "../modules/modules"; import Modules from "../modules/modules";
const mapStateToProps = (state) => ({ const UserProfile = () => {
modules: state.userStore.get("modules"), const dispatch = useDispatch();
modulesLoading: state.userStore.get("modulesLoading"), const modules = useSelector((state) => state.userStore.get("modules"));
}); const modulesLoading = useSelector((state) =>
state.userStore.get("modulesLoading")
);
const mapDispatchToProps = { getUserModules };
const UserProfile = ({ modules, modulesLoading, getUserModules }) => {
useEffect(() => { useEffect(() => {
getUserModules(); dispatch(getUserModules());
}, [getUserModules]); }, [dispatch]);
return ( return (
<div> <div>
@ -29,10 +26,5 @@ const UserProfile = ({ modules, modulesLoading, getUserModules }) => {
</div> </div>
); );
}; };
UserProfile.propTypes = {
getUserModules: PropTypes.func.isRequired,
modules: PropTypes.instanceOf(Map),
modulesLoading: PropTypes.bool.isRequired,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserProfile); export default UserProfile;

View File

@ -1,33 +1,33 @@
import React, { useState } from "react"; import React, { useState } from "react";
import PropTypes from "prop-types"; import { useDispatch, useSelector } from "react-redux";
import { connect } from "react-redux";
import { Redirect } from "react-router-dom"; import { Redirect } from "react-router-dom";
import { userSignUp } from "../../actions/users"; import { userSignUp } from "../../actions/users";
const mapStateToProps = (state) => ({ const UserSignUp = () => {
isLogged: state.userStore.get("isLogged"), const dispatch = useDispatch();
isLoading: state.userStore.get("loading"),
error: state.userStore.get("error"),
});
const mapDispatchToProps = { userSignUp };
const UserSignUp = (props) => {
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [passwordConfirm, setPasswordConfirm] = useState(""); const [passwordConfirm, setPasswordConfirm] = useState("");
if (props.isLogged) { const isLogged = useSelector((state) => state.userStore.get("isLogged"));
const isLoading = useSelector((state) => state.userStore.get("loading"));
const error = useSelector((state) => state.userStore.get("error"));
if (isLogged) {
return <Redirect to="/" />; return <Redirect to="/" />;
} }
const handleSubmit = (e) => { const handleSubmit = (e) => {
e.preventDefault(); e.preventDefault();
props.userSignUp({ dispatch(
userSignUp({
username: username, username: username,
password: password, password: password,
password_confirm: passwordConfirm, // eslint-disable-line camelcase password_confirm: passwordConfirm, // eslint-disable-line camelcase
}); })
);
}; };
return ( return (
@ -35,8 +35,8 @@ const UserSignUp = (props) => {
<div className="col-10 offset-1 col-md-6 offset-md-3"> <div className="col-10 offset-1 col-md-6 offset-md-3">
<h2>Sign up</h2> <h2>Sign up</h2>
<hr /> <hr />
{props.error && props.error !== "" && ( {error && error !== "" && (
<div className="alert alert-danger">{props.error}</div> <div className="alert alert-danger">{error}</div>
)} )}
<form className="form-horizontal" onSubmit={(e) => handleSubmit(e)}> <form className="form-horizontal" onSubmit={(e) => handleSubmit(e)}>
@ -70,12 +70,12 @@ const UserSignUp = (props) => {
/> />
</div> </div>
<div> <div>
{props.isLoading && ( {isLoading && (
<button className="btn btn-primary pull-right"> <button className="btn btn-primary pull-right">
<i className="fa fa-spinner fa-spin"></i> <i className="fa fa-spinner fa-spin"></i>
</button> </button>
)} )}
{props.isLoading || ( {isLoading || (
<span> <span>
<input <input
className="btn btn-primary pull-right" className="btn btn-primary pull-right"
@ -90,11 +90,5 @@ const UserSignUp = (props) => {
</div> </div>
); );
}; };
UserSignUp.propTypes = {
isLogged: PropTypes.bool.isRequired,
isLoading: PropTypes.bool.isRequired,
userSignUp: PropTypes.func.isRequired,
error: PropTypes.string,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserSignUp); export default UserSignUp;

View File

@ -1,40 +1,35 @@
import React, { useState } from "react"; import React, { useEffect } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { connect } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { UAParser } from "ua-parser-js"; import { UAParser } from "ua-parser-js";
import moment from "moment"; import moment from "moment";
import { Map, List } from "immutable"; import { Map } from "immutable";
import { getUserTokens, deleteUserToken } from "../../actions/users"; import { getUserTokens, deleteUserToken } from "../../actions/users";
const mapStateToProps = (state) => ({ const UserTokens = () => {
tokens: state.userStore.get("tokens"), const dispatch = useDispatch();
});
const mapDispatchToProps = { getUserTokens, deleteUserToken };
const UserTokens = (props) => { const tokens = useSelector((state) => state.userStore.get("tokens"));
const [fetched, setIsFetched] = useState(false);
if (!fetched) { useEffect(() => {
props.getUserTokens(); dispatch(getUserTokens());
setIsFetched(true); }, [dispatch]);
}
return ( return (
<div className="row"> <div className="row">
<div className="col-12"> <div className="col-12">
{props.tokens.map((el, index) => ( {tokens.map((el, index) => (
<Token key={index} data={el} deleteToken={props.deleteUserToken} /> <Token
key={index}
data={el}
deleteToken={(token) => dispatch(deleteUserToken(token))}
/>
))} ))}
</div> </div>
</div> </div>
); );
}; };
UserTokens.propTypes = {
tokens: PropTypes.instanceOf(List),
isLoading: PropTypes.bool,
getUserTokens: PropTypes.func.isRequired,
deleteUserToken: PropTypes.func.isRequired,
};
const Token = (props) => { const Token = (props) => {
const ua = UAParser(props.data.get("user_agent")); const ua = UAParser(props.data.get("user_agent"));
@ -171,4 +166,4 @@ Browser.propTypes = {
version: PropTypes.string, version: PropTypes.string,
}; };
export default connect(mapStateToProps, mapDispatchToProps)(UserTokens); export default UserTokens;