'use client' import React, {ChangeEvent, useCallback, useEffect, useMemo} from 'react'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faEye, faFont, faIndent, faPalette, faTextHeight, faTextWidth} from '@fortawesome/free-solid-svg-icons'; import {useTranslations} from "next-intl"; import SelectBox from "@/components/form/SelectBox"; interface UserEditorSettingsProps { settings: EditorDisplaySettings; onSettingsChange: (settings: EditorDisplaySettings) => void; } export interface EditorDisplaySettings { zoomLevel: number; indent: number; lineHeight: number; theme: 'clair' | 'sombre' | 'sépia'; fontFamily: 'lora' | 'serif' | 'sans-serif' | 'monospace'; maxWidth: number; focusMode: boolean; } const ZOOM_LABELS = ['Très petit', 'Petit', 'Normal', 'Grand', 'Très grand'] as const; const FONT_SIZES = [14, 16, 18, 20, 22] as const; const THEMES = ['clair', 'sombre', 'sépia'] as const; const DEFAULT_SETTINGS: EditorDisplaySettings = { zoomLevel: 3, indent: 30, lineHeight: 1.5, theme: 'sombre', fontFamily: 'lora', maxWidth: 768, focusMode: false }; export default function UserEditorSettings({settings, onSettingsChange}: UserEditorSettingsProps) { const t = useTranslations(); const handleSettingChange = useCallback(( key: K, value: EditorDisplaySettings[K] ) => { onSettingsChange({...settings, [key]: value}); }, [settings, onSettingsChange]); const resetToDefaults = useCallback(() => { onSettingsChange(DEFAULT_SETTINGS); }, [onSettingsChange]); const zoomOptions = useMemo(() => ZOOM_LABELS.map((label, index) => ({ value: (index + 1).toString(), label: `${t(`userEditorSettings.zoom.${label}`)} (${FONT_SIZES[index]}px)` })) , [t]); const themeButtons = useMemo(() => THEMES.map(theme => ({ key: theme, isActive: settings.theme === theme, className: `p-2.5 rounded-xl border capitalize transition-all duration-200 font-medium ${ settings.theme === theme ? 'bg-primary text-text-primary border-primary shadow-md scale-105' : 'bg-secondary/50 border-secondary/50 text-muted hover:text-text-primary hover:border-secondary hover:bg-secondary hover:scale-102' }` })) , [settings.theme]); useEffect((): void => { try { const savedSettings: string | null = localStorage.getItem('userEditorSettings'); if (savedSettings) { const parsed = JSON.parse(savedSettings); if (parsed && typeof parsed === 'object') { onSettingsChange({...DEFAULT_SETTINGS, ...parsed}); } } } catch (e: unknown) { onSettingsChange(DEFAULT_SETTINGS); } }, [onSettingsChange]); useEffect((): () => void => { const timeoutId = setTimeout((): void => { try { localStorage.setItem('userEditorSettings', JSON.stringify(settings)); } catch (error) { console.error('Erreur lors de la sauvegarde des settings:', error); } }, 100); return (): void => clearTimeout(timeoutId); }, [settings]); return (

{t("userEditorSettings.displayPreferences")}

) => { handleSettingChange('zoomLevel', Number(e.target.value)) }} data={zoomOptions} />
handleSettingChange('indent', Number(e.target.value))} className="w-full accent-primary" />
{t("userEditorSettings.indentNone")} {settings.indent}px {t("userEditorSettings.indentMax")}
) => handleSettingChange('lineHeight', Number(e.target.value))} data={[ {value: "1.2", label: t("userEditorSettings.lineHeightCompact")}, {value: "1.5", label: t("userEditorSettings.lineHeightNormal")}, {value: "1.75", label: t("userEditorSettings.lineHeightSpaced")}, {value: "2", label: t("userEditorSettings.lineHeightDouble")} ]} />
) => handleSettingChange('fontFamily', e.target.value as EditorDisplaySettings['fontFamily'])} data={[ {value: "lora", label: t("userEditorSettings.fontLora")}, {value: "serif", label: t("userEditorSettings.fontSerif")}, {value: "sans-serif", label: t("userEditorSettings.fontSansSerif")}, {value: "monospace", label: t("userEditorSettings.fontMonospace")} ]} />
handleSettingChange('maxWidth', Number(e.target.value))} className="w-full accent-primary" />
{t("userEditorSettings.maxWidthNarrow")} {settings.maxWidth}px {t("userEditorSettings.maxWidthWide")}
{themeButtons.map((themeBtn) => ( ))}
); }