Skip to content

Commit

Permalink
Merge pull request #557 from UKHSA-Internal/feature/CDD-2361-wha-card…
Browse files Browse the repository at this point in the history
…-update

Feature/CDD-2361: WHA card update
  • Loading branch information
rhys-burendo authored Dec 13, 2024
2 parents 192237f + 699267e commit ee6642b
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 51 deletions.
2 changes: 1 addition & 1 deletion e2e/fixtures/pages/landing/landing.fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export class LandingPage {

const regions = this.page.getByRole('list', { name: 'Weather health alerts by region' })
await expect(regions).toBeVisible()
await expect(await regions.getByRole('listitem').all()).toHaveLength(9)
await expect(await regions.getByRole('listitem').all()).toHaveLength(13)
await expect(card.getByRole('button', { name: 'Enter fullscreen' })).toBeVisible()
}

Expand Down
7 changes: 4 additions & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ const customJestConfig = {
// lines: 95,
// functions: 96,

// Will update back up as part of CDD-2370
statements: 91,
branches: 81,
lines: 93,
functions: 89,
branches: 80,
lines: 92,
functions: 87,
},
},
watchPathIgnorePatterns: ['node_modules'],
Expand Down
100 changes: 78 additions & 22 deletions src/app/components/ui/ukhsa/MiniMap/MiniMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import { useDebounceValue } from 'usehooks-ts'
import { HealthAlertStatus, HealthAlertTypes } from '@/api/models/Alerts'
import RightArrowCircleIcon from '@/app/components/ui/ukhsa/Icons/RightArrowCircle'
import useWeatherHealthAlertList from '@/app/hooks/queries/useWeatherHealthAlertList'
import { getCssVariableFromColour } from '@/app/utils/weather-health-alert.utils'
import { useTranslation } from '@/app/i18n/client'
import {
getCssVariableFromColour,
getTailwindBackgroundFromColour,
getTextColourCssFromColour,
} from '@/app/utils/weather-health-alert.utils'
import { clsx } from '@/lib/clsx'

