27a6e2952c
useButtonType: Hamburger-, Profil-, Kategorie-, Ein-/Ausklapp- und Logout-
Buttons (kein Formular in diesen Dateien) erhalten type="button".
noSvgWithoutTitle: Icons neben sichtbarem Text werden dekorativ
(aria-hidden="true"). Zwei bislang unbenannte interaktive Elemente erhalten
zusaetzlich ein aria-label, weil ihr Text im eingeklappten Sidebar-Zustand
verschwindet bzw. ganz fehlte: die Dashboard-/Marketplace-Links und der
"Einstellungen"-Button in der Seitenleiste (t('dashboard')/t('marketplace')/
t('settings'), alle bereits vorhandene Schluessel) sowie der mobile
Schliessen-Button (tCommon('close')).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TPPB4ApQxzSU1rwV2Ffj9J
35 lines
1.0 KiB
TypeScript
35 lines
1.0 KiB
TypeScript
'use client';
|
|
|
|
import { useRouter } from 'next/navigation';
|
|
import { useLocale, useTranslations } from 'next-intl';
|
|
import { useTransition } from 'react';
|
|
|
|
export function LocaleSwitcher() {
|
|
const router = useRouter();
|
|
const locale = useLocale();
|
|
const t = useTranslations('locale');
|
|
const [isPending, startTransition] = useTransition();
|
|
|
|
function switchLocale() {
|
|
const newLocale = locale === 'de' ? 'en' : 'de';
|
|
document.cookie = `NEXT_LOCALE=${newLocale};path=/;max-age=31536000`;
|
|
startTransition(() => {
|
|
router.refresh();
|
|
});
|
|
}
|
|
|
|
const currentLabel = locale === 'de' ? t('de') : t('en');
|
|
|
|
return (
|
|
<button
|
|
type="button"
|
|
onClick={switchLocale}
|
|
disabled={isPending}
|
|
className="inline-flex items-center justify-center rounded-md px-2.5 py-1.5 text-sm font-medium text-muted-foreground hover:bg-muted hover:text-foreground transition-colors disabled:opacity-50"
|
|
aria-label={currentLabel}
|
|
>
|
|
{locale === 'de' ? 'EN' : 'DE'}
|
|
</button>
|
|
);
|
|
}
|