Skip to content

Commit

Permalink
Add Signals demo (#29)
Browse files Browse the repository at this point in the history
* Add signals demo

* Change footer cell

* Add menu, return skiplink

* Align with current v2 design

* Use react router for nav

* Start content on correct column

* Include Signalen in list on homepage

* Fix link on logo

* Add entry to index, fix type

* Fix logo link

* Add onSubmit navigation

* Replace back button with back link

* Update src/shared/components/Link.tsx

Co-authored-by: Vincent Smedinga <[email protected]>

* Remove fixed TODO comment

* Use signalen scoped class instead of generic one

---------

Co-authored-by: Vincent Smedinga <[email protected]>
  • Loading branch information
alimpens and VincentSmedinga authored Jan 16, 2024
1 parent 4c821ee commit 3f9ca65
Show file tree
Hide file tree
Showing 15 changed files with 469 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { RootPage } from './shared/pages/RootPage'

import { routes as amopisRoutes } from './sites/amopis/routes'
import { routes as amsterdamRoutes } from './sites/amsterdam/routes'
import { routes as signalenRoutes } from './sites/signalen/routes'

import '@amsterdam/design-system-tokens/dist/root.css'
import '@amsterdam/design-system-assets/font/index.css'
Expand All @@ -21,6 +22,7 @@ const router = createBrowserRouter([
},
amopisRoutes,
amsterdamRoutes,
signalenRoutes,
])

ReactDOM.createRoot(document.getElementById('root')!).render(
Expand Down
41 changes: 41 additions & 0 deletions src/shared/components/Link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { LinkProps as LinkComponentProps } from '@amsterdam/design-system-react'
import { Link as LinkComponent } from '@amsterdam/design-system-react'
import { ForwardedRef, forwardRef, HTMLAttributeAnchorTarget, MouseEvent, PropsWithChildren } from 'react'
import { useHref, useLinkClickHandler } from 'react-router-dom'

type LinkProps = LinkComponentProps & {
to: string
target?: HTMLAttributeAnchorTarget
replace?: boolean
state?: unknown
onClick?: (event: MouseEvent<HTMLElement>) => void
}

export const Link = forwardRef(
(
// TODO: Remove `PropsWithChildren` when using @amsterdam/design-system-react ^0.4.0
{ children, onClick, replace = false, state, target, to, ...rest }: PropsWithChildren<LinkProps>,
ref: ForwardedRef<HTMLAnchorElement>,
) => {
const href = useHref(to)
const handleClick = useLinkClickHandler(to, { replace, state, target })

return (
<LinkComponent
{...rest}
href={href}
onClick={(event) => {
window.scrollTo(0, 0)
onClick?.(event)
if (!event.defaultPrevented) {
handleClick(event)
}
}}
ref={ref}
target={target}
>
{children}
</LinkComponent>
)
},
)
5 changes: 5 additions & 0 deletions src/shared/pages/RootPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Grid, Heading, Link, PageHeading, Screen, UnorderedList } from '@amsterdam/design-system-react'
import { siteUrl as amopisSiteUrl } from '../../sites/amopis/constants'
import { siteUrl as amsterdamSiteUrl } from '../../sites/amsterdam/constants'
import { siteUrl as signalenSiteUrl } from '../../sites/signalen/constants'

type Site = {
label: string
Expand All @@ -16,6 +17,10 @@ const sites: Site[] = [
label: 'Amopis',
href: amopisSiteUrl,
},
{
label: 'Signalen',
href: `${signalenSiteUrl}beschrijf`,
},
]

export const RootPage = () => (
Expand Down
23 changes: 23 additions & 0 deletions src/sites/signalen/components/FormNavigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Button } from '@amsterdam/design-system-react'
import { Link } from '../../../shared/components/Link'

const FormNavigation = ({
firstPage,
lastPage,
backlinkUrl,
}: {
firstPage?: boolean
lastPage?: boolean
backlinkUrl?: string
}) => (
<div className="signalen-form-navigation">
{!firstPage && backlinkUrl && (
<Link to={backlinkUrl} variant="inList" className="signalen-back-link">
Vorige
</Link>
)}
<Button type="submit">{lastPage ? 'Versturen' : 'Volgende'}</Button>
</div>
)

export default FormNavigation
44 changes: 44 additions & 0 deletions src/sites/signalen/components/SiteFooter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Footer, Grid, Heading, Link, PageMenu, Paragraph, VisuallyHidden } from '@amsterdam/design-system-react'

