diff --git a/src/components/ProfilePage.jsx b/src/components/ProfilePage.jsx index 79bafec..3a9dc43 100644 --- a/src/components/ProfilePage.jsx +++ b/src/components/ProfilePage.jsx @@ -101,6 +101,7 @@ export class ProfilePage extends React.Component { onSave={this.handleSaveProfilePhoto} onDelete={this.handleDeleteProfilePhoto} savePhotoState={this.props.savePhotoState} + isEditable={this.props.isCurrentUserProfile} />

{username}

@@ -201,7 +202,8 @@ ProfilePage.defaultProps = { const mapStateToProps = (state) => { const profileImage = state.profilePage.account.profileImage != null - ? state.profilePage.account.profileImage.imageUrlLarge + // TODO: This will change back to camelcase in the future + ? state.profilePage.account.profileImage.image_url_large : null; return { isCurrentUserProfile: state.userAccount.username === state.profilePage.account.username, diff --git a/src/components/ProfilePage/ProfileAvatar.jsx b/src/components/ProfilePage/ProfileAvatar.jsx index 09791e0..9b21bfa 100644 --- a/src/components/ProfilePage/ProfileAvatar.jsx +++ b/src/components/ProfilePage/ProfileAvatar.jsx @@ -1,21 +1,28 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Input, Spinner } from 'reactstrap'; +import { Input, Spinner, Dropdown, DropdownToggle, DropdownMenu, DropdownItem, Button } from 'reactstrap'; +import { FormattedMessage } from 'react-intl'; + class ProfileAvatar extends React.Component { constructor(props) { super(props); + this.state = { + dropdownOpen: false, + }; + this.fileInput = React.createRef(); this.form = React.createRef(); - this.onClick = this.onClick.bind(this); + this.onClickUpload = this.onClickUpload.bind(this); this.onClickDelete = this.onClickDelete.bind(this); this.onInput = this.onInput.bind(this); this.onSubmit = this.onSubmit.bind(this); + this.toggleDropdown = this.toggleDropdown.bind(this); } - onClick() { + onClickUpload() { this.fileInput.current.click(); } @@ -32,58 +39,104 @@ class ProfileAvatar extends React.Component { this.props.onSave(new FormData(this.form.current)); } - render() { - const { - src, - } = this.props; + toggleDropdown() { + this.setState({ + dropdownOpen: !this.state.dropdownOpen, + }); + } + + renderPending() { + return ( +
+ +
+ ); + } + + renderMenu() { + if (!this.props.isEditable) return null; + + // TODO: only checking for null now. We need a way to + // check if this src is the default image + const hasImage = this.props.src === null; + + if (hasImage) { + return ( + + ); + } return ( -
-
- {this.props.savePhotoState === 'pending' ? ( -
- -
- ) : null} - - - -
- profile avatar - - {/* The name of this input must be 'file' */} - + + + + + + - + + + + +
+ + ); + } + render() { + return ( +
+
+
+ {this.props.savePhotoState === 'pending' ? this.renderPending() : this.renderMenu() } +
+ profile avatar
- {src ? ( - - ) : null} +
+ {/* The name of this input must be 'file' */} + +
); } @@ -97,9 +150,11 @@ ProfileAvatar.propTypes = { onSave: PropTypes.func.isRequired, onDelete: PropTypes.func.isRequired, savePhotoState: PropTypes.oneOf([null, 'pending', 'complete', 'error']), + isEditable: PropTypes.bool, }; ProfileAvatar.defaultProps = { src: null, savePhotoState: null, + isEditable: false, }; diff --git a/src/index.scss b/src/index.scss index 71e85b9..1478596 100755 --- a/src/index.scss +++ b/src/index.scss @@ -57,6 +57,27 @@ $fa-font-path: "~font-awesome/fonts"; } } + .profile-avatar-menu-container { + background: rgba(0,0,0,.65); + position: absolute; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + @include media-breakpoint-up(md) { + background: linear-gradient(to top, rgba(0,0,0,.65) 4rem, rgba(0,0,0,0) 4rem); + align-items: flex-end; + } + .btn { + text-decoration: none; + @include media-breakpoint-up(md) { + margin-bottom: 1.2rem; + } + } + } + .profile-avatar { width: 5rem; height: 5rem;