Added back EditProfileModal to all edit profile action buttons

• Added:
- back EditProfileModal to all edit profile action buttons
- AccountActionButton, UserPanel, ProfileHeader
This commit is contained in:
mgabdev 2020-07-17 15:25:05 -05:00
parent 1e55e2e920
commit 10a410be53
4 changed files with 201 additions and 54 deletions

View File

@ -8,6 +8,7 @@ import {
} from '../actions/accounts' } from '../actions/accounts'
import { openModal } from '../actions/modal' import { openModal } from '../actions/modal'
import { me, unfollowModal } from '../initial_state' import { me, unfollowModal } from '../initial_state'
import { MODAL_EDIT_PROFILE } from '../constants'
import Button from './button' import Button from './button'
import Text from './text' import Text from './text'
@ -51,6 +52,10 @@ const mapDispatchToProps = (dispatch) => ({
} }
}, },
onOpenEditProfile() {
dispatch(openModal(MODAL_EDIT_PROFILE))
},
}); });
export default export default
@ -64,6 +69,7 @@ class AccountActionButton extends ImmutablePureComponent {
isSmall: PropTypes.bool, isSmall: PropTypes.bool,
onBlock: PropTypes.func.isRequired, onBlock: PropTypes.func.isRequired,
onFollow: PropTypes.func.isRequired, onFollow: PropTypes.func.isRequired,
onOpenEditProfile: PropTypes.func.isRequired,
} }
updateOnProps = [ updateOnProps = [
@ -78,6 +84,10 @@ class AccountActionButton extends ImmutablePureComponent {
this.props.onBlock(this.props.account) this.props.onBlock(this.props.account)
} }
handleOnEditProfile = () => {
this.props.onOpenEditProfile()
}
render() { render() {
const { const {
account, account,
@ -98,7 +108,7 @@ class AccountActionButton extends ImmutablePureComponent {
if (isMe) { if (isMe) {
buttonText = intl.formatMessage(messages.edit_profile) buttonText = intl.formatMessage(messages.edit_profile)
buttonOptions = { buttonOptions = {
href: '/settings/profile', onClick: this.handleOnEditProfile,
color: 'brand', color: 'brand',
backgroundColor: 'none', backgroundColor: 'none',
isOutline: true, isOutline: true,

View File

@ -1,89 +1,222 @@
import { Fragment } from 'react'
import { defineMessages, injectIntl } from 'react-intl' import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component' import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes' import ImmutablePropTypes from 'react-immutable-proptypes'
import { saveUserProfileInformation } from '../../actions/user'
import { me } from '../../initial_state' import { me } from '../../initial_state'
import ModalLayout from './modal_layout'
import Avatar from '../avatar'
import Button from '../button' import Button from '../button'
import Block from '../block'
import Divider from '../divider' import Divider from '../divider'
import Image from '../image' import FileInput from '../file_input'
import Input from '../input' import Input from '../input'
import Text from '../text' import Switch from '../switch'
import Heading from '../heading'
import Textarea from '../textarea' import Textarea from '../textarea'
const messages = defineMessages({ const messages = defineMessages({
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
headerPhoto: { id: 'header_photo', defaultMessage: 'Header photo' }, headerPhoto: { id: 'header_photo', defaultMessage: 'Header photo' },
close: { id: 'lightbox.close', defaultMessage: 'Close' },
save: { id: 'lightbox.save', defaultMessage: 'Save' },
}) })
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
account: state.getIn(['accounts', me]), account: state.getIn(['accounts', me]),
}) })
const mapDispatchToProps = (dispatch) => ({
onSave: (data) => dispatch(saveUserProfileInformation(data)),
})
export default export default
@injectIntl @injectIntl
@connect(mapStateToProps) @connect(mapStateToProps, mapDispatchToProps)
class EditProfileModal extends ImmutablePureComponent { class EditProfileModal extends ImmutablePureComponent {
static propTypes = { static propTypes = {
account: ImmutablePropTypes.map, account: ImmutablePropTypes.map,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired,
onSave: PropTypes.func.isRequired,
}
state = {
avatarSrc: this.props.account ? this.props.account.get('avatar_static') : undefined,
bioValue: this.props.account ? this.props.account.get('note_plain') : '',
displayNameValue: this.props.account ? this.props.account.get('display_name_plain') : '',
headerSrc: this.props.account ? this.props.account.get('header_static') : undefined,
locked: this.props.account ? this.props.account.get('locked') : false,
}
componentDidUpdate (prevProps) {
if (prevProps.account !== this.props.account) {
if (this.props.account) {
this.setState({
avatarSrc: this.props.account.get('avatar_static'),
bioValue: this.props.account.get('note_plain'),
displayNameValue: this.props.account.get('display_name_plain'),
headerSrc: this.props.account.get('header_static'),
locked: this.props.account.get('locked'),
})
} else {
this.setState({
avatarSrc: undefined,
bioValue: '',
displayNameValue: '',
headerSrc: undefined,
locked: false,
})
}
}
}
handleCoverPhotoChange = (e) => {
try {
this.setState({ headerSrc: e.target.files[0] })
} catch (error) {
//
}
}
handleProfilePhotoChange = (e) => {
try {
this.setState({ avatarSrc: e.target.files[0] })
} catch (error) {
//
}
}
handleDisplayNameChange = (value) => {
this.setState({ displayNameValue: value })
}
handleBioChange = (value) => {
this.setState({ bioValue: value })
}
handleLockedChange = ({ target }) => {
this.setState({ locked: target.checked })
}
handleOnClose = () => {
this.props.onClose()
}
handleOnSave = () => {
const { account } = this.props
const {
avatarSrc,
bioValue,
displayNameValue,
headerSrc,
locked,
} = this.state
const isPro = account.get('is_pro')
const obj = {}
obj.locked = locked
if (!isPro && account.get('display_name_plain') !== displayNameValue) obj.displayName = displayNameValue
if (account.get('note_plain') !== bioValue) obj.note = bioValue
if (account.get('avatar_static') !== avatarSrc) obj.avatar = avatarSrc
if (account.get('header_static') !== headerSrc) obj.header = headerSrc
this.props.onSave(obj)
this.handleOnClose()
} }
render() { render() {
const { account, intl, onClose } = this.props const { intl, account } = this.props
const {
avatarSrc,
bioValue,
displayNameValue,
headerSrc,
locked,
} = this.state
const headerSrc = !!account ? account.get('header') : '' const isPro = account.get('is_pro')
return ( return (
<ModalLayout <div style={{ width: '440px' }} className={[_s.default, _s.modal].join(' ')}>
title={intl.formatMessage(messages.edit_profile)} <Block>
noPadding <div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.justifyContentCenter, _s.borderBottom1PX, _s.borderColorSecondary, _s.height53PX, _s.px15].join(' ')}>
width={460} <Button
onClose={onClose} backgroundColor='none'
title={intl.formatMessage(messages.close)}
className={[_s.mrAuto, _s.width60PX, _s.pl0].join(' ')}
onClick={this.handleOnClose}
color='secondary'
icon='close'
iconSize='10px'
/>
<Heading size='h2'>
{intl.formatMessage(messages.edit_profile)}
</Heading>
<Button
title={intl.formatMessage(messages.save)}
className={[_s.mlAuto, _s.width60PX].join(' ')}
onClick={this.handleOnSave}
> >
<div className={[_s.default, _s.py5, _s.px5, _s.width100PC, _s.overflowHidden].join(' ')}> {intl.formatMessage(messages.save)}
<Image </Button>
alt={intl.formatMessage(messages.headerPhoto)} </div>
className={_s.radiusSmall} <div className={[_s.default, _s.heightMax80VH, _s.overflowYScroll].join(' ')}>
<div className={[_s.default, _s.width100PC, _s.alignItemsCenter].join(' ')}>
<FileInput
width='440px'
height='180px' height='180px'
src={headerSrc} id='cover-photo'
onChange={this.handleCoverPhotoChange}
file={headerSrc}
/>
<div className={[_s.default, _s.mtNeg50PX, _s.alignItemsCenter, _s.justifyContentCenter].join(' ')}>
<FileInput
width='132px'
height='132px'
id='profile-photo'
file={avatarSrc}
className={[_s.circle, _s.border6PX, _s.borderColorWhite, _s.bgPrimary].join(' ')}
onChange={this.handleProfilePhotoChange}
/> />
</div> </div>
<div className={[_s.default, _s.py5, _s.px15, _s.mt5, _s.mb15, _s.width100PC].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.pl25].join(' ')}> {
<div className={[_s.default, _s.circle, _s.mtNeg75PX, _s.boxShadowProfileAvatar].join(' ')}> !isPro &&
<Avatar <Fragment>
size={98}
account={account}
noHover
/>
</div>
</div>
<div className={[_s.default, _s.px15, _s.py15].join(' ')}>
<Input <Input
title='Name' id='display-name'
value='' title='Display name'
value={displayNameValue}
onChange={this.handleDisplayNameChange}
onBlur={this.handleDisplayNameBlur}
/>
<Divider isInvisible />
</Fragment>
}
<Textarea
title='Bio'
value={bioValue}
disabled={false} disabled={false}
// onChange={this.handleTitleChange} onChange={this.handleBioChange}
placeholder='Add your name...' placeholder='Add your bio...'
/> />
<Divider isInvisible /> <Divider isInvisible />
<Textarea <div className={[_s.default, _s.px10].join(' ')}>
title='Bio' <Switch
value='' label='Private account'
disabled={false} checked={locked}
// onChange={this.handleDescriptionChange} onChange={this.handleLockedChange}
placeholder='Add your bio...'
/> />
</div> </div>
</div>
</ModalLayout> </div>
</div>
</Block>
</div>
) )
} }
} }

View File

@ -62,6 +62,10 @@ class UserPanel extends ImmutablePureComponent {
this.setState({ hovering: false }) this.setState({ hovering: false })
} }
handleOnEditProfile = () => {
this.props.onOpenEditProfile()
}
render() { render() {
const { const {
account, account,
@ -98,7 +102,7 @@ class UserPanel extends ImmutablePureComponent {
backgroundColor='secondary' backgroundColor='secondary'
radiusSmall radiusSmall
className={buttonClasses} className={buttonClasses}
href='/settings/profile' onClick={this.handleOnEditProfile}
> >
{intl.formatMessage(messages.edit_profile)} {intl.formatMessage(messages.edit_profile)}
</Button> </Button>

View File

@ -208,7 +208,7 @@ class ProfileHeader extends ImmutablePureComponent {
backgroundColor='none' backgroundColor='none'
color='brand' color='brand'
className={[_s.justifyContentCenter, _s.alignItemsCenter].join(' ')} className={[_s.justifyContentCenter, _s.alignItemsCenter].join(' ')}
href='/settings/profile' onClick={this.handleOnEditProfile}
> >
<Text color='inherit' weight='bold' size='medium' className={_s.px15}> <Text color='inherit' weight='bold' size='medium' className={_s.px15}>
{intl.formatMessage(messages.editProfile)} {intl.formatMessage(messages.editProfile)}
@ -310,7 +310,7 @@ class ProfileHeader extends ImmutablePureComponent {
backgroundColor='none' backgroundColor='none'
color='brand' color='brand'
className={[_s.justifyContentCenter, _s.alignItemsCenter].join(' ')} className={[_s.justifyContentCenter, _s.alignItemsCenter].join(' ')}
href='/settings/profile' onClick={this.handleOnEditProfile}
> >
<Text color='inherit' weight='bold' size='medium' className={_s.px15}> <Text color='inherit' weight='bold' size='medium' className={_s.px15}>
{intl.formatMessage(messages.editProfile)} {intl.formatMessage(messages.editProfile)}