All files / packages/app/features/settings language-settings.tsx

95% Statements 19/20
75% Branches 3/4
100% Functions 8/8
94.73% Lines 18/19

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76                              22x         22x         22x       262x 262x 262x 262x   2x       2x 2x 2x 2x       262x         524x           290x       2x   1048x     524x                    
import React from "react";
 
import { useTranslation } from "react-i18next";
import { entries } from "remeda";
 
import { StoreDataContext } from "~app/contexts/store-data-context";
import { changeValidatorLocale } from "~app/utils/i18n";
import type { Language } from "~app/utils/i18n-data";
import type { Locale } from "~app/utils/locale";
import { LANGUAGE_STORE_NAME } from "~app/utils/store/language";
import { LOCALE_STORE_NAME } from "~app/utils/store/locale";
import { Select } from "~components/select";
import { Text } from "~components/text";
import { View } from "~components/view";
 
const LANGUAGE_TEXT: Record<Language, string> = {
	en: "English",
	ru: "Русский",
};
 
const LANGUAGE_TO_LOCALE_MAP: Record<Language, Locale> = {
	en: "en-US",
	ru: "ru-RU",
};
 
export const LanguageSettings: React.FC = () => {
	const {
		[LOCALE_STORE_NAME]: [, setLocale],
		[LANGUAGE_STORE_NAME]: [, setLanguage],
	} = React.use(StoreDataContext);
	const { i18n, t } = useTranslation("settings");
	const currentLanguage = i18n.language as Language;
	const onChange = React.useCallback(
		async (nextLanguage: Language) => {
			Iif (nextLanguage === currentLanguage) {
				return;
			}
			// oxlint-disable-next-line react/invariant
			setLanguage(nextLanguage);
			setLocale(LANGUAGE_TO_LOCALE_MAP[nextLanguage]);
			await i18n.changeLanguage(nextLanguage);
			await changeValidatorLocale(nextLanguage, i18n);
		},
		[currentLanguage, i18n, setLocale, setLanguage],
	);
	return (
		<View className="flex-row items-center gap-4">
			<Text className="text-xl">{t("languages.header")}</Text>
			<Select
				testID="language-select"
				items={entries(LANGUAGE_TEXT).map(([language, text]) => ({
					language,
					text,
				}))}
				label={t("languages.dropdown.label")}
				placeholder={t("languages.dropdown.placeholder")}
				renderValue={(values) => values.map((value) => value.text).join(", ")}
				selectedKeys={[currentLanguage]}
				onSelectionChange={(key) => {
					// oxlint-disable-next-line typescript/no-non-null-assertion
					void onChange(key[0]!);
				}}
				getKey={({ language }) => language}
			>
				{({ language, text }) => (
					<Text
						className={language === currentLanguage ? "font-bold" : undefined}
					>
						{text}
					</Text>
				)}
			</Select>
		</View>
	);
};