Files
lettersoup-online/002_source/cms/src/components/dashboard/layout/language-popover.tsx
louiscklaw 6c931c1fe8 build ok,
2025-04-14 09:26:24 +08:00

78 lines
2.2 KiB
TypeScript

'use client';
import * as React from 'react';
import Box from '@mui/material/Box';
import ListItemIcon from '@mui/material/ListItemIcon';
import Menu from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import Typography from '@mui/material/Typography';
import { useTranslation } from 'react-i18next';
import { toast } from '@/components/core/toaster';
export type Language = 'en' | 'de' | 'es';
export const languageFlags = {
en: '/assets/flag-uk.svg',
de: '/assets/flag-de.svg',
es: '/assets/flag-es.svg',
} as const;
const languageOptions = {
en: { icon: '/assets/flag-uk.svg', label: 'English' },
de: { icon: '/assets/flag-de.svg', label: 'German' },
es: { icon: '/assets/flag-es.svg', label: 'Spanish' },
} as const;
export interface LanguagePopoverProps {
anchorEl: null | Element;
onClose?: () => void;
open?: boolean;
}
export function LanguagePopover({ anchorEl, onClose, open = false }: LanguagePopoverProps): React.JSX.Element {
const { i18n, t } = useTranslation();
const handleChange = React.useCallback(
async (language: Language): Promise<void> => {
onClose?.();
await i18n.changeLanguage(language);
toast.success(t('languageChanged'));
},
[onClose, i18n, t]
);
return (
<Menu
anchorEl={anchorEl}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
onClose={onClose}
open={open}
slotProps={{ paper: { sx: { width: '220px' } } }}
transformOrigin={{ horizontal: 'right', vertical: 'top' }}
>
{(Object.keys(languageOptions) as Language[]).map((language) => {
const option = languageOptions[language];
return (
<MenuItem
key={language}
onClick={(): void => {
handleChange(language).catch(() => {
// ignore
});
}}
>
<ListItemIcon>
<Box sx={{ height: '28px', width: '28px' }}>
<Box alt={option.label} component="img" src={option.icon} sx={{ height: 'auto', width: '100%' }} />
</Box>
</ListItemIcon>
<Typography variant="subtitle2">{option.label}</Typography>
</MenuItem>
);
})}
</Menu>
);
}