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 = ({
- - {t('boards.title')} - - ({ + label: t(`localization.firstDayOfWeek.options.${day}`) as string, + value: day, + }))} + {...form.getInputProps('firstDayOfWeek')} /> @@ -158,10 +151,10 @@ const SettingsComponent = ({ {t('searchEngine.title')} - + @@ -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); }