import { useEffect, useState } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { apiFetch } from '../lib/api'; import type { StatementData } from '../lib/types'; // ── Constants ───────────────────────────────────────────────── const STEPS = ['Basic Information', 'Your Efforts', 'Conformance Status', 'Technical Specs', 'Feedback']; const PREDEFINED_EFFORTS = [ 'Accessibility is part of our mission statement.', 'Accessibility is part of our internal policies.', 'Accessibility is integrated into our procurement practices.', 'An accessibility officer or official has been appointed.', 'Continual accessibility training is provided for employees.', 'Clear accessibility targets and responsibilities exist within the organisation.', 'Formal accessibility quality assurance methods exist within the organisation.', ]; const BROWSERS = ['Chrome', 'Firefox', 'Safari', 'Edge', 'Internet Explorer']; const OS_LIST = ['Windows', 'macOS', 'iOS', 'Android', 'Linux']; const AT_LIST = ['JAWS', 'NVDA', 'VoiceOver', 'TalkBack', 'Dragon NaturallySpeaking']; const TECH_LIST = ['HTML', 'CSS', 'JavaScript', 'WAI-ARIA']; const WCAG_STANDARDS = [ { value: 'wcag22-aa', label: 'WCAG 2.2 Level AA' }, { value: 'wcag21-aaa', label: 'WCAG 2.1 Level AAA' }, { value: 'wcag21-aa', label: 'WCAG 2.1 Level AA' }, { value: 'wcag21-a', label: 'WCAG 2.1 Level A' }, { value: 'wcag20-aaa', label: 'WCAG 2.0 Level AAA' }, { value: 'wcag20-aa', label: 'WCAG 2.0 Level AA' }, { value: 'wcag20-a', label: 'WCAG 2.0 Level A' }, { value: 'section508', label: 'Section 508' }, { value: 'other', label: 'Other' }, ]; const CONFORMANCE_LEVELS = [ { value: 'fully-conformant', label: 'Fully conformant', desc: 'The content fully conforms to the accessibility standard without any exceptions.' }, { value: 'partially-conformant', label: 'Partially conformant', desc: 'Some parts of the content do not fully conform to the accessibility standard.' }, { value: 'non-conformant', label: 'Non conformant', desc: 'The content does not conform to the accessibility standard.' }, { value: 'not-assessed', label: 'Not assessed', desc: 'The content has not been evaluated or the evaluation results are not available.' }, ]; const EMPTY: StatementData = { status: 'none', page_id: 0, page_url: '', edit_url: '', updated_at: '', basic_info: { org_name: '', website: '', website_name: '' }, efforts: { selected: [], additional: [] }, conformance:{ standard: 'wcag21-aa', custom_standard: '', level: 'partially-conformant', additional_notes: '' }, tech_specs: { browsers: ['Chrome', 'Firefox', 'Safari', 'Edge'], operating_systems: ['Windows', 'macOS'], assistive_tech: [], technology_reliance: ['HTML', 'CSS', 'JavaScript'] }, feedback: { phone: '', email: '', address: '', response_duration: '2 business days' }, }; // ── Stepper ─────────────────────────────────────────────────── function Stepper({ step, total, labels }: { step: number; total: number; labels: string[] }) { return (
{Array.from({ length: total }, (_, i) => (
{i < step ? '✓' : i + 1}
{i === step && {labels[i]}} {i < total - 1 &&
}
))}
); } // ── Toggle ──────────────────────────────────────────────────── function Toggle({ checked, onChange }: { checked: boolean; onChange: (v: boolean) => void }) { return (
); } // ── Wizard ── return (

Accessibility Statement

Generate and manage your website's accessibility statement.

Generate statement

{/* ── Step 1: Basic Information ── */} {step === 0 && (

{STEPS[0]}

To get started, tell us about your business and website. Fields marked with * must be filled in.

Example: Example Inc.

setBasic('org_name', e.target.value)} placeholder="Your organisation name" />

Example: https://yourwebsite.com

setBasic('website', e.target.value)} placeholder="https://yourwebsite.com" />

Example: Example Site

setBasic('website_name', e.target.value)} placeholder="Your website name" />
)} {/* ── Step 2: Your Efforts ── */} {step === 1 && (

{STEPS[1]}

Select any current actions your organisation is taking to ensure web accessibility.

setEfforts('selected', v)} /> {data.efforts.additional.map((eff, i) => (
{ const next = [...data.efforts.additional]; next[i] = e.target.value; setEfforts('additional', next); }} />
))} {showAdd ? (
setAddEffort(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter' && addEffort.trim()) { setEfforts('additional', [...data.efforts.additional, addEffort.trim()]); setAddEffort(''); setShowAdd(false); } }} placeholder="Describe your effort…" />
) : ( )}
)} {/* ── Step 3: Conformance Status ── */} {step === 2 && (

{STEPS[2]}

{WCAG_STANDARDS.map((s) => ( ))}
{data.conformance.standard === 'other' && ( setConformance('custom_standard', e.target.value)} placeholder="Describe the standard" /> )}
{CONFORMANCE_LEVELS.map((l) => ( ))}

Example: While aiming for WCAG 2.1 Level AA conformance, we also implemented some Level AAA criteria.