import { regionPaths } from './constants'
Expand Down Expand Up @@ -37,8 +42,9 @@ const AlertListItem = memo(
onKeyDown={onClick}
>
<span
className={clsx(`absolute left-0 top-[3px] mr-2 inline-block size-3 rounded-full`)}
style={{ background: getCssVariableFromColour(status) }}
className={clsx(
`absolute left-0 top-[3px] mr-2 inline-block size-3 rounded-full ${getTailwindBackgroundFromColour(status)}`
)}
/>
<span className="ml-5 block">{name}</span>
</li>
Expand Down Expand Up @@ -86,11 +92,22 @@ interface MiniMapProps {
alertType: HealthAlertTypes
}

interface AlertObject {
slug: string
status: HealthAlertStatus
geography_name: string
geography_code: string
refresh_date: string | null
}

export function MiniMap({ alertType }: MiniMapProps): React.ReactElement | null {
const [hoveredRegion, setHoveredRegion] = useState<string | null>(null)
const alerts = useWeatherHealthAlertList({ type: alertType })

const router = useRouter()

const { t } = useTranslation('weatherHealthAlerts')

const [debouncedHoveredRegion] = useDebounceValue(hoveredRegion, 80)

const handleMouseEnter = useCallback((region: string) => {
Expand All @@ -102,40 +119,72 @@ export function MiniMap({ alertType }: MiniMapProps): React.ReactElement | null
}, [])

const handleClick = useCallback(
(regionId: string) => {
(regionId?: string) => {
const url = new URL('/', window.location.origin)
url.searchParams.set('v', 'map')
url.searchParams.set('type', alertType)
url.searchParams.set('fid', regionId)
regionId ? url.searchParams.set('fid', regionId) : null
router.push(url.toString(), { scroll: false })
},
[router]
)

if (alerts.isLoading || !alerts.data) return null

const groupedAlerts = Object.entries(
alerts.data.reduce(
(statusGrouped, alert) => {
const { status } = alert
if (!statusGrouped[status]) {
statusGrouped[status] = []
}
statusGrouped[status].push(alert)
return statusGrouped
},
{} as Record<string, AlertObject[]>
)
).map(([status, alerts]) => ({
status: status as HealthAlertStatus,
alerts,
}))

return (
<>
<ul
className="govuk-list govuk-!-font-size-16 mb-1 flex max-w-[80%] flex-wrap gap-1"
aria-label="Weather health alerts by region"
>
{alerts.data.map((alert) => (
<AlertListItem
key={alert.geography_code}
name={alert.geography_name}
status={alert.status}
isHovered={debouncedHoveredRegion === alert.geography_code}
isAnyHovered={debouncedHoveredRegion !== null}
onMouseEnter={() => handleMouseEnter(alert.geography_code)}
onMouseLeave={handleMouseLeave}
onClick={(evt) => {
evt.preventDefault()
evt.stopPropagation()
handleClick(alert.geography_code)
}}
/>
))}
{groupedAlerts.map(({ status, alerts }) => {
if (alerts.length > 0) {
return (
<>
<li className="m-0 mt-2 w-full">
<div
className={`m-0 w-[100px] text-center capitalize ${getTailwindBackgroundFromColour(status)} ${getTextColourCssFromColour(status)}`}
>
{status == 'Green' ? t('map.no-alert') : t('map.alert', { level: status })}
</div>
</li>
{alerts.map((alert) => (
<AlertListItem
key={alert.geography_code}
name={alert.geography_name}
status={alert.status}
isHovered={debouncedHoveredRegion === alert.geography_code}
isAnyHovered={debouncedHoveredRegion !== null}
onMouseEnter={() => handleMouseEnter(alert.geography_code)}
onMouseLeave={handleMouseLeave}
onClick={(evt) => {
evt.preventDefault()
evt.stopPropagation()
handleClick(alert.geography_code)
}}
/>
))}
</>
)
}
})}
</ul>
<div>
<svg
Expand Down Expand Up @@ -168,7 +217,14 @@ export function MiniMap({ alertType }: MiniMapProps): React.ReactElement | null
})}
</svg>
</div>
<button type="button" className="govuk-!-margin-top-3 flex">
<button
type="button"
className="govuk-!-margin-top-3 flex"
onClick={(evt) => {
evt.preventDefault()
handleClick()
}}
>
<RightArrowCircleIcon />
<div className="govuk-link ml-2 font-bold">Enter Fullscreen</div>
</button>
Expand Down
11 changes: 1 addition & 10 deletions src/app/components/ui/ukhsa/MiniMap/MiniMapCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use client'

import Link from 'next/link'
import { useRouter } from 'next/navigation'

import { HealthAlertTypes } from '@/api/models/Alerts'

Expand All @@ -15,21 +14,13 @@ interface MiniMapCardProps {
}

export function MiniMapCard({ title, subTitle, alertType }: MiniMapCardProps) {
const router = useRouter()
return (
<Card
asChild
aria-labelledby={`chart-row-card-heading-x4`}
className="govuk-link--no-visited-state govuk-!-padding-5 ukhsa-chart-card relative flex flex-col bg-[var(--colour-chart-background)] no-underline transition-colors duration-200 ukhsa-focus hover:bg-[var(--colour-chart-background-hover)] focus:bg-[var(--colour-chart-background-hover)]"
>
<Link
href={`/weather-health-alerts/${alertType}`}
scroll={false}
onClick={(evt) => {
evt.preventDefault()
router.push(`/?v=map&type=${alertType}`)
}}
>
<Link href={`/weather-health-alerts/${alertType}`}>
<h3 id="chart-row-card-heading-x4" className="govuk-heading-m mb-1">
{title}
</h3>
Expand Down
30 changes: 15 additions & 15 deletions src/app/utils/weather-health-alert.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ export enum ColourVariableMap {
Red = 'var(--colour-red)',
}

export enum ColourBackgroundMap {
Green = 'bg-green',
Amber = 'bg-orange',
Yellow = 'bg-custard',
Red = 'bg-red',
}

export enum HoverColourVariableMap {
Green = 'var(--colour-green-dark)',
Amber = 'var(--colour-orange-dark)',
Expand All @@ -39,25 +46,10 @@ export enum ActiveColourVariableMap {
Red = 'var(--colour-red-darkest)',
}

export enum ColourBackgroundMap {
Green = 'bg-green',
Amber = 'bg-orange',
Yellow = 'bg-custard',
Red = 'bg-red',
}

export function getCssVariableFromColour(color: keyof typeof ColourVariableMap) {
return ColourVariableMap[color]
}

export function getHoverCssVariableFromColour(color: keyof typeof HoverColourVariableMap) {
return `${HoverColourVariableMap[color]}`
}

export function getActiveCssVariableFromColour(color: keyof typeof ActiveColourVariableMap) {
return `${ActiveColourVariableMap[color]}`
}

export function getTailwindBackgroundFromColour(color: keyof typeof ColourBackgroundMap) {
return ColourBackgroundMap[color]
}
Expand All @@ -69,3 +61,11 @@ export function getTextColourCssFromColour(colour: string) {
return 'text-white'
}
}

export function getHoverCssVariableFromColour(color: keyof typeof HoverColourVariableMap) {
return `${HoverColourVariableMap[color]}`
}

export function getActiveCssVariableFromColour(color: keyof typeof ActiveColourVariableMap) {
return `${ActiveColourVariableMap[color]}`
}

1 comment on commit ee6642b

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit tests coverage

Lines Statements Branches Functions
Coverage: 93%
91.9% (1771/1927) 81.72% (416/509) 88.85% (263/296)
Tests Skipped Failures Errors Time
476 0 💤 0 ❌ 0 🔥 15.904s ⏱️

Please sign in to comment.