Initial commit

This commit is contained in:
dahoud
2025-10-01 01:39:07 +00:00
commit b430bf3b96
826 changed files with 255287 additions and 0 deletions

View File

@@ -0,0 +1,266 @@
'use client';
import React, { useState, useContext, useEffect } from 'react';
import { Panel } from 'primereact/panel';
import { InputSwitch } from 'primereact/inputswitch';
import { Slider } from 'primereact/slider';
import { Dropdown } from 'primereact/dropdown';
import { Button } from 'primereact/button';
import { Message } from 'primereact/message';
import { LayoutContext } from '../../layout/context/layoutcontext';
interface AtlantisAccessibilityControlsProps {
className?: string;
}
interface AccessibilitySettings {
fontSize: number;
highContrast: boolean;
reduceMotion: boolean;
screenReader: boolean;
keyboardNav: boolean;
}
const AtlantisAccessibilityControls: React.FC<AtlantisAccessibilityControlsProps> = ({
className = ''
}) => {
const { layoutConfig, setLayoutConfig } = useContext(LayoutContext);
const [settings, setSettings] = useState<AccessibilitySettings>({
fontSize: 14,
highContrast: false,
reduceMotion: false,
screenReader: false,
keyboardNav: true
});
// Options de thème pour l'accessibilité
const contrastThemes = [
{ label: 'Thème normal', value: 'magenta' },
{ label: 'Contraste élevé - Bleu', value: 'blue' },
{ label: 'Contraste élevé - Sombre', value: 'dark' }
];
// Appliquer les paramètres d'accessibilité
useEffect(() => {
// Appliquer la taille de police via scale Atlantis
setLayoutConfig(prev => ({
...prev,
scale: settings.fontSize
}));
// Appliquer le thème de contraste
if (settings.highContrast) {
setLayoutConfig(prev => ({
...prev,
theme: 'blue', // Thème avec meilleur contraste
colorScheme: 'dark'
}));
}
// Classes CSS pour les animations
const rootElement = document.documentElement;
if (settings.reduceMotion) {
rootElement.style.setProperty('--transition-duration', '0ms');
} else {
rootElement.style.removeProperty('--transition-duration');
}
// Annoncer les changements pour les lecteurs d'écran
if (settings.screenReader) {
announceChange('Paramètres d\'accessibilité mis à jour');
}
}, [settings, setLayoutConfig]);
// Fonction d'annonce pour lecteurs d'écran
const announceChange = (message: string) => {
const announcement = document.createElement('div');
announcement.setAttribute('aria-live', 'polite');
announcement.setAttribute('aria-atomic', 'true');
announcement.className = 'sr-only';
announcement.textContent = message;
document.body.appendChild(announcement);
setTimeout(() => document.body.removeChild(announcement), 1000);
};
const updateSetting = (key: keyof AccessibilitySettings, value: any) => {
setSettings(prev => ({ ...prev, [key]: value }));
};
const resetToDefaults = () => {
setSettings({
fontSize: 14,
highContrast: false,
reduceMotion: false,
screenReader: false,
keyboardNav: true
});
setLayoutConfig(prev => ({
...prev,
scale: 14,
theme: 'magenta',
colorScheme: 'dark'
}));
announceChange('Paramètres d\'accessibilité réinitialisés');
};
return (
<Panel
header="Paramètres d'accessibilité"
toggleable
collapsed
className={`card ${className}`}
pt={{
header: { className: 'surface-100' },
content: { className: 'surface-50' }
}}
>
<div className="grid">
{/* Taille de police */}
<div className="col-12 md:col-6">
<div className="field">
<label htmlFor="fontSize" className="font-semibold text-color">
Taille de police: {settings.fontSize}px
</label>
<Slider
id="fontSize"
value={settings.fontSize}
onChange={(e) => updateSetting('fontSize', e.value)}
min={12}
max={20}
step={1}
className="w-full mt-2"
/>
<div className="flex justify-content-between text-xs text-color-secondary mt-1">
<span>Petit</span>
<span>Normal</span>
<span>Grand</span>
</div>
</div>
</div>
{/* Contraste élevé */}
<div className="col-12 md:col-6">
<div className="field">
<label htmlFor="highContrast" className="font-semibold text-color">
Mode contraste élevé
</label>
<div className="flex align-items-center gap-2 mt-2">
<InputSwitch
id="highContrast"
checked={settings.highContrast}
onChange={(e) => updateSetting('highContrast', e.value)}
/>
<span className="text-sm text-color-secondary">
{settings.highContrast ? 'Activé' : 'Désactivé'}
</span>
</div>
</div>
</div>
{/* Réduction des animations */}
<div className="col-12 md:col-6">
<div className="field">
<label htmlFor="reduceMotion" className="font-semibold text-color">
Réduire les animations
</label>
<div className="flex align-items-center gap-2 mt-2">
<InputSwitch
id="reduceMotion"
checked={settings.reduceMotion}
onChange={(e) => updateSetting('reduceMotion', e.value)}
/>
<span className="text-sm text-color-secondary">
Pour les utilisateurs sensibles au mouvement
</span>
</div>
</div>
</div>
{/* Mode lecteur d'écran */}
<div className="col-12 md:col-6">
<div className="field">
<label htmlFor="screenReader" className="font-semibold text-color">
Mode lecteur d'écran
</label>
<div className="flex align-items-center gap-2 mt-2">
<InputSwitch
id="screenReader"
checked={settings.screenReader}
onChange={(e) => updateSetting('screenReader', e.value)}
/>
<span className="text-sm text-color-secondary">
Annonces vocales activées
</span>
</div>
</div>
</div>
</div>
{/* Informations et aide */}
<div className="mt-4">
<Message
severity="info"
text="Ces paramètres améliorent l'accessibilité selon vos besoins"
className="w-full"
/>
</div>
{/* Raccourcis clavier */}
<div className="card mt-3">
<h6 className="mt-0 mb-3 text-color">Raccourcis clavier disponibles</h6>
<div className="grid text-sm">
<div className="col-12 md:col-6">
<div className="flex align-items-center gap-2 mb-2">
<kbd className="bg-surface-200 text-color px-2 py-1 border-round text-xs">Tab</kbd>
<span className="text-color-secondary">Naviguer entre les éléments</span>
</div>
<div className="flex align-items-center gap-2 mb-2">
<kbd className="bg-surface-200 text-color px-2 py-1 border-round text-xs">Entrée</kbd>
<span className="text-color-secondary">Activer un élément</span>
</div>
</div>
<div className="col-12 md:col-6">
<div className="flex align-items-center gap-2 mb-2">
<kbd className="bg-surface-200 text-color px-2 py-1 border-round text-xs">Échap</kbd>
<span className="text-color-secondary">Fermer un dialogue</span>
</div>
<div className="flex align-items-center gap-2 mb-2">
<kbd className="bg-surface-200 text-color px-2 py-1 border-round text-xs">↑↓</kbd>
<span className="text-color-secondary">Naviguer dans les listes</span>
</div>
</div>
</div>
</div>
{/* Actions */}
<div className="flex justify-content-between align-items-center mt-4">
<Button
label="Réinitialiser"
icon="pi pi-refresh"
className="p-button-outlined"
onClick={resetToDefaults}
/>
<div className="flex align-items-center gap-2">
<i className="pi pi-info-circle text-primary" />
<span className="text-sm text-color-secondary">
Paramètres sauvegardés automatiquement
</span>
</div>
</div>
{/* Région pour les annonces lecteurs d'écran */}
<div
aria-live="polite"
aria-atomic="true"
className="sr-only"
id="accessibility-announcements"
/>
</Panel>
);
};
export default AtlantisAccessibilityControls;