Files
deighton-ar/website/src/Teams/Teams.js
2018-03-30 10:42:22 -07:00

311 lines
8.8 KiB
JavaScript

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,
teams: [],
yesNoModal: null,
messageModal: null,
waitModal: null,
changeEmailModal: null,
}
}
componentDidMount() {
this.props.changeTitle('Teams')
api.listTeams().then((list) => {
list.items.sort((teamA, teamB) => (teamA.name.localeCompare(teamB.name)))
this.setState({ teams: list.items })
}).catch((error) => {
this.setState({
messageModal: {
icon: 'hand',
message: 'Unable to get the list of teams.',
detail: error.message,
}
})
})
}
componentWillUnmount() {
this.props.changeTitle('')
}
removeUnfinishedNewTeam() {
let teams = this.state.teams
if (teams.length > 0 && !teams[0]._id) {
this.setState({ teams: this.state.teams.slice(1) })
}
}
@autobind
handleTeamListClick(e, index) {
let team = this.state.teams[index]
if (this.state.modified) {
this.nextSelectedTeam = team
this.setState({
yesNoModal: {
question: 'This team has been modified. Are you sure you would like to navigate away?',
onDismiss: this.handleModifiedModalDismiss
}
})
} else {
this.setState({ selectedTeam: team })
this.removeUnfinishedNewTeam()
}
}
@autobind
handleSave(team) {
if (team._id) {
this.setState({ waitModal: { message: 'Updating Team' } })
api.updateTeam(team).then((updatedTeam) => {
this.setState({
waitModal: null,
teams: this.state.teams.map((team) => (team._id === updatedTeam._id ? updatedTeam : team)),
modified: false,
selectedTeam: updatedTeam
})
}).catch((error) => {
this.setState({
waitModal: null,
messageModal: {
icon: 'hand',
message: 'Unable to save the team changes',
detail: error.message,
}
})
})
} else {
this.setState({ waitModal: { message: 'Creating Team' } })
api.createTeam(team).then((createdTeam) => {
this.setState({
waitModal: false,
teams: this.state.teams.map((team) => (!team._id ? createdTeam : team)).sort((a, b) => (
a.name < b.name ? -1 : a.name > b.name ? 1 : 0
)),
modified: false,
selectedTeam: createdTeam
})
}).catch((error) => {
this.setState({
waitModal: null,
messageModal: {
icon: 'hand',
message: 'Unable to create the team.',
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 team? 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.teams.findIndex((team) => (team._id === selectedTeamId))
if (selectedIndex >= 0) {
this.setState({ waitModal: { message: 'Removing Team' } })
api.deleteTeam(selectedTeamId).then(() => {
this.setState({
waitModal: null,
teams: [...this.state.teams.slice(0, selectedIndex), ...this.state.teams.slice(selectedIndex + 1)],
selectedTeam: null
})
}).catch((error) => {
this.setState({
waitModal: null,
messageModal: {
icon: 'hand',
message: 'Unable to remove the team.',
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.teams)
this.setState({ teams: 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 teams={this.state.teams} 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 team={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>
)
}
}