[New Feature] Add more fields for edit profile

This commit is contained in:
Qolzam
2018-02-25 22:36:28 +07:00
parent 16ecaa33c6
commit 5fb4b4095f
9 changed files with 172 additions and 29 deletions

View File

@@ -33,6 +33,7 @@
"lodash": "^4.17.4", "lodash": "^4.17.4",
"material-ui": "^1.0.0-beta.34", "material-ui": "^1.0.0-beta.34",
"material-ui-icons": "^1.0.0-beta.17", "material-ui-icons": "^1.0.0-beta.17",
"material-ui-pickers": "^1.0.0-beta.15.1",
"moment": "^2.18.1", "moment": "^2.18.1",
"morgan": "^1.8.1", "morgan": "^1.8.1",
"node-sass-chokidar": "0.0.3", "node-sass-chokidar": "0.0.3",

View File

@@ -106,7 +106,7 @@
padding: 0.01em 16px; padding: 0.01em 16px;
} }
</style> </style>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head> </head>
<body> <body>

View File

@@ -34,7 +34,11 @@ export const dbGetUserInfo = () => {
fullName: userProfile.fullName, fullName: userProfile.fullName,
banner: userProfile.banner, banner: userProfile.banner,
tagLine: userProfile.tagLine, tagLine: userProfile.tagLine,
creationDate: userProfile.creationDate creationDate: userProfile.creationDate,
birthday: userProfile.birthday,
companyName: userProfile.companyName,
webUrl: userProfile.webUrl,
twitterId: userProfile.twitterId,
})) }))
}) })
.catch((error: SocialError) => dispatch(globalActions.showMessage(error.message))) .catch((error: SocialError) => dispatch(globalActions.showMessage(error.message)))
@@ -63,7 +67,11 @@ export const dbGetUserInfoByUserId = (uid: string, callerKey: string) => {
fullName: userProfile.fullName, fullName: userProfile.fullName,
banner: userProfile.banner, banner: userProfile.banner,
tagLine: userProfile.tagLine, tagLine: userProfile.tagLine,
creationDate: userProfile.creationDate creationDate: userProfile.creationDate,
birthday: userProfile.birthday,
companyName: userProfile.companyName,
webUrl: userProfile.webUrl,
twitterId: userProfile.twitterId,
})) }))
switch (callerKey) { switch (callerKey) {
@@ -87,7 +95,7 @@ export const dbGetUserInfoByUserId = (uid: string, callerKey: string) => {
*/ */
export const dbUpdateUserInfo = (newProfile: Profile) => { export const dbUpdateUserInfo = (newProfile: Profile) => {
return (dispatch: any, getState: Function) => { return (dispatch: any, getState: Function) => {
console.trace('newProfile', newProfile)
// Get current user id // Get current user id
let uid: string = getState().authorize.uid let uid: string = getState().authorize.uid
@@ -98,6 +106,10 @@ export const dbUpdateUserInfo = (newProfile: Profile) => {
email: newProfile.email || profile.email || '', email: newProfile.email || profile.email || '',
fullName: newProfile.fullName || profile.fullName || '', fullName: newProfile.fullName || profile.fullName || '',
tagLine: newProfile.tagLine || profile.tagLine || '', tagLine: newProfile.tagLine || profile.tagLine || '',
birthday: newProfile.birthday,
companyName: newProfile.companyName || '',
webUrl: newProfile.webUrl || '',
twitterId: newProfile.twitterId || '',
creationDate: newProfile.creationDate creationDate: newProfile.creationDate
} }
return userService.updateUserProfile(uid,updatedProfile).then(() => { return userService.updateUserProfile(uid,updatedProfile).then(() => {

View File

@@ -3,6 +3,7 @@ import React, { Component } from 'react'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { getTranslate, getActiveLanguage } from 'react-localize-redux' import { getTranslate, getActiveLanguage } from 'react-localize-redux'
import moment from 'moment/moment'
import { grey } from 'material-ui/colors' import { grey } from 'material-ui/colors'
import IconButton from 'material-ui/IconButton' import IconButton from 'material-ui/IconButton'
@@ -25,6 +26,7 @@ import TextField from 'material-ui/TextField'
import Input, { InputLabel } from 'material-ui/Input' import Input, { InputLabel } from 'material-ui/Input'
import { FormControl, FormHelperText } from 'material-ui/Form' import { FormControl, FormHelperText } from 'material-ui/Form'
import { withStyles } from 'material-ui/styles' import { withStyles } from 'material-ui/styles'
import { TimePicker, DatePicker, DateTimePicker } from 'material-ui-pickers'
// - Import app components // - Import app components
import ImgCover from 'components/imgCover' import ImgCover from 'components/imgCover'
@@ -72,11 +74,19 @@ const styles = (theme: any) => ({
width: '100%' width: '100%'
} }
}, },
bottomSpace: { bottomPaperSpace: {
height: 16, height: 16,
[theme.breakpoints.down('xs')]: { [theme.breakpoints.down('xs')]: {
height: 90 height: 90
} }
},
box: {
padding: '0px 24px 0px',
display: 'flex'
},
bottomTextSpace: {
marginBottom: 15
} }
}) })
@@ -130,11 +140,6 @@ export class EditProfileComponent extends Component<IEditProfileComponentProps,
updateButton: { updateButton: {
marginLeft: '10px' marginLeft: '10px'
}, },
box: {
padding: '0px 24px 20px 24px',
display: 'flex'
},
dialogGallery: { dialogGallery: {
width: '', width: '',
maxWidth: '530px', maxWidth: '530px',
@@ -186,7 +191,27 @@ export class EditProfileComponent extends Component<IEditProfileComponentProps,
/** /**
* It's true if the image gallery for avatar is open * It's true if the image gallery for avatar is open
*/ */
openAvatar: false openAvatar: false,
/**
* Default birth day
*/
defaultBirthday: (props.info && props.info.birthday) ? moment.unix(props.info!.birthday!).toDate() : new Date(),
/**
* Seleted birth day
*/
selectedBirthday: 0,
/**
* Web URL
*/
webUrl: (props.info && props.info.webUrl) ? props.info.webUrl : '',
/**
* User company name
*/
companyName: (props.info && props.info.companyName) ? props.info.companyName : '',
/**
* User twitter id
*/
twitterId: (props.info && props.info.twitterId) ? props.info.twitterId : ''
} }
@@ -258,7 +283,8 @@ export class EditProfileComponent extends Component<IEditProfileComponentProps,
* @memberof EditProfile * @memberof EditProfile
*/ */
handleUpdate = () => { handleUpdate = () => {
const { fullNameInput, tagLineInput, avatar, banner } = this.state const { fullNameInput, tagLineInput, avatar, banner, selectedBirthday, companyName, webUrl, twitterId} = this.state
const {info} = this.props
if (this.state.fullNameInput.trim() === '') { if (this.state.fullNameInput.trim() === '') {
this.setState({ this.setState({
@@ -274,7 +300,11 @@ export class EditProfileComponent extends Component<IEditProfileComponentProps,
tagLine: tagLineInput, tagLine: tagLineInput,
avatar: avatar, avatar: avatar,
banner: banner, banner: banner,
creationDate: this.props.info!.creationDate companyName: companyName,
webUrl: webUrl,
twitterId: twitterId,
creationDate: this.props.info!.creationDate,
birthday: selectedBirthday > 0 ? selectedBirthday : ((info && info.birthday) ? info!.birthday! : 0)
}) })
} }
} }
@@ -313,6 +343,14 @@ export class EditProfileComponent extends Component<IEditProfileComponentProps,
} }
} }
/**
* Handle birthday date changed
*/
handleBirthdayDateChange = (date: moment.Moment) => {
console.trace('changed', date)
this.setState({ selectedBirthday: date.unix() })
}
componentDidMount() { componentDidMount() {
this.handleResize(null) this.handleResize(null)
} }
@@ -324,6 +362,7 @@ export class EditProfileComponent extends Component<IEditProfileComponentProps,
render() { render() {
const { classes, translate } = this.props const { classes, translate } = this.props
const {defaultBirthday, webUrl, twitterId, companyName} = this.state
const iconButtonElement = ( const iconButtonElement = (
<IconButton style={this.state.isSmall ? this.styles.iconButtonSmall : this.styles.iconButton}> <IconButton style={this.state.isSmall ? this.styles.iconButtonSmall : this.styles.iconButton}>
<MoreVertIcon style={{ ...(this.state.isSmall ? this.styles.iconButtonSmall : this.styles.iconButton), color: grey[400] }} viewBox='10 0 24 24' /> <MoreVertIcon style={{ ...(this.state.isSmall ? this.styles.iconButtonSmall : this.styles.iconButton), color: grey[400] }} viewBox='10 0 24 24' />
@@ -385,31 +424,70 @@ export class EditProfileComponent extends Component<IEditProfileComponentProps,
{/* Edit user information box*/} {/* Edit user information box*/}
<Paper style={this.styles.paper} elevation={1}> <Paper style={this.styles.paper} elevation={1}>
<div style={this.styles.title as any}>{translate!('profile.personalInformationLabel')}</div> <div style={this.styles.title as any}>{translate!('profile.personalInformationLabel')}</div>
<div style={this.styles.box}> <div className={classes.box}>
<FormControl aria-describedby='fullNameInputError'> <FormControl fullWidth aria-describedby='fullNameInputError'>
<InputLabel htmlFor='fullNameInput'>{translate!('profile.fullName')}</InputLabel> <InputLabel htmlFor='fullNameInput'>{translate!('profile.fullName')}</InputLabel>
<Input id='fullNameInput' <Input id='fullNameInput'
onChange={this.handleInputChange} onChange={this.handleInputChange}
name='fullNameInput' name='fullNameInput'
value={this.state.fullNameInput} /> value={this.state.fullNameInput}
/>
<FormHelperText id='fullNameInputError'>{this.state.fullNameInputError}</FormHelperText> <FormHelperText id='fullNameInputError'>{this.state.fullNameInputError}</FormHelperText>
</FormControl> </FormControl>
</div> </div>
<br /> <div className={classes.box}>
<div style={this.styles.box}> <FormControl fullWidth aria-describedby='tagLineInputError'>
<FormControl aria-describedby='tagLineInputError'>
<InputLabel htmlFor='tagLineInput'>{translate!('profile.tagline')}</InputLabel> <InputLabel htmlFor='tagLineInput'>{translate!('profile.tagline')}</InputLabel>
<Input id='tagLineInput' <Input id='tagLineInput'
onChange={this.handleInputChange} onChange={this.handleInputChange}
name='tagLineInput' name='tagLineInput'
value={this.state.tagLineInput} /> value={this.state.tagLineInput}
/>
<FormHelperText id='tagLineInputError'>{this.state.fullNameInputError}</FormHelperText> <FormHelperText id='tagLineInputError'>{this.state.fullNameInputError}</FormHelperText>
</FormControl> </FormControl>
</div> </div>
<div className={classes.box}>
<TextField
className={classes.bottomTextSpace}
onChange={this.handleInputChange}
name='companyName'
value={companyName}
label={translate!('profile.companyName')}
fullWidth
/>
</div>
<div className={classes.box}>
<TextField
className={classes.bottomTextSpace}
onChange={this.handleInputChange}
name='twitterId'
value={twitterId}
label={translate!('profile.twitterId')}
fullWidth
/>
</div>
<div className={classes.box}>
<TextField
className={classes.bottomTextSpace}
onChange={this.handleInputChange}
name='webUrl'
value={webUrl}
label={translate!('profile.webUrl')}
fullWidth
/>
</div>
<div className={classes.box}>
<DatePicker
value={defaultBirthday}
onChange={this.handleBirthdayDateChange}
label={translate!('profile.birthday')}
fullWidth
/>
</div>
<br/> <br/>
</Paper> </Paper>
<div className={classes.bottomSpace}></div> <div className={classes.bottomPaperSpace}></div>
</DialogContent> </DialogContent>
<DialogActions className={classes.fixedDownStickyXS}> <DialogActions className={classes.fixedDownStickyXS}>
<Button onClick={this.props.onRequestClose} > {translate!('profile.cancelButton')} </Button> <Button onClick={this.props.onRequestClose} > {translate!('profile.cancelButton')} </Button>

View File

@@ -65,4 +65,29 @@ export interface IEditProfileComponentState {
*/ */
openAvatar: boolean openAvatar: boolean
/**
* Default birth day
*/
defaultBirthday: Date
/**
* Seleted birth day
*/
selectedBirthday: number
/**
* Web URL
*/
webUrl: string
/**
* User company name
*/
companyName: string
/**
* User twitter id
*/
twitterId: string
} }

View File

@@ -105,7 +105,7 @@ export class ShareDialogComponent extends Component<IShareDialogComponentProps,
<div> <div>
<FacebookShareButton <FacebookShareButton
onShareWindowClose={onClose} onShareWindowClose={onClose}
url={`https://test-4515a.firebaseapp.com/${post.ownerUserId}/posts/${post.id}`} url={`${location.origin}/${post.ownerUserId}/posts/${post.id}`}
quote={post.body} quote={post.body}
hashtag={`#${post.tags![0]}`}> hashtag={`#${post.tags![0]}`}>
<MenuItem > <MenuItem >
@@ -121,7 +121,7 @@ export class ShareDialogComponent extends Component<IShareDialogComponentProps,
<div> <div>
<TwitterShareButton <TwitterShareButton
onShareWindowClose={onClose} onShareWindowClose={onClose}
url={`https://test-4515a.firebaseapp.com/${post.ownerUserId}/posts/${post.id}`} url={`${location.origin}/${post.ownerUserId}/posts/${post.id}`}
quote={post.body} quote={post.body}
hashtag={`#${post.tags![0]}`}> hashtag={`#${post.tags![0]}`}>
<MenuItem > <MenuItem >
@@ -137,7 +137,7 @@ export class ShareDialogComponent extends Component<IShareDialogComponentProps,
<div> <div>
<LinkedinShareButton <LinkedinShareButton
onShareWindowClose={onClose} onShareWindowClose={onClose}
url={`https://test-4515a.firebaseapp.com/${post.ownerUserId}/posts/${post.id}`} url={`${location.origin}/${post.ownerUserId}/posts/${post.id}`}
quote={post.body} quote={post.body}
hashtag={`#${post.tags![0]}`}> hashtag={`#${post.tags![0]}`}>
<MenuItem > <MenuItem >
@@ -153,7 +153,7 @@ export class ShareDialogComponent extends Component<IShareDialogComponentProps,
<div> <div>
<GooglePlusShareButton <GooglePlusShareButton
onShareWindowClose={onClose} onShareWindowClose={onClose}
url={`https://test-4515a.firebaseapp.com/${post.ownerUserId}/posts/${post.id}`} url={`${location.origin}/${post.ownerUserId}/posts/${post.id}`}
quote={post.body} quote={post.body}
hashtag={`#${post.tags![0]}`}> hashtag={`#${post.tags![0]}`}>
<MenuItem > <MenuItem >

View File

@@ -7,7 +7,11 @@ export class Profile extends BaseDomain {
public banner: string, public banner: string,
public tagLine: string, public tagLine: string,
public creationDate: number, public creationDate: number,
public email?: string | null public email?: string | null,
public birthday?: number,
public webUrl?: string,
public companyName?: string,
public twitterId?: string
) { ) {
super() super()

View File

@@ -60,6 +60,10 @@
"updateButton": "UPDATE", "updateButton": "UPDATE",
"fullName": "Full Name", "fullName": "Full Name",
"tagline": "Tagline", "tagline": "Tagline",
"birthday": "Birthday",
"companyName": "Company Name",
"twitterId": "Twitter",
"webUrl": "Web address",
"personalInformationLabel": "Personal Information", "personalInformationLabel": "Personal Information",
"headPostsLabel": "${userName}'s posts", "headPostsLabel": "${userName}'s posts",
"nothingSharedLabel": " Nothing shared", "nothingSharedLabel": " Nothing shared",

View File

@@ -2076,7 +2076,7 @@ es6-set@~0.1.5:
es6-symbol "3.1.1" es6-symbol "3.1.1"
event-emitter "~0.3.5" event-emitter "~0.3.5"
es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: es6-symbol@3.1.1, es6-symbol@^3.1.0, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
dependencies: dependencies:
@@ -4426,6 +4426,13 @@ material-ui-icons@^1.0.0-beta.17:
dependencies: dependencies:
recompose "^0.26.0" recompose "^0.26.0"
material-ui-pickers@^1.0.0-beta.15.1:
version "1.0.0-beta.15.1"
resolved "https://registry.yarnpkg.com/material-ui-pickers/-/material-ui-pickers-1.0.0-beta.15.1.tgz#37f29e8e26a1b5fbc8a183a61fe1d8f9e830d47c"
dependencies:
moment-range "^3.0.3"
react-text-mask "^5.0.2"
material-ui@^1.0.0-beta.34: material-ui@^1.0.0-beta.34:
version "1.0.0-beta.34" version "1.0.0-beta.34"
resolved "https://registry.yarnpkg.com/material-ui/-/material-ui-1.0.0-beta.34.tgz#bea328d3d34df7ab8bf01c936d08adee11195b80" resolved "https://registry.yarnpkg.com/material-ui/-/material-ui-1.0.0-beta.34.tgz#bea328d3d34df7ab8bf01c936d08adee11195b80"
@@ -4660,6 +4667,12 @@ mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkd
dependencies: dependencies:
minimist "0.0.8" minimist "0.0.8"
moment-range@^3.0.3:
version "3.1.1"
resolved "https://registry.yarnpkg.com/moment-range/-/moment-range-3.1.1.tgz#5c52cf9fab29db9dd9bcd86d37e52b04a7a7271a"
dependencies:
es6-symbol "^3.1.0"
moment@^2.18.1: moment@^2.18.1:
version "2.20.1" version "2.20.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd"
@@ -5871,7 +5884,7 @@ promzard@^0.3.0:
dependencies: dependencies:
read "1" read "1"
prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0: prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0:
version "15.6.0" version "15.6.0"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
dependencies: dependencies:
@@ -6276,6 +6289,12 @@ react-tap-event-plugin@^3.0.2:
dependencies: dependencies:
fbjs "^0.8.6" fbjs "^0.8.6"
react-text-mask@^5.0.2:
version "5.1.0"
resolved "https://registry.yarnpkg.com/react-text-mask/-/react-text-mask-5.1.0.tgz#490aa519aae73398d491edd675c821dc947b764b"
dependencies:
prop-types "^15.5.6"
react-transition-group@^2.2.1: react-transition-group@^2.2.1:
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10"