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:
@@ -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}
|
||||||
|
|||||||
@@ -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='S’enregistrer' 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>
|
||||||
|
|||||||
@@ -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'>
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user