Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use i18n keys instead of hardcoded texts #748

Merged
merged 20 commits into from
Mar 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/public/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"ignorePatterns": ["!**/*", ".next/**/*"],
"overrides": [
{
"files": ["**/page.tsx", "**/layout.tsx", "next.config.ts"],
"files": ["**/page.tsx", "**/layout.tsx", "next.config.ts", "request.ts"],
"rules": {
"import/no-default-export": "off",
"react/jsx-no-bind": "off"
Expand Down
10 changes: 10 additions & 0 deletions apps/public/i18n/request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { getRequestConfig } from 'next-intl/server'

export default getRequestConfig(async () => {
const locale = 'nl'

return {
locale,
messages: (await import(`../translations/${locale}.json`)).default,
}
})
8 changes: 6 additions & 2 deletions apps/public/next.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
const nextConfig = {
import type { NextConfig } from 'next'
import createNextIntlPlugin from 'next-intl/plugin'

const nextConfig: NextConfig = {
output: 'standalone',
}

export default nextConfig
const withNextIntl = createNextIntlPlugin()
export default withNextIntl(nextConfig)
2 changes: 1 addition & 1 deletion apps/public/src/app/(general)/Home.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe('Page', () => {
render(<Home formData={mockFormData} />)

expect(screen.queryByRole('textbox', { name: mockQuestionText })).toBeInTheDocument()
expect(screen.queryByRole('button', { name: 'Volgende vraag' })).toBeInTheDocument()
expect(screen.queryByRole('button', { name: 'submit-button' })).toBeInTheDocument()
})

it('should render an error message', () => {
Expand Down
5 changes: 4 additions & 1 deletion apps/public/src/app/(general)/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Paragraph } from '@amsterdam/design-system-react'
import type { StaticFormPanelComponentOutput, StaticFormTextFieldInputComponentOutput } from '@meldingen/api-client'
import { FormRenderer } from '@meldingen/form-renderer'
import { Grid } from '@meldingen/ui'
import { useTranslations } from 'next-intl'
import { useActionState } from 'react'

import { postPrimaryForm } from './actions'
Expand All @@ -15,11 +16,13 @@ const initialState: { message?: string } = {}
export const Home = ({ formData }: { formData: Component[] }) => {
const [formState, formAction] = useActionState(postPrimaryForm, initialState)

const t = useTranslations('homepage')

return (
<Grid paddingBottom="large" paddingTop="medium">
<Grid.Cell span={{ narrow: 4, medium: 6, wide: 6 }} start={{ narrow: 1, medium: 2, wide: 3 }}>
{formState?.message && <Paragraph>{formState.message}</Paragraph>}
<FormRenderer formData={formData} action={formAction} />
<FormRenderer action={formAction} formData={formData} submitButtonText={t('submit-button')} />
</Grid.Cell>
</Grid>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('AdditionalQuestions', () => {
it('renders a heading', () => {
render(<AdditionalQuestions {...defaultProps} />)

const heading = screen.getByRole('heading', { name: 'Beschrijf uw melding' })
const heading = screen.getByRole('heading', { name: 'step.title' })

expect(heading).toBeInTheDocument()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { Grid, Heading, Paragraph } from '@amsterdam/design-system-react'
import { FormRenderer } from '@meldingen/form-renderer'
import { useTranslations } from 'next-intl'
import { useActionState } from 'react'

import { BackLink } from '../../../_components/BackLink'
Expand All @@ -18,15 +19,17 @@ const initialState: { message?: string } = {}
export const AdditionalQuestions = ({ action, formData, previousPanelPath }: Props) => {
const [formState, formAction] = useActionState(action, initialState)

const t = useTranslations('additional-questions')

return (
<Grid paddingBottom="large" paddingTop="medium">
<Grid.Cell span={{ narrow: 4, medium: 6, wide: 6 }} start={{ narrow: 1, medium: 2, wide: 3 }}>
{formState?.message && <Paragraph>{formState.message}</Paragraph>}
<BackLink href={previousPanelPath} className="ams-mb--xs">
Vorige vraag
{t('back-link')}
</BackLink>
<Heading>Beschrijf uw melding</Heading>
<FormRenderer formData={formData} action={formAction} />
<Heading>{t('step.title')}</Heading>
<FormRenderer formData={formData} action={formAction} submitButtonText={t('submit-button')} />
</Grid.Cell>
</Grid>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { FormPanelComponentOutput } from '@meldingen/api-client'
import type { Metadata } from 'next'
import { getTranslations } from 'next-intl/server'

import { getFormClassificationByClassificationId } from 'apps/public/src/apiClientProxy'

Expand Down Expand Up @@ -38,8 +38,12 @@ export const dynamic = 'force-dynamic'
// return panelIdsByForm.flat()
// }

export const metadata: Metadata = {
title: 'Stap 1 van 4 - Beschrijf uw melding - Gemeente Amsterdam',
export const generateMetadata = async () => {
const t = await getTranslations('additional-questions')

return {
title: t('metadata.title'),
}
}

type Params = Promise<{
Expand Down
8 changes: 5 additions & 3 deletions apps/public/src/app/(general)/bedankt/Thanks.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ import { render, screen } from '@testing-library/react'
import { Thanks } from './Thanks'

describe('Thanks', () => {
it('should render meldingId and Doe een melding-link', () => {
it('should render', () => {
render(<Thanks meldingId="1" />)

const paragraph = screen.getByText('Wij hebben uw melding ontvangen op 21-11-2023 om 17:11. Uw meldnummer is 1.')
const link = screen.getByRole('link', { name: 'Doe een melding' })
const heading = screen.getByRole('heading', { name: 'title' })
const paragraph = screen.getByText('description')
const link = screen.getByRole('link', { name: 'link' })

expect(heading).toBeInTheDocument()
expect(paragraph).toBeInTheDocument()
expect(link).toBeInTheDocument()
})
Expand Down
53 changes: 17 additions & 36 deletions apps/public/src/app/(general)/bedankt/Thanks.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,27 @@
'use client'

import { Heading, Link, Paragraph } from '@amsterdam/design-system-react'
import { Heading, Link } from '@amsterdam/design-system-react'
import { MarkdownToHtml } from '@meldingen/markdown-to-html'
import { Grid } from '@meldingen/ui'
import NextLink from 'next/link'
import { useTranslations } from 'next-intl'

type Props = {
meldingId: string
}

export const Thanks = ({ meldingId }: Props) => (
<Grid paddingBottom="large" paddingTop="medium">
<Grid.Cell span={{ narrow: 4, medium: 6, wide: 6 }} start={{ narrow: 1, medium: 2, wide: 3 }}>
<Heading className="ams-mb--xs">Bedankt</Heading>
<Paragraph>Bedankt voor uw melding.</Paragraph>
<Paragraph className="ams-mb--sm">{`Wij hebben uw melding ontvangen op 21-11-2023 om 17:11. Uw meldnummer is ${meldingId}.`}</Paragraph>
export const Thanks = ({ meldingId }: Props) => {
const t = useTranslations('thanks')

<Heading level={2} size="level-3" className="ams-mb--xs">
Wat doen we met uw melding?
</Heading>
<Paragraph className="ams-mb--sm">Meldingen pakken we binnen 3 werkdagen op.</Paragraph>

<Heading level={2} size="level-3" className="ams-mb--xs">
Vragen of meer informatie?
</Heading>
<Paragraph className="ams-mb--sm">
Neem dan contact met ons op via{' '}
<Link href="tel:14020" variant="inline">
14 020
</Link>
. Vermeld hierbij alstublieft uw meldnummer. Meer informatie kunt u eventueel ook vinden op{' '}
<Link href="https://www.amsterdam.nl/" variant="inline" target="_blank">
www.amsterdam.nl
</Link>
.
</Paragraph>

<Heading level={2} size="level-3" className="ams-mb--xs">
Wilt u nog een andere melding doen?
</Heading>
<NextLink href="/" legacyBehavior passHref>
<Link href="dummy-href">Doe een melding</Link>
</NextLink>
</Grid.Cell>
</Grid>
)
return (
<Grid paddingBottom="large" paddingTop="medium">
<Grid.Cell span={{ narrow: 4, medium: 6, wide: 6 }} start={{ narrow: 1, medium: 2, wide: 3 }}>
<Heading className="ams-mb--xs">{t('title')}</Heading>
<MarkdownToHtml className="ams-mb--xs">{t('description', { meldingId })}</MarkdownToHtml>
<NextLink href="/" legacyBehavior passHref>
<Link href="dummy-href">{t('link')}</Link>
</NextLink>
</Grid.Cell>
</Grid>
)
}
10 changes: 7 additions & 3 deletions apps/public/src/app/(general)/bedankt/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import type { Metadata } from 'next'
import { cookies } from 'next/headers'
import { getTranslations } from 'next-intl/server'

import { Thanks } from './Thanks'

export const metadata: Metadata = {
title: 'Bedankt - Gemeente Amsterdam',
export const generateMetadata = async () => {
const t = await getTranslations('thanks')

return {
title: t('metadata.title'),
}
}

export default async () => {
Expand Down
12 changes: 6 additions & 6 deletions apps/public/src/app/(general)/locatie/Location.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const defaultProps = {
prevPage: '/previous',
}

describe('Locatie', () => {
describe('Location', () => {
beforeEach(() => {
vi.clearAllMocks()
;(useActionState as Mock).mockReturnValue([{}, vi.fn()])
Expand All @@ -25,15 +25,15 @@ describe('Locatie', () => {
it('renders', () => {
render(<Location {...defaultProps} />)

const heading = screen.getByRole('heading', { name: 'Locatie' })
const heading = screen.getByRole('heading', { name: 'step.title' })

expect(heading).toBeInTheDocument()
})

it('renders the correct backlink', () => {
render(<Location {...defaultProps} />)

const backLink = screen.getByRole('link', { name: 'Vorige vraag' })
const backLink = screen.getByRole('link', { name: 'back-link' })

expect(backLink).toBeInTheDocument()
expect(backLink).toHaveAttribute('href', '/previous')
Expand All @@ -59,7 +59,7 @@ describe('Locatie', () => {
it('renders the default text when there is no location data', () => {
render(<Location {...defaultProps} />)

const paragraph = screen.getByText('In het volgende scherm kunt u op de kaart een adres of container opzoeken.')
const paragraph = screen.getByText('description')

expect(paragraph).toBeInTheDocument()
})
Expand All @@ -75,15 +75,15 @@ describe('Locatie', () => {
it('renders a link with the default text when there is no location data', () => {
render(<Location {...defaultProps} />)

const link = screen.getByRole('link', { name: 'Selecteer de locatie' })
const link = screen.getByRole('link', { name: 'link.without-location' })

expect(link).toBeInTheDocument()
})

it('renders a link with updated text when there is location data', () => {
render(<Location {...defaultProps} locationData={{ name: 'Test location' }} />)

const link = screen.getByRole('link', { name: 'Wijzig locatie' })
const link = screen.getByRole('link', { name: 'link.with-location' })

expect(link).toBeInTheDocument()
})
Expand Down
18 changes: 9 additions & 9 deletions apps/public/src/app/(general)/locatie/Location.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { Heading, Link, Paragraph } from '@amsterdam/design-system-react'
import { Grid, SubmitButton } from '@meldingen/ui'
import NextLink from 'next/link'
import { useTranslations } from 'next-intl'
import { useActionState } from 'react'

import type { Coordinates } from 'apps/public/src/types'
Expand All @@ -24,27 +25,26 @@ type Props = {
export const Location = ({ prevPage, locationData }: Props) => {
const [formState, formAction] = useActionState(postLocationForm, initialState)

const t = useTranslations('location')

return (
<Grid paddingBottom="large" paddingTop="medium">
<Grid.Cell span={{ narrow: 4, medium: 6, wide: 6 }} start={{ narrow: 1, medium: 2, wide: 3 }}>
<BackLink href={prevPage} className="ams-mb--xs">
Vorige vraag
{t('back-link')}
</BackLink>
<Heading className="ams-mb--sm">Locatie</Heading>
<Heading className="ams-mb--sm">{t('step.title')}</Heading>

{formState?.message && <Paragraph>{formState.message}</Paragraph>}

{/* TODO: text should come from api */}
<Heading level={2} size="level-4">
Waar staat de container?
{t('title')}
</Heading>
<Paragraph className="ams-mb--xs">
{locationData?.name ?? 'In het volgende scherm kunt u op de kaart een adres of container opzoeken.'}
</Paragraph>
<Paragraph className="ams-mb--xs">{locationData?.name ?? t('description')}</Paragraph>

<NextLink href="/locatie/kies" legacyBehavior passHref>
<Link variant="standalone" href="dummy-href" className="ams-mb--md">
{locationData?.name ? 'Wijzig locatie' : 'Selecteer de locatie'}
{locationData?.name ? t('link.with-location') : t('link.without-location')}
</Link>
</NextLink>

Expand All @@ -54,7 +54,7 @@ export const Location = ({ prevPage, locationData }: Props) => {
name="coordinates"
value={locationData?.coordinates ? JSON.stringify(locationData?.coordinates) : undefined}
/>
<SubmitButton>Volgende vraag</SubmitButton>
<SubmitButton>{t('submit-button')}</SubmitButton>
</form>
</Grid.Cell>
</Grid>
Expand Down
2 changes: 1 addition & 1 deletion apps/public/src/app/(general)/locatie/actions.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('postLocationForm', () => {
const formData = new FormData()
const result = await postLocationForm(null, formData)

expect(result).toEqual({ message: 'Vul een locatie in.' })
expect(result).toEqual({ message: 'errors.no-location' })
})

it('posts the location and redirects to /bijlage', async () => {
Expand Down
5 changes: 4 additions & 1 deletion apps/public/src/app/(general)/locatie/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
import { getTranslations } from 'next-intl/server'

import { postMeldingByMeldingIdLocation } from 'apps/public/src/apiClientProxy'

Expand All @@ -14,7 +15,9 @@ export const postLocationForm = async (_: unknown, formData: FormData) => {

const coordinates = formData.get('coordinates')

if (!coordinates) return { message: 'Vul een locatie in.' }
const t = await getTranslations('location')

if (!coordinates) return { message: t('errors.no-location') }

const parsedCoordinates = JSON.parse(coordinates as string)

Expand Down
10 changes: 7 additions & 3 deletions apps/public/src/app/(general)/locatie/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import type { Metadata } from 'next'
import { cookies } from 'next/headers'
import { getTranslations } from 'next-intl/server'

import { Location } from './Location'

export const metadata: Metadata = {
title: 'Stap 1 van 4 - Beschrijf uw melding - Gemeente Amsterdam',
export const generateMetadata = async () => {
const t = await getTranslations('location')

return {
title: t('metadata.title'),
}
}

export default async () => {
Expand Down
10 changes: 7 additions & 3 deletions apps/public/src/app/(general)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Metadata } from 'next'
import { getTranslations } from 'next-intl/server'

import { getStaticForm, getStaticFormByStaticFormId } from 'apps/public/src/apiClientProxy'

Expand All @@ -8,8 +8,12 @@ import { Home } from './Home'
// We can remove this when the api is deployed.
export const dynamic = 'force-dynamic'

export const metadata: Metadata = {
title: 'Stap 1 van 4 - Beschrijf uw melding - Gemeente Amsterdam',
export const generateMetadata = async () => {
const t = await getTranslations('homepage')

return {
title: t('metadata.title'),
}
}

export default async () => {
Expand Down
Loading