export const SiteFooter = () => (
<Footer>
<Footer.Top>
<VisuallyHidden>
<Heading>Colofon</Heading>
</VisuallyHidden>
<Grid gapVertical="large" paddingVertical="medium">
<Grid.Cell span={{ narrow: 3, medium: 4, wide: 4 }}>
<div style={{ display: 'grid' }} className="amsterdam-gap-xs">
<Heading level={2} size="level-4" inverseColor>
Contact
</Heading>
<Paragraph size="small" inverseColor>
Lukt het niet om een melding te doen? Bel het telefoonnummer{' '}
<Link href="tel:+3114020" onBackground="dark" variant="inline">
14 020
</Link>
.
</Paragraph>
<Paragraph size="small" inverseColor>
Wij zijn bereikbaar van maandag tot en met vrijdag van 08.00 tot 18.00 uur.
</Paragraph>
</div>
</Grid.Cell>
</Grid>
</Footer.Top>
<Footer.Bottom>
<VisuallyHidden>
<Heading level={2}>Over deze website</Heading>
</VisuallyHidden>
<Grid paddingVertical="small">
<Grid.Cell span="all">
<PageMenu>
<PageMenu.Link href="#">Over deze site</PageMenu.Link>
<PageMenu.Link href="#">Privacy</PageMenu.Link>
<PageMenu.Link href="#">Toegankelijkheid</PageMenu.Link>
</PageMenu>
</Grid.Cell>
</Grid>
</Footer.Bottom>
</Footer>
)
22 changes: 22 additions & 0 deletions src/sites/signalen/components/SiteHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Grid, Header, PageMenu, SkipLink } from '@amsterdam/design-system-react'
import { siteUrl } from '../constants'
import { PageMenuLink } from '../../../shared/components/PageMenuLink'

export const SiteHeader = () => (
<Grid>
<Grid.Cell span="all">
<SkipLink href="#main">Direct naar inhoud</SkipLink>
<Header
logoLink={`${siteUrl}beschrijf`}
logoLinkTitle="Naar de homepage van Signalen Amsterdam"
links={
<PageMenu alignEnd>
<PageMenuLink to={`${siteUrl}beschrijf`}>Doe een melding</PageMenuLink>
<PageMenu.Link href="#">Meldingenkaart</PageMenu.Link>
<PageMenu.Link href="#">Mijn meldingen</PageMenu.Link>
</PageMenu>
}
/>
</Grid.Cell>
</Grid>
)
15 changes: 15 additions & 0 deletions src/sites/signalen/components/signalen.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.signalen-form-navigation {
align-items: center;
display: flex;
gap: 1rem;
justify-content: space-between;
}

.signalen-summary-heading {
display: flex;
justify-content: space-between;
}

.signalen-back-link svg {
transform: rotate(180deg);
}
3 changes: 3 additions & 0 deletions src/sites/signalen/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { rootUrl } from '../../shared/constants'

export const siteUrl = `${rootUrl}signalen/`
51 changes: 51 additions & 0 deletions src/sites/signalen/pages/Add.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { FormEvent } from 'react'
import { useNavigate } from 'react-router-dom'
import { FormLabel, Grid, Heading, Paragraph } from '@amsterdam/design-system-react'
import FormNavigation from '../components/FormNavigation'
import { siteUrl } from '../constants'

export const Add = () => {
const navigate = useNavigate()

const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault()

navigate(`${siteUrl}contact`)
}

return (
<Grid paddingBottom="medium">
<Grid.Cell span={{ narrow: 4, medium: 6, wide: 7 }} start={{ narrow: 1, medium: 2, wide: 2 }}>
<form style={{ display: 'grid' }} className="amsterdam-gap-md" onSubmit={handleSubmit}>
<Heading>Doe een melding</Heading>

<Heading level={2}>Locatie en vragen</Heading>

<fieldset>
<legend>Waar is het?</legend>
<Paragraph>KAART SELECTOR</Paragraph>
</fieldset>

<fieldset>
<legend>Wanneer was het?</legend>
<div>
<input type="radio" id="nu" name="when" value="nu" />
<label htmlFor="nu">Nu</label>
</div>
<div>
<input type="radio" id="eerder" name="when" value="eerder" />
<label htmlFor="eerder">Eerder</label>
</div>
</fieldset>

<div>
<FormLabel htmlFor="where">Waar komt het afval vandaan, denkt u? (niet verplicht)</FormLabel>
<textarea id="where" />
</div>

<FormNavigation backlinkUrl={`${siteUrl}beschrijf`} />
</form>
</Grid.Cell>
</Grid>
)
}
60 changes: 60 additions & 0 deletions src/sites/signalen/pages/Contact.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { FormEvent } from 'react'
import { useNavigate } from 'react-router-dom'
import { Checkbox, FormLabel, Grid, Heading, Paragraph } from '@amsterdam/design-system-react'
import FormNavigation from '../components/FormNavigation'
import { siteUrl } from '../constants'

