Added team page
This commit is contained in:
310
website/src/Teams/Teams.js
Normal file
310
website/src/Teams/Teams.js
Normal file
@@ -0,0 +1,310 @@
|
||||
import React, { Component, Fragment } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import autobind from 'autobind-decorator'
|
||||
import { TeamList } from './TeamList'
|
||||
import { TeamForm } from './TeamForm'
|
||||
import { TeamFormPlaceholder } from './TeamFormPlaceholder'
|
||||
import { api } from 'src/API'
|
||||
import { Row, Column, Box } from 'ui'
|
||||
import { YesNoMessageModal, MessageModal, ChangeEmailModal, WaitModal } from '../Modal'
|
||||
import { sizeInfo, colorInfo } from 'ui/style'
|
||||
|
||||
export class Teams extends Component {
|
||||
static propTypes = {
|
||||
changeTitle: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
modified: false,
|
||||
selectedTeam: null,
|
||||
users: [],
|
||||
yesNoModal: null,
|
||||
messageModal: null,
|
||||
waitModal: null,
|
||||
changeEmailModal: null,
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.changeTitle('Teams')
|
||||
|
||||
api.listTeams().then((list) => {
|
||||
list.items.sort((userA, userB) => (userA.lastName.localeCompare(userB.lastName)))
|
||||
this.setState({ users: list.items, selectedTeam: list.items[0] }) // TODO: <- Remove
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
messageModal: {
|
||||
icon: 'hand',
|
||||
message: 'Unable to get the list of teams.',
|
||||
detail: error.message,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.changeTitle('')
|
||||
}
|
||||
|
||||
removeUnfinishedNewTeam() {
|
||||
let users = this.state.users
|
||||
|
||||
if (users.length > 0 && !users[0]._id) {
|
||||
this.setState({ users: this.state.users.slice(1) })
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleTeamListClick(e, index) {
|
||||
let user = this.state.users[index]
|
||||
|
||||
if (this.state.modified) {
|
||||
this.nextSelectedTeam = user
|
||||
this.setState({
|
||||
yesNoModal: {
|
||||
question: 'This user has been modified. Are you sure you would like to navigate away?',
|
||||
onDismiss: this.handleModifiedModalDismiss
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.setState({ selectedTeam: user })
|
||||
this.removeUnfinishedNewTeam()
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleSave(user) {
|
||||
if (user._id) {
|
||||
this.setState({ waitModal: { message: 'Updating Team' } })
|
||||
api.updateTeam(user).then((updatedTeam) => {
|
||||
this.setState({
|
||||
waitModal: null,
|
||||
users: this.state.users.map((user) => (user._id === updatedTeam._id ? updatedTeam : user)),
|
||||
modified: false,
|
||||
selectedTeam: updatedTeam
|
||||
})
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
icon: 'hand',
|
||||
message: 'Unable to save the user changes',
|
||||
detail: error.message,
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.setState({ waitModal: { message: 'Creating Team' } })
|
||||
api.createTeam(user).then((createdTeam) => {
|
||||
this.setState({
|
||||
waitModal: false,
|
||||
users: this.state.users.map((user) => (!user._id ? createdTeam : user)).sort((a, b) => (
|
||||
a.lastName < b.lastName ? -1 : a.lastName > b.lastName : 0
|
||||
)),
|
||||
modified: false,
|
||||
selectedTeam: createdTeam
|
||||
})
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
icon: 'hand',
|
||||
message: 'Unable to create the user.',
|
||||
detail: error.message,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleChangeEmail() {
|
||||
this.setState({ changeEmailModal: { oldEmail: this.state.selectedTeam.email } })
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleResendEmail() {
|
||||
this.setState({
|
||||
waitModal: { message: 'Resending Email...' }
|
||||
})
|
||||
api.sendConfirmEmail({ existingEmail: this.state.selectedTeam.email }).then(() => {
|
||||
this.setState({
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
icon: 'thumb',
|
||||
message: `An email has been sent to '${this.state.selectedTeam.email}' with further instructions.`
|
||||
}
|
||||
})
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
error: true,
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
icon: 'hand',
|
||||
message: 'Unable to request email change.',
|
||||
detail: error.message,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleChangeEmailDismiss(newEmail) {
|
||||
this.setState({ changeEmailModal: null })
|
||||
if (!newEmail) {
|
||||
return
|
||||
}
|
||||
this.setState({
|
||||
waitModal: { message: 'Requesting Email Change...' }
|
||||
})
|
||||
if (this.state.selectedTeam) {
|
||||
api.sendConfirmEmail({ existingEmail: this.state.selectedTeam.email, newEmail }).then(() => {
|
||||
this.setState({
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
icon: 'hand',
|
||||
message: `An email has been sent to '${newEmail}' to confirm this email.`
|
||||
}
|
||||
})
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
error: true,
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
icon: 'hand',
|
||||
message: 'Unable to request email change.',
|
||||
detail: error.message,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleRemove() {
|
||||
this.setState({
|
||||
yesNoModal: {
|
||||
question: 'Are you sure you want to remove this user? This will also remove them from any teams they belong to.',
|
||||
onDismiss: this.handleRemoveModalDismiss
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleRemoveModalDismiss(yes) {
|
||||
if (yes) {
|
||||
const selectedTeamId = this.state.selectedTeam._id
|
||||
const selectedIndex = this.state.users.findIndex((user) => (user._id === selectedTeamId))
|
||||
|
||||
if (selectedIndex >= 0) {
|
||||
this.setState({ waitModal: { message: 'Removing Team' } })
|
||||
api.deleteTeam(selectedTeamId).then(() => {
|
||||
this.setState({
|
||||
waitModal: null,
|
||||
users: [...this.state.users.slice(0, selectedIndex), ...this.state.users.slice(selectedIndex + 1)],
|
||||
selectedTeam: null
|
||||
})
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
waitModal: null,
|
||||
messageModal: {
|
||||
icon: 'hand',
|
||||
message: 'Unable to remove the user.',
|
||||
detail: error.message,
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.setState({
|
||||
yesNoModal: null
|
||||
})
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleModifiedModalDismiss(yes) {
|
||||
if (yes) {
|
||||
this.setState({
|
||||
selectedTeam: this.nextSelectedTeam,
|
||||
modified: false
|
||||
})
|
||||
this.removeUnfinishedNewTeam()
|
||||
delete this.nextSelectedTeam
|
||||
}
|
||||
|
||||
this.setState({
|
||||
yesNoModal: null
|
||||
})
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleMessageModalDismiss() {
|
||||
this.setState({ messageModal: null })
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleModifiedChanged(modified) {
|
||||
this.setState({ modified: modified })
|
||||
}
|
||||
|
||||
@autobind
|
||||
handleAddNewTeam() {
|
||||
let newTeam = {}
|
||||
let newTeams = [newTeam].concat(this.state.users)
|
||||
this.setState({ users: newTeams, selectedTeam: newTeam })
|
||||
}
|
||||
|
||||
render() {
|
||||
const { messageModal, yesNoModal, changeEmailModal } = this.state
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<Column.Item height={sizeInfo.formColumnSpacing} />
|
||||
<Column.Item grow>
|
||||
<Row fillParent>
|
||||
<Row.Item width={sizeInfo.formRowSpacing} />
|
||||
<Row.Item width='25vw'>
|
||||
<TeamList users={this.state.users} selectedTeam={this.state.selectedTeam}
|
||||
selectionModified={this.state.modified} onTeamListClick={this.handleTeamListClick}
|
||||
onAddNewTeam={this.handleAddNewTeam} />
|
||||
</Row.Item>
|
||||
<Row.Item width={sizeInfo.formRowSpacing} />
|
||||
<Row.Item grow>
|
||||
<Box border={{ width: sizeInfo.headerBorderWidth, color: colorInfo.headerBorder }} radius={sizeInfo.formBoxRadius}>
|
||||
{
|
||||
this.state.selectedTeam
|
||||
? <TeamForm user={this.state.selectedTeam} onSave={this.handleSave}
|
||||
onRemove={this.handleRemove} onModifiedChanged={this.handleModifiedChanged}
|
||||
onChangeEmail={this.handleChangeEmail} onResendEmail={this.handleResendEmail} />
|
||||
: <TeamFormPlaceholder />
|
||||
}
|
||||
</Box>
|
||||
</Row.Item>
|
||||
<Row.Item width={sizeInfo.formRowSpacing} />
|
||||
</Row>
|
||||
</Column.Item>
|
||||
<Column.Item height={sizeInfo.formColumnSpacing}>
|
||||
<ChangeEmailModal open={!!changeEmailModal}
|
||||
oldEmail={changeEmailModal && changeEmailModal.oldEmail}
|
||||
onDismiss={this.handleChangeEmailDismiss} />
|
||||
|
||||
<YesNoMessageModal open={!!yesNoModal}
|
||||
question={yesNoModal ? yesNoModal.question : ''}
|
||||
onDismiss={yesNoModal && yesNoModal.onDismiss} />
|
||||
|
||||
<MessageModal
|
||||
open={!!messageModal}
|
||||
icon={messageModal ? messageModal.icon : ''}
|
||||
message={messageModal ? messageModal.message : ''}
|
||||
detail={messageModal && messageModal.detail}
|
||||
onDismiss={this.handleMessageModalDismiss} />
|
||||
|
||||
<WaitModal active={!!this.state.waitModal} message={this.state.waitModal ? this.state.waitModal.message : ''} />
|
||||
</Column.Item>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user