Enhance accessibility and improve form semantics across multiple pages
Build & Push Docker Image / build (push) Successful in 4m4s

- Added `htmlFor` attributes to labels for better accessibility in Calendar, Dashboard, GuestJoin, Login, Register, RoomDetail, and Settings pages.
- Included `aria-hidden` attributes for icons to improve screen reader experience.
- Set `autoComplete` attributes for input fields to enhance user experience during form filling.
- Implemented `role` and `aria` attributes for radio groups and buttons to improve accessibility compliance.
This commit is contained in:
2026-05-28 10:07:19 +02:00
parent cff5398ebd
commit 7f48685717
18 changed files with 288 additions and 133 deletions
+13 -5
View File
@@ -103,9 +103,11 @@ export default function Dashboard() {
</div>
<div className="flex items-center gap-2">
{/* View toggle */}
<div className="hidden sm:flex items-center bg-th-bg-s rounded-lg border border-th-border p-0.5">
<div role="group" aria-label={t('common.gridView') + ' / ' + t('common.listView')} className="hidden sm:flex items-center bg-th-bg-s rounded-lg border border-th-border p-0.5">
<button
onClick={() => setViewMode('grid')}
aria-label={t('common.gridView')}
aria-pressed={viewMode === 'grid'}
className={`p-1.5 rounded-md transition-colors ${
viewMode === 'grid' ? 'bg-th-accent text-th-accent-t' : 'text-th-text-s hover:text-th-text'
}`}
@@ -114,6 +116,8 @@ export default function Dashboard() {
</button>
<button
onClick={() => setViewMode('list')}
aria-label={t('common.listView')}
aria-pressed={viewMode === 'list'}
className={`p-1.5 rounded-md transition-colors ${
viewMode === 'list' ? 'bg-th-accent text-th-accent-t' : 'text-th-text-s hover:text-th-text'
}`}
@@ -197,8 +201,9 @@ export default function Dashboard() {
<Modal title={t('dashboard.createRoom')} onClose={() => setShowCreate(false)}>
<form onSubmit={handleCreate} className="space-y-4">
<div>
<label className="block text-sm font-medium text-th-text mb-1.5">{t('dashboard.roomName')} *</label>
<label htmlFor="create-room-name" className="block text-sm font-medium text-th-text mb-1.5">{t('dashboard.roomName')} *</label>
<input
id="create-room-name"
type="text"
value={newRoom.name}
onChange={e => setNewRoom({ ...newRoom, name: e.target.value })}
@@ -210,8 +215,9 @@ export default function Dashboard() {
</div>
<div>
<label className="block text-sm font-medium text-th-text mb-1.5">{t('dashboard.welcomeMessage')}</label>
<label htmlFor="create-room-welcome" className="block text-sm font-medium text-th-text mb-1.5">{t('dashboard.welcomeMessage')}</label>
<textarea
id="create-room-welcome"
value={newRoom.welcome_message}
onChange={e => setNewRoom({ ...newRoom, welcome_message: e.target.value })}
className="input-field resize-none"
@@ -222,8 +228,9 @@ export default function Dashboard() {
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium text-th-text mb-1.5">{t('dashboard.maxParticipants')}</label>
<label htmlFor="create-room-max" className="block text-sm font-medium text-th-text mb-1.5">{t('dashboard.maxParticipants')}</label>
<input
id="create-room-max"
type="number"
value={newRoom.max_participants}
onChange={e => setNewRoom({ ...newRoom, max_participants: parseInt(e.target.value) || 0 })}
@@ -233,8 +240,9 @@ export default function Dashboard() {
/>
</div>
<div>
<label className="block text-sm font-medium text-th-text mb-1.5">{t('dashboard.accessCode')}</label>
<label htmlFor="create-room-access-code" className="block text-sm font-medium text-th-text mb-1.5">{t('dashboard.accessCode')}</label>
<input
id="create-room-access-code"
type="text"
value={newRoom.access_code}
onChange={e => setNewRoom({ ...newRoom, access_code: e.target.value })}