diff --git a/public/locales/en/authentication/login.json b/public/locales/en/authentication/login.json new file mode 100644 index 000000000..f52e3da6f --- /dev/null +++ b/public/locales/en/authentication/login.json @@ -0,0 +1,27 @@ +{ + "title": "Welcome back!", + "text": "Please enter the Password", + "form": { + "fields": { + "password": { + "label": "Password", + "placeholder": "Your password" + } + }, + "buttons": { + "submit": "Sign in" + } + }, + "notifications": { + "checking": { + "title": "Checking your password", + "message": "Your password is being checked..." + }, + "correct": { + "title": "Password correct, redirecting you..." + }, + "wrong": { + "title": "Password is wrong, please try again." + } + } +} diff --git a/src/components/Settings/LanguageSwitch.tsx b/src/components/Settings/LanguageSwitch.tsx index cbd7ddc13..35f3b0d80 100644 --- a/src/components/Settings/LanguageSwitch.tsx +++ b/src/components/Settings/LanguageSwitch.tsx @@ -11,7 +11,7 @@ export default function LanguageSwitch() { const { t, i18n } = useTranslation('settings/general/internationalization'); const { changeLanguage } = i18n; const configLocale = getCookie('config-locale'); - const { locale, locales, push } = useRouter(); + const { locale, locales, pathname, query, asPath, push } = useRouter(); const [selectedLanguage, setSelectedLanguage] = useState( (configLocale as string) ?? locale ?? 'en' ); @@ -36,7 +36,14 @@ export default function LanguageSwitch() { sameSite: 'strict', }); - push('/', '/', { locale: value }); + push( + { + pathname, + query, + }, + asPath, + { locale: value } + ); showNotification({ title: 'Language changed', diff --git a/src/pages/[slug].tsx b/src/pages/[slug].tsx index 3417ea0f6..a1ae53141 100644 --- a/src/pages/[slug].tsx +++ b/src/pages/[slug].tsx @@ -1,23 +1,30 @@ -import { GetServerSidePropsContext } from 'next'; -import path from 'path'; +import { getCookie } from 'cookies-next'; import fs from 'fs'; +import { GetServerSidePropsContext } from 'next'; +import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; +import path from 'path'; import { useEffect } from 'react'; import AppShelf from '../components/AppShelf/AppShelf'; import LoadConfigComponent from '../components/Config/LoadConfig'; -import { Config } from '../tools/types'; -import { useConfig } from '../tools/state'; import Layout from '../components/layout/Layout'; +import { getConfig } from '../tools/getConfig'; +import { useConfig } from '../tools/state'; +import { dashboardNamespaces } from '../tools/translation-namespaces'; +import { Config } from '../tools/types'; -export async function getServerSideProps( - context: GetServerSidePropsContext -): Promise<{ props: { config: Config } }> { - const configByUrl = context.query.slug; +export async function getServerSideProps({ + req, + res, + locale, + query, +}: GetServerSidePropsContext): Promise<{ props: { config: Config } }> { + const configByUrl = query.slug; const configPath = path.join(process.cwd(), 'data/configs', `${configByUrl}.json`); const configExists = fs.existsSync(configPath); if (!configExists) { // Redirect to 404 - context.res.writeHead(301, { Location: '/404' }); - context.res.end(); + res.writeHead(301, { Location: '/404' }); + res.end(); return { props: { config: { @@ -31,13 +38,11 @@ export async function getServerSideProps( }, }; } - const config = fs.readFileSync(configPath, 'utf8'); - // Print loaded config - return { - props: { - config: JSON.parse(config), - }, - }; + + const configLocale = getCookie('config-locale', { req, res }); + const targetLanguage = (configLocale ?? locale) as string; + const translations = await serverSideTranslations(targetLanguage, dashboardNamespaces); + return getConfig(configByUrl as string, translations); } export default function HomePage(props: any) { diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 724e8e882..4e57a6ae9 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -11,6 +11,7 @@ import { migrateToIdConfig } from '../tools/migrate'; import { getConfig } from '../tools/getConfig'; import { useColorTheme } from '../tools/color'; import Layout from '../components/layout/Layout'; +import { dashboardNamespaces } from '../tools/translation-namespaces'; export async function getServerSideProps({ req, @@ -29,37 +30,10 @@ export async function getServerSideProps({ configName = 'default'; } - const translations = await serverSideTranslations((configLocale ?? locale) as string, [ - 'common', - 'layout/app-shelf', - 'layout/add-service-app-shelf', - 'layout/app-shelf-menu', - 'settings/common', - 'settings/general/theme-selector', - 'settings/general/config-changer', - 'settings/general/internationalization', - 'settings/general/module-enabler', - 'settings/general/search-engine', - 'settings/general/widget-positions', - 'settings/customization/color-selector', - 'settings/customization/page-appearance', - 'settings/customization/shade-selector', - 'settings/customization/app-width', - 'settings/customization/opacity-selector', - 'modules/common', - 'modules/date', - 'modules/calendar', - 'modules/dlspeed', - 'modules/usenet', - 'modules/search', - 'modules/torrents-status', - 'modules/weather', - 'modules/ping', - 'modules/docker', - 'modules/dashdot', - 'modules/overseerr', - 'modules/common-media-cards', - ]); + const translations = await serverSideTranslations( + (configLocale ?? locale) as string, + dashboardNamespaces + ); return getConfig(configName as string, translations); } diff --git a/src/pages/login.tsx b/src/pages/login.tsx index 7fe0db813..b831acb06 100644 --- a/src/pages/login.tsx +++ b/src/pages/login.tsx @@ -5,12 +5,16 @@ import { showNotification, updateNotification } from '@mantine/notifications'; import axios from 'axios'; import { IconCheck, IconX } from '@tabler/icons'; import { useRouter } from 'next/router'; +import { Trans, useTranslation } from 'next-i18next'; import { useForm } from '@mantine/form'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; +import { loginNamespaces } from '../tools/translation-namespaces'; // TODO: Add links to the wiki articles about the login process. export default function AuthenticationTitle() { const router = useRouter(); + const { t } = useTranslation('authentication/login'); + const form = useForm({ initialValues: { password: '', @@ -33,15 +37,12 @@ export default function AuthenticationTitle() { align="center" sx={(theme) => ({ fontFamily: `Greycliff CF, ${theme.fontFamily}`, fontWeight: 900 })} > - Welcome back! + {t('title')} - Please enter the{' '} - href="#" size="sm" onClick={(event) => event.preventDefault()}> - password - + {t('text')} , autoClose: 1000, @@ -87,7 +88,7 @@ export default function AuthenticationTitle() { updateNotification({ id: 'load-data', color: 'red', - title: 'Password is wrong, please try again.', + title: t('notifications.wrong.title'), message: undefined, icon: , autoClose: 2000, @@ -99,15 +100,15 @@ export default function AuthenticationTitle() { > @@ -115,10 +116,10 @@ export default function AuthenticationTitle() { ); } -export async function getStaticProps({ locale }: { locale: string }) { +export async function getServerSideProps({ locale }: { locale: string }) { return { props: { - ...(await serverSideTranslations(locale, ['common'])), + ...(await serverSideTranslations(locale, loginNamespaces)), // Will be passed to the page component as props }, }; diff --git a/src/tools/translation-namespaces.ts b/src/tools/translation-namespaces.ts new file mode 100644 index 000000000..37587bd6d --- /dev/null +++ b/src/tools/translation-namespaces.ts @@ -0,0 +1,35 @@ +export const dashboardNamespaces = [ + 'common', + 'layout/app-shelf', + 'layout/add-service-app-shelf', + 'layout/app-shelf-menu', + 'settings/common', + 'settings/general/theme-selector', + 'settings/general/config-changer', + 'settings/general/internationalization', + 'settings/general/module-enabler', + 'settings/general/search-engine', + 'settings/general/widget-positions', + 'settings/customization/color-selector', + 'settings/customization/page-appearance', + 'settings/customization/shade-selector', + 'settings/customization/app-width', + 'settings/customization/opacity-selector', + 'modules/common', + 'modules/date', + 'modules/calendar', + 'modules/dlspeed', + 'modules/usenet', + 'modules/search', + 'modules/torrents-status', + 'modules/weather', + 'modules/ping', + 'modules/docker', + 'modules/dashdot', + 'modules/overseerr', + 'modules/common-media-cards', +]; + +export const loginNamespaces = [ + 'authentication/login', +];