mirror of
https://github.com/ajnart/homarr.git
synced 2025-11-11 16:05:47 +01:00
✨ add language switch, add german
This commit is contained in:
@@ -2,6 +2,7 @@ import { ActionIcon, Menu, Modal, Text, useMantineTheme } from '@mantine/core';
|
||||
import { showNotification } from '@mantine/notifications';
|
||||
import { useState } from 'react';
|
||||
import { IconCheck as Check, IconEdit as Edit, IconMenu, IconTrash as Trash } from '@tabler/icons';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useConfig } from '../../tools/state';
|
||||
import { serviceItem } from '../../tools/types';
|
||||
import { AddAppShelfItemForm } from './AddAppShelfItem';
|
||||
@@ -11,7 +12,7 @@ export default function AppShelfMenu(props: any) {
|
||||
const { service }: { service: serviceItem } = props;
|
||||
const { config, setConfig } = useConfig();
|
||||
const { secondaryColor } = useColorTheme();
|
||||
const theme = useMantineTheme();
|
||||
const { t } = useTranslation('layout/app-shelf-menu');
|
||||
const [opened, setOpened] = useState(false);
|
||||
return (
|
||||
<>
|
||||
@@ -20,9 +21,9 @@ export default function AppShelfMenu(props: any) {
|
||||
radius="md"
|
||||
opened={props.opened || opened}
|
||||
onClose={() => setOpened(false)}
|
||||
title="Modify a service"
|
||||
title={t('modal.title')}
|
||||
>
|
||||
<AddAppShelfItemForm setOpened={setOpened} {...service} message="Save service" />
|
||||
<AddAppShelfItemForm setOpened={setOpened} {...service} message={t('modal.buttons.save')} />
|
||||
</Modal>
|
||||
<Menu
|
||||
withinPortal
|
||||
@@ -44,11 +45,11 @@ export default function AppShelfMenu(props: any) {
|
||||
</ActionIcon>
|
||||
</Menu.Target>
|
||||
<Menu.Dropdown>
|
||||
<Menu.Label>Settings</Menu.Label>
|
||||
<Menu.Label>{t('menu.labels.settings')}</Menu.Label>
|
||||
<Menu.Item color={secondaryColor} icon={<Edit />} onClick={() => setOpened(true)}>
|
||||
Edit
|
||||
{t('menu.actions.edit')}
|
||||
</Menu.Item>
|
||||
<Menu.Label>Danger zone</Menu.Label>
|
||||
<Menu.Label>{t('menu.labels.dangerZone')}</Menu.Label>
|
||||
<Menu.Item
|
||||
color="red"
|
||||
onClick={(e: any) => {
|
||||
@@ -70,7 +71,7 @@ export default function AppShelfMenu(props: any) {
|
||||
}}
|
||||
icon={<Trash />}
|
||||
>
|
||||
Delete
|
||||
{t('menu.actions.delete')}
|
||||
</Menu.Item>
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import React from 'react';
|
||||
import { Text, Slider, Stack } from '@mantine/core';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useConfig } from '../../tools/state';
|
||||
|
||||
export function AppCardWidthSelector() {
|
||||
const { config, setConfig } = useConfig();
|
||||
const { t } = useTranslation('settings/customization/app-width');
|
||||
|
||||
const setappCardWidth = (appCardWidth: number) => {
|
||||
setConfig({
|
||||
@@ -17,7 +19,7 @@ export function AppCardWidthSelector() {
|
||||
|
||||
return (
|
||||
<Stack spacing="xs">
|
||||
<Text>App Width</Text>
|
||||
<Text>{t('label')}</Text>
|
||||
<Slider
|
||||
label={null}
|
||||
defaultValue={config.settings.appCardWidth}
|
||||
|
||||
@@ -12,10 +12,7 @@ import LanguageSwitch from './LanguageSwitch';
|
||||
|
||||
export default function CommonSettings(args: any) {
|
||||
const { config, setConfig } = useConfig();
|
||||
const { t } = useTranslation([
|
||||
'settings/general/search-engine',
|
||||
'settings/general/config-changer',
|
||||
]);
|
||||
const { t } = useTranslation(['settings/general/search-engine', 'settings/common']);
|
||||
|
||||
const matches = [
|
||||
{ label: 'Google', value: 'https://google.com/search?q=' },
|
||||
@@ -84,7 +81,7 @@ export default function CommonSettings(args: any) {
|
||||
<LanguageSwitch />
|
||||
<ConfigChanger />
|
||||
<SaveConfigComponent />
|
||||
<Tip>{t('configTip')}</Tip>
|
||||
<Tip>{t('settings/common:tips.configTip')}</Tip>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,29 +4,35 @@ import { IconLanguage } from '@tabler/icons';
|
||||
|
||||
import { forwardRef, useState } from 'react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useRouter } from 'next/router';
|
||||
import { getLanguageByCode, Language } from '../../languages/language';
|
||||
|
||||
export default function LanguageSwitch() {
|
||||
const { t, i18n } = useTranslation('settings/general/internationalization');
|
||||
/*const { language, languages, changeLanguage } = i18n;
|
||||
const { changeLanguage } = i18n;
|
||||
|
||||
const [selectedLanguage, setSelectedLanguage] = useState<string | null>(language);
|
||||
const { locale, locales } = useRouter();
|
||||
const [selectedLanguage, setSelectedLanguage] = useState<string | null>(locale);
|
||||
|
||||
const data = languages.map((language) => ({
|
||||
image: `https://countryflagsapi.com/png/${language.split('-').pop()}`,
|
||||
label: 'JA',
|
||||
value: language,
|
||||
}));*/
|
||||
const data = locales
|
||||
? locales.map((localeItem) => ({
|
||||
value: localeItem,
|
||||
label: getLanguageByCode(localeItem).originalName,
|
||||
image: `imgs/flags/${localeItem}.png`,
|
||||
language: getLanguageByCode(localeItem),
|
||||
}))
|
||||
: [];
|
||||
|
||||
const onChangeSelect = (value: string) => {
|
||||
//setSelectedLanguage(value);
|
||||
setSelectedLanguage(value);
|
||||
|
||||
const languageName = 'JA IS HALZ SCHEISSE NE';
|
||||
const newLanguage = getLanguageByCode(value);
|
||||
|
||||
/*changeLanguage(value)
|
||||
changeLanguage(value)
|
||||
.then(() => {
|
||||
showNotification({
|
||||
title: 'Language changed',
|
||||
message: `You changed the language to '${languageName}'`,
|
||||
message: `You changed the language to '${newLanguage.originalName}'`,
|
||||
color: 'green',
|
||||
autoClose: 5000,
|
||||
});
|
||||
@@ -34,31 +40,45 @@ export default function LanguageSwitch() {
|
||||
.catch((err) => {
|
||||
showNotification({
|
||||
title: 'Failed to change language',
|
||||
message: `Failed to change to '${languageName}', Error:'${err}`,
|
||||
message: `Failed to change to '${newLanguage.originalName}', Error:'${err}`,
|
||||
color: 'red',
|
||||
autoClose: 5000,
|
||||
});
|
||||
});*/
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Stack>
|
||||
<Select
|
||||
icon={<IconLanguage size={18} />}
|
||||
icon={
|
||||
<Image
|
||||
width={30}
|
||||
height={18}
|
||||
src={`/imgs/flags/${selectedLanguage}.png`}
|
||||
alt="country flag"
|
||||
styles={{
|
||||
root: {
|
||||
borderRadius: 1.5,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
}
|
||||
label={t('label')}
|
||||
data={[
|
||||
{
|
||||
value: 'uwu',
|
||||
label: 'asdf',
|
||||
},
|
||||
]}
|
||||
data={data}
|
||||
itemComponent={SelectItem}
|
||||
nothingFound="Nothing found"
|
||||
onChange={onChangeSelect}
|
||||
/*
|
||||
value={selectedLanguage}
|
||||
defaultValue={language}
|
||||
*/
|
||||
defaultValue={locale}
|
||||
styles={{
|
||||
icon: {
|
||||
width: 42,
|
||||
},
|
||||
input: {
|
||||
paddingLeft: '45px !important',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
);
|
||||
@@ -66,17 +86,19 @@ export default function LanguageSwitch() {
|
||||
|
||||
interface ItemProps extends React.ComponentPropsWithoutRef<'div'> {
|
||||
image: string;
|
||||
label: string;
|
||||
language: Language;
|
||||
}
|
||||
|
||||
const SelectItem = forwardRef<HTMLDivElement, ItemProps>(
|
||||
({ image, label, ...others }: ItemProps, ref) => (
|
||||
({ language, image, ...others }: ItemProps, ref) => (
|
||||
<div ref={ref} {...others}>
|
||||
<Group noWrap>
|
||||
<Image src={image} width={30} height={20} radius="xs" />
|
||||
|
||||
<div>
|
||||
<Text size="sm">{label}</Text>
|
||||
<Text size="sm">
|
||||
{language.originalName} ({language.translatedName})
|
||||
</Text>
|
||||
</div>
|
||||
</Group>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Text } from '@mantine/core';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
|
||||
interface TipProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export default function Tip(props: TipProps) {
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
return (
|
||||
<Text
|
||||
style={{
|
||||
@@ -13,7 +16,8 @@ export default function Tip(props: TipProps) {
|
||||
marginBottom: '0.5rem',
|
||||
}}
|
||||
>
|
||||
Tip: {props.children}
|
||||
{t('tip')}
|
||||
{props.children}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user