Skip to content

Commit

Permalink
Added additional disclaimer text to the state seal component and made…
Browse files Browse the repository at this point in the history
… it editable on the settings page
  • Loading branch information
crismali committed Nov 14, 2023
1 parent a9b4c4a commit ed96e88
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 45 deletions.
5 changes: 5 additions & 0 deletions src/pages/settings.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.settings-header-and-forms {
display: flex;
flex-direction: column;
}

.heading-container {
margin-bottom: 6rem;
}
Expand Down
41 changes: 22 additions & 19 deletions src/pages/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { SkipNavContent } from '@reach/skip-nav'
import { Heading, Layout, PageContent, Paragraph, Sidebar, SpacedContainer } from 'src/ui/Layout'
import { SidebarNavigation } from 'src/ui/SidebarNavigation'
import { EditDisclaimer, EditBanner, EditStateSeal, EditDepartmentSeal } from 'src/ui/Settings'

import './settings.css'
import { formatPageTitle } from 'src/utils/formatPageTitle'
import { EditingEmailCSS } from 'src/templates/emailHtmlDocument/EmailCSS'

const SettingsPage: FC = () => {
return (
Expand All @@ -17,29 +17,32 @@ const SettingsPage: FC = () => {
<SkipNavContent />
<PageContent element="main">
<SpacedContainer>
<div className="heading-container">
<Heading element="h1">Settings</Heading>
<Paragraph>
Set up your state's logos and seal. Your selections here will appear in the emails you
create.
</Paragraph>
</div>
<div className="settings-header-and-forms">
<div className="heading-container">
<Heading element="h1">Settings</Heading>
<Paragraph>
Set up your state's logos and seal. Your selections here will appear in the emails
you create.
</Paragraph>
</div>

<div className="section-container">
<EditBanner />
</div>
<div className="section-container">
<EditBanner />
</div>

<div className="section-container">
<EditDepartmentSeal />
</div>
<div className="section-container">
<EditStateSeal />
</div>
<div className="section-container">
<EditDisclaimer />
<div className="section-container">
<EditDepartmentSeal />
</div>
<div className="section-container">
<EditStateSeal />
</div>
<div className="section-container">
<EditDisclaimer />
</div>
</div>
</SpacedContainer>
</PageContent>
<EditingEmailCSS />
</Layout>
)
}
Expand Down
76 changes: 59 additions & 17 deletions src/templates/EmailTemplateComponents/StateSeal.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,84 @@
import React, { CSSProperties, FC } from 'react'
import React, { CSSProperties, FC, ReactElement } from 'react'
import { EmailComponentProps } from './shared'
import { useLocalStorageJSON } from 'src/utils/useLocalStorage'
import { EmailBlock } from 'src/ui'
import startCase from 'lodash.startcase'
import { StateSealKey, StateSeals } from 'src/ui/StateSeal'
import { StyleDefaults } from '../styles'
import { Spacing, SpacingCell, StyleDefaults, Text } from '../styles'
import Config from '../../../gatsby-config'

const defaultValue: StateSealKey = 'US'
export interface StateSealValue {
stateSealKey: StateSealKey
additionalDisclaimer: string
[key: string]: null | string
}

const defaultValue: StateSealValue = {
additionalDisclaimer: `The [Insert State] Department of Labor and Workforce Development is an equal opportunity employer and provides equal opportunity programs. Auxiliary aids and services are available upon request to assist individuals with disabilities.`,
stateSealKey: 'US',
}

export const useStateSealValue = () => {
return useLocalStorageJSON<StateSealKey>('stateSeal', defaultValue)
return useLocalStorageJSON<StateSealValue>('stateSeal', defaultValue)
}

const { Row } = EmailBlock
const { Row, Cell } = EmailBlock

interface StateSealMarkupProps {
stateSealKey: StateSealKey
additionalDisclaimer: string | ReactElement
}

export const StateSealMarkup: FC<StateSealMarkupProps> = ({
additionalDisclaimer,
stateSealKey,
}) => {
return (
<>
<Row>
<Cell className={StyleDefaults.layout.narrow} style={additionalDisclaimerStyles}>
{additionalDisclaimer}
</Cell>
</Row>
<Row>
<SpacingCell size="medium" />
</Row>
<Row>
<Cell className={StyleDefaults.layout.narrow} style={imageContainerStyles}>
<img
src={`${Config.siteMetadata?.siteUrl}/state-seal-designation/${StateSeals[stateSealKey]}.png`}
alt={startCase(stateSealKey)}
style={imageStyles}
/>
</Cell>
</Row>
</>
)
}

export const StateSeal: FC<EmailComponentProps> = ({}) => {
const [value] = useStateSealValue()

return (
<Row>
<td className={StyleDefaults.layout.narrow} style={tdStyles}>
<img
src={`${Config.siteMetadata?.siteUrl}/state-seal-designation/${StateSeals[value]}.png`}
alt={startCase(value)}
style={styles}
/>
</td>
</Row>
<StateSealMarkup
additionalDisclaimer={value.additionalDisclaimer}
stateSealKey={value.stateSealKey}
/>
)
}

const tdStyles: CSSProperties = {
const additionalDisclaimerStyles: CSSProperties = {
...Text.caption.small.regular,
color: '#777777',
lineHeight: 1.5,
}

const imageContainerStyles: CSSProperties = {
...StyleDefaults.inline.colors,
display: 'block',
}

const styles: CSSProperties = {
height: '30px',
const imageStyles: CSSProperties = {
height: 30,
display: 'block',
}
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ describe('Banner', () => {
})

it('when there is no banner value saved it renders without issue', () => {
localStorage.removeItem('banner')
const { queryAllByRole } = render(<Banner emailComponent={emailComponent}>{null}</Banner>, {
wrapper: emailPartWrapper,
})
Expand Down
65 changes: 65 additions & 0 deletions src/templates/EmailTemplateComponents/__tests__/StateSeal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { render } from '@testing-library/react'
import React from 'react'
import { StateSeal, StateSealMarkup, StateSealValue } from '../StateSeal'
import { faker } from '@faker-js/faker'
import { buildUniqueEmailComponent, emailPartWrapper } from 'src/testHelpers'

describe('StateSealMarkup', () => {
it('displays the additional content', () => {
const text = faker.lorem.paragraph()
const { baseElement } = render(
<StateSealMarkup additionalDisclaimer={<span>{text}</span>} stateSealKey="NewJersey" />,
{ wrapper: emailPartWrapper },
)
expect(baseElement).toContainHTML(`<span>${text}</span>`)
})

it('displays the selected state seal', () => {
const { getByRole } = render(
<StateSealMarkup additionalDisclaimer={faker.lorem.paragraph()} stateSealKey="NewJersey" />,
{ wrapper: emailPartWrapper },
)
const img: HTMLImageElement = getByRole('img') as any
expect(img.alt).toEqual('New Jersey')
expect(img.src).toContain('/state-seal-designation/New-Jersey.png')
})
})

describe('StateSeal', () => {
let stateSealValue: StateSealValue

beforeEach(() => {
stateSealValue = {
additionalDisclaimer: faker.lorem.paragraph(),
stateSealKey: 'NewJersey',
}
localStorage.setItem('stateSeal', JSON.stringify(stateSealValue))
})

it('displays the additional content', () => {
const { baseElement } = render(
<StateSeal emailComponent={buildUniqueEmailComponent('StateSeal')}>{null}</StateSeal>,
{ wrapper: emailPartWrapper },
)
expect(baseElement).toContainHTML(stateSealValue.additionalDisclaimer)
})

it('displays the selected state seal', () => {
const { getByRole } = render(
<StateSeal emailComponent={buildUniqueEmailComponent('StateSeal')}>{null}</StateSeal>,
{ wrapper: emailPartWrapper },
)
const img: HTMLImageElement = getByRole('img') as any
expect(img.alt).toEqual('New Jersey')
expect(img.src).toContain('/state-seal-designation/New-Jersey.png')
})

it('when there is no state seal value saved it renders without issue', () => {
localStorage.removeItem('stateSeal')
const { queryByRole, queryByText } = render(
<StateSeal emailComponent={buildUniqueEmailComponent('StateSeal')}>{null}</StateSeal>,
{ wrapper: emailPartWrapper },
)
expect(queryByRole('img')).not.toBeNull()
})
})
2 changes: 1 addition & 1 deletion src/ui/Settings/EditBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const EditBanner: FC = () => {
Banner
</Heading>
<Paragraph>At the very top of every email, it will show this:</Paragraph>
<EmailBlock.Table maxWidth={Spacing.layout.maxWidth}>
<EmailBlock.Table maxWidth={Spacing.layout.maxWidth} className="desktop">
<BannerMarkup
disableLinks
backgroundColor={banner.backgroundColor}
Expand Down
2 changes: 1 addition & 1 deletion src/ui/Settings/EditDepartmentSeal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const EditDepartmentSeal: FC = () => {
/>
</div>
<div className="department-seal-preview-container">
<EmailBlock.Table maxWidth={Spacing.layout.maxWidth}>
<EmailBlock.Table maxWidth={Spacing.layout.maxWidth} className="desktop">
<DepartmentSealMarkup departmentSealKey={value} />
</EmailBlock.Table>
</div>
Expand Down
3 changes: 2 additions & 1 deletion src/ui/Settings/EditDisclaimer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
styles as disclaimerStyles,
} from 'src/templates/EmailTemplateComponents/Disclaimer'
import { EditableElement } from '../EditableElement'
import { Spacing } from 'src/templates/styles'

export const EditDisclaimer: FC = () => {
const [disclaimer, setDisclaimer] = useDisclaimerValue()
Expand All @@ -19,7 +20,7 @@ export const EditDisclaimer: FC = () => {
Below every email, there is a disclaimer that is used for confidentiality purposes as well
as security purposes.
</Paragraph>
<EmailBlock.Table elements={['row']}>
<EmailBlock.Table elements={['row']} className="desktop" maxWidth={Spacing.layout.maxWidth}>
<EditableElement
label="Disclaimer"
element="td"
Expand Down
29 changes: 23 additions & 6 deletions src/ui/Settings/EditStateSeal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@ import startCase from 'lodash.startcase'
import { VisuallyHidden } from '@reach/visually-hidden'
import { Heading, Paragraph } from 'src/ui/Layout'
import { Select } from 'src/ui/Select'
import { StateSeal, StateSeals, StateSealKey } from 'src/ui/StateSeal'
import { useStateSealValue } from 'src/templates/EmailTemplateComponents/StateSeal'
import { StateSeals, StateSealKey } from 'src/ui/StateSeal'
import { StateSealMarkup, useStateSealValue } from 'src/templates/EmailTemplateComponents/StateSeal'
import { EmailBlock } from '../EmailBlock'
import { EditableElement } from '../EditableElement'
import { Spacing } from 'src/templates/styles'

const stateSealOptions = Object.keys(StateSeals).map((key) => ({
label: startCase(key),
value: key,
}))

export const EditStateSeal: FC = () => {
const [stateSeal, setStateSeal] = useStateSealValue()
const [value, setValue] = useStateSealValue()

return (
<>
Expand All @@ -28,14 +31,28 @@ export const EditStateSeal: FC = () => {
</VisuallyHidden>
<Select
labelId="state-seal-select"
onChange={(value) => setStateSeal(value as StateSealKey)}
onChange={((stateSealKey: StateSealKey) => setValue({ ...value, stateSealKey })) as any}
options={stateSealOptions}
value={stateSeal}
value={value.stateSealKey}
/>
</div>
</form>
<div className="edit-state-seal-preview">
<StateSeal state={stateSeal} />
<EmailBlock.Table className="desktop" maxWidth={Spacing.layout.maxWidth}>
<StateSealMarkup
stateSealKey={value.stateSealKey}
additionalDisclaimer={
<EditableElement
element="span"
label="Additional Disclaimer"
value={value.additionalDisclaimer}
onValueChange={(additionalDisclaimer) =>
setValue({ ...value, additionalDisclaimer })
}
/>
}
/>
</EmailBlock.Table>
</div>
</>
)
Expand Down
38 changes: 38 additions & 0 deletions src/ui/Settings/__tests__/EditStateSeal.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react'
import { render } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { EditStateSeal } from '../EditStateSeal'
import { StateSealValue } from 'src/templates/EmailTemplateComponents/StateSeal'
import { faker } from '@faker-js/faker'

describe('EditStateSeal', () => {
const stored = (): StateSealValue => {
const stored = localStorage.getItem('stateSeal') ?? '{}'
return JSON.parse(stored)
}

it('has an editable state seal dropdown', async () => {
const user = userEvent.setup()
const { getByRole } = render(<EditStateSeal />)

const stateSealSelect = () => getByRole('button')
expect(stateSealSelect()).toHaveTextContent('US')

await user.click(stateSealSelect())
await user.click(getByRole('option', { name: 'California' }))

expect(stateSealSelect()).toHaveTextContent('California')
expect(stored().stateSealKey).toEqual('California')
})

it('has an editable additional disclaimer text', async () => {
const user = userEvent.setup()
const { getByLabelText } = render(<EditStateSeal />)
const value = faker.lorem.paragraph()
const additionalDisclaimerField = () => getByLabelText('Additional Disclaimer')

await user.clear(additionalDisclaimerField())
await user.type(additionalDisclaimerField(), value)
expect(additionalDisclaimerField()).toHaveTextContent(value)
})
})

0 comments on commit ed96e88

Please sign in to comment.