Skip to content

Commit 83ae238

Browse files
committed
Merge branch 'develop' into feature/team-badge-column
2 parents cf05fa7 + 4ca4ef3 commit 83ae238

30 files changed

+460
-178
lines changed

app/manage/login.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ async function loginAccept(req, res) {
7777

7878
// Store id token in session
7979
req.session.idToken = result.id_token
80-
return res.redirect(`${APP_URL}/profile`)
80+
return res.redirect(`${APP_URL}/dashboard`)
8181
} catch (error) {
8282
logger.error(error)
8383
return res.status(500).json('Authentication failed')

cypress/e2e/auth.cy.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ describe('Check protected routes', () => {
1515
'/organizations/1/edit',
1616
'/organizations/1/profile',
1717
'/organizations/create',
18-
'/profile',
18+
'/dashboard',
1919
]
2020

2121
protectedRoutes.forEach((testRoute) => {

cypress/e2e/profile.cy.js renamed to cypress/e2e/dashboard.cy.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const user3teams = generateSequenceArray(TEAMS_COUNT, 2 * TEAMS_COUNT).map(
3434
})
3535
)
3636

37-
describe('Profile page', () => {
37+
describe('Dashboard page', () => {
3838
before(() => {
3939
cy.task('db:reset')
4040
})
@@ -43,7 +43,7 @@ describe('Profile page', () => {
4343
cy.login(user1)
4444

4545
// Check state when no teams are available
46-
cy.visit('/profile')
46+
cy.visit('/dashboard')
4747
cy.get('[data-cy=my-teams-table]').contains(
4848
'You are not part of a team yet.'
4949
)
@@ -73,9 +73,9 @@ describe('Profile page', () => {
7373
moderatorId: user3.id,
7474
})
7575

76-
// Log in and visit profile
76+
// Log in and visit dashboard
7777
cy.login(user1)
78-
cy.visit('/profile')
78+
cy.visit('/dashboard')
7979

8080
// Check page and total count
8181
cy.get('[data-cy=my-teams-table-pagination]').contains('Showing 1-10 of 50')

cypress/e2e/teams/invitations.cy.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,15 @@ describe('Team invitation page', () => {
8181
cy.visit(
8282
`/teams/${validInvitation.teamId}/invitations/${validInvitation.uuid}`
8383
)
84-
cy.get('body').contains('Invitation accepted successfully.')
84+
cy.get('[data-cy=invite-accepted]').contains(
85+
'Invitation accepted successfully'
86+
)
8587

8688
cy.visit(
8789
`/teams/${anotherValidInvitation.teamId}/invitations/${anotherValidInvitation.uuid}`
8890
)
89-
cy.get('body').contains('Invitation accepted successfully.')
91+
cy.get('[data-cy=invite-accepted]').contains(
92+
'Invitation accepted successfully'
93+
)
9094
})
9195
})

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
"knex-postgis": "^0.14.3",
7474
"leaflet": "^1.7.1",
7575
"leaflet-control-geocoder": "^1.13.0",
76+
"leaflet-gesture-handling": "^1.2.2",
7677
"next": "^13.0.1",
7778
"next-auth": "^4.18.8",
7879
"next-connect": "^0.13.0",

src/components/edit-team-form.js

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
Select,
1414
Checkbox,
1515
VStack,
16+
Flex,
17+
Text,
1618
} from '@chakra-ui/react'
1719
import dynamic from 'next/dynamic'
1820
import { uniqBy, prop } from 'ramda'
@@ -44,12 +46,14 @@ export default function EditTeamForm({
4446
initialValues,
4547
onSubmit,
4648
staff,
49+
team,
4750
isCreateForm,
4851
orgTeamTags = [],
4952
teamTags = [],
5053
profileValues,
5154
}) {
5255
const [orgTeam, setOrgTeam] = useState(false)
56+
const [hasLocation, setHasLocation] = useState(initialValues.location)
5357
if (profileValues) {
5458
initialValues.tags = {}
5559
profileValues.forEach(({ id, value }) => {
@@ -83,13 +87,13 @@ export default function EditTeamForm({
8387
}
8488
if (orgTeamTags.length > 0) {
8589
extraOrgTeamFields = orgTeamTags.map(
86-
({ id, name, required, description }) => {
90+
({ id, name, key_type, required, description }) => {
8791
return (
8892
<FormControl isRequired={required} key={`extra-tag-${id}`}>
8993
<FormLabel htmlFor={`extra-tag-${id}`}>{name}</FormLabel>
9094
<Field
9195
as={Input}
92-
type='text'
96+
type={key_type}
9397
name={`tags.key-${id}`}
9498
id={`extra-tag-${id}`}
9599
required={required}
@@ -106,13 +110,13 @@ export default function EditTeamForm({
106110

107111
if (teamTags.length > 0) {
108112
extraTeamFields = teamTags.map(
109-
({ id, name, required, description }) => {
113+
({ id, name, key_type, required, description }) => {
110114
return (
111115
<FormControl isRequired={required} key={`extra-tag-${id}`}>
112116
<FormLabel htmlFor={`extra-tag-${id}`}>{name}</FormLabel>
113117
<Field
114118
as={Input}
115-
type='text'
119+
type={key_type}
116120
name={`tags.key-${id}`}
117121
id={`extra-tag-${id}`}
118122
required={required}
@@ -129,8 +133,8 @@ export default function EditTeamForm({
129133

130134
return (
131135
<Form>
132-
<VStack alignItems={'flex-start'}>
133-
<Heading variant='sectionHead'>Details</Heading>
136+
<VStack alignItems={'flex-start'} spacing={4}>
137+
<Heading variant='sectionHead'>Team Details</Heading>
134138
<FormControl isRequired isInvalid={errors.name}>
135139
<FormLabel htmlFor='name'>Name</FormLabel>
136140
<Field
@@ -192,18 +196,20 @@ export default function EditTeamForm({
192196
</FormHelperText>
193197
</FormControl>
194198
{staff && isCreateForm && (
195-
<FormControl>
196-
<FormLabel htmlFor='orgTeam-checkbox'>
199+
<FormControl pt={4}>
200+
<Flex alignItems='center' gap={2}>
197201
<Checkbox
198202
id='orgTeam-checkbox'
199203
name='orgTeam-checkbox'
200204
type='checkbox'
201-
checked={orgTeam}
205+
isChecked={orgTeam}
202206
style={{ minWidth: '1rem' }}
203207
onChange={(e) => setOrgTeam(e.target.checked)}
204208
/>
205-
This team belongs to an organization
206-
</FormLabel>
209+
<FormLabel htmlFor='orgTeam-checkbox' m={0}>
210+
This team belongs to an organization
211+
</FormLabel>
212+
</Flex>
207213
{orgTeam && (
208214
<Field
209215
as={Select}
@@ -222,18 +228,29 @@ export default function EditTeamForm({
222228
</FormControl>
223229
)}
224230
{extraOrgTeamFields.length > 0 ? (
225-
<>
226-
<Heading as='h3' size='sm'>
227-
Organization Attributes
231+
<Flex
232+
flexDir='column'
233+
alignItems='flex-start'
234+
border={'1px'}
235+
borderRadius='base'
236+
p={8}
237+
borderColor='brand.50'
238+
>
239+
<Heading as='h3' size='sm' variant='sectionHead'>
240+
{team.org?.name} Details
228241
</Heading>
242+
<Text fontSize='sm' pb={4}>
243+
Organization {team.org?.name} requests the following
244+
additional details
245+
</Text>
229246
{extraOrgTeamFields}
230-
</>
247+
</Flex>
231248
) : (
232249
''
233250
)}
234251
{extraTeamFields.length > 0 ? (
235252
<>
236-
<Heading as='h3' size='sm'>
253+
<Heading as='h3' size='sm' variant='sectionHead'>
237254
Other Team Attributes
238255
</Heading>
239256
{extraTeamFields}
@@ -242,12 +259,32 @@ export default function EditTeamForm({
242259
''
243260
)}
244261
<Heading variant='sectionHead'>Location</Heading>
245-
<FormMap
246-
style={{ height: '300px', width: '100%' }}
247-
name='location'
248-
value={values.location}
249-
onChange={setFieldValue}
250-
/>
262+
<FormControl>
263+
<Flex alignItems='center' gap={2}>
264+
<Checkbox
265+
id='hasLocation-checkbox'
266+
name='hasLocation-checkbox'
267+
type='checkbox'
268+
isChecked={hasLocation}
269+
style={{ minWidth: '1rem' }}
270+
onChange={(e) => {
271+
setHasLocation(e.target.checked)
272+
setFieldValue('location', null)
273+
}}
274+
/>
275+
<FormLabel htmlFor='hasLocation-checkbox' m={0}>
276+
This team has a location
277+
</FormLabel>
278+
</Flex>
279+
</FormControl>
280+
{hasLocation && (
281+
<FormMap
282+
style={{ height: '300px', width: '100%' }}
283+
name='location'
284+
value={values.location}
285+
onChange={setFieldValue}
286+
/>
287+
)}
251288
<FormControl>
252289
<Button
253290
isDisabled={isSubmitting}

src/components/error-boundary.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { Box, Button, Container, Heading, Text } from '@chakra-ui/react'
2+
import React from 'react'
3+
import InpageHeader from './inpage-header'
4+
5+
class ErrorBoundary extends React.Component {
6+
constructor(props) {
7+
super(props)
8+
9+
// Define a state variable to track whether is an error or not
10+
this.state = { hasError: false }
11+
}
12+
// eslint-disable-next-line no-unused-vars
13+
static getDerivedStateFromError(error) {
14+
// Update state so the next render will show the fallback UI
15+
16+
return { hasError: true }
17+
}
18+
componentDidCatch(error, errorInfo) {
19+
// You can use your own error logging service here
20+
// eslint-disable-next-line no-console
21+
console.error({ error, errorInfo })
22+
}
23+
render() {
24+
// Check if the error is thrown
25+
if (this.state.hasError) {
26+
// You can render any custom fallback UI
27+
return (
28+
<Box as='main' mb={8}>
29+
<InpageHeader>
30+
<Heading color='white' mb={2}>
31+
Application error
32+
</Heading>
33+
</InpageHeader>
34+
<Container maxW='container.xl' as='section'>
35+
<Box layerStyle={'shadowed'}>
36+
<Text fontSize='2xl'>
37+
Sorry, there was an error loading this page
38+
</Text>
39+
<Button onClick={() => this.setState({ hasError: false })}>
40+
Try again?
41+
</Button>
42+
<Text>
43+
Still having problems? Try logging out and back in or contacting
44+
a system administrator.
45+
</Text>
46+
</Box>
47+
</Container>
48+
</Box>
49+
)
50+
}
51+
52+
// Return children components in case of no error
53+
54+
return this.props.children
55+
}
56+
}
57+
58+
export default ErrorBoundary

src/components/form-map.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@ import React, { Component } from 'react'
22
import { Map, CircleMarker, TileLayer } from 'react-leaflet'
33
import { reverse } from 'ramda'
44
import Geocoder from 'leaflet-control-geocoder'
5+
import 'leaflet-gesture-handling'
56

67
export default class FormMap extends Component {
78
constructor(props) {
89
super(props)
910
this.map = React.createRef()
1011
this.state = {
11-
zoom: 15,
12+
zoom: 10,
1213
}
1314
}
1415

@@ -51,6 +52,7 @@ export default class FormMap extends Component {
5152
this.setZoom(zoom)
5253
this.props.onChange(this.props.name, toGeojson)
5354
}}
55+
gestureHandling={true}
5456
>
5557
<TileLayer
5658
attribution='&amp;copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'

src/components/list-map.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import React, { Component, createRef } from 'react'
2-
import { Map, CircleMarker, TileLayer } from 'react-leaflet'
2+
import { Map, CircleMarker, TileLayer, Tooltip } from 'react-leaflet'
3+
import Router from 'next/router'
4+
import join from 'url-join'
5+
6+
const APP_URL = process.env.APP_URL
37

48
export default class ListMap extends Component {
59
constructor(props) {
@@ -12,9 +16,14 @@ export default class ListMap extends Component {
1216
<CircleMarker
1317
key={marker.id}
1418
center={marker.center}
15-
color='blue'
19+
color='var(--chakra-colors-brand-500)'
1620
radius={2}
17-
/>
21+
onclick={() => {
22+
Router.push(join(APP_URL, `/teams/${marker.id}`))
23+
}}
24+
>
25+
<Tooltip>{marker.name}</Tooltip>
26+
</CircleMarker>
1827
))
1928

2029
return (

src/components/page-header.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export default function PageHeader() {
104104
</NavLink>
105105
))}
106106
{isAuthenticated && (
107-
<NavLink href={'/profile'} passHref legacyBehavior>
107+
<NavLink href={'/dashboard'} passHref legacyBehavior>
108108
<Button
109109
as='a'
110110
variant='outline'
@@ -175,7 +175,7 @@ export default function PageHeader() {
175175
<MenuDivider />
176176

177177
<MenuItem bg='inherit'>
178-
<NavLink href='/profile'>
178+
<NavLink href='/dashboard'>
179179
<span>Dashboard</span>
180180
</NavLink>
181181
</MenuItem>
@@ -229,7 +229,7 @@ export default function PageHeader() {
229229
))}
230230
{isAuthenticated && (
231231
<ListItem>
232-
<NavLink href={'/profile'}>
232+
<NavLink href={'/dashboard'}>
233233
<span>Dashboard</span>
234234
</NavLink>
235235
</ListItem>

0 commit comments

Comments
 (0)