Add basic profile editor

This commit is contained in:
Alex Gleason 2020-04-21 18:00:05 -05:00
parent 6db6793b8b
commit f2b1305ce9
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
5 changed files with 133 additions and 4 deletions

View file

@ -25,7 +25,6 @@ export function fetchMe() {
api(getState).get('/api/v1/accounts/verify_credentials').then(response => {
dispatch(fetchMeSuccess(response.data));
dispatch(importFetchedAccount(response.data));
}).catch(error => {
dispatch(fetchMeFail(error));
});
@ -34,6 +33,7 @@ export function fetchMe() {
export function patchMe(params) {
return (dispatch, getState) => {
dispatch(patchMeRequest());
return api(getState)
.patch('/api/v1/accounts/update_credentials', params)
.then(response => {
@ -51,9 +51,12 @@ export function fetchMeRequest() {
}
export function fetchMeSuccess(me) {
return {
type: ME_FETCH_SUCCESS,
me,
return (dispatch, getState) => {
dispatch(importFetchedAccount(me));
dispatch({
type: ME_FETCH_SUCCESS,
me,
});
};
}

View file

@ -0,0 +1,87 @@
import React from 'react';
import { connect } from 'react-redux';
import { defineMessages, injectIntl } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Column from '../ui/components/column';
import {
SimpleForm,
FieldsGroup,
TextInput,
} from 'gabsocial/features/forms';
import { patchMe } from 'gabsocial/actions/me';
const messages = defineMessages({
heading: { id: 'column.edit_profile', defaultMessage: 'Edit profile' },
});
const mapStateToProps = state => {
const me = state.get('me');
return {
account: state.getIn(['accounts', me]),
};
};
export default @connect(mapStateToProps)
@injectIntl
class EditProfile extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map,
};
constructor(props) {
super(props);
this.state = { isLoading: false };
}
getFormData = (form) => {
return Object.fromEntries(
new FormData(form).entries()
);
}
handleSubmit = (event) => {
const { dispatch } = this.props;
const formData = this.getFormData(event.target);
dispatch(patchMe(formData)).then(() => {
this.setState({ isLoading: false });
}).catch((error) => {
this.setState({ isLoading: false });
});
this.setState({ isLoading: true });
event.preventDefault();
}
render() {
const { account, intl } = this.props;
return (
<Column icon='users' heading={intl.formatMessage(messages.heading)} backBtnSlim>
<SimpleForm onSubmit={this.handleSubmit}>
<fieldset disabled={this.state.isLoading}>
<FieldsGroup>
<TextInput
label='Display name'
name='display_name'
defaultValue={account.get('display_name')}
/>
<TextInput
label='Bio'
name='note'
defaultValue={account.get('bio')}
/>
</FieldsGroup>
</fieldset>
<div className='actions'>
<button name='button' type='submit' className='btn button button-primary'>Save changes</button>
</div>
</SimpleForm>
</Column>
);
}
}

View file

@ -184,3 +184,36 @@ export class SelectDropdown extends ImmutablePureComponent {
}
}
export class TextInput extends ImmutablePureComponent {
static propTypes = {
label: PropTypes.string,
name: PropTypes.string,
defaultValue: PropTypes.string,
maxLength: PropTypes.number,
}
render() {
const { label, name, defaultValue, maxLength } = this.props;
return (
<div className='input with_label string optional'>
<div className='label_input'>
<label className='string optional' htmlFor={name}>{label}</label>
<div className='label_input__wrapper'>
<input
maxlength={maxLength}
className='string optional'
size={maxLength}
type='text'
defaultValue={defaultValue}
name={name}
id={name}
/>
</div>
</div>
</div>
);
}
}

View file

@ -67,6 +67,7 @@ import {
// GroupEdit,
LoginPage,
Preferences,
EditProfile,
} from './util/async-components';
// Dummy import, to make sure that <Status /> ends up in the application bundle.
@ -236,6 +237,7 @@ class SwitchingColumnsArea extends React.PureComponent {
<WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
<WrappedRoute path='/settings/preferences' layout={LAYOUT.DEFAULT} component={Preferences} content={children} />
<WrappedRoute path='/settings/profile' layout={LAYOUT.DEFAULT} component={EditProfile} content={children} />
<WrappedRoute layout={LAYOUT.EMPTY} component={GenericNotFound} content={children} />
</Switch>

View file

@ -165,3 +165,7 @@ export function LoginPage() {
export function Preferences() {
return import(/* webpackChunkName: "features/preferences" */'../../preferences');
}
export function EditProfile() {
return import(/* webpackChunkName: "features/edit_profile" */'../../edit_profile');
}