95 lines
3.0 KiB
TypeScript
95 lines
3.0 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import { useLanguage } from '@/context/LanguageContext';
|
|
import { Locale, localeNames, localeFlags } from '@/i18n';
|
|
import { ChevronDownIcon, GlobeAltIcon } from '@heroicons/react/24/outline';
|
|
import clsx from 'clsx';
|
|
|
|
interface LanguageToggleProps {
|
|
variant?: 'dropdown' | 'buttons';
|
|
showFlags?: boolean;
|
|
}
|
|
|
|
export default function LanguageToggle({
|
|
variant = 'dropdown',
|
|
showFlags = true
|
|
}: LanguageToggleProps) {
|
|
const { locale, setLocale } = useLanguage();
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
|
|
const availableLocales = Object.keys(localeNames) as Locale[];
|
|
|
|
if (variant === 'buttons') {
|
|
return (
|
|
<div className="flex items-center gap-1 bg-secondary-gray rounded-btn p-1">
|
|
{availableLocales.map((loc) => (
|
|
<button
|
|
key={loc}
|
|
onClick={() => setLocale(loc)}
|
|
className={clsx(
|
|
'px-3 py-1.5 rounded-btn text-sm font-medium transition-colors',
|
|
{
|
|
'bg-white shadow-sm text-primary-dark': locale === loc,
|
|
'text-gray-600 hover:text-primary-dark': locale !== loc,
|
|
}
|
|
)}
|
|
>
|
|
{showFlags && <span className="mr-1">{localeFlags[loc]}</span>}
|
|
{loc.toUpperCase()}
|
|
</button>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="relative">
|
|
<button
|
|
onClick={() => setIsOpen(!isOpen)}
|
|
className="flex items-center gap-2 px-3 py-2 rounded-btn hover:bg-secondary-gray transition-colors"
|
|
>
|
|
<GlobeAltIcon className="w-5 h-5 text-gray-600" />
|
|
{showFlags && <span>{localeFlags[locale]}</span>}
|
|
<span className="text-sm font-medium">{localeNames[locale]}</span>
|
|
<ChevronDownIcon
|
|
className={clsx(
|
|
'w-4 h-4 text-gray-500 transition-transform',
|
|
{ 'rotate-180': isOpen }
|
|
)}
|
|
/>
|
|
</button>
|
|
|
|
{isOpen && (
|
|
<>
|
|
<div
|
|
className="fixed inset-0 z-10"
|
|
onClick={() => setIsOpen(false)}
|
|
/>
|
|
<div className="absolute right-0 mt-2 w-40 bg-white rounded-card shadow-card-hover border border-secondary-light-gray z-20 overflow-hidden">
|
|
{availableLocales.map((loc) => (
|
|
<button
|
|
key={loc}
|
|
onClick={() => {
|
|
setLocale(loc);
|
|
setIsOpen(false);
|
|
}}
|
|
className={clsx(
|
|
'w-full flex items-center gap-2 px-4 py-2.5 text-left transition-colors',
|
|
{
|
|
'bg-secondary-gray': locale === loc,
|
|
'hover:bg-gray-50': locale !== loc,
|
|
}
|
|
)}
|
|
>
|
|
{showFlags && <span>{localeFlags[loc]}</span>}
|
|
<span className="text-sm font-medium">{localeNames[loc]}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|