project done
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
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';
|
||||
|
||||
const Profile = ({ getProfileById, profile: { profile }, auth }) => {
|
||||
const { id } = useParams();
|
||||
useEffect(() => {
|
||||
getProfileById(id);
|
||||
}, [getProfileById, id]);
|
||||
|
||||
return (
|
||||
<section className="container">
|
||||
{profile === null ? (
|
||||
<Spinner />
|
||||
) : (
|
||||
<Fragment>
|
||||
<Link to="/profiles" className="btn btn-light">
|
||||
Back To Profiles
|
||||
</Link>
|
||||
{auth.isAuthenticated &&
|
||||
auth.loading === false &&
|
||||
auth.user._id === profile.user._id && (
|
||||
<Link to="/edit-profile" className="btn btn-dark">
|
||||
Edit Profile
|
||||
</Link>
|
||||
)}
|
||||
<div className="profile-grid my-1">
|
||||
<ProfileTop profile={profile} />
|
||||
<ProfileAbout profile={profile} />
|
||||
<div className="profile-exp bg-white p-2">
|
||||
<h2 className="text-primary">Experience</h2>
|
||||
{profile.experience.length > 0 ? (
|
||||
<Fragment>
|
||||
{profile.experience.map((experience) => (
|
||||
<ProfileExperience
|
||||
key={experience._id}
|
||||
experience={experience}
|
||||
/>
|
||||
))}
|
||||
</Fragment>
|
||||
) : (
|
||||
<h4>No experience credentials</h4>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="profile-edu bg-white p-2">
|
||||
<h2 className="text-primary">Education</h2>
|
||||
{profile.education.length > 0 ? (
|
||||
<Fragment>
|
||||
{profile.education.map((education) => (
|
||||
<ProfileEducation
|
||||
key={education._id}
|
||||
education={education}
|
||||
/>
|
||||
))}
|
||||
</Fragment>
|
||||
) : (
|
||||
<h4>No education credentials</h4>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{profile.githubusername && (
|
||||
<ProfileGithub username={profile.githubusername} />
|
||||
)}
|
||||
</div>
|
||||
</Fragment>
|
||||
)}
|
||||
</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);
|
||||
@@ -0,0 +1,34 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const ProfileAbout = ({
|
||||
profile: {
|
||||
bio,
|
||||
skills,
|
||||
user: { name }
|
||||
}
|
||||
}) => (
|
||||
<div className='profile-about bg-light p-2'>
|
||||
{bio && (
|
||||
<Fragment>
|
||||
<h2 className='text-primary'>{name.trim().split(' ')[0]}s Bio</h2>
|
||||
<p>{bio}</p>
|
||||
<div className='line' />
|
||||
</Fragment>
|
||||
)}
|
||||
<h2 className='text-primary'>Skill Set</h2>
|
||||
<div className='skills'>
|
||||
{skills.map((skill, index) => (
|
||||
<div key={index} className='p-1'>
|
||||
<i className='fas fa-check' /> {skill}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
ProfileAbout.propTypes = {
|
||||
profile: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default ProfileAbout;
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import formatDate from '../../utils/formatDate';
|
||||
|
||||
const ProfileEducation = ({
|
||||
education: { school, degree, fieldofstudy, current, to, from, description }
|
||||
}) => (
|
||||
<div>
|
||||
<h3 className="text-dark">{school}</h3>
|
||||
<p>
|
||||
{formatDate(from)} - {to ? formatDate(to) : 'Now'}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Degree: </strong> {degree}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Field Of Study: </strong> {fieldofstudy}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Description: </strong> {description}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
ProfileEducation.propTypes = {
|
||||
education: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default ProfileEducation;
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import formatDate from '../../utils/formatDate';
|
||||
|
||||
const ProfileExperience = ({
|
||||
experience: { company, title, location, current, to, from, description }
|
||||
}) => (
|
||||
<div>
|
||||
<h3 className="text-dark">{company}</h3>
|
||||
<p>
|
||||
{formatDate(from)} - {to ? formatDate(to) : 'Now'}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Position: </strong> {title}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Location: </strong> {location}
|
||||
</p>
|
||||
<p>
|
||||
<strong>Description: </strong> {description}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
ProfileExperience.propTypes = {
|
||||
experience: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default ProfileExperience;
|
||||
@@ -0,0 +1,51 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect } from 'react-redux';
|
||||
import { getGithubRepos } from '../../actions/profile';
|
||||
|
||||
const ProfileGithub = ({ username, getGithubRepos, repos }) => {
|
||||
useEffect(() => {
|
||||
getGithubRepos(username);
|
||||
}, [getGithubRepos, username]);
|
||||
|
||||
return (
|
||||
<div className="profile-github">
|
||||
<h2 className="text-primary my-1">Github Repos</h2>
|
||||
{repos.map(repo => (
|
||||
<div key={repo.id} className="repo bg-white p-1 my-1">
|
||||
<div>
|
||||
<h4>
|
||||
<a href={repo.html_url} target="_blank" rel="noopener noreferrer">
|
||||
{repo.name}
|
||||
</a>
|
||||
</h4>
|
||||
<p>{repo.description}</p>
|
||||
</div>
|
||||
<div>
|
||||
<ul>
|
||||
<li className="badge badge-primary">
|
||||
Stars: {repo.stargazers_count}
|
||||
</li>
|
||||
<li className="badge badge-dark">
|
||||
Watchers: {repo.watchers_count}
|
||||
</li>
|
||||
<li className="badge badge-light">Forks: {repo.forks_count}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
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);
|
||||
@@ -0,0 +1,51 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const ProfileTop = ({
|
||||
profile: {
|
||||
status,
|
||||
company,
|
||||
location,
|
||||
website,
|
||||
social,
|
||||
user: { name, avatar }
|
||||
}
|
||||
}) => {
|
||||
return (
|
||||
<div className="profile-top bg-primary p-2">
|
||||
<img className="round-img my-1" src={avatar} alt="" />
|
||||
<h1 className="large">{name}</h1>
|
||||
<p className="lead">
|
||||
{status} {company ? <span> at {company}</span> : null}
|
||||
</p>
|
||||
<p>{location ? <span>{location}</span> : null}</p>
|
||||
<div className="icons my-1">
|
||||
{website ? (
|
||||
<a href={website} target="_blank" rel="noopener noreferrer">
|
||||
<i className="fas fa-globe fa-2x" />
|
||||
</a>
|
||||
) : null}
|
||||
{social
|
||||
? Object.entries(social)
|
||||
.filter(([_, value]) => value)
|
||||
.map(([key, value]) => (
|
||||
<a
|
||||
key={key}
|
||||
href={value}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<i className={`fab fa-${key} fa-2x`}></i>
|
||||
</a>
|
||||
))
|
||||
: null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ProfileTop.propTypes = {
|
||||
profile: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default ProfileTop;
|
||||
Reference in New Issue
Block a user