Skip to content

Commit

Permalink
Merge pull request ONEARMY#3033 from benfurber/3018-add-impact-data
Browse files Browse the repository at this point in the history
feat: add user setting to update impact
  • Loading branch information
thisislawatts authored Dec 6, 2023
2 parents 560a665 + b29ab98 commit 4b7fe10
Show file tree
Hide file tree
Showing 23 changed files with 611 additions and 90 deletions.
42 changes: 41 additions & 1 deletion packages/cypress/src/integration/settings.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { DbCollectionName } from '../utils/TestUtils'
import { UserMenuItem } from '../support/commands'
import type { IUser } from '../../../../src/models/user.models'
import { SingaporeStubResponse } from '../fixtures/searchResults'
import { form } from '../../../../src/pages/UserSettings/labels'

import type { IUser } from '../../../../src/models/user.models'

interface Info {
username: string
Expand Down Expand Up @@ -92,6 +94,33 @@ describe('[Settings]', () => {
type: 'image/jpeg',
},
],
impact: {
2022: [
{
label: 'plastic recycled',
value: 43000,
suffix: 'Kg of',
isVisible: true,
},
{
label: 'revenue',
value: 100000,
prefix: '$',
suffix: 'in',
isVisible: false,
},
{
label: 'full time employees',
value: 3,
isVisible: true,
},
{
label: 'volunteers',
value: 45,
isVisible: false,
},
],
},
isContactableByPublic: true,
links: [
{
Expand Down Expand Up @@ -155,6 +184,17 @@ describe('[Settings]', () => {
locationName: expected.location.value,
})

cy.step('Save impact data')
cy.get('[data-cy="impact-button-expand"]').click()
cy.get('[data-cy="impactForm-2022-button-edit"]').click()
cy.get('[data-cy="impactForm-2022-field-revenue-value"]')
.clear()
.type('100000')
cy.get('[data-cy="impactForm-2022-field-revenue-isVisible"]').click()
cy.get('[data-cy="impactForm-2022-field-machines built-value"]').clear()
cy.get('[data-cy="impactForm-2022-button-save"]').click()
cy.contains(form.saveSuccess)

cy.step('Opt-in to being contacted by users')
cy.get('[data-cy=isContactableByPublic]').should('not.be.checked')
cy.get('[data-cy=isContactableByPublic]').check({ force: true })
Expand Down
68 changes: 33 additions & 35 deletions shared/mocks/data/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,41 +303,39 @@ export const users = {
collectedPlasticTypes: null,
email: '[email protected]',
password: 'test1234',
impact: [
{
year: 2022,
fields: [
{
label: 'plastic recycled',
value: 43000,
suffix: 'Kg of',
isVisible: true,
},
{
label: 'revenue',
value: 36000,
prefix: '$',
suffix: 'in',
isVisible: true,
},
{
label: 'full time employees',
value: 3,
isVisible: true,
},
{
label: 'volunteers',
value: 45,
isVisible: false,
},
{
label: 'machines built',
value: 2,
isVisible: true,
},
],
},
],
userRoles: ['beta-tester'],
impact: {
2022: [
{
label: 'plastic recycled',
value: 43000,
suffix: 'Kg of',
isVisible: true,
},
{
label: 'revenue',
value: 36000,
prefix: '$',
suffix: 'in',
isVisible: true,
},
{
label: 'full time employees',
value: 3,
isVisible: true,
},
{
label: 'volunteers',
value: 45,
isVisible: false,
},
{
label: 'machines built',
value: 2,
isVisible: true,
},
],
},
},
mapview_testing_rejected: {
openingHours: [],
Expand Down
11 changes: 5 additions & 6 deletions src/models/user.models.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,20 @@ export interface IUser {
isContactableByPublic?: boolean
}

export type IUserImpact = IImpactData[] | []

export interface IImpactData {
year: IImpactYear
fields: ImpactDataField[]
export interface IUserImpact {
[key: number]: IImpactYearFieldList
}

export interface ImpactDataField {
export interface IImpactDataField {
label: string
value: number
prefix?: string
suffix?: string
isVisible: boolean
}

export type IImpactYearFieldList = IImpactDataField[]

export type IImpactYear = 2021 | 2022 | 2023

export interface IUserBadges {
Expand Down
2 changes: 1 addition & 1 deletion src/pages/User/contact/UserContactError.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Text } from 'theme-ui'
import { TextNotification } from 'oa-components'

type SubmitResults = { type: 'success' | 'error'; message: string }
export type SubmitResults = { type: 'success' | 'error'; message: string }

interface Props {
submitResults: SubmitResults | null
Expand Down
57 changes: 26 additions & 31 deletions src/pages/User/impact/Impact.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { missing } from './labels'
import { IMPACT_YEARS } from './constants'
import { Impact } from './Impact'

import type { IImpactYear } from 'src/models'

jest.mock('src/index', () => {
return {
useCommonStores: () => ({
Expand All @@ -23,35 +21,32 @@ jest.mock('src/index', () => {

describe('Impact', () => {
it('renders all fields with data formatted correctly', async () => {
const impact = [
{
year: 2022 as IImpactYear,
fields: [
{
label: 'volunteers',
value: 45,
isVisible: true,
},
{
label: 'plastic recycled',
suffix: 'Kg of',
value: 23000,
isVisible: true,
},
{
label: 'revenue',
prefix: '$',
value: 54000,
isVisible: true,
},
{
label: 'machines built',
value: 13,
isVisible: false,
},
],
},
]
const impact = {
2022: [
{
label: 'volunteers',
value: 45,
isVisible: true,
},
{
label: 'plastic recycled',
suffix: 'Kg of',
value: 23000,
isVisible: true,
},
{
label: 'revenue',
prefix: '$',
value: 54000,
isVisible: true,
},
{
label: 'machines built',
value: 13,
isVisible: false,
},
],
}
const user = FactoryUser({ impact })

render(
Expand Down
5 changes: 3 additions & 2 deletions src/pages/User/impact/Impact.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ interface Props {

export const Impact = ({ impact, user }: Props) => {
const renderByYear = IMPACT_YEARS.map((year, index) => {
const found = impact.find((data) => data.year === year)
const foundYear = Object.keys(impact).find((key) => Number(key) === year)

return (
<ImpactItem
fields={found && found.fields}
fields={foundYear && impact[foundYear]}
year={year}
key={index}
user={user}
Expand Down
4 changes: 2 additions & 2 deletions src/pages/User/impact/ImpactEmoji.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ImpactDataField } from 'src/models'
import type { IImpactDataField } from 'src/models'

interface Props {
label: ImpactDataField['label']
label: IImpactDataField['label']
}

const EMOJI_MAP = {
Expand Down
4 changes: 2 additions & 2 deletions src/pages/User/impact/ImpactField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { Box, Text } from 'theme-ui'
import { numberWithCommas } from 'src/utils/helpers'
import { ImpactEmoji } from './ImpactEmoji'

import type { ImpactDataField } from 'src/models'
import type { IImpactDataField } from 'src/models'

interface Props {
field: ImpactDataField
field: IImpactDataField
}

export const ImpactField = ({ field }: Props) => {
Expand Down
4 changes: 2 additions & 2 deletions src/pages/User/impact/ImpactItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { Box, Heading } from 'theme-ui'
import { ImpactField } from './ImpactField'
import { ImpactMissing } from './ImpactMissing'

import type { ImpactDataField, IImpactYear, IUserPP } from 'src/models'
import type { IImpactYearFieldList, IImpactYear, IUserPP } from 'src/models'

interface Props {
year: IImpactYear
fields: ImpactDataField[] | undefined
fields: IImpactYearFieldList | undefined
user: IUserPP
}

Expand Down
12 changes: 8 additions & 4 deletions src/pages/User/impact/ImpactMissing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,22 @@ export const ImpactMissing = observer(({ user, year }: Props) => {

const isPageOwner = userStore.activeUser && user

const button = `${year} ${missing.user.link}`
const href = IMPACT_REPORT_LINKS[year]
const userButton = `${year} ${missing.user.link}`
const label = isPageOwner ? missing.owner.label : missing.user.label

return (
<Flex sx={{ flexFlow: 'column', gap: 2, mt: 2 }}>
<Text>{label}</Text>
{!isPageOwner && (
<ExternalLink href={href}>
<Button>{button}</Button>
<ExternalLink href={IMPACT_REPORT_LINKS[year]}>
<Button>{userButton}</Button>
</ExternalLink>
)}
{isPageOwner && (
<a href="/settings">
<Button>{missing.owner.link}</Button>
</a>
)}
</Flex>
)
})
1 change: 1 addition & 0 deletions src/pages/User/impact/labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ export const missing = {
},
owner: {
label: "Looks like you haven't added your Impact Data yet.",
link: 'Enter impact data',
},
}
9 changes: 9 additions & 0 deletions src/pages/UserSettings/SettingsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import arrayMutators from 'final-form-arrays'
import { Form } from 'react-final-form'
import { v4 as uuid } from 'uuid'

import { AuthWrapper } from 'src/common/AuthWrapper'
import { UserInfosSection } from './content/formSections/UserInfos.section'
import { FocusSection } from './content/formSections/Focus.section'
import { ExpertiseSection } from './content/formSections/Expertise.section'
Expand All @@ -20,6 +21,7 @@ import { ProfileGuidelines } from './content/PostingGuidelines'
import { WorkspaceMapPinSection } from './content/formSections/WorkspaceMapPin.section'
import { MemberMapPinSection } from './content/formSections/MemberMapPin.section'
import { PublicContactSection } from './content/formSections/PublicContact.section'
import { ImpactSection } from './content/formSections/Impact/Impact.section'

import { buttons, headings } from './labels'
import INITIAL_VALUES from './Template'
Expand Down Expand Up @@ -306,6 +308,13 @@ export class SettingsPage extends React.Component<IProps, IState> {
showLocationDropdown={this.state.showLocationDropdown}
/>
</Flex>

{!isMember && (
<AuthWrapper roleRequired={'beta-tester'}>
<ImpactSection />
</AuthWrapper>
)}

<EmailNotificationsSection
notificationSettings={values.notification_settings}
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useState } from 'react'
import { Heading, Box, Button, Text } from 'theme-ui'

import { buttons, fields } from 'src/pages/UserSettings/labels'
import { IMPACT_YEARS } from 'src/pages/User/impact/constants'
import { FlexSectionContainer } from '../elements'
import { ImpactYearSection } from './ImpactYear.section'

export const ImpactSection = () => {
const [isExpanded, setIsExpanded] = useState<boolean>(false)
const { description, title } = fields.impact
const { expandClose, expandOpen } = buttons.impact

const buttonLabel = isExpanded ? expandClose : expandOpen

return (
<FlexSectionContainer>
<Heading dangerouslySetInnerHTML={{ __html: title }} variant="small" />
<Text mt={4} mb={4}>
{description}
</Text>
{isExpanded && (
<Box>
{IMPACT_YEARS.map((year) => {
return <ImpactYearSection year={year} key={year} />
})}
</Box>
)}
<Box mt={2}>
<Button
dangerouslySetInnerHTML={{ __html: buttonLabel }}
data-cy="impact-button-expand"
onClick={() => setIsExpanded(!isExpanded)}
variant="secondary"
/>
</Box>
</FlexSectionContainer>
)
}
Loading

0 comments on commit 4b7fe10

Please sign in to comment.