export const Contact = () => {
const navigate = useNavigate()

const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault()

navigate(`${siteUrl}versturen`)
}

return (
<Grid paddingBottom="medium">
<Grid.Cell span={{ narrow: 4, medium: 6, wide: 7 }} start={{ narrow: 1, medium: 2, wide: 2 }}>
<form style={{ display: 'grid' }} className="amsterdam-gap-md" onSubmit={handleSubmit}>
<Heading>Doe een melding</Heading>

<Heading level={2}>Contactgegevens</Heading>

<Paragraph size="large">Mogen we u bellen voor vragen? En op de hoogte houden via e-mail?</Paragraph>

<Paragraph>
Vaak hebben we nog een vraag. Daarmee kunnen we het probleem sneller of beter oplossen. Of we willen iets
uitleggen. Wij willen u dan graag even bellen. Of anders e-mailen wij u. Wij gebruiken uw telefoonnummer en
e-mailadres alléén voor deze melding.
</Paragraph>

<div>
<FormLabel htmlFor="phone">Wat is uw telefoonnummer?(niet verplicht)</FormLabel>
<input type="tel" id="phone" />
</div>

<div>
<FormLabel htmlFor="mail">Wat is uw e-mailadres?(niet verplicht)</FormLabel>
<input type="email" id="mail" />
</div>

<fieldset>
<legend>Mogen we uw melding doorsturen?</legend>
<Paragraph className="amsterdam-mb-md">
Soms kan de gemeente niets doen. Een andere organisatie moet dan aan het werk. Als dat zo is kunnen wij uw
melding soms doorsturen. Wij sturen uw telefoonnummer of e-mailadres mee. Maar dat doen we alleen als u
dat goed vindt.
</Paragraph>
<Checkbox>
Ja, ik geef de gemeente Amsterdam toestemming om mijn melding door te sturen naar andere organisaties als
de melding niet voor de gemeente is bestemd.
</Checkbox>
</fieldset>

<FormNavigation backlinkUrl={`${siteUrl}vul-aan`} />
</form>
</Grid.Cell>
</Grid>
)
}
50 changes: 50 additions & 0 deletions src/sites/signalen/pages/Describe.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { FormEvent } from 'react'
import { useNavigate } from 'react-router-dom'
import { FormLabel, Grid, Heading, Paragraph } from '@amsterdam/design-system-react'
import FormNavigation from '../components/FormNavigation'
import { siteUrl } from '../constants'

export const Describe = () => {
const navigate = useNavigate()

const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault()

navigate(`${siteUrl}vul-aan`)
}

return (
<Grid paddingBottom="medium">
<Grid.Cell span={{ narrow: 4, medium: 6, wide: 7 }} start={{ narrow: 1, medium: 2, wide: 2 }}>
<form style={{ display: 'grid' }} className="amsterdam-gap-md" onSubmit={handleSubmit}>
<Heading>Doe een melding</Heading>

<Heading level={2}>Beschrijf uw melding</Heading>

<div>
<FormLabel htmlFor="description">Waar gaat het om?</FormLabel>
<Paragraph size="small">Typ geen persoonsgegevens in deze omschrijving, dit wordt apart gevraagd</Paragraph>
<textarea id="description" />
<Paragraph size="small">8/1000 tekens</Paragraph>
</div>

<fieldset>
<legend>Foto's toevoegen (niet verplicht)</legend>
<Paragraph size="small">Voeg een foto toe om de situatie te verduidelijken</Paragraph>
<input
type="file"
id="fileUpload"
data-testid="file-input-upload"
accept="image/jpeg,image/jpg,image/png,image/gif"
name="images"
multiple
aria-label="Toevoegen foto"
/>
<label htmlFor="fileUpload">Toevoegen foto</label>
</fieldset>
<FormNavigation firstPage />
</form>
</Grid.Cell>
</Grid>
)
}
15 changes: 15 additions & 0 deletions src/sites/signalen/pages/SignalenRootPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Screen } from '@amsterdam/design-system-react'
import { Outlet } from 'react-router-dom'
import { SiteFooter } from '../components/SiteFooter'
import { SiteHeader } from '../components/SiteHeader'
import '../components/signalen.css'

export const SignalenRootPage = () => (
<Screen maxWidth="wide">
<SiteHeader />
<main id="main">
<Outlet />
</main>
<SiteFooter />
</Screen>
)
Loading

0 comments on commit 3f9ca65

Please sign in to comment.