69 lines
3.4 KiB
TypeScript
69 lines
3.4 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState, useRef, useEffect } from 'react';
|
|
import { useLanguage } from '@/providers/LanguageProvider';
|
|
import { SupportedLanguage } from '@/lib/i18n/translations';
|
|
import { Globe, ChevronDown } from 'lucide-react';
|
|
|
|
const languages: { code: SupportedLanguage; label: string; flag: string }[] = [
|
|
{ code: 'fr', label: 'Français', flag: 'https://flagcdn.com/fr.svg' },
|
|
{ code: 'en', label: 'English', flag: 'https://flagcdn.com/gb.svg' },
|
|
{ code: 'es', label: 'Español', flag: 'https://flagcdn.com/es.svg' },
|
|
{ code: 'de', label: 'Deutsch', flag: 'https://flagcdn.com/de.svg' },
|
|
];
|
|
|
|
export const LanguageSwitcher: React.FC = () => {
|
|
const { language, setLanguage } = useLanguage();
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const dropdownRef = useRef<HTMLDivElement>(null);
|
|
|
|
const currentLang = languages.find(l => l.code === language) || languages[0];
|
|
|
|
useEffect(() => {
|
|
const handleClickOutside = (event: MouseEvent) => {
|
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
|
|
setIsOpen(false);
|
|
}
|
|
};
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
return () => document.removeEventListener('mousedown', handleClickOutside);
|
|
}, []);
|
|
|
|
return (
|
|
<div className="relative" ref={dropdownRef}>
|
|
<button
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm font-medium hover:bg-slate-100 dark:hover:bg-slate-800 text-slate-600 dark:text-slate-300 transition-colors"
|
|
title="Changer de langue"
|
|
>
|
|
<img src={currentLang.flag} alt={currentLang.label} className="w-5 h-3.5 object-cover rounded-[2px] shadow-sm" />
|
|
<span className="hidden sm:inline font-bold">{currentLang.code.toUpperCase()}</span>
|
|
<ChevronDown size={14} className={`transition-transform text-slate-400 ${isOpen ? 'rotate-180' : ''}`} />
|
|
</button>
|
|
|
|
{isOpen && (
|
|
<div className="absolute right-0 mt-2 w-40 bg-white dark:bg-slate-800 border border-slate-200 dark:border-slate-700 rounded-xl shadow-lg z-50 overflow-hidden">
|
|
<div className="py-1">
|
|
{languages.map((lang) => (
|
|
<button
|
|
key={lang.code}
|
|
data-umami-event="Change Language"
|
|
onClick={() => {
|
|
setLanguage(lang.code);
|
|
setIsOpen(false);
|
|
}}
|
|
className={`w-full text-left px-4 py-2 text-sm flex items-center gap-3 hover:bg-slate-50 dark:hover:bg-slate-700 transition-colors
|
|
${language === lang.code ? 'bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 font-medium' : 'text-slate-700 dark:text-slate-300'}
|
|
`}
|
|
>
|
|
<img src={lang.flag} alt={lang.label} className="w-5 h-3.5 object-cover rounded-[2px] shadow-sm" />
|
|
{lang.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
};
|