diff --git a/design/Deighton AR Design.sketch b/design/Deighton AR Design.sketch
index b669cee..685e011 100644
Binary files a/design/Deighton AR Design.sketch and b/design/Deighton AR Design.sketch differ
diff --git a/mobile/src/ui/Icon.js b/mobile/src/ui/Icon.js
index 4771f84..64f2adc 100644
--- a/mobile/src/ui/Icon.js
+++ b/mobile/src/ui/Icon.js
@@ -16,6 +16,9 @@ const images = {
done: require("./images/done.png"),
target: require("./images/target.png"),
pin: require("./images/pin.png"),
+ hardhat: require("./images/hardhat.png"),
+ clipboard: require("./images/clipboard.png"),
+ question: require("./images/question.png"),
}
export class Icon extends Component {
diff --git a/mobile/src/ui/images/clipboard.png b/mobile/src/ui/images/clipboard.png
new file mode 100644
index 0000000..ae94ee7
Binary files /dev/null and b/mobile/src/ui/images/clipboard.png differ
diff --git a/mobile/src/ui/images/hardhat.png b/mobile/src/ui/images/hardhat.png
new file mode 100644
index 0000000..b9f20b9
Binary files /dev/null and b/mobile/src/ui/images/hardhat.png differ
diff --git a/mobile/src/ui/images/question.png b/mobile/src/ui/images/question.png
new file mode 100644
index 0000000..b7f20dc
Binary files /dev/null and b/mobile/src/ui/images/question.png differ
diff --git a/website/src/Teams/Teams.js b/website/src/Teams/Teams.js
index 17c36c8..13be65b 100644
--- a/website/src/Teams/Teams.js
+++ b/website/src/Teams/Teams.js
@@ -1,13 +1,18 @@
-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'
+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 = {
@@ -28,24 +33,27 @@ export class Teams extends Component {
}
componentDidMount() {
- this.props.changeTitle('Teams')
+ 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,
- }
+ 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('')
+ this.props.changeTitle("")
}
removeUnfinishedNewTeam() {
@@ -64,9 +72,10 @@ export class Teams extends Component {
this.nextSelectedTeam = team
this.setState({
yesNoModal: {
- question: 'This team has been modified. Are you sure you would like to navigate away?',
- onDismiss: this.handleModifiedModalDismiss
- }
+ question:
+ "This team has been modified. Are you sure you would like to navigate away?",
+ onDismiss: this.handleModifiedModalDismiss,
+ },
})
} else {
this.setState({ selectedTeam: team })
@@ -77,77 +86,92 @@ export class Teams extends Component {
@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
+ 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,
- }
+ .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
+ 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,
- }
+ .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 } })
+ this.setState({
+ changeEmailModal: { oldEmail: this.state.selectedTeam.email },
+ })
}
@autobind
handleResendEmail() {
this.setState({
- waitModal: { message: 'Resending Email...' }
+ 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.`
- }
+ 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,
- }
+ .catch((error) => {
+ this.setState({
+ error: true,
+ waitModal: null,
+ messageModal: {
+ icon: "hand",
+ message: "Unable to request email change.",
+ detail: error.message,
+ },
+ })
})
- })
}
@autobind
@@ -157,28 +181,34 @@ export class Teams extends Component {
return
}
this.setState({
- waitModal: { message: 'Requesting Email Change...' }
+ 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.`
- }
+ api
+ .sendConfirmEmail({
+ existingEmail: this.state.selectedTeam.email,
+ newEmail,
})
- }).catch((error) => {
- this.setState({
- error: true,
- waitModal: null,
- messageModal: {
- icon: 'hand',
- message: 'Unable to request email change.',
- detail: error.message,
- }
+ .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,
+ },
+ })
})
- })
}
}
@@ -186,9 +216,10 @@ export class Teams extends Component {
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
- }
+ question:
+ "Are you sure you want to remove this team? This will also remove them from any teams they belong to.",
+ onDismiss: this.handleRemoveModalDismiss,
+ },
})
}
@@ -196,31 +227,39 @@ export class Teams extends Component {
handleRemoveModalDismiss(yes) {
if (yes) {
const selectedTeamId = this.state.selectedTeam._id
- const selectedIndex = this.state.teams.findIndex((team) => (team._id === selectedTeamId))
+ 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
+ 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,
- }
+ .catch((error) => {
+ this.setState({
+ waitModal: null,
+ messageModal: {
+ icon: "hand",
+ message: "Unable to remove the team.",
+ detail: error.message,
+ },
+ })
})
- })
}
}
this.setState({
- yesNoModal: null
+ yesNoModal: null,
})
}
@@ -229,14 +268,14 @@ export class Teams extends Component {
if (yes) {
this.setState({
selectedTeam: this.nextSelectedTeam,
- modified: false
+ modified: false,
})
this.removeUnfinishedNewTeam()
delete this.nextSelectedTeam
}
this.setState({
- yesNoModal: null
+ yesNoModal: null,
})
}
@@ -252,9 +291,13 @@ export class Teams extends Component {
@autobind
handleAddNewTeam() {
- let newTeam = {}
- let newTeams = [newTeam].concat(this.state.teams)
- this.setState({ teams: newTeams, selectedTeam: newTeam })
+ let teams = this.state.teams
+
+ if (teams.length > 0 && !!teams[0]._id) {
+ let newTeam = {}
+ let newTeams = [newTeam].concat(this.state.teams)
+ this.setState({ teams: newTeams, selectedTeam: newTeam })
+ }
}
render() {
@@ -266,43 +309,65 @@ export class Teams extends Component {
-
-
+
+
-
- {
- this.state.selectedTeam
- ?
- :
- }
+
+ {this.state.selectedTeam ? (
+
+ ) : (
+
+ )}
-
+ onDismiss={this.handleChangeEmailDismiss}
+ />
-
+
+ onDismiss={this.handleMessageModalDismiss}
+ />
-
+
)
diff --git a/website/src/Users/Users.js b/website/src/Users/Users.js
index 04e8022..2181b70 100644
--- a/website/src/Users/Users.js
+++ b/website/src/Users/Users.js
@@ -1,13 +1,18 @@
-import React, { Component, Fragment } from 'react'
-import PropTypes from 'prop-types'
-import autobind from 'autobind-decorator'
-import { UserList } from './UserList'
-import { UserForm } from './UserForm'
-import { UserFormPlaceholder } from './UserFormPlaceholder'
-import { api } from 'src/API'
-import { Row, Column, Box } from 'ui'
-import { YesNoMessageModal, MessageModal, ChangeEmailModal, WaitModal } from '../Modal'
-import { sizeInfo, colorInfo } from 'ui/style'
+import React, { Component, Fragment } from "react"
+import PropTypes from "prop-types"
+import autobind from "autobind-decorator"
+import { UserList } from "./UserList"
+import { UserForm } from "./UserForm"
+import { UserFormPlaceholder } from "./UserFormPlaceholder"
+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 Users extends Component {
static propTypes = {
@@ -28,24 +33,29 @@ export class Users extends Component {
}
componentDidMount() {
- this.props.changeTitle('Users')
+ this.props.changeTitle("Users")
- api.listUsers().then((list) => {
- list.items.sort((userA, userB) => (userA.lastName.localeCompare(userB.lastName)))
- this.setState({ users: list.items })
- }).catch((error) => {
- this.setState({
- messageModal: {
- icon: 'hand',
- message: 'Unable to get the list of users.',
- detail: error.message,
- }
+ api
+ .listUsers()
+ .then((list) => {
+ list.items.sort((userA, userB) =>
+ userA.lastName.localeCompare(userB.lastName)
+ )
+ this.setState({ users: list.items })
+ })
+ .catch((error) => {
+ this.setState({
+ messageModal: {
+ icon: "hand",
+ message: "Unable to get the list of users.",
+ detail: error.message,
+ },
+ })
})
- })
}
componentWillUnmount() {
- this.props.changeTitle('')
+ this.props.changeTitle("")
}
removeUnfinishedNewUser() {
@@ -64,9 +74,10 @@ export class Users extends Component {
this.nextSelectedUser = user
this.setState({
yesNoModal: {
- question: 'This user has been modified. Are you sure you would like to navigate away?',
- onDismiss: this.handleModifiedModalDismiss
- }
+ question:
+ "This user has been modified. Are you sure you would like to navigate away?",
+ onDismiss: this.handleModifiedModalDismiss,
+ },
})
} else {
this.setState({ selectedUser: user })
@@ -77,77 +88,95 @@ export class Users extends Component {
@autobind
handleSave(user) {
if (user._id) {
- this.setState({ waitModal: { message: 'Updating User' } })
- api.updateUser(user).then((updatedUser) => {
- this.setState({
- waitModal: null,
- users: this.state.users.map((user) => (user._id === updatedUser._id ? updatedUser : user)),
- modified: false,
- selectedUser: updatedUser
+ this.setState({ waitModal: { message: "Updating User" } })
+ api
+ .updateUser(user)
+ .then((updatedUser) => {
+ this.setState({
+ waitModal: null,
+ users: this.state.users.map(
+ (user) => (user._id === updatedUser._id ? updatedUser : user)
+ ),
+ modified: false,
+ selectedUser: updatedUser,
+ })
})
- }).catch((error) => {
- this.setState({
- waitModal: null,
- messageModal: {
- icon: 'hand',
- message: 'Unable to save the user changes',
- detail: error.message,
- }
+ .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 User' } })
- api.createUser(user).then((createdUser) => {
- this.setState({
- waitModal: false,
- users: this.state.users.map((user) => (!user._id ? createdUser : user)).sort((a, b) => (
- a.lastName < b.lastName ? -1 : a.lastName > b.lastName : 0
- )),
- modified: false,
- selectedUser: createdUser
+ this.setState({ waitModal: { message: "Creating User" } })
+ api
+ .createUser(user)
+ .then((createdUser) => {
+ this.setState({
+ waitModal: false,
+ users: this.state.users
+ .map((user) => (!user._id ? createdUser : user))
+ .sort(
+ (a, b) =>
+ ((a.lastName < b.lastName ? -1 : a.lastName > b.lastName): 0)
+ ),
+ modified: false,
+ selectedUser: createdUser,
+ })
})
- }).catch((error) => {
- this.setState({
- waitModal: null,
- messageModal: {
- icon: 'hand',
- message: 'Unable to create the user.',
- detail: error.message,
- }
+ .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.selectedUser.email } })
+ this.setState({
+ changeEmailModal: { oldEmail: this.state.selectedUser.email },
+ })
}
@autobind
handleResendEmail() {
this.setState({
- waitModal: { message: 'Resending Email...' }
+ waitModal: { message: "Resending Email..." },
})
- api.sendConfirmEmail({ existingEmail: this.state.selectedUser.email }).then(() => {
- this.setState({
- waitModal: null,
- messageModal: {
- icon: 'thumb',
- message: `An email has been sent to '${this.state.selectedUser.email}' with further instructions.`
- }
+ api
+ .sendConfirmEmail({ existingEmail: this.state.selectedUser.email })
+ .then(() => {
+ this.setState({
+ waitModal: null,
+ messageModal: {
+ icon: "thumb",
+ message: `An email has been sent to '${
+ this.state.selectedUser.email
+ }' with further instructions.`,
+ },
+ })
})
- }).catch((error) => {
- this.setState({
- error: true,
- waitModal: null,
- messageModal: {
- icon: 'hand',
- message: 'Unable to request email change.',
- detail: error.message,
- }
+ .catch((error) => {
+ this.setState({
+ error: true,
+ waitModal: null,
+ messageModal: {
+ icon: "hand",
+ message: "Unable to request email change.",
+ detail: error.message,
+ },
+ })
})
- })
}
@autobind
@@ -157,28 +186,34 @@ export class Users extends Component {
return
}
this.setState({
- waitModal: { message: 'Requesting Email Change...' }
+ waitModal: { message: "Requesting Email Change..." },
})
if (this.state.selectedUser) {
- api.sendConfirmEmail({ existingEmail: this.state.selectedUser.email, newEmail }).then(() => {
- this.setState({
- waitModal: null,
- messageModal: {
- icon: 'hand',
- message: `An email has been sent to '${newEmail}' to confirm this email.`
- }
+ api
+ .sendConfirmEmail({
+ existingEmail: this.state.selectedUser.email,
+ newEmail,
})
- }).catch((error) => {
- this.setState({
- error: true,
- waitModal: null,
- messageModal: {
- icon: 'hand',
- message: 'Unable to request email change.',
- detail: error.message,
- }
+ .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,
+ },
+ })
})
- })
}
}
@@ -186,9 +221,10 @@ export class Users extends Component {
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
- }
+ question:
+ "Are you sure you want to remove this user? This will also remove them from any teams they belong to.",
+ onDismiss: this.handleRemoveModalDismiss,
+ },
})
}
@@ -196,31 +232,39 @@ export class Users extends Component {
handleRemoveModalDismiss(yes) {
if (yes) {
const selectedUserId = this.state.selectedUser._id
- const selectedIndex = this.state.users.findIndex((user) => (user._id === selectedUserId))
+ const selectedIndex = this.state.users.findIndex(
+ (user) => user._id === selectedUserId
+ )
if (selectedIndex >= 0) {
- this.setState({ waitModal: { message: 'Removing User' } })
- api.deleteUser(selectedUserId).then(() => {
- this.setState({
- waitModal: null,
- users: [...this.state.users.slice(0, selectedIndex), ...this.state.users.slice(selectedIndex + 1)],
- selectedUser: null
+ this.setState({ waitModal: { message: "Removing User" } })
+ api
+ .deleteUser(selectedUserId)
+ .then(() => {
+ this.setState({
+ waitModal: null,
+ users: [
+ ...this.state.users.slice(0, selectedIndex),
+ ...this.state.users.slice(selectedIndex + 1),
+ ],
+ selectedUser: null,
+ })
})
- }).catch((error) => {
- this.setState({
- waitModal: null,
- messageModal: {
- icon: 'hand',
- message: 'Unable to remove the user.',
- detail: error.message,
- }
+ .catch((error) => {
+ this.setState({
+ waitModal: null,
+ messageModal: {
+ icon: "hand",
+ message: "Unable to remove the user.",
+ detail: error.message,
+ },
+ })
})
- })
}
}
this.setState({
- yesNoModal: null
+ yesNoModal: null,
})
}
@@ -229,14 +273,14 @@ export class Users extends Component {
if (yes) {
this.setState({
selectedUser: this.nextSelectedUser,
- modified: false
+ modified: false,
})
this.removeUnfinishedNewUser()
delete this.nextSelectedUser
}
this.setState({
- yesNoModal: null
+ yesNoModal: null,
})
}
@@ -252,9 +296,13 @@ export class Users extends Component {
@autobind
handleAddNewUser() {
- let newUser = {}
- let newUsers = [newUser].concat(this.state.users)
- this.setState({ users: newUsers, selectedUser: newUser })
+ let users = this.state.users
+
+ if (users.length > 0 && !!users[0]._id) {
+ let newUser = {}
+ let newUsers = [newUser].concat(users)
+ this.setState({ users: newUsers, selectedUser: newUser })
+ }
}
render() {
@@ -266,43 +314,65 @@ export class Users extends Component {
-
-
+
+
-
- {
- this.state.selectedUser
- ?
- :
- }
+
+ {this.state.selectedUser ? (
+
+ ) : (
+
+ )}
-
+ onDismiss={this.handleChangeEmailDismiss}
+ />
-
+
+ onDismiss={this.handleMessageModalDismiss}
+ />
-
+
)