diff options
author | akshitkrnagpal <akshitkrnagpal@gmail.com> | 2018-06-09 21:40:00 +0530 |
---|---|---|
committer | Saúl Ibarra Corretgé <s@saghul.net> | 2018-06-21 07:55:32 +0200 |
commit | 8f79e886fc56760694b3e1f470a8e61993b1ffba (patch) | |
tree | cb966209f7664e17cc92b56206eb2be42f412abf /app/features/settings/components | |
parent | 93d8268a68db286cfec44f4020117c7087863402 (diff) |
Added settings drawer with persistent settings
Diffstat (limited to 'app/features/settings/components')
-rw-r--r-- | app/features/settings/components/SettingsAction.js | 60 | ||||
-rw-r--r-- | app/features/settings/components/SettingsDrawer.js | 193 | ||||
-rw-r--r-- | app/features/settings/components/index.js | 2 |
3 files changed, 255 insertions, 0 deletions
diff --git a/app/features/settings/components/SettingsAction.js b/app/features/settings/components/SettingsAction.js new file mode 100644 index 0000000..080e3c6 --- /dev/null +++ b/app/features/settings/components/SettingsAction.js @@ -0,0 +1,60 @@ +// @flow + +import SettingsIcon from '@atlaskit/icon/glyph/settings'; + +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import type { Dispatch } from 'redux'; + +import { openDrawer } from '../../navbar'; + +import SettingsDrawer from './SettingsDrawer'; + +type Props = { + + /** + * Redux dispatch. + */ + dispatch: Dispatch<*>; +}; + +/** + * Setttings Action for Navigation Bar. + */ +class SettingsAction extends Component<Props, *> { + /** + * Initializes a new {@code SettingsAction} instance. + * + * @inheritdoc + */ + constructor() { + super(); + + this._onIconClick = this._onIconClick.bind(this); + } + + /** + * Render function of component. + * + * @returns {ReactElement} + */ + render() { + return ( + <SettingsIcon + onClick = { this._onIconClick } /> + ); + } + + _onIconClick: (*) => void; + + /** + * Open Settings drawer when SettingsAction is clicked. + * + * @returns {void} + */ + _onIconClick() { + this.props.dispatch(openDrawer(SettingsDrawer)); + } +} + +export default connect()(SettingsAction); diff --git a/app/features/settings/components/SettingsDrawer.js b/app/features/settings/components/SettingsDrawer.js new file mode 100644 index 0000000..7869cd2 --- /dev/null +++ b/app/features/settings/components/SettingsDrawer.js @@ -0,0 +1,193 @@ +// @flow + +import Avatar from '@atlaskit/avatar'; +import FieldText from '@atlaskit/field-text'; +import ArrowLeft from '@atlaskit/icon/glyph/arrow-left'; +import { AkCustomDrawer } from '@atlaskit/navigation'; + +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import type { Dispatch } from 'redux'; + +import { closeDrawer, DrawerContainer, Logo } from '../../navbar'; +import { AvatarContainer, ProfileContainer } from '../styled'; +import { setEmail, setName } from '../actions'; + +type Props = { + + /** + * Redux dispatch. + */ + dispatch: Dispatch<*>; + + /** + * Is the drawer open or not. + */ + isOpen: boolean; + + /** + * Avatar URL. + */ + _avatarURL: string; + + /** + * Email of the user. + */ + _email: string; + + /** + * Name of the user. + */ + _name: string; +}; + +/** + * Drawer that open when SettingsAction is clicked. + */ +class SettingsDrawer extends Component<Props, *> { + /** + * Initializes a new {@code SettingsDrawer} instance. + * + * @inheritdoc + */ + constructor(props) { + super(props); + + this._onBackButton = this._onBackButton.bind(this); + this._onEmailBlur = this._onEmailBlur.bind(this); + this._onEmailFormSubmit = this._onEmailFormSubmit.bind(this); + this._onNameBlur = this._onNameBlur.bind(this); + this._onNameFormSubmit = this._onNameFormSubmit.bind(this); + } + + /** + * Render function of component. + * + * @returns {ReactElement} + */ + render() { + return ( + <AkCustomDrawer + backIcon = { <ArrowLeft label = 'Back' /> } + isOpen = { this.props.isOpen } + onBackButton = { this._onBackButton } + primaryIcon = { <Logo /> } > + <DrawerContainer> + <ProfileContainer> + <AvatarContainer> + <Avatar + size = 'xlarge' + src = { this.props._avatarURL } /> + </AvatarContainer> + <form onSubmit = { this._onNameFormSubmit }> + <FieldText + label = 'Name' + onBlur = { this._onNameBlur } + shouldFitContainer = { true } + type = 'text' + value = { this.props._name } /> + </form> + <form onSubmit = { this._onEmailFormSubmit }> + <FieldText + label = 'Email' + onBlur = { this._onEmailBlur } + shouldFitContainer = { true } + type = 'text' + value = { this.props._email } /> + </form> + </ProfileContainer> + </DrawerContainer> + </AkCustomDrawer> + ); + } + + + _onBackButton: (*) => void; + + /** + * Closes the drawer when back button is clicked. + * + * @returns {void} + */ + _onBackButton() { + this.props.dispatch(closeDrawer()); + } + + _onEmailBlur: (*) => void; + + /** + * Updates Avatar URL in (redux) state when email is updated. + * + * @param {SyntheticInputEvent<HTMLInputElement>} event - Event by which + * this function is called. + * @returns {void} + */ + _onEmailBlur(event: SyntheticInputEvent<HTMLInputElement>) { + this.props.dispatch(setEmail(event.currentTarget.value)); + } + + _onEmailFormSubmit: (*) => void; + + /** + * Prevents submission of the form and updates email. + * + * @param {SyntheticEvent<HTMLFormElement>} event - Event by which + * this function is called. + * @returns {void} + */ + _onEmailFormSubmit(event: SyntheticEvent<HTMLFormElement>) { + event.preventDefault(); + + // $FlowFixMe + this.props.dispatch(setEmail(event.currentTarget.elements[0].value)); + } + + _onNameBlur: (*) => void; + + /** + * Updates Avatar URL in (redux) state when name is updated. + * + * @param {SyntheticInputEvent<HTMLInputElement>} event - Event by which + * this function is called. + * @returns {void} + */ + _onNameBlur(event: SyntheticInputEvent<HTMLInputElement>) { + this.props.dispatch(setName(event.currentTarget.value)); + } + + _onNameFormSubmit: (*) => void; + + /** + * Prevents submission of the form and updates name. + * + * @param {SyntheticEvent<HTMLFormElement>} event - Event by which + * this function is called. + * @returns {void} + */ + _onNameFormSubmit(event: SyntheticEvent<HTMLFormElement>) { + event.preventDefault(); + + // $FlowFixMe + this.props.dispatch(setName(event.currentTarget.elements[0].value)); + } +} + +/** + * Maps (parts of) the redux state to the React props. + * + * @param {Object} state - The redux state. + * @returns {{ + * _avatarURL: string, + * _email: string, + * _name: string + * }} + */ +function _mapStateToProps(state: Object) { + return { + _avatarURL: state.settings.avatarURL, + _email: state.settings.email, + _name: state.settings.name + }; +} + +export default connect(_mapStateToProps)(SettingsDrawer); diff --git a/app/features/settings/components/index.js b/app/features/settings/components/index.js new file mode 100644 index 0000000..63dd49d --- /dev/null +++ b/app/features/settings/components/index.js @@ -0,0 +1,2 @@ +export { default as SettingsAction } from './SettingsAction'; +export { default as SettingsDrawer } from './SettingsDrawer'; |