Files
frontend-app-profile/src/components/ProfilePage.jsx
Adam Butterworth 6f4753b7db Add "member since 2017" (#44)
* Add date joined

* Create a Date object to get the year

* Add date joined

* Create a Date object to get the year

* add i18n

* Update 18n key
2019-02-28 16:08:09 -05:00

234 lines
6.9 KiB
JavaScript

import React from 'react';
import PropTypes from 'prop-types';
import { Container, Row, Col } from 'reactstrap';
import { connect } from 'react-redux';
// Actions
import {
fetchProfile,
saveProfile,
saveProfilePhoto,
deleteProfilePhoto,
openForm,
closeForm,
updateVisibilityDraft,
updateAccountDraft,
} from '../actions/ProfileActions';
// Components
import ProfileAvatar from './ProfilePage/ProfileAvatar';
import Name from './ProfilePage/Name';
import Country from './ProfilePage/Country';
import Education from './ProfilePage/Education';
import SocialLinks from './ProfilePage/SocialLinks';
import Bio from './ProfilePage/Bio';
import Certificates from './ProfilePage/Certificates';
import AgeMessage from './ProfilePage/AgeMessage';
import DateJoined from './ProfilePage/DateJoined';
export class ProfilePage extends React.Component {
constructor(props) {
super(props);
this.handleSaveProfilePhoto = this.handleSaveProfilePhoto.bind(this);
this.handleDeleteProfilePhoto = this.handleDeleteProfilePhoto.bind(this);
this.handleClose = this.handleClose.bind(this);
this.handleOpen = this.handleOpen.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
componentDidMount() {
this.props.fetchProfile(this.props.match.params.username);
}
handleSaveProfilePhoto(formData) {
this.props.saveProfilePhoto(this.props.username, formData);
}
handleDeleteProfilePhoto() {
this.props.deleteProfilePhoto(this.props.username);
}
handleClose(formId) {
this.props.closeForm(formId);
}
handleOpen(formId) {
this.props.openForm(formId);
}
handleSubmit(formId) {
this.props.saveProfile(formId);
}
handleChange(formId, name, value) {
if (name === 'visibility') {
this.props.updateVisibilityDraft(formId, value);
} else {
this.props.updateAccountDraft(formId, value);
}
}
render() {
const {
profileImage, username, dateJoined, errors,
} = this.props;
const commonFormProps = {
openHandler: this.handleOpen,
closeHandler: this.handleClose,
submitHandler: this.handleSubmit,
changeHandler: this.handleChange,
errors,
};
return (
<div className="profile-page">
<div className="bg-banner bg-program-micro-masters d-none d-md-block p-relative" />
<Container fluid>
<Row>
<Col md={4} lg={3}>
<div className="d-flex align-items-center d-md-block mt-4 mt-md-0">
<ProfileAvatar
className="mb-md-3"
src={profileImage}
onSave={this.handleSaveProfilePhoto}
onDelete={this.handleDeleteProfilePhoto}
savePhotoState={this.props.savePhotoState}
/>
<div>
<h2 className="mb-0">{username}</h2>
<DateJoined date={dateJoined} />
</div>
</div>
</Col>
</Row>
<Row>
<Col xs={{ order: 2 }} md={{ size: 4, order: 1 }} lg={3} className="mt-md-4">
<Name formId="name" {...commonFormProps} />
<Country formId="country" {...commonFormProps} />
<Education formId="education" {...commonFormProps} />
<SocialLinks formId="socialLinks" {...commonFormProps} />
</Col>
<Col
xs={{ order: 1 }}
md={{ size: 8, order: 2 }}
lg={{ size: 8, offset: 1 }}
className="mt-4 mt-md-n5"
>
{this.props.requiresParentalConsent ? <AgeMessage accountURL="#account" /> : null}
<Bio formId="bio" {...commonFormProps} />
<Certificates formId="certificates" {...commonFormProps} />
</Col>
</Row>
</Container>
</div>
);
}
}
ProfilePage.propTypes = {
// Page state helpers
currentlyEditingField: PropTypes.string,
saveState: PropTypes.oneOf([null, 'pending', 'complete', 'error']),
savePhotoState: PropTypes.oneOf([null, 'pending', 'complete', 'error']),
isCurrentUserProfile: PropTypes.bool.isRequired,
errors: PropTypes.objectOf(PropTypes.string),
// Profile data
username: PropTypes.string,
dateJoined: PropTypes.string,
profileImage: PropTypes.string,
accountPrivacy: PropTypes.string,
certificates: PropTypes.arrayOf(PropTypes.shape({
title: PropTypes.string,
})),
// Profile data for form fields
education: PropTypes.string,
socialLinks: PropTypes.arrayOf(PropTypes.shape({
platform: PropTypes.string,
socialLink: PropTypes.string,
})),
bio: PropTypes.string,
visibility: PropTypes.objectOf(PropTypes.string),
// Actions
fetchProfile: PropTypes.func.isRequired,
saveProfile: PropTypes.func.isRequired,
saveProfilePhoto: PropTypes.func.isRequired,
deleteProfilePhoto: PropTypes.func.isRequired,
openForm: PropTypes.func.isRequired,
closeForm: PropTypes.func.isRequired,
updateVisibilityDraft: PropTypes.func.isRequired,
updateAccountDraft: PropTypes.func.isRequired,
// Router
match: PropTypes.shape({
params: PropTypes.shape({
username: PropTypes.string.isRequired,
}).isRequired,
}).isRequired,
yearOfBirth: PropTypes.number,
requiresParentalConsent: PropTypes.bool,
};
ProfilePage.defaultProps = {
currentlyEditingField: null,
saveState: null,
savePhotoState: null,
errors: {},
profileImage: null,
username: null,
education: null,
socialLinks: [],
bio: null,
certificates: null,
accountPrivacy: null,
visibility: {}, // eslint-disable-line
yearOfBirth: null,
requiresParentalConsent: null,
dateJoined: null,
};
const mapStateToProps = (state) => {
const profileImage =
state.profilePage.account.profileImage != null
? state.profilePage.account.profileImage.imageUrlLarge
: null;
return {
isCurrentUserProfile: state.userAccount.username === state.profilePage.account.username,
currentlyEditingField: state.profilePage.currentlyEditingField,
saveState: state.profilePage.saveState,
savePhotoState: state.profilePage.savePhotoState,
error: state.profilePage.error,
profileImage,
username: state.profilePage.account.username,
education: state.profilePage.account.levelOfEducation,
socialLinks: state.profilePage.account.socialLinks,
bio: state.profilePage.account.bio,
certificates: state.profilePage.account.certificates,
accountPrivacy: state.profilePage.preferences.accountPrivacy,
visibility: state.profilePage.preferences.visibility || {},
yearOfBirth: state.profilePage.account.yearOfBirth,
requiresParentalConsent: state.profilePage.account.requiresParentalConsent,
dateJoined: state.profilePage.account.dateJoined,
};
};
export default connect(
mapStateToProps,
{
fetchProfile,
saveProfilePhoto,
deleteProfilePhoto,
saveProfile,
openForm,
closeForm,
updateVisibilityDraft,
updateAccountDraft,
},
)(ProfilePage);