now everything works with React ToolKit
This commit is contained in:
@@ -1,23 +1,22 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Link, Navigate } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { login } from '../../actions/auth';
|
||||
import React, { useState } from "react";
|
||||
import { Link, Navigate } from "react-router-dom";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { login } from "../../actions/auth";
|
||||
|
||||
const Login = ({ login, isAuthenticated }) => {
|
||||
const Login = () => {
|
||||
const [formData, setFormData] = useState({
|
||||
email: '',
|
||||
password: ''
|
||||
email: "",
|
||||
password: "",
|
||||
});
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const { email, password } = formData;
|
||||
|
||||
const isAuthenticated = useSelector((state) => state.auth.isAuthenticated);
|
||||
const onChange = (e) =>
|
||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||
|
||||
const onSubmit = (e) => {
|
||||
const onSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
login(email, password);
|
||||
await dispatch(login(email, password));
|
||||
};
|
||||
|
||||
if (isAuthenticated) {
|
||||
@@ -59,13 +58,4 @@ const Login = ({ login, isAuthenticated }) => {
|
||||
);
|
||||
};
|
||||
|
||||
Login.propTypes = {
|
||||
login: PropTypes.func.isRequired,
|
||||
isAuthenticated: PropTypes.bool
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isAuthenticated: state.auth.isAuthenticated
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { login })(Login);
|
||||
export default Login;
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
import React, { useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { useDispatch,useSelector } from 'react-redux';
|
||||
import { Link, Navigate } from 'react-router-dom';
|
||||
import { setAlert } from '../../actions/alert';
|
||||
import { createAlert } from '../../actions/alert';
|
||||
import { register } from '../../actions/auth';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const Register = ({ setAlert, register, isAuthenticated }) => {
|
||||
|
||||
const Register = () => {
|
||||
const dispatch = useDispatch();
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
email: '',
|
||||
password: '',
|
||||
password2: ''
|
||||
});
|
||||
|
||||
const isAuthenticated = useSelector(state=>state.auth.isAuthenticated)
|
||||
const { name, email, password, password2 } = formData;
|
||||
|
||||
const onChange = (e) =>
|
||||
@@ -21,9 +22,9 @@ const Register = ({ setAlert, register, isAuthenticated }) => {
|
||||
const onSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
if (password !== password2) {
|
||||
setAlert('Passwords do not match', 'danger');
|
||||
await dispatch(createAlert('Passwords do not match', 'danger'));
|
||||
} else {
|
||||
register({ name, email, password });
|
||||
await dispatch(register({ name, email, password }));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -87,14 +88,4 @@ const Register = ({ setAlert, register, isAuthenticated }) => {
|
||||
);
|
||||
};
|
||||
|
||||
Register.propTypes = {
|
||||
setAlert: PropTypes.func.isRequired,
|
||||
register: PropTypes.func.isRequired,
|
||||
isAuthenticated: PropTypes.bool
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isAuthenticated: state.auth.isAuthenticated
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { setAlert, register })(Register);
|
||||
export default Register;
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import DashboardActions from './DashboardActions';
|
||||
import Experience from './Experience';
|
||||
import Education from './Education';
|
||||
import { getCurrentProfile, deleteAccount } from '../../actions/profile';
|
||||
import React, { useEffect } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import DashboardActions from "./DashboardActions";
|
||||
import Experience from "./Experience";
|
||||
import Education from "./Education";
|
||||
import { getCurrentProfile, deleteAccount } from "../../actions/profile";
|
||||
|
||||
|
||||
const Dashboard = ({
|
||||
getCurrentProfile,
|
||||
deleteAccount,
|
||||
auth: { user },
|
||||
profile: { profile }
|
||||
}) => {
|
||||
const Dashboard = () => {
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
getCurrentProfile();
|
||||
}, [getCurrentProfile]);
|
||||
|
||||
function fetchData() {
|
||||
dispatch(getCurrentProfile());
|
||||
}
|
||||
fetchData();
|
||||
}, [dispatch]);
|
||||
const user = useSelector((state) => state.auth.user);
|
||||
const profile = useSelector((state) => state.profile.profile);
|
||||
return (
|
||||
<section className="container">
|
||||
<h1 className="large text-primary">Dashboard</h1>
|
||||
@@ -31,7 +29,10 @@ const Dashboard = ({
|
||||
<Education education={profile.education} />
|
||||
|
||||
<div className="my-2">
|
||||
<button className="btn btn-danger" onClick={() => deleteAccount()}>
|
||||
<button
|
||||
className="btn btn-danger"
|
||||
onClick={async () => await dispatch(deleteAccount())}
|
||||
>
|
||||
<i className="fas fa-user" /> Delete My Account
|
||||
</button>
|
||||
</div>
|
||||
@@ -48,18 +49,4 @@ const Dashboard = ({
|
||||
);
|
||||
};
|
||||
|
||||
Dashboard.propTypes = {
|
||||
getCurrentProfile: PropTypes.func.isRequired,
|
||||
deleteAccount: PropTypes.func.isRequired,
|
||||
auth: PropTypes.object.isRequired,
|
||||
profile: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
auth: state.auth,
|
||||
profile: state.profile,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { getCurrentProfile, deleteAccount })(
|
||||
Dashboard
|
||||
);
|
||||
export default Dashboard;
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { deleteEducation } from '../../actions/profile';
|
||||
import formatDate from '../../utils/formatDate';
|
||||
import React, { Fragment } from "react";
|
||||
import {useDispatch } from "react-redux";
|
||||
import { deleteEducation } from "../../actions/profile";
|
||||
import formatDate from "../../utils/formatDate";
|
||||
|
||||
const Education = ({ education, deleteEducation }) => {
|
||||
const Education = ({education}) => {
|
||||
const dispatch = useDispatch();
|
||||
const educations = education.map((edu) => (
|
||||
<tr key={edu._id}>
|
||||
<td>{edu.school}</td>
|
||||
<td className="hide-sm">{edu.degree}</td>
|
||||
<td>
|
||||
{formatDate(edu.from)} - {edu.to ? formatDate(edu.to) : 'Now'}
|
||||
{formatDate(edu.from)} - {edu.to ? formatDate(edu.to) : "Now"}
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
onClick={() => deleteEducation(edu._id)}
|
||||
onClick={async () => await dispatch(deleteEducation(edu._id))}
|
||||
className="btn btn-danger"
|
||||
>
|
||||
Delete
|
||||
@@ -41,9 +41,4 @@ const Education = ({ education, deleteEducation }) => {
|
||||
);
|
||||
};
|
||||
|
||||
Education.propTypes = {
|
||||
education: PropTypes.array.isRequired,
|
||||
deleteEducation: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(null, { deleteEducation })(Education);
|
||||
export default Education;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import {useDispatch } from 'react-redux';
|
||||
import { deleteExperience } from '../../actions/profile';
|
||||
import formatDate from '../../utils/formatDate';
|
||||
|
||||
const Experience = ({ experience, deleteExperience }) => {
|
||||
const Experience = ({experience}) => {
|
||||
const dispatch = useDispatch();
|
||||
const experiences = experience.map((exp) => (
|
||||
<tr key={exp._id}>
|
||||
<td>{exp.company}</td>
|
||||
@@ -14,7 +14,7 @@ const Experience = ({ experience, deleteExperience }) => {
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
onClick={() => deleteExperience(exp._id)}
|
||||
onClick={async () => dispatch(deleteExperience(exp._id))}
|
||||
className="btn btn-danger"
|
||||
>
|
||||
Delete
|
||||
@@ -41,9 +41,6 @@ const Experience = ({ experience, deleteExperience }) => {
|
||||
);
|
||||
};
|
||||
|
||||
Experience.propTypes = {
|
||||
experience: PropTypes.array.isRequired,
|
||||
deleteExperience: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(null, { deleteExperience })(Experience);
|
||||
|
||||
export default Experience;
|
||||
|
||||
@@ -1,23 +1,16 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
const Alert = ({ alerts }) => (
|
||||
<div className="alert-wrapper">
|
||||
{alerts.map((alert) => (
|
||||
<div key={alert.id} className={`alert alert-${alert.alertType}`}>
|
||||
{alert.msg}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
Alert.propTypes = {
|
||||
alerts: PropTypes.array.isRequired
|
||||
import React from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
const Alert = () => {
|
||||
const alerts = useSelector((state) => state.alert);
|
||||
return (
|
||||
<div className="alert-wrapper">
|
||||
{alerts.map((alert) => (
|
||||
<div key={alert.id} className={`alert alert-${alert.alertType}`}>
|
||||
{alert.msg}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
alerts: state.alert
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(Alert);
|
||||
export default Alert;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import { Link, Navigate } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from "react";
|
||||
import { Link, Navigate } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
const Landing = ({ isAuthenticated }) => {
|
||||
const Landing = () => {
|
||||
const isAuthenticated = useSelector((state) => state.auth.isAuthenticated);
|
||||
if (isAuthenticated) {
|
||||
return <Navigate to="/dashboard" />;
|
||||
}
|
||||
@@ -31,13 +31,4 @@ const Landing = ({ isAuthenticated }) => {
|
||||
);
|
||||
};
|
||||
|
||||
Landing.propTypes = {
|
||||
isAuthenticated: PropTypes.bool
|
||||
};
|
||||
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
isAuthenticated: state.auth.isAuthenticated
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps)(Landing);
|
||||
export default Landing;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import { logout } from '../../actions/auth';
|
||||
import React, { Fragment } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { logOut } from "../../reducers/auth";
|
||||
|
||||
const Navbar = ({ auth: { isAuthenticated }, logout }) => {
|
||||
const Navbar = () => {
|
||||
const isAuthenticated = useSelector((state) => state.auth.isAuthenticated);
|
||||
const dispatch = useDispatch();
|
||||
const authLinks = (
|
||||
<ul>
|
||||
<li>
|
||||
@@ -15,12 +16,11 @@ const Navbar = ({ auth: { isAuthenticated }, logout }) => {
|
||||
</li>
|
||||
<li>
|
||||
<Link to="/dashboard">
|
||||
<i className="fas fa-user" />{' '}
|
||||
<span className="hide-sm">Profile</span>
|
||||
<i className="fas fa-user" /> <span className="hide-sm">Profile</span>
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a onClick={logout} href="#!">
|
||||
<a onClick={()=>dispatch(logOut())} href="#!">
|
||||
<i className="fas fa-sign-out-alt" />{' '}
|
||||
<span className="hide-sm">Logout</span>
|
||||
</a>
|
||||
@@ -54,13 +54,4 @@ const Navbar = ({ auth: { isAuthenticated }, logout }) => {
|
||||
);
|
||||
};
|
||||
|
||||
Navbar.propTypes = {
|
||||
logout: PropTypes.func.isRequired,
|
||||
auth: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
auth: state.auth
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { logout })(Navbar);
|
||||
export default Navbar;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { addComment } from '../../actions/post';
|
||||
|
||||
const CommentForm = ({ postId, addComment }) => {
|
||||
const CommentForm = ({ postId }) => {
|
||||
const [text, setText] = useState('');
|
||||
const dispatch = useDispatch();
|
||||
|
||||
return (
|
||||
<div className='post-form'>
|
||||
@@ -13,9 +13,9 @@ const CommentForm = ({ postId, addComment }) => {
|
||||
</div>
|
||||
<form
|
||||
className='form my-1'
|
||||
onSubmit={e => {
|
||||
onSubmit={async(e) => {
|
||||
e.preventDefault();
|
||||
addComment(postId, { text });
|
||||
await dispatch(addComment(postId, { text }));
|
||||
setText('');
|
||||
}}
|
||||
>
|
||||
@@ -34,12 +34,6 @@ const CommentForm = ({ postId, addComment }) => {
|
||||
);
|
||||
};
|
||||
|
||||
CommentForm.propTypes = {
|
||||
addComment: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(
|
||||
null,
|
||||
{ addComment }
|
||||
)(CommentForm);
|
||||
export default CommentForm
|
||||
|
||||
|
||||
@@ -1,49 +1,38 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import formatDate from '../../utils/formatDate';
|
||||
import { deleteComment } from '../../actions/post';
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import formatDate from "../../utils/formatDate";
|
||||
import { deleteComment } from "../../actions/post";
|
||||
|
||||
const CommentItem = ({
|
||||
postId,
|
||||
comment: { _id, text, name, avatar, user, date },
|
||||
auth,
|
||||
deleteComment
|
||||
}) => (
|
||||
<div className="post bg-white p-1 my-1">
|
||||
<div>
|
||||
<Link to={`/profile/${user}`}>
|
||||
<img className="round-img" src={avatar} alt="" />
|
||||
<h4>{name}</h4>
|
||||
</Link>
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const auth = useSelector((state) => state.auth);
|
||||
return (
|
||||
<div className="post bg-white p-1 my-1">
|
||||
<div>
|
||||
<Link to={`/profile/${user}`}>
|
||||
<img className="round-img" src={avatar} alt="" />
|
||||
<h4>{name}</h4>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<p className="my-1">{text}</p>
|
||||
<p className="post-date">Posted on {formatDate(date)}</p>
|
||||
{!auth.loading && user === auth.user._id && (
|
||||
<button
|
||||
onClick={async () => await dispatch(deleteComment(postId, _id))}
|
||||
type="button"
|
||||
className="btn btn-danger"
|
||||
>
|
||||
<i className="fas fa-times" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="my-1">{text}</p>
|
||||
<p className="post-date">Posted on {formatDate(date)}</p>
|
||||
{!auth.loading && user === auth.user._id && (
|
||||
<button
|
||||
onClick={() => deleteComment(postId, _id)}
|
||||
type="button"
|
||||
className="btn btn-danger"
|
||||
>
|
||||
<i className="fas fa-times" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
CommentItem.propTypes = {
|
||||
postId: PropTypes.string.isRequired,
|
||||
comment: PropTypes.object.isRequired,
|
||||
auth: PropTypes.object.isRequired,
|
||||
deleteComment: PropTypes.func.isRequired
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
auth: state.auth
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { deleteComment })(CommentItem);
|
||||
|
||||
export default CommentItem;
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import Spinner from '../layout/Spinner';
|
||||
import PostItem from '../posts/PostItem';
|
||||
import CommentForm from '../post/CommentForm';
|
||||
import CommentItem from '../post/CommentItem';
|
||||
import { getPost } from '../../actions/post';
|
||||
import React, { useEffect } from "react";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import Spinner from "../layout/Spinner";
|
||||
import PostItem from "../posts/PostItem";
|
||||
import CommentForm from "../post/CommentForm";
|
||||
import CommentItem from "../post/CommentItem";
|
||||
import { getPost } from "../../actions/post";
|
||||
|
||||
const Post = ({ getPost, post: { post, loading } }) => {
|
||||
const Post = () => {
|
||||
const dispatch = useDispatch();
|
||||
const { post, loading } = useSelector((state) => state.post);
|
||||
const { id } = useParams();
|
||||
useEffect(() => {
|
||||
getPost(id);
|
||||
}, [getPost, id]);
|
||||
async function fetchData() {
|
||||
await dispatch(getPost(id));
|
||||
}
|
||||
fetchData();
|
||||
}, [dispatch, id]);
|
||||
|
||||
return loading || post === null ? (
|
||||
<Spinner />
|
||||
@@ -32,14 +36,4 @@ const Post = ({ getPost, post: { post, loading } }) => {
|
||||
);
|
||||
};
|
||||
|
||||
Post.propTypes = {
|
||||
getPost: PropTypes.func.isRequired,
|
||||
post: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
post: state.post
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { getPost })(Post);
|
||||
|
||||
export default Post;
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import React, { useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import { connect } from "react-redux";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { addPost } from "../../actions/post";
|
||||
|
||||
const PostForm = ({ addPost }) => {
|
||||
const PostForm = () => {
|
||||
const [text, setText] = useState("");
|
||||
const [category, setCategory] = useState("");
|
||||
//const onChange = (e) =>
|
||||
//setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||
|
||||
const dispatch = useDispatch();
|
||||
return (
|
||||
<div className="post-form">
|
||||
<div className="bg-primary p">
|
||||
@@ -16,9 +12,9 @@ const PostForm = ({ addPost }) => {
|
||||
</div>
|
||||
<form
|
||||
className="form my-1"
|
||||
onSubmit={(e) => {
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
addPost({ text, category });
|
||||
await dispatch(addPost({ text }));
|
||||
setText("");
|
||||
}}
|
||||
>
|
||||
@@ -31,25 +27,10 @@ const PostForm = ({ addPost }) => {
|
||||
onChange={(e) => setText(e.target.value)}
|
||||
required
|
||||
/>
|
||||
|
||||
<p className="lead">Choose a category:</p>
|
||||
<select name="category" value={category} onChange={setCategory}>
|
||||
<option>* Select Category</option>
|
||||
<option value="opinion">Opinion</option>
|
||||
<option value="question">Question</option>
|
||||
<option value="asssitance">Asking for asssitance</option>
|
||||
<option value="news">News</option>
|
||||
<option value="other">Other</option>
|
||||
</select>
|
||||
|
||||
<input type="submit" className="btn btn-dark my-1" value="Submit" />
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
PostForm.propTypes = {
|
||||
addPost: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default connect(null, { addPost })(PostForm);
|
||||
export default PostForm;
|
||||
|
||||
@@ -1,74 +1,57 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link } from 'react-router-dom';
|
||||
import formatDate from '../../utils/formatDate';
|
||||
import { connect } from 'react-redux';
|
||||
import { addLike, removeLike, deletePost } from '../../actions/post';
|
||||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import formatDate from "../../utils/formatDate";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { addLike, removeLike, deletePost } from "../../actions/post";
|
||||
|
||||
const PostItem = ({
|
||||
addLike,
|
||||
removeLike,
|
||||
deletePost,
|
||||
auth,
|
||||
post: { _id, text, name, avatar, user, likes, comments, date }
|
||||
}) => (
|
||||
<div className="post bg-white p-1 my-1">
|
||||
<div>
|
||||
<Link to={`/profile/${user}`}>
|
||||
<img className="round-img" src={avatar} alt="" />
|
||||
<h4>{name}</h4>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<p className="my-1">{text}</p>
|
||||
<p className="post-date">Posted on {formatDate(date)}</p>
|
||||
<button
|
||||
onClick={() => addLike(_id)}
|
||||
type="button"
|
||||
className="btn btn-light"
|
||||
>
|
||||
<i className="fas fa-thumbs-up" />{' '}
|
||||
<span>{likes.length > 0 && <span>{likes.length}</span>}</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => removeLike(_id)}
|
||||
type="button"
|
||||
className="btn btn-light"
|
||||
>
|
||||
<i className="fas fa-thumbs-down" />
|
||||
</button>
|
||||
<Link to={`/posts/${_id}`} className="btn btn-primary">
|
||||
Discussion{' '}
|
||||
{comments.length > 0 && (
|
||||
<span className="comment-count">{comments.length}</span>
|
||||
)}
|
||||
</Link>
|
||||
{!auth.loading && user === auth.user._id && (
|
||||
post: { _id, text, name, avatar, user, likes, comments, date },
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const auth = useSelector((state) => state.auth);
|
||||
return (
|
||||
<div className="post bg-white p-1 my-1">
|
||||
<div>
|
||||
<Link to={`/profile/${user}`}>
|
||||
<img className="round-img" src={avatar} alt="" />
|
||||
<h4>{name}</h4>
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<p className="my-1">{text}</p>
|
||||
<p className="post-date">Posted on {formatDate(date)}</p>
|
||||
<button
|
||||
onClick={() => deletePost(_id)}
|
||||
onClick={async () => await dispatch(addLike(_id))}
|
||||
type="button"
|
||||
className="btn btn-danger"
|
||||
className="btn btn-light"
|
||||
>
|
||||
<i className="fas fa-times" />
|
||||
<i className="fas fa-thumbs-up" />{" "}
|
||||
<span>{likes.length > 0 && <span>{likes.length}</span>}</span>
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
onClick={async () => await dispatch(removeLike(_id))}
|
||||
type="button"
|
||||
className="btn btn-light"
|
||||
>
|
||||
<i className="fas fa-thumbs-down" />
|
||||
</button>
|
||||
<Link to={`/posts/${_id}`} className="btn btn-primary">
|
||||
Discussion{" "}
|
||||
{comments.length > 0 && (
|
||||
<span className="comment-count">{comments.length}</span>
|
||||
)}
|
||||
</Link>
|
||||
{!auth.loading && user === auth.user._id && (
|
||||
<button
|
||||
onClick={async () => await dispatch(deletePost(_id))}
|
||||
type="button"
|
||||
className="btn btn-danger"
|
||||
>
|
||||
<i className="fas fa-times" />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
PostItem.propTypes = {
|
||||
post: PropTypes.object.isRequired,
|
||||
auth: PropTypes.object.isRequired,
|
||||
addLike: PropTypes.func.isRequired,
|
||||
removeLike: PropTypes.func.isRequired,
|
||||
deletePost: PropTypes.func.isRequired
|
||||
);
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
auth: state.auth
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { addLike, removeLike, deletePost })(
|
||||
PostItem
|
||||
);
|
||||
|
||||
export default PostItem;
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import PostItem from './PostItem';
|
||||
import PostForm from './PostForm';
|
||||
import { getPosts } from '../../actions/post';
|
||||
import React, { useEffect } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import PostItem from "./PostItem";
|
||||
import PostForm from "./PostForm";
|
||||
import { getPosts } from "../../actions/post";
|
||||
|
||||
const Posts = ({ getPosts, post: { posts } }) => {
|
||||
const Posts = () => {
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
getPosts();
|
||||
}, [getPosts]);
|
||||
async function fetchData() {
|
||||
await dispatch(getPosts());
|
||||
}
|
||||
fetchData();
|
||||
}, [dispatch]);
|
||||
const posts = useSelector((state) => state.post.posts);
|
||||
|
||||
|
||||
return (
|
||||
<section className="container">
|
||||
@@ -26,13 +31,4 @@ const Posts = ({ getPosts, post: { posts } }) => {
|
||||
);
|
||||
};
|
||||
|
||||
Posts.propTypes = {
|
||||
getPosts: PropTypes.func.isRequired,
|
||||
post: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
post: state.post
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { getPosts })(Posts);
|
||||
export default Posts;
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { addEducation } from '../../actions/profile';
|
||||
import React, { useState } from "react";
|
||||
import { Link, useNavigate } from "react-router-dom";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { addEducation } from "../../actions/profile";
|
||||
|
||||
const AddEducation = ({ addEducation }) => {
|
||||
const AddEducation = () => {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const [formData, setFormData] = useState({
|
||||
school: '',
|
||||
degree: '',
|
||||
fieldofstudy: '',
|
||||
from: '',
|
||||
to: '',
|
||||
school: "",
|
||||
degree: "",
|
||||
fieldofstudy: "",
|
||||
from: "",
|
||||
to: "",
|
||||
current: false,
|
||||
description: ''
|
||||
description: "",
|
||||
});
|
||||
|
||||
const { school, degree, fieldofstudy, from, to, description, current } =
|
||||
@@ -32,9 +32,10 @@ const AddEducation = ({ addEducation }) => {
|
||||
<small>* = required field</small>
|
||||
<form
|
||||
className="form"
|
||||
onSubmit={(e) => {
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
addEducation(formData).then(() => navigate('/dashboard'));
|
||||
await dispatch(addEducation(formData)).then(() => navigate("/dashboard"));
|
||||
// i have no idea how this works used to work, i removed the navigate function from the addEducation and it does now
|
||||
}}
|
||||
>
|
||||
<div className="form-group">
|
||||
@@ -78,7 +79,7 @@ const AddEducation = ({ addEducation }) => {
|
||||
checked={current}
|
||||
value={current}
|
||||
onChange={() => setFormData({ ...formData, current: !current })}
|
||||
/>{' '}
|
||||
/>{" "}
|
||||
Current School
|
||||
</p>
|
||||
</div>
|
||||
@@ -111,8 +112,5 @@ const AddEducation = ({ addEducation }) => {
|
||||
);
|
||||
};
|
||||
|
||||
AddEducation.propTypes = {
|
||||
addEducation: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(null, { addEducation })(AddEducation);
|
||||
export default AddEducation;
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { addExperience } from '../../actions/profile';
|
||||
|
||||
const AddExperience = ({ addExperience }) => {
|
||||
const AddExperience = () => {
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const [formData, setFormData] = useState({
|
||||
company: '',
|
||||
@@ -31,9 +31,9 @@ const AddExperience = ({ addExperience }) => {
|
||||
<small>* = required field</small>
|
||||
<form
|
||||
className="form"
|
||||
onSubmit={(e) => {
|
||||
onSubmit={async(e) => {
|
||||
e.preventDefault();
|
||||
addExperience(formData).then(() => navigate('/dashboard'));
|
||||
await dispatch(addExperience(formData)).then(() => navigate('/dashboard'));
|
||||
}}
|
||||
>
|
||||
<div className="form-group">
|
||||
@@ -112,8 +112,4 @@ const AddExperience = ({ addExperience }) => {
|
||||
);
|
||||
};
|
||||
|
||||
AddExperience.propTypes = {
|
||||
addExperience: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(null, { addExperience })(AddExperience);
|
||||
export default AddExperience;
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
import React, { Fragment, useState, useEffect } from 'react';
|
||||
import { Link, useMatch, useNavigate } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { createProfile, getCurrentProfile } from '../../actions/profile';
|
||||
import React, { Fragment, useState, useEffect } from "react";
|
||||
import { Link, useMatch, useNavigate } from "react-router-dom";
|
||||
import { createProfile, getCurrentProfile } from "../../actions/profile";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
|
||||
const initialState = {
|
||||
company: '',
|
||||
website: '',
|
||||
location: '',
|
||||
status: '',
|
||||
skills: '',
|
||||
githubusername: '',
|
||||
bio: '',
|
||||
twitter: '',
|
||||
facebook: '',
|
||||
linkedin: '',
|
||||
youtube: '',
|
||||
instagram: ''
|
||||
company: "",
|
||||
website: "",
|
||||
location: "",
|
||||
status: "",
|
||||
skills: "",
|
||||
githubusername: "",
|
||||
bio: "",
|
||||
twitter: "",
|
||||
facebook: "",
|
||||
linkedin: "",
|
||||
youtube: "",
|
||||
instagram: "",
|
||||
};
|
||||
|
||||
const ProfileForm = ({
|
||||
profile: { profile, loading },
|
||||
createProfile,
|
||||
getCurrentProfile
|
||||
}) => {
|
||||
const ProfileForm = () => {
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { profile, loading } = useSelector((state) => state.profile);
|
||||
|
||||
const [formData, setFormData] = useState(initialState);
|
||||
|
||||
const creatingProfile = useMatch('/create-profile');
|
||||
const creatingProfile = useMatch("/create-profile");
|
||||
|
||||
const [displaySocialInputs, toggleSocialInputs] = useState(false);
|
||||
|
||||
@@ -34,7 +34,10 @@ const ProfileForm = ({
|
||||
|
||||
useEffect(() => {
|
||||
// if there is no profile, attempt to fetch one
|
||||
if (!profile) getCurrentProfile();
|
||||
async function fetchData(){
|
||||
await dispatch(getCurrentProfile())
|
||||
}
|
||||
if (!profile) fetchData();
|
||||
|
||||
// if we finished loading and we do have a profile
|
||||
// then build our profileData
|
||||
@@ -48,11 +51,11 @@ const ProfileForm = ({
|
||||
}
|
||||
// the skills may be an array from our API response
|
||||
if (Array.isArray(profileData.skills))
|
||||
profileData.skills = profileData.skills.join(', ');
|
||||
profileData.skills = profileData.skills.join(", ");
|
||||
// set local state with the profileData
|
||||
setFormData(profileData);
|
||||
}
|
||||
}, [loading, getCurrentProfile, profile]);
|
||||
}, [loading, dispatch, profile]);
|
||||
|
||||
const {
|
||||
company,
|
||||
@@ -66,30 +69,31 @@ const ProfileForm = ({
|
||||
facebook,
|
||||
linkedin,
|
||||
youtube,
|
||||
instagram
|
||||
instagram,
|
||||
} = formData;
|
||||
|
||||
const onChange = (e) =>
|
||||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||
|
||||
const onSubmit = (e) => {
|
||||
const onSubmit = async (e) => {
|
||||
const editing = profile ? true : false;
|
||||
e.preventDefault();
|
||||
createProfile(formData, editing).then(() => {
|
||||
if (!editing) navigate('/dashboard');
|
||||
await dispatch(createProfile(formData, editing)).then(() => {
|
||||
console.log(editing)
|
||||
if (!editing) navigate("/dashboard");
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="container">
|
||||
<h1 className="large text-primary">
|
||||
{creatingProfile ? 'Create Your Profile' : 'Edit Your Profile'}
|
||||
{creatingProfile ? "Create Your Profile" : "Edit Your Profile"}
|
||||
</h1>
|
||||
<p className="lead">
|
||||
<i className="fas fa-user" />
|
||||
{creatingProfile
|
||||
? ` Let's get some information to make your`
|
||||
: ' Add some changes to your profile'}
|
||||
: " Add some changes to your profile"}
|
||||
</p>
|
||||
<small>* = required field</small>
|
||||
<form className="form" onSubmit={onSubmit}>
|
||||
@@ -259,17 +263,4 @@ const ProfileForm = ({
|
||||
);
|
||||
};
|
||||
|
||||
ProfileForm.propTypes = {
|
||||
createProfile: PropTypes.func.isRequired,
|
||||
getCurrentProfile: PropTypes.func.isRequired,
|
||||
profile: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
profile: state.profile
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { createProfile, getCurrentProfile })(
|
||||
ProfileForm
|
||||
);
|
||||
|
||||
export default ProfileForm;
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
import React, { Fragment, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Link, useParams } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import Spinner from '../layout/Spinner';
|
||||
import ProfileTop from './ProfileTop';
|
||||
import ProfileAbout from './ProfileAbout';
|
||||
import ProfileExperience from './ProfileExperience';
|
||||
import ProfileEducation from './ProfileEducation';
|
||||
import ProfileGithub from './ProfileGithub';
|
||||
import { getProfileById } from '../../actions/profile';
|
||||
import React, { Fragment, useEffect } from "react";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import Spinner from "../layout/Spinner";
|
||||
import ProfileTop from "./ProfileTop";
|
||||
import ProfileAbout from "./ProfileAbout";
|
||||
import ProfileExperience from "./ProfileExperience";
|
||||
import ProfileEducation from "./ProfileEducation";
|
||||
import ProfileGithub from "./ProfileGithub";
|
||||
import { getProfileById } from "../../actions/profile";
|
||||
|
||||
const Profile = ({ getProfileById, profile: { profile }, auth }) => {
|
||||
const Profile = () => {
|
||||
const profile = useSelector((state) => state.profile.profile);
|
||||
const auth = useSelector((state) => state.auth);
|
||||
const dispatch = useDispatch();
|
||||
const { id } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
getProfileById(id);
|
||||
}, [getProfileById, id]);
|
||||
async function fetchData(){
|
||||
await dispatch(getProfileById(id));
|
||||
}
|
||||
fetchData();
|
||||
}, [dispatch,id]);
|
||||
|
||||
return (
|
||||
<section className="container">
|
||||
@@ -76,15 +82,5 @@ const Profile = ({ getProfileById, profile: { profile }, auth }) => {
|
||||
</section>
|
||||
);
|
||||
};
|
||||
Profile.propTypes = {
|
||||
getProfileById: PropTypes.func.isRequired,
|
||||
profile: PropTypes.object.isRequired,
|
||||
auth: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
profile: state.profile,
|
||||
auth: state.auth
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { getProfileById })(Profile);
|
||||
export default Profile;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const ProfileAbout = ({
|
||||
profile: {
|
||||
@@ -27,8 +26,5 @@ const ProfileAbout = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
ProfileAbout.propTypes = {
|
||||
profile: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default ProfileAbout;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import formatDate from '../../utils/formatDate';
|
||||
|
||||
const ProfileEducation = ({
|
||||
@@ -22,9 +21,6 @@ const ProfileEducation = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
ProfileEducation.propTypes = {
|
||||
education: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
|
||||
export default ProfileEducation;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import formatDate from '../../utils/formatDate';
|
||||
|
||||
const ProfileExperience = ({
|
||||
@@ -22,9 +21,5 @@ const ProfileExperience = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
ProfileExperience.propTypes = {
|
||||
experience: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
|
||||
export default ProfileExperience;
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { getGithubRepos } from '../../actions/profile';
|
||||
import React, { useEffect } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { getGithubRepos } from "../../actions/profile";
|
||||
|
||||
const ProfileGithub = ({ username, getGithubRepos, repos }) => {
|
||||
const ProfileGithub = ({ username }) => {
|
||||
const repos = useSelector((state) => state.profile.repos);
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
getGithubRepos(username);
|
||||
}, [getGithubRepos, username]);
|
||||
async function fetchData() {
|
||||
await dispatch(getGithubRepos(username));
|
||||
}
|
||||
fetchData();
|
||||
}, [dispatch, username]);
|
||||
|
||||
return (
|
||||
<div className="profile-github">
|
||||
<h2 className="text-primary my-1">Github Repos</h2>
|
||||
{repos.map(repo => (
|
||||
{repos.map((repo) => (
|
||||
<div key={repo.id} className="repo bg-white p-1 my-1">
|
||||
<div>
|
||||
<h4>
|
||||
@@ -38,15 +42,4 @@ const ProfileGithub = ({ username, getGithubRepos, repos }) => {
|
||||
);
|
||||
};
|
||||
|
||||
ProfileGithub.propTypes = {
|
||||
getGithubRepos: PropTypes.func.isRequired,
|
||||
repos: PropTypes.array.isRequired,
|
||||
username: PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
repos: state.profile.repos
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { getGithubRepos })(ProfileGithub);
|
||||
|
||||
export default ProfileGithub;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from "react";
|
||||
|
||||
const ProfileTop = ({
|
||||
profile: {
|
||||
@@ -8,8 +7,8 @@ const ProfileTop = ({
|
||||
location,
|
||||
website,
|
||||
social,
|
||||
user: { name, avatar }
|
||||
}
|
||||
user: { name, avatar },
|
||||
},
|
||||
}) => {
|
||||
return (
|
||||
<div className="profile-top bg-primary p-2">
|
||||
@@ -44,9 +43,4 @@ const ProfileTop = ({
|
||||
);
|
||||
};
|
||||
|
||||
ProfileTop.propTypes = {
|
||||
profile: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
|
||||
export default ProfileTop;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const ProfileItem = ({
|
||||
profile: {
|
||||
@@ -35,9 +34,5 @@ const ProfileItem = ({
|
||||
);
|
||||
};
|
||||
|
||||
ProfileItem.propTypes = {
|
||||
profile: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default ProfileItem;
|
||||
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
import React, { Fragment, useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import Spinner from '../layout/Spinner';
|
||||
import ProfileItem from './ProfileItem';
|
||||
import { getProfiles } from '../../actions/profile';
|
||||
import React, { Fragment, useEffect } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import Spinner from "../layout/Spinner";
|
||||
import ProfileItem from "./ProfileItem";
|
||||
import { getProfiles } from "../../actions/profile";
|
||||
|
||||
const Profiles = ({ getProfiles, profile: { profiles, loading } }) => {
|
||||
const Profiles = () => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
getProfiles();
|
||||
}, [getProfiles]);
|
||||
|
||||
async function fetchData() {
|
||||
await dispatch(getProfiles());
|
||||
}
|
||||
fetchData();
|
||||
}, [dispatch]);
|
||||
|
||||
const { profiles, loading } = useSelector((state) => state.profile);
|
||||
return (
|
||||
<section className="container">
|
||||
{loading ? (
|
||||
@@ -36,13 +41,4 @@ const Profiles = ({ getProfiles, profile: { profiles, loading } }) => {
|
||||
);
|
||||
};
|
||||
|
||||
Profiles.propTypes = {
|
||||
getProfiles: PropTypes.func.isRequired,
|
||||
profile: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
profile: state.profile
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, { getProfiles })(Profiles);
|
||||
export default Profiles;
|
||||
|
||||
@@ -1,26 +1,14 @@
|
||||
import React from 'react';
|
||||
import { Navigate } from 'react-router-dom';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import Spinner from '../layout/Spinner';
|
||||
import React from "react";
|
||||
import { Navigate } from "react-router-dom";
|
||||
import { useSelector } from "react-redux";
|
||||
import Spinner from "../layout/Spinner";
|
||||
|
||||
const PrivateRoute = ({
|
||||
component: Component,
|
||||
auth: { isAuthenticated, loading }
|
||||
}) => {
|
||||
const PrivateRoute = ({ component: Component }) => {
|
||||
const { isAuthenticated, loading } = useSelector((state) => state.auth);
|
||||
if (loading) return <Spinner />;
|
||||
if (isAuthenticated) return <Component />;
|
||||
|
||||
return <Navigate to="/login" />;
|
||||
};
|
||||
|
||||
PrivateRoute.propTypes = {
|
||||
auth: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
auth: state.auth
|
||||
});
|
||||
|
||||
|
||||
export default connect(mapStateToProps)(PrivateRoute);
|
||||
export default PrivateRoute;
|
||||
|
||||
Reference in New Issue
Block a user