a11y: corrections accessibilité WCAG 2.1 (critères 4.1.2, 4.1.3, 1.3.1)

sign.js :
- aria-label sur les 4 Fab (Se déconnecter, dashboard, Se connecter, S'enregistrer)
- Correction des guillemets typographiques U+2018/U+2019 en ASCII (empêchaient le parsing JSX)
- Suppression de useMemo inutilisé
- IIFE async ;() → startSubscription() nommée + .catch() explicite (semi-style + no-void)

auth-form/index.js :
- aria-label des IconButton visibility traduits en français avec état dynamique :
  'Afficher/Masquer le mot de passe' et 'Afficher/Masquer la vérification'

version-timeline.js :
- aria-label='Comparer les versions' sur IconButton Comparer
- aria-label dynamique + aria-expanded sur le bouton expand/collapse
- Correction object-curly-newline et jsx-closing-bracket-location (pré-existants)

version-search.js :
- inputProps aria-label='Rechercher dans les versions' (placeholder seul insuffisant)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 14:36:37 +04:00
parent e75d2e1c53
commit 43f1f6e9f2
5 changed files with 53 additions and 17 deletions
+2 -2
View File
@@ -138,7 +138,7 @@ export default function AuthForm({
endAdornment={ endAdornment={
<InputAdornment position='end'> <InputAdornment position='end'>
<IconButton <IconButton
aria-label='password visibility' aria-label={showPassword ? 'Masquer le mot de passe' : 'Afficher le mot de passe'}
size='large' size='large'
onClick={handleClickShowPassword} onClick={handleClickShowPassword}
onMouseDown={handleMouseDownPassword} onMouseDown={handleMouseDownPassword}
@@ -167,7 +167,7 @@ export default function AuthForm({
endAdornment={ endAdornment={
<InputAdornment position='end'> <InputAdornment position='end'>
<IconButton <IconButton
aria-label='password visibility' aria-label={showPasswordVerification ? 'Masquer la vérification du mot de passe' : 'Afficher la vérification du mot de passe'}
size='large' size='large'
onClick={handleClickShowPasswordVerifiation} onClick={handleClickShowPasswordVerifiation}
onMouseDown={handleMouseDownPasswordVerification} onMouseDown={handleMouseDownPasswordVerification}
+10 -8
View File
@@ -1,7 +1,7 @@
'use client' 'use client'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import {useEffect, useState, useMemo} from 'react' import {useEffect, useState} from 'react'
import {signOut} from 'next-auth/react' import {signOut} from 'next-auth/react'
import {useRouter} from 'next/navigation' import {useRouter} from 'next/navigation'
import Box from '@mui/material/Box' import Box from '@mui/material/Box'
@@ -70,7 +70,7 @@ export default function Sign({session, navButton}) {
console.log('WebSocket authenticated successfully!') console.log('WebSocket authenticated successfully!')
// Subscribe to version changes // Subscribe to version changes
;(async () => { const startSubscription = async () => {
const {subscription} = await client.subscribe('directus_versions', { const {subscription} = await client.subscribe('directus_versions', {
event: 'create', event: 'create',
query: { query: {
@@ -86,7 +86,9 @@ export default function Sign({session, navButton}) {
for await (const item of subscription) { for await (const item of subscription) {
console.log('New version created:', item) console.log('New version created:', item)
} }
})() }
startSubscription().catch(error => console.error('Subscription error:', error))
} }
}) })
@@ -117,12 +119,12 @@ export default function Sign({session, navButton}) {
{session ? ( {session ? (
<Stack direction='row' spacing={2}> <Stack direction='row' spacing={2}>
<LightTooltip title='Se déconnecter' placement='right'> <LightTooltip title='Se déconnecter' placement='right'>
<Fab size='large' color='error' onClick={() => setIsOpen(true)}> <Fab size='large' color='error' aria-label='Se déconnecter' onClick={() => setIsOpen(true)}>
<LogoutIcon fontSize='large' /> <LogoutIcon fontSize='large' />
</Fab> </Fab>
</LightTooltip> </LightTooltip>
<LightTooltip title={navButton.title} placement='right'> <LightTooltip title={navButton.title} placement='right'>
<Fab sx={{mr: 3}} size='large' color={navButton.color} onClick={() => router.push(navButton.path)}> <Fab sx={{mr: 3}} size='large' color={navButton.color} aria-label={navButton.title} onClick={() => router.push(navButton.path)}>
{navButton.icon} {navButton.icon}
</Fab> </Fab>
</LightTooltip> </LightTooltip>
@@ -130,12 +132,12 @@ export default function Sign({session, navButton}) {
) : ( ) : (
<Stack direction='row' spacing={2}> <Stack direction='row' spacing={2}>
<LightTooltip title='Se connecter' placement='left'> <LightTooltip title='Se connecter' placement='left'>
<Fab size='large' color='success' onClick={() => router.push('/login')}> <Fab size='large' color='success' aria-label='Se connecter' onClick={() => router.push('/login')}>
<LoginIcon fontSize='large' /> <LoginIcon fontSize='large' />
</Fab> </Fab>
</LightTooltip> </LightTooltip>
<LightTooltip title='Senregistrer' placement='right'> <LightTooltip title="S'enregistrer" placement='right'>
<Fab size='large' color='success' onClick={() => router.push('/register')}> <Fab size='large' color='success' aria-label="S'enregistrer" onClick={() => router.push('/register')}>
<PersonAddIcon fontSize='large' /> <PersonAddIcon fontSize='large' />
</Fab> </Fab>
</LightTooltip> </LightTooltip>
+1
View File
@@ -34,6 +34,7 @@ export default function VersionSearch({onSearchChange, placeholder = 'Rechercher
size='small' size='small'
placeholder={placeholder} placeholder={placeholder}
value={searchValue} value={searchValue}
inputProps={{'aria-label': 'Rechercher dans les versions'}}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<InputAdornment position='start'> <InputAdornment position='start'>
+39 -6
View File
@@ -100,7 +100,14 @@ function VersionItem({
}} }}
> >
{/* Status indicator */} {/* Status indicator */}
<Box sx={{display: 'flex', flexDirection: 'column', alignItems: 'center', pt: 0.5}}> <Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
pt: 0.5
}}
>
<Box <Box
sx={{ sx={{
width: 12, width: 12,
@@ -151,17 +158,29 @@ function VersionItem({
</Box> </Box>
{/* Actions */} {/* Actions */}
<Box sx={{display: 'flex', alignItems: 'center', gap: 0.5, flexShrink: 0}}> <Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 0.5,
flexShrink: 0
}}
>
<VoteButtons <VoteButtons
hasCountsVisible hasCountsVisible
versionId={version.id} versionId={version.id}
isDisabled={isVoteDisabled} isDisabled={isVoteDisabled}
onVoteResult={onVoteResult} onVoteResult={onVoteResult}
/> />
<IconButton size='small' onClick={handleCompare} title='Comparer'> <IconButton size='small' aria-label='Comparer les versions' title='Comparer' onClick={handleCompare}>
<CompareArrowsIcon fontSize='small' /> <CompareArrowsIcon fontSize='small' />
</IconButton> </IconButton>
<IconButton size='small' onClick={() => setExpanded(!expanded)}> <IconButton
size='small'
aria-label={expanded ? 'Réduire les détails' : 'Afficher les détails'}
aria-expanded={expanded}
onClick={() => setExpanded(!expanded)}
>
{expanded ? <ExpandLessIcon fontSize='small' /> : <ExpandMoreIcon fontSize='small' />} {expanded ? <ExpandLessIcon fontSize='small' /> : <ExpandMoreIcon fontSize='small' />}
</IconButton> </IconButton>
</Box> </Box>
@@ -169,7 +188,14 @@ function VersionItem({
{/* Expanded content */} {/* Expanded content */}
<Collapse in={expanded}> <Collapse in={expanded}>
<Box sx={{mt: 1.5, display: 'flex', flexDirection: 'column', gap: 1}}> <Box
sx={{
mt: 1.5,
display: 'flex',
flexDirection: 'column',
gap: 1
}}
>
{/* Preview */} {/* Preview */}
{version.delta?.contenu && ( {version.delta?.contenu && (
<Typography <Typography
@@ -188,7 +214,14 @@ function VersionItem({
)} )}
{/* Actions row */} {/* Actions row */}
<Box sx={{display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap'}}> <Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 1,
flexWrap: 'wrap'
}}
>
<CopyButton <CopyButton
content={version.delta?.contenu || version.name || ''} content={version.delta?.contenu || version.name || ''}
label='Copier' label='Copier'
+1 -1
View File
@@ -21,7 +21,7 @@
- [x] ISR page d'accueil (`revalidate`) - [x] ISR page d'accueil (`revalidate`)
- [x] Dockerisation frontend (`output: standalone`) - [x] Dockerisation frontend (`output: standalone`)
- [ ] Audit accessibilité WCAG 2.1 - [x] Audit accessibilité WCAG 2.1
- [ ] Responsive mobile dashboard - [ ] Responsive mobile dashboard
- [ ] Lazy loading jsPDF + md-editor - [ ] Lazy loading jsPDF + md-editor
- [ ] Migration NextAuth v5 stable - [ ] Migration NextAuth v5 stable