diff --git a/public/locales/en/user/preferences.json b/public/locales/en/user/preferences.json
index 4867794f6..069cd7065 100644
--- a/public/locales/en/user/preferences.json
+++ b/public/locales/en/user/preferences.json
@@ -1,6 +1,7 @@
{
+ "metaTitle": "Preferences",
+ "pageTitle": "Your preferences",
"boards": {
- "title": "Boards",
"defaultBoard": {
"label": "Default board"
}
@@ -21,7 +22,12 @@
"label": "Language"
},
"firstDayOfWeek": {
- "label": "First day of the week"
+ "label": "First day of the week",
+ "options": {
+ "monday": "Monday",
+ "saturday": "Saturday",
+ "sunday": "Sunday"
+ }
}
},
"searchEngine": {
diff --git a/src/components/Dashboard/Tiles/Widgets/Inputs/LocationSelection.tsx b/src/components/Dashboard/Tiles/Widgets/Inputs/LocationSelection.tsx
index dd7d257b0..c65adc110 100644
--- a/src/components/Dashboard/Tiles/Widgets/Inputs/LocationSelection.tsx
+++ b/src/components/Dashboard/Tiles/Widgets/Inputs/LocationSelection.tsx
@@ -17,13 +17,12 @@ import {
} from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import { IconAlertTriangle, IconClick, IconListSearch } from '@tabler/icons-react';
+import { useTranslation } from 'next-i18next';
import { useState } from 'react';
-import { useTranslation } from 'react-i18next';
import { City } from '~/server/api/routers/weather';
import { api } from '~/utils/api';
import { IntegrationOptionsValueType } from '../WidgetsEditModal';
-import Link from 'next/link';
type LocationSelectionProps = {
widgetId: string;
@@ -166,16 +165,16 @@ const CitySelectModal = ({ opened, closeModal, query, onCitySelected }: CitySele
onClose={closeModal}
zIndex={250}
>
-
-
-
- Nothing found
- Nothing was found, please try again
-
-
+
+
+
+ Nothing found
+ Nothing was found, please try again
+
+
);
-
+
const formatter = Intl.NumberFormat('en', { notation: 'compact' });
return (
@@ -220,15 +219,20 @@ const CitySelectModal = ({ opened, closeModal, query, onCitySelected }: CitySele
{city.country}
-
-
- {city.latitude}, {city.longitude}
-
+
+
+ {city.latitude}, {city.longitude}
+
|
{city.population ? (
- {formatter.format(city.population)}
+
+ {formatter.format(city.population)}
+
) : (
{t('modal.table.population.fallback')}
)}
diff --git a/src/components/User/Preferences/AccessibilitySettings.tsx b/src/components/User/Preferences/AccessibilitySettings.tsx
index 3a30f519f..1ae4d7f48 100644
--- a/src/components/User/Preferences/AccessibilitySettings.tsx
+++ b/src/components/User/Preferences/AccessibilitySettings.tsx
@@ -1,5 +1,5 @@
import { Stack, Switch } from '@mantine/core';
-import { useTranslation } from 'react-i18next';
+import { useTranslation } from 'next-i18next';
import { useUserPreferencesFormContext } from '~/pages/user/preferences';
export const AccessibilitySettings = () => {
diff --git a/src/components/User/Preferences/SearchEngineSelector.tsx b/src/components/User/Preferences/SearchEngineSelector.tsx
index 99be1522f..6c34f4fa0 100644
--- a/src/components/User/Preferences/SearchEngineSelector.tsx
+++ b/src/components/User/Preferences/SearchEngineSelector.tsx
@@ -3,22 +3,7 @@ import { useTranslation } from 'next-i18next';
import { useMemo } from 'react';
import { useUserPreferencesFormContext } from '~/pages/user/preferences';
-const searchEngineOptions = [
- { label: 'Google', value: 'https://google.com/search?q=%s' },
- { label: 'DuckDuckGo', value: 'https://duckduckgo.com/?q=%s' },
- { label: 'Bing', value: 'https://bing.com/search?q=%s' },
- { value: 'custom' },
-] as const;
-
-const useSegmentData = () => {
- const { t } = useTranslation('user/preferences');
- return searchEngineOptions.map((option) => ({
- label: option.value === 'custom' ? t('searchEngine.custom') : option.label,
- value: option.value,
- }));
-};
-
-export const SearchEngineSelector = () => {
+export const SearchEngineSettings = () => {
const { t } = useTranslation('user/preferences');
const form = useUserPreferencesFormContext();
const segmentData = useSegmentData();
@@ -51,6 +36,7 @@ export const SearchEngineSelector = () => {
label={t('searchEngine.template.label')}
description={t('searchEngine.template.description')}
inputWrapperOrder={['label', 'input', 'description', 'error']}
+ withAsterisk
{...form.getInputProps('searchTemplate')}
/>
@@ -58,3 +44,18 @@ export const SearchEngineSelector = () => {
);
};
+
+const searchEngineOptions = [
+ { label: 'Google', value: 'https://google.com/search?q=%s' },
+ { label: 'DuckDuckGo', value: 'https://duckduckgo.com/?q=%s' },
+ { label: 'Bing', value: 'https://bing.com/search?q=%s' },
+ { value: 'custom' },
+] as const;
+
+const useSegmentData = () => {
+ const { t } = useTranslation('user/preferences');
+ return searchEngineOptions.map((option) => ({
+ label: option.value === 'custom' ? t('searchEngine.custom') : option.label,
+ value: option.value,
+ }));
+};
diff --git a/src/pages/user/preferences.tsx b/src/pages/user/preferences.tsx
index 22826a217..da4ef4201 100644
--- a/src/pages/user/preferences.tsx
+++ b/src/pages/user/preferences.tsx
@@ -10,16 +10,17 @@ import {
Title,
} from '@mantine/core';
import { createFormContext } from '@mantine/form';
-import type { InferGetServerSidePropsType } from 'next';
-import { GetServerSidePropsContext } from 'next';
+import { createServerSideHelpers } from '@trpc/react-query/server';
+import { GetServerSideProps, GetServerSidePropsContext } from 'next';
+import { useTranslation } from 'next-i18next';
import Head from 'next/head';
import { forwardRef } from 'react';
-import { useTranslation } from 'react-i18next';
import { z } from 'zod';
import { AccessibilitySettings } from '~/components/User/Preferences/AccessibilitySettings';
-import { SearchEngineSelector } from '~/components/User/Preferences/SearchEngineSelector';
+import { SearchEngineSettings } from '~/components/User/Preferences/SearchEngineSelector';
import { MainLayout } from '~/components/layout/Templates/MainLayout';
-import { sleep } from '~/tools/client/time';
+import { createTrpcServersideHelpers } from '~/server/api/helper';
+import { getServerAuthSession } from '~/server/auth';
import { languages } from '~/tools/language';
import { getServerSideTranslations } from '~/tools/server/getServerSideTranslations';
import { manageNamespaces } from '~/tools/server/translation-namespaces';
@@ -27,18 +28,19 @@ import { RouterOutputs, api } from '~/utils/api';
import { useI18nZodResolver } from '~/utils/i18n-zod-resolver';
import { updateSettingsValidationSchema } from '~/validations/user';
-const PreferencesPage = ({ locale }: InferGetServerSidePropsType) => {
+const PreferencesPage = () => {
const { data } = api.user.withSettings.useQuery();
const { data: boardsData } = api.boards.all.useQuery();
+ const { t } = useTranslation('user/preferences');
return (
- Preferences • Homarr
+ {t('metaTitle')} • Homarr
- Preferences
+ {t('pageTitle')}
{data && boardsData && (
@@ -103,10 +105,6 @@ const SettingsComponent = ({
@@ -193,9 +186,23 @@ const SelectItem = forwardRef(
)
);
-export async function getServerSideProps({ req, res, locale }: GetServerSidePropsContext) {
+const firstDayOfWeekOptions = ['monday', 'sunday', 'saturday'] as const;
+
+export const getServerSideProps: GetServerSideProps = async ({ req, res, locale }) => {
+ const session = await getServerAuthSession({ req, res });
+ if (!session) {
+ return {
+ notFound: true,
+ };
+ }
+
+ const helpers = await createTrpcServersideHelpers({ req, res });
+
+ await helpers.user.withSettings.prefetch();
+ await helpers.boards.all.prefetch();
+
const translations = await getServerSideTranslations(
- manageNamespaces,
+ ['user/preferences'],
locale,
undefined,
undefined
@@ -204,8 +211,9 @@ export async function getServerSideProps({ req, res, locale }: GetServerSideProp
props: {
...translations,
locale: locale,
+ trpcState: helpers.dehydrate(),
},
};
-}
+};
export default PreferencesPage;
diff --git a/src/tools/server/getServerSideTranslations.ts b/src/tools/server/getServerSideTranslations.ts
index 3e803fc63..b7baec05c 100644
--- a/src/tools/server/getServerSideTranslations.ts
+++ b/src/tools/server/getServerSideTranslations.ts
@@ -10,6 +10,8 @@ export const getServerSideTranslations = async (
req?: IncomingMessage,
res?: ServerResponse
) => {
+ namespaces = namespaces.concat(['common', 'zod']);
+
if (!req || !res) {
return serverSideTranslations(requestLocale ?? 'en', namespaces);
}
|