Skip to content

Commit 5597e13

Browse files
committedJun 1, 2020
Added profile directory with components, not found page. Finished with profile.
1 parent eb38358 commit 5597e13

File tree

15 files changed

+443
-9
lines changed

15 files changed

+443
-9
lines changed
 

‎client/src/App.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import EditProfile from "./components/edit-profile/EditProfile";
2424
import AddExperience from "./components/add-credentials/AddExperience";
2525
import AddEducation from "./components/add-credentials/AddEducation";
2626
import Profiles from "./components/profiles/Profiles";
27+
import Profile from "./components/profile/Profile";
28+
import NotFound from "./components/not-found/NotFound";
2729

2830
import "./App.css";
2931

@@ -61,6 +63,7 @@ class App extends Component {
6163
<Route exact path="/register" component={Register} />
6264
<Route exact path="/login" component={Login} />
6365
<Route exact path="/profiles" component={Profiles} />
66+
<Route exact path="/profile/:handle" component={Profile} />
6467
<Switch>
6568
<PrivateRoute exact path="/dashboard" component={Dashboard} />
6669
</Switch>
@@ -92,6 +95,7 @@ class App extends Component {
9295
component={AddEducation}
9396
/>
9497
</Switch>
98+
<Route exact path="/not-found" component={NotFound} />
9599
</div>
96100
<Footer />
97101
</Router>

‎client/src/actions/profileActions.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@ export const getCurrentProfile = () => (dispatch) => {
2828
);
2929
};
3030

31+
// get profile by handle
32+
export const getProfileByHandle = (handle) => (dispatch) => {
33+
dispatch(setProfileLoading());
34+
axios
35+
.get(`/api/profile/handle/${handle}`)
36+
.then((res) =>
37+
dispatch({
38+
type: GET_PROFILE,
39+
payload: res.data,
40+
})
41+
)
42+
.catch((err) =>
43+
dispatch({
44+
type: GET_PROFILE,
45+
payload: null,
46+
})
47+
);
48+
};
49+
3150
// create profile
3251
export const createProfile = (profileData, history) => (dispatch) => {
3352
axios

‎client/src/components/auth/Login.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Login extends Component {
2222
}
2323
}
2424

25-
componentWillReceiveProps(nextProps) {
25+
UNSAFE_componentWillReceiveProps(nextProps) {
2626
if (nextProps.auth.isAuthenticated) {
2727
this.props.history.push("/dashboard");
2828
}
@@ -94,7 +94,7 @@ Login.propTypes = {
9494
errors: PropTypes.object.isRequired,
9595
};
9696

97-
const mapStateToProps = state => ({
97+
const mapStateToProps = (state) => ({
9898
auth: state.auth,
9999
errors: state.errors,
100100
});

‎client/src/components/auth/Register.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class Register extends Component {
2525
}
2626
}
2727

28-
componentWillReceiveProps(nextProps) {
28+
UNSAFE_componentWillReceiveProps(nextProps) {
2929
if (nextProps.errors) {
3030
this.setState({ errors: nextProps.errors });
3131
}
@@ -114,7 +114,7 @@ Register.propTypes = {
114114
errors: PropTypes.object.isRequired,
115115
};
116116

117-
const mapStatetoProps = state => ({
117+
const mapStatetoProps = (state) => ({
118118
auth: state.auth,
119119
errors: state.errors,
120120
});

‎client/src/components/create-profile/CreateProfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class CreateProfile extends Component {
3333
this.onSubmit = this.onSubmit.bind(this);
3434
}
3535

36-
componentWillReceiveProps(nextProps) {
36+
UNSAFE_componentWillReceiveProps(nextProps) {
3737
if (nextProps.errors) {
3838
this.setState({ errors: nextProps.errors });
3939
}

‎client/src/components/dashboard/Education.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Education extends Component {
1010
}
1111
render() {
1212
const education = this.props.education.map((edu) => (
13-
<tr key={edu.id}>
13+
<tr key={edu._id}>
1414
<td>{edu.school}</td>
1515
<td>{edu.degree}</td>
1616
<td>

‎client/src/components/dashboard/Experience.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class Experience extends Component {
1010
}
1111
render() {
1212
const experience = this.props.experience.map((exp) => (
13-
<tr key={exp.id}>
13+
<tr key={exp._id}>
1414
<td>{exp.company}</td>
1515
<td>{exp.title}</td>
1616
<td>

‎client/src/components/edit-profile/EditProfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class CreateProfile extends Component {
3838
this.props.getCurrentProfile();
3939
}
4040

41-
componentWillReceiveProps(nextProps) {
41+
UNSAFE_componentWillReceiveProps(nextProps) {
4242
if (nextProps.errors) {
4343
this.setState({ errors: nextProps.errors });
4444
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from "react";
2+
3+
export default () => {
4+
return (
5+
<div className="container">
6+
<div className="row">
7+
<div className="col-md-6">
8+
<h1 className="display-4">Page Not Found</h1>
9+
<p>Sorry, this page does not exist</p>
10+
</div>
11+
</div>
12+
</div>
13+
);
14+
};
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import React, { Component } from "react";
2+
import { connect } from "react-redux";
3+
import PropTypes from "prop-types";
4+
import { Link } from "react-router-dom";
5+
import ProfileHeader from "./ProfileHeader";
6+
import ProfileAbout from "./ProfileAbout";
7+
import ProfileCreds from "./ProfileCreds";
8+
import ProfileGithub from "./ProfileGithub";
9+
import Spinner from "../common/Spinner";
10+
import { getProfileByHandle } from "../../actions/profileActions";
11+
12+
class Profile extends Component {
13+
componentDidMount() {
14+
if (this.props.match.params.handle) {
15+
this.props.getProfileByHandle(this.props.match.params.handle);
16+
}
17+
}
18+
19+
UNSAFE_componentWillReceiveProps(nextProps) {
20+
if (nextProps.profile.profile === null && this.props.profile.loading) {
21+
this.props.history.push("/not-found");
22+
}
23+
}
24+
25+
render() {
26+
const { profile, loading } = this.props.profile;
27+
let profileContent;
28+
29+
if (profile === null || loading) {
30+
profileContent = <Spinner />;
31+
} else {
32+
profileContent = (
33+
<div>
34+
<div className="row">
35+
<div className="col-md-6">
36+
<Link to="/profiles" className="btn btn-success mb-3 float-left">
37+
Back To Profiles
38+
</Link>
39+
<div className="col-md-6" />
40+
</div>
41+
</div>
42+
<ProfileHeader profile={profile} />
43+
<ProfileAbout profile={profile} />
44+
<ProfileCreds
45+
education={profile.education}
46+
experience={profile.experience}
47+
/>
48+
49+
{profile.githubusername ? (
50+
<ProfileGithub username={profile.githubusername} />
51+
) : null}
52+
</div>
53+
);
54+
}
55+
return (
56+
<div className="profile">
57+
<div className="container">
58+
<div className="row">
59+
<div className="col-md-12">{profileContent}</div>
60+
</div>
61+
</div>
62+
</div>
63+
);
64+
}
65+
}
66+
67+
Profile.propTypes = {
68+
getProfileByHandle: PropTypes.func.isRequired,
69+
profile: PropTypes.object.isRequired,
70+
};
71+
72+
const mapStatetoProps = (state) => ({
73+
profile: state.profile,
74+
});
75+
76+
export default connect(mapStatetoProps, { getProfileByHandle })(Profile);
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import React, { Component } from "react";
2+
import PropTypes from "prop-types";
3+
import isEmpty from "../../validation/is-empty";
4+
5+
class ProfileAbout extends Component {
6+
render() {
7+
const { profile } = this.props;
8+
9+
const getFirstName = profile.user.name.trim().split(" ")[0];
10+
11+
const skills = profile.skills.map((skill, index) => (
12+
<div className="p-3" key={index}>
13+
<i className="fa fa-check" />
14+
{skill}
15+
</div>
16+
));
17+
return (
18+
<div className="row">
19+
<div className="card card-body bg-light mb-3">
20+
<h3 className="text-center text-info">{getFirstName}'s Bio</h3>
21+
<p className="lead">
22+
{isEmpty(profile.bio) ? (
23+
<span>{getFirstName} does not have a Bio yet!</span>
24+
) : (
25+
<span>{profile.bio}</span>
26+
)}
27+
</p>
28+
<hr />
29+
<h3 className="text-center text-info">Skill Set</h3>
30+
<div className="row">
31+
<div className="d-flex flex-wrap justify-content-center align-items-center">
32+
{skills}
33+
</div>
34+
</div>
35+
</div>
36+
</div>
37+
);
38+
}
39+
}
40+
41+
ProfileAbout.propTypes = {
42+
profile: PropTypes.object.isRequired,
43+
};
44+
45+
export default ProfileAbout;
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import React, { Component } from "react";
2+
import Moment from "react-moment";
3+
4+
class ProfileCreds extends Component {
5+
render() {
6+
const { experience, education } = this.props;
7+
8+
const expItems = experience.map((exp) => (
9+
<li className="list-group-item" key={exp._id}>
10+
<h4>{exp.company}</h4>
11+
<p>
12+
<Moment format="YYYY/MM/DD">{exp.from}</Moment> -
13+
{exp.to === null ? (
14+
" Now"
15+
) : (
16+
<Moment format="YYYY/MM/DD">{exp.to}</Moment>
17+
)}
18+
</p>
19+
<p>
20+
<strong>Position: </strong>
21+
{exp.title}
22+
</p>
23+
<p>
24+
{exp.location === "" ? null : (
25+
<span>
26+
<strong>Location: </strong>
27+
{exp.location}
28+
</span>
29+
)}
30+
</p>
31+
<p>
32+
{exp.description === "" ? null : (
33+
<span>
34+
<strong>Description: </strong>
35+
{exp.description}
36+
</span>
37+
)}
38+
</p>
39+
</li>
40+
));
41+
42+
const eduItems = education.map((edu) => (
43+
<li className="list-group-item" key={edu._id}>
44+
<h4>{edu.school}</h4>
45+
<p>
46+
<Moment format="YYYY/MM/DD">{edu.from}</Moment> -
47+
{edu.to === null ? (
48+
" Now"
49+
) : (
50+
<Moment format="YYYY/MM/DD">{edu.to}</Moment>
51+
)}
52+
</p>
53+
<p>
54+
<strong>Degree: </strong>
55+
{edu.degree}
56+
</p>
57+
<p>
58+
<strong>Field of Study: </strong>
59+
{edu.fieldofstudy}
60+
</p>
61+
<p>
62+
{edu.description === "" ? null : (
63+
<span>
64+
<strong>Description: </strong>
65+
{edu.description}
66+
</span>
67+
)}
68+
</p>
69+
</li>
70+
));
71+
72+
return (
73+
<div className="row">
74+
<div className="col-md-6">
75+
<h3 className="text-center text-info">Experience</h3>
76+
{expItems.length > 0 ? (
77+
<ul className="list-group">{expItems}</ul>
78+
) : (
79+
<p className="text-center">No Experience Listed</p>
80+
)}
81+
</div>
82+
83+
<div className="col-md-6">
84+
<h3 className="text-center text-info">Education</h3>
85+
{expItems.length > 0 ? (
86+
<ul className="list-group">{eduItems}</ul>
87+
) : (
88+
<p className="text-center">No Education Listed</p>
89+
)}
90+
</div>
91+
</div>
92+
);
93+
}
94+
}
95+
96+
export default ProfileCreds;

0 commit comments

Comments
 (0)
Please sign in to comment.