Add preferences to preferences page

This commit is contained in:
Manuel
2023-07-30 16:22:45 +02:00
parent 9de710bfd8
commit d100d41ce6
5 changed files with 112 additions and 3 deletions

View File

@@ -66,6 +66,7 @@
"dayjs": "^1.11.7", "dayjs": "^1.11.7",
"dockerode": "^3.3.2", "dockerode": "^3.3.2",
"fily-publish-gridstack": "^0.0.13", "fily-publish-gridstack": "^0.0.13",
"flag-icons": "^6.9.2",
"framer-motion": "^10.0.0", "framer-motion": "^10.0.0",
"html-entities": "^2.3.3", "html-entities": "^2.3.3",
"i18next": "^22.5.1", "i18next": "^22.5.1",

View File

@@ -34,6 +34,7 @@ import {
getServiceSidePackageAttributes, getServiceSidePackageAttributes,
} from '../tools/server/getPackageVersion'; } from '../tools/server/getPackageVersion';
import { theme } from '../tools/server/theme/theme'; import { theme } from '../tools/server/theme/theme';
import "/node_modules/flag-icons/css/flag-icons.min.css";
function App( function App(
this: any, this: any,

View File

@@ -1,16 +1,84 @@
import { Title } from '@mantine/core'; import { Group, Select, Stack, Text, Title } from '@mantine/core';
import Head from 'next/head'; import Head from 'next/head';
import { forwardRef } from 'react';
import { AccessibilitySettings } from '~/components/Settings/Customization/Accessibility/AccessibilitySettings';
import { MainLayout } from '~/components/layout/admin/main-admin.layout'; import { MainLayout } from '~/components/layout/admin/main-admin.layout';
import { languages } from '~/tools/language';
const PreferencesPage = () => { const PreferencesPage = () => {
const data = languages.map((language) => ({
image: 'https://img.icons8.com/clouds/256/000000/futurama-bender.png',
label: language.originalName,
description: language.translatedName,
value: language.shortName,
country: language.country,
}));
return ( return (
<MainLayout> <MainLayout>
<Head> <Head>
<title>Preferences Homarr</title> <title>Preferences Homarr</title>
</Head> </Head>
<Title>Preferences</Title> <Title mb="xl">Preferences</Title>
<Stack spacing={5}>
<Title order={2} size="lg">
Localization
</Title>
<Select
label="Language"
itemComponent={SelectItem}
data={data}
searchable
maxDropdownHeight={400}
filter={(value, item) =>
item.label.toLowerCase().includes(value.toLowerCase().trim()) ||
item.description.toLowerCase().includes(value.toLowerCase().trim())
}
withAsterisk
/>
<Select
label="First day of the week"
data={[
{ value: 'monday', label: 'Monday' },
{ value: 'sunday', label: 'Sunday' },
{ value: 'saturday', label: 'Saturday' },
]}
/>
<Title order={2} size="lg" mt="lg" mb="md">
Accessibility
</Title>
<AccessibilitySettings />
</Stack>
</MainLayout> </MainLayout>
); );
}; };
interface ItemProps extends React.ComponentPropsWithoutRef<'div'> {
image: string;
label: string;
description: string;
country: string;
}
const SelectItem = forwardRef<HTMLDivElement, ItemProps>(
({ image, label, description, country, ...others }: ItemProps, ref) => (
<div ref={ref} {...others}>
<Group noWrap>
<span className={`fi fi-${country?.toLowerCase()}`}></span>
<div>
<Text size="sm">{label}</Text>
<Text size="xs" opacity={0.65}>
{description}
</Text>
</div>
</Group>
</div>
)
);
export default PreferencesPage; export default PreferencesPage;

View File

@@ -4,11 +4,18 @@ export class Language {
translatedName: string; translatedName: string;
emoji: string; emoji: string;
constructor(shortName: string, originalName: string, translatedName: string, emoji: string) { /**
* The country identified b<y the ISO-3166 alpha 2 code:
* https://www.iso.org/obp/ui/#search
*/
country?: string;
constructor(shortName: string, originalName: string, translatedName: string, emoji: string, country: string) {
this.shortName = shortName; this.shortName = shortName;
this.originalName = originalName; this.originalName = originalName;
this.translatedName = translatedName; this.translatedName = translatedName;
this.emoji = emoji; this.emoji = emoji;
this.country = country;
} }
} }
@@ -18,12 +25,14 @@ export const languages: Language[] = [
originalName: 'Deutsch', originalName: 'Deutsch',
translatedName: 'German', translatedName: 'German',
emoji: '🇩🇪', emoji: '🇩🇪',
country: 'DE'
}, },
{ {
shortName: 'en', shortName: 'en',
originalName: 'English', originalName: 'English',
translatedName: 'English', translatedName: 'English',
emoji: '🇬🇧', emoji: '🇬🇧',
country: 'GB'
}, },
// Danish // Danish
{ {
@@ -31,6 +40,7 @@ export const languages: Language[] = [
originalName: 'Dansk', originalName: 'Dansk',
translatedName: 'Danish', translatedName: 'Danish',
emoji: '🇩🇰', emoji: '🇩🇰',
country: 'DK'
}, },
// Hebrew // Hebrew
{ {
@@ -38,36 +48,42 @@ export const languages: Language[] = [
originalName: 'עברית', originalName: 'עברית',
translatedName: 'Hebrew', translatedName: 'Hebrew',
emoji: '🇮🇱', emoji: '🇮🇱',
country: 'IL'
}, },
{ {
shortName: 'es', shortName: 'es',
originalName: 'Español', originalName: 'Español',
translatedName: 'Spanish', translatedName: 'Spanish',
emoji: '🇪🇸', emoji: '🇪🇸',
country: 'ES'
}, },
{ {
shortName: 'fr', shortName: 'fr',
originalName: 'Français', originalName: 'Français',
translatedName: 'French', translatedName: 'French',
emoji: '🇫🇷', emoji: '🇫🇷',
country: 'FR'
}, },
{ {
shortName: 'it', shortName: 'it',
originalName: 'Italiano', originalName: 'Italiano',
translatedName: 'Italian', translatedName: 'Italian',
emoji: '🇮🇹', emoji: '🇮🇹',
country: 'IT'
}, },
{ {
shortName: 'ja', shortName: 'ja',
originalName: '日本語', originalName: '日本語',
translatedName: 'Japanese', translatedName: 'Japanese',
emoji: '🇯🇵', emoji: '🇯🇵',
country: 'JP'
}, },
{ {
shortName: 'ko', shortName: 'ko',
originalName: '한국어', originalName: '한국어',
translatedName: 'Korean', translatedName: 'Korean',
emoji: '🇰🇷', emoji: '🇰🇷',
country: 'KR'
}, },
{ {
shortName: 'lol', shortName: 'lol',
@@ -81,6 +97,7 @@ export const languages: Language[] = [
originalName: 'Norsk', originalName: 'Norsk',
translatedName: 'Norwegian', translatedName: 'Norwegian',
emoji: '🇳🇴', emoji: '🇳🇴',
country: 'NO'
}, },
// Slovak // Slovak
{ {
@@ -88,36 +105,42 @@ export const languages: Language[] = [
originalName: 'Slovenčina', originalName: 'Slovenčina',
translatedName: 'Slovak', translatedName: 'Slovak',
emoji: '🇸🇰', emoji: '🇸🇰',
country: 'SK'
}, },
{ {
shortName: 'nl', shortName: 'nl',
originalName: 'Nederlands', originalName: 'Nederlands',
translatedName: 'Dutch', translatedName: 'Dutch',
emoji: '🇳🇱', emoji: '🇳🇱',
country: 'NL'
}, },
{ {
shortName: 'pl', shortName: 'pl',
originalName: 'Polski', originalName: 'Polski',
translatedName: 'Polish', translatedName: 'Polish',
emoji: '🇵🇱', emoji: '🇵🇱',
country: 'PL'
}, },
{ {
shortName: 'pt', shortName: 'pt',
originalName: 'Português', originalName: 'Português',
translatedName: 'Portuguese', translatedName: 'Portuguese',
emoji: '🇵🇹', emoji: '🇵🇹',
country: 'PT'
}, },
{ {
shortName: 'ru', shortName: 'ru',
originalName: 'Русский', originalName: 'Русский',
translatedName: 'Russian', translatedName: 'Russian',
emoji: '🇷🇺', emoji: '🇷🇺',
country: 'RU'
}, },
{ {
shortName: 'sl', shortName: 'sl',
originalName: 'Slovenščina', originalName: 'Slovenščina',
translatedName: 'Slovenian', translatedName: 'Slovenian',
emoji: '🇸🇮', emoji: '🇸🇮',
country: 'SI'
}, },
{ {
@@ -125,12 +148,14 @@ export const languages: Language[] = [
originalName: 'Svenska', originalName: 'Svenska',
translatedName: 'Swedish', translatedName: 'Swedish',
emoji: '🇸🇪', emoji: '🇸🇪',
country: 'SE'
}, },
{ {
shortName: 'uk', shortName: 'uk',
originalName: 'Українська', originalName: 'Українська',
translatedName: 'Ukrainian', translatedName: 'Ukrainian',
emoji: '🇺🇦', emoji: '🇺🇦',
country: 'UA'
}, },
// Vietnamese // Vietnamese
{ {
@@ -138,30 +163,35 @@ export const languages: Language[] = [
originalName: 'Tiếng Việt', originalName: 'Tiếng Việt',
translatedName: 'Vietnamese', translatedName: 'Vietnamese',
emoji: '🇻🇳', emoji: '🇻🇳',
country: 'VN'
}, },
{ {
shortName: 'zh', shortName: 'zh',
originalName: '中文', originalName: '中文',
translatedName: 'Chinese', translatedName: 'Chinese',
emoji: '🇨🇳', emoji: '🇨🇳',
country: 'CN'
}, },
{ {
shortName: 'el', shortName: 'el',
originalName: 'Ελληνικά', originalName: 'Ελληνικά',
translatedName: 'Greek', translatedName: 'Greek',
emoji: '🇬🇷', emoji: '🇬🇷',
country: 'GR'
}, },
{ {
shortName: 'tr', shortName: 'tr',
originalName: 'Türkçe', originalName: 'Türkçe',
translatedName: 'Turkish', translatedName: 'Turkish',
emoji: '🇹🇷', emoji: '🇹🇷',
country: 'TR'
}, },
{ {
shortName: 'lv', shortName: 'lv',
originalName: 'Latvian', originalName: 'Latvian',
translatedName: 'Latvian', translatedName: 'Latvian',
emoji: '🇱🇻', emoji: '🇱🇻',
country: 'LV'
}, },
// Croatian // Croatian
{ {
@@ -169,6 +199,7 @@ export const languages: Language[] = [
originalName: 'Hrvatski', originalName: 'Hrvatski',
translatedName: 'Croatian', translatedName: 'Croatian',
emoji: '🇭🇷', emoji: '🇭🇷',
country: 'HR'
}, },
]; ];

View File

@@ -5217,6 +5217,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"flag-icons@npm:^6.9.2":
version: 6.9.2
resolution: "flag-icons@npm:6.9.2"
checksum: ba2754c65ae4a943ac7042be9ec039243bd5fc2d6cec59228c46549ccadf20f272b22a1d1e8940a830b86b0d2fda1e53f8dd3866937a40c7d90b8fae789b122d
languageName: node
linkType: hard
"flat-cache@npm:^3.0.4": "flat-cache@npm:^3.0.4":
version: 3.0.4 version: 3.0.4
resolution: "flat-cache@npm:3.0.4" resolution: "flat-cache@npm:3.0.4"
@@ -5882,6 +5889,7 @@ __metadata:
eslint-plugin-unused-imports: ^3.0.0 eslint-plugin-unused-imports: ^3.0.0
eslint-plugin-vitest: ^0.2.0 eslint-plugin-vitest: ^0.2.0
fily-publish-gridstack: ^0.0.13 fily-publish-gridstack: ^0.0.13
flag-icons: ^6.9.2
framer-motion: ^10.0.0 framer-motion: ^10.0.0
happy-dom: ^10.0.0 happy-dom: ^10.0.0
html-entities: ^2.3.3 html-entities: ^2.3.3