feat(kiosk): implement kiosk report submission functionality with offline support test(outbox): add tests for outbox functionality including report submission and error handling feat(outbox): create outbox management for queued reports with IndexedDB persistence feat(uuid): add UUID generation utility for client IDs feat(qr): implement QR code generation for reporting links by site and area feat(kiosk): create Kiosk page for reporting incidents without an account
42 lines
1.1 KiB
TypeScript
42 lines
1.1 KiB
TypeScript
import type { ReactNode } from 'react'
|
|
|
|
interface FormSectionProps {
|
|
number: string
|
|
title: string
|
|
copy: string
|
|
children: ReactNode
|
|
}
|
|
|
|
export function FormSection({ number, title, copy, children }: FormSectionProps) {
|
|
return (
|
|
<div className="border-b border-line px-5 py-6 sm:px-9 sm:py-7">
|
|
<div className="mb-6 flex gap-[13px]">
|
|
<span className="pt-[3px] font-mono text-xs text-coral">{number}</span>
|
|
<div>
|
|
<h2 className="mb-1 font-display text-[19px] font-semibold">{title}</h2>
|
|
<p className="text-xs text-muted">{copy}</p>
|
|
</div>
|
|
</div>
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
interface FieldProps {
|
|
label: string
|
|
optional?: boolean
|
|
/** Translated "Optional" marker. */
|
|
optionalLabel?: string
|
|
children: ReactNode
|
|
}
|
|
|
|
export function Field({ label, optional = false, optionalLabel = 'Optional', children }: FieldProps) {
|
|
return (
|
|
<label className="mb-[17px] block text-2xs font-semibold text-[#586762]">
|
|
{label}
|
|
{optional && <em className="float-right font-normal text-[#9ba7a2] not-italic">{optionalLabel}</em>}
|
|
{children}
|
|
</label>
|
|
)
|
|
}
|