From 5d1735919a8dc7c719c8b6bb763dbc9eb7907751 Mon Sep 17 00:00:00 2001 From: Kai Schlamp Date: Sun, 15 Oct 2023 21:36:15 +0000 Subject: [PATCH] Working template translations with MicroI18n --- locales/de/common.yml | 3 +- locales/de/drafts.yml | 10 -- .../de/{structuredReport.yml => template.yml} | 0 locales/en/common.yml | 3 +- locales/en/drafts.yml | 10 -- .../en/{structuredReport.yml => template.yml} | 0 src/components/common/FlagIcon.tsx | 3 + .../common/SiteTranslationProvider.tsx | 9 +- .../inputs/MeasurementsInput.stories.tsx | 15 ++- .../inputs/MeasurementsInput/index.tsx | 5 +- src/components/outputs/MeasurementsOutput.tsx | 4 +- src/components/storybook/SiteTranslations.tsx | 3 +- .../template/TemplateTranslationProvider.tsx | 12 ++- src/contexts/I18nSiteContext.ts | 7 +- src/hocs/withTranslations.tsx | 30 ++---- src/hooks/useSiteLanguageListener.ts | 3 +- src/pages/tools/adrenal-mri.tsx | 2 +- src/pages/tools/adrenal-washout.tsx | 2 +- src/pages/tools/fleischner2017.tsx | 2 +- src/pages/tools/gfr.tsx | 2 +- src/pages/tools/kidney-volume.tsx | 2 +- src/pages/tools/measurements-table.tsx | 2 +- src/pages/tools/sandbox.tsx | 2 +- src/server/utils/figureUtils.ts | 15 +-- src/server/utils/siteTranslations.ts | 6 +- src/types/general.ts | 7 +- src/types/resources.ts | 11 -- src/utils/figureUtils.ts | 100 ------------------ src/utils/localizationUtils.ts | 23 +--- 29 files changed, 60 insertions(+), 233 deletions(-) delete mode 100644 locales/de/drafts.yml rename locales/de/{structuredReport.yml => template.yml} (100%) delete mode 100644 locales/en/drafts.yml rename locales/en/{structuredReport.yml => template.yml} (100%) delete mode 100644 src/types/resources.ts delete mode 100644 src/utils/figureUtils.ts diff --git a/locales/de/common.yml b/locales/de/common.yml index 997e6284..873c637a 100644 --- a/locales/de/common.yml +++ b/locales/de/common.yml @@ -1,7 +1,8 @@ formError: alreadyUsed: Bereits vergeben. invalidChars: "Enthält ungültige Zeichen. Erlaubt: {{chars}}" - reservedKeyword: "Reserviertes Schlüsselwort." + invalidLocale: Ungültiges Sprachschema. + reservedKeyword: Reserviertes Schlüsselwort. tooLong: Zu lang. Maximal {{max}} Zeichen. tooShort: Zu kurz. Mindestens {{min}} Zeichen. unexpected: "Ein unerwarteter Fehler ist aufgetreten: " diff --git a/locales/de/drafts.yml b/locales/de/drafts.yml deleted file mode 100644 index fd96c5c8..00000000 --- a/locales/de/drafts.yml +++ /dev/null @@ -1,10 +0,0 @@ -Figure: - title: Beispielabbildung - description: Eine einfache Beispielabbildung für Demonstrationszwecke. - optionTriangle: Dreieck - optionCircle: Kreis - optionSquare: Quadrat -Module: - title: Beispielmodul - description: Ein einfaches Beispielsmodul für Demonstrationszwecke. - fieldLabel: Beispielfeld diff --git a/locales/de/structuredReport.yml b/locales/de/template.yml similarity index 100% rename from locales/de/structuredReport.yml rename to locales/de/template.yml diff --git a/locales/en/common.yml b/locales/en/common.yml index c8bb1dd7..4919c77a 100644 --- a/locales/en/common.yml +++ b/locales/en/common.yml @@ -1,7 +1,8 @@ formError: alreadyUsed: Already in use. invalidChars: "Contains invalid characters. Allowed: {{chars}}" - reservedKeyword: "Reserved keyword." + invalidLocale: Invalid locale name. + reservedKeyword: Reserved keyword. tooLong: Too long. Maximum {{max}} characters. tooShort: Too short. Minimum {{min}} characters. unexpected: "An unexpected error occurred: " diff --git a/locales/en/drafts.yml b/locales/en/drafts.yml deleted file mode 100644 index 50175c65..00000000 --- a/locales/en/drafts.yml +++ /dev/null @@ -1,10 +0,0 @@ -Figure: - title: Example figure - description: A simple example figure for demonstration purposes. - optionTriangle: Triangle - optionCircle: Circle - optionSquare: Square -Module: - title: Example module - description: A simple example module for demonstration purposes. - fieldLabel: Example field diff --git a/locales/en/structuredReport.yml b/locales/en/template.yml similarity index 100% rename from locales/en/structuredReport.yml rename to locales/en/template.yml diff --git a/src/components/common/FlagIcon.tsx b/src/components/common/FlagIcon.tsx index 3103cc29..219ced69 100644 --- a/src/components/common/FlagIcon.tsx +++ b/src/components/common/FlagIcon.tsx @@ -22,5 +22,8 @@ interface FlagImageProps { export const FlagIcon = ({ language, size = 18 }: FlagImageProps) => { const Img = flagIcons[language] + if (!Img) { + throw new Error(`Missing flag for language: ${language}`) + } return } diff --git a/src/components/common/SiteTranslationProvider.tsx b/src/components/common/SiteTranslationProvider.tsx index 1f8226ed..4ec9b6d4 100644 --- a/src/components/common/SiteTranslationProvider.tsx +++ b/src/components/common/SiteTranslationProvider.tsx @@ -1,9 +1,10 @@ import { i18n } from "i18next" import { useRouter } from "next/router" +import { Locale } from "nextjs-routes" import { ReactNode, useCallback, useRef, useState } from "react" import { I18nSiteContextProvider } from "~/contexts/I18nSiteContext" import { useOnRouteChange } from "~/hooks/useOnRouteChange" -import { I18nSite, SiteLanguageOption } from "~/types/general" +import { I18nSite } from "~/types/general" import { createClient } from "~/utils/i18nBrowserClient" import { registerInstance } from "~/utils/i18nextReloader" @@ -16,7 +17,7 @@ export const SiteTranslationProvider = ({ i18nSiteProps, children, }: SiteTranslationProviderProps) => { - const [currentSiteLanguage, _setCurrentSiteLanguage] = useState( + const [currentSiteLanguage, _setCurrentSiteLanguage] = useState( i18nSiteProps.initialSiteLanguage! ) @@ -44,7 +45,7 @@ export const SiteTranslationProvider = ({ }) const setCurrentSiteLanguage = useCallback( - (language: SiteLanguageOption) => { + (language: string) => { i18nInstance.current!.i18nSite.changeLanguage(language, () => { if (language !== "cimode") { router.push( @@ -55,7 +56,7 @@ export const SiteTranslationProvider = ({ }, }, undefined, - { shallow: true, locale: language } + { shallow: true, locale: language as Locale } ) } _setCurrentSiteLanguage(language) diff --git a/src/components/inputs/MeasurementsInput.stories.tsx b/src/components/inputs/MeasurementsInput.stories.tsx index 72a4f9f5..5b9de875 100644 --- a/src/components/inputs/MeasurementsInput.stories.tsx +++ b/src/components/inputs/MeasurementsInput.stories.tsx @@ -3,7 +3,6 @@ import { ComponentProps, useState } from "react" import { calcStats, createEmptyMeasurements, createStatsText } from "~/utils/measurementsUtils" import { MeasurementsData } from "../../types/measurements" import { SiteTranslations } from "../storybook/SiteTranslations" -import { StructuredReportTranslations } from "../storybook/StructuredReportTranslations" import { MeasurementsInput } from "./MeasurementsInput" const meta: Meta = { @@ -25,14 +24,12 @@ const MeasurementsInputWithState = ({ return ( - - - + ) } diff --git a/src/components/inputs/MeasurementsInput/index.tsx b/src/components/inputs/MeasurementsInput/index.tsx index 54576407..107516e5 100644 --- a/src/components/inputs/MeasurementsInput/index.tsx +++ b/src/components/inputs/MeasurementsInput/index.tsx @@ -1,6 +1,6 @@ import { Box, Stack } from "@mantine/core" import { ReactNode, useCallback, useRef } from "react" -import { useStructureTranslation } from "~/hooks/useStructureTranslation" +import { useSiteTranslation } from "~/hooks/useSiteTranslation" import { MeasurementsAction, MeasurementsData } from "~/types/measurements" import { getMeasurementsDataParams, measurementsReducer } from "~/utils/measurementsUtils" import { InputLabel } from "../InputLabel" @@ -38,7 +38,8 @@ export const MeasurementsInput = ({ [onChange] ) - const { t } = useStructureTranslation() + const { t } = useSiteTranslation() + // TODO: make label configurable props const labels = { clearAll: t("MeasurementsInput.toolClearAll"), clearReferences: t("MeasurementsInput.toolClearReferences"), diff --git a/src/components/outputs/MeasurementsOutput.tsx b/src/components/outputs/MeasurementsOutput.tsx index 4c257ea1..ffd2a992 100644 --- a/src/components/outputs/MeasurementsOutput.tsx +++ b/src/components/outputs/MeasurementsOutput.tsx @@ -1,5 +1,5 @@ import { ReactNode } from "react" -import { useReportTranslation } from "~/hooks/useReportTranslation" +import { useSiteTranslation } from "~/hooks/useSiteTranslation" import { useStructureLink } from "~/hooks/useStructureLink" import { selectOutputFormat } from "~/state/displaySlice" import { useAppSelector } from "~/state/store" @@ -31,7 +31,7 @@ export const MeasurementsOutput = ({ }: MeasurementsOutputProps) => { const { activateLink } = useStructureLink({ fieldId }) const outputFormat = useAppSelector(selectOutputFormat) - const { t } = useReportTranslation() + const { t } = useSiteTranslation() const labels = { previous: previousLabel || t("MeasurementsOutput.columnPrevious"), diff --git a/src/components/storybook/SiteTranslations.tsx b/src/components/storybook/SiteTranslations.tsx index c767b7ac..f8c0bf33 100644 --- a/src/components/storybook/SiteTranslations.tsx +++ b/src/components/storybook/SiteTranslations.tsx @@ -1,12 +1,11 @@ import { ReactNode, Suspense, useMemo } from "react" import { I18nSiteContextProvider } from "~/contexts/I18nSiteContext" -import { SiteLanguageOption } from "~/types/general" import { createClient } from "~/utils/i18nStorybookClient" const DEFAULT_ADDITIONAL_NAMESPACES: string[] = [] interface SiteTranslationsProps { - language?: SiteLanguageOption + language?: string additionalNamespaces?: string[] children: ReactNode } diff --git a/src/components/template/TemplateTranslationProvider.tsx b/src/components/template/TemplateTranslationProvider.tsx index ae3e2dc6..56efb350 100644 --- a/src/components/template/TemplateTranslationProvider.tsx +++ b/src/components/template/TemplateTranslationProvider.tsx @@ -25,7 +25,9 @@ export const TemplateTranslationProvider = ({ const setStructureLanguage = useCallback( (language: TemplateLanguage) => { i18nStructure.options = { debugKeys: language === "cimode" } - i18nStructure.changeLanguage(language === "asSite" ? currentSiteLanguage : language) + if (language !== "cimode") { + i18nStructure.changeLanguage(language === "asSite" ? currentSiteLanguage : language) + } _setStructureLanguage(language) }, [i18nStructure, currentSiteLanguage] @@ -34,17 +36,19 @@ export const TemplateTranslationProvider = ({ const setReportLanguage = useCallback( (language: TemplateLanguage) => { i18nReport.options = { debugKeys: language === "cimode" } - i18nReport.changeLanguage(language === "asSite" ? currentSiteLanguage : language) + if (language !== "cimode") { + i18nReport.changeLanguage(language === "asSite" ? currentSiteLanguage : language) + } _setReportLanguage(language) }, [i18nReport, currentSiteLanguage] ) useSiteLanguageListener((language) => { - if (structureLanguage === "asSite") { + if (structureLanguage === "asSite" && language !== "cimode") { i18nStructure.changeLanguage(language) } - if (reportLanguage === "asSite") { + if (reportLanguage === "asSite" && language !== "cimode") { i18nReport.changeLanguage(language) } }) diff --git a/src/contexts/I18nSiteContext.ts b/src/contexts/I18nSiteContext.ts index 66bc609c..2fb6031f 100644 --- a/src/contexts/I18nSiteContext.ts +++ b/src/contexts/I18nSiteContext.ts @@ -1,12 +1,11 @@ import { i18n } from "i18next" -import { SiteLanguageOption } from "~/types/general" import { createRequiredContext } from "~/utils/createRequiredContext" export interface I18nSiteContext { i18nSite: i18n - supportedSiteLanguages: SiteLanguageOption[] - currentSiteLanguage: SiteLanguageOption - setCurrentSiteLanguage: (language: SiteLanguageOption) => void + supportedSiteLanguages: string[] + currentSiteLanguage: string + setCurrentSiteLanguage: (language: string) => void } export const [useI18nSite, I18nSiteContextProvider] = diff --git a/src/hocs/withTranslations.tsx b/src/hocs/withTranslations.tsx index 300ad49d..5d83884f 100644 --- a/src/hocs/withTranslations.tsx +++ b/src/hocs/withTranslations.tsx @@ -1,7 +1,6 @@ import hoistNonReactStatics from "hoist-non-react-statics" import { ComponentType } from "react" import { SiteTranslationProvider } from "~/components/common/SiteTranslationProvider" -import { StructuredReportTranslationProvider } from "~/components/common/StructuredReportTranslationProvider" import { ServerSideProps } from "~/types/general" interface AppProps { @@ -13,33 +12,16 @@ export const withTranslations = ( ): ComponentType => { const WithTranslations = (props: AppProps) => { const i18nSiteProps = props.pageProps?.i18nSite - const i18nStructuredReportProps = props.pageProps?.i18nStructuredReport - if (!i18nSiteProps && !i18nStructuredReportProps) { + if (!i18nSiteProps) { return } - if (i18nSiteProps && !i18nStructuredReportProps) { - return ( - - - - ) - } - - if (i18nSiteProps && i18nStructuredReportProps) { - return ( - - - - - - ) - } - - throw new Error("Invalid translations setup.") + return ( + + + + ) } return hoistNonReactStatics(WithTranslations, WrappedComponent) diff --git a/src/hooks/useSiteLanguageListener.ts b/src/hooks/useSiteLanguageListener.ts index e9dee5c6..c376ecd5 100644 --- a/src/hooks/useSiteLanguageListener.ts +++ b/src/hooks/useSiteLanguageListener.ts @@ -1,8 +1,7 @@ import { useEffect } from "react" -import { SiteLanguageOption } from "../types/general" import { useSiteTranslation } from "./useSiteTranslation" -type Callback = (language: SiteLanguageOption) => void +type Callback = (language: string) => void export const useSiteLanguageListener = (callback: Callback) => { const { i18n } = useSiteTranslation() diff --git a/src/pages/tools/adrenal-mri.tsx b/src/pages/tools/adrenal-mri.tsx index ee379670..0ef8385e 100644 --- a/src/pages/tools/adrenal-mri.tsx +++ b/src/pages/tools/adrenal-mri.tsx @@ -16,7 +16,7 @@ export const getServerSideProps: GetServerSideProps = async ({ }) => ({ props: { session: await getServerSideSession(req, res), - i18nSite: await getServerSideSiteTranslations(locale, locales), + i18nSite: await getServerSideSiteTranslations(locale, locales, ["template"]), preloadedReduxState: {}, }, }) diff --git a/src/pages/tools/adrenal-washout.tsx b/src/pages/tools/adrenal-washout.tsx index d979e08e..2de0341a 100644 --- a/src/pages/tools/adrenal-washout.tsx +++ b/src/pages/tools/adrenal-washout.tsx @@ -16,7 +16,7 @@ export const getServerSideProps: GetServerSideProps = async ({ }) => ({ props: { session: await getServerSideSession(req, res), - i18nSite: await getServerSideSiteTranslations(locale, locales), + i18nSite: await getServerSideSiteTranslations(locale, locales, ["template"]), preloadedReduxState: {}, }, }) diff --git a/src/pages/tools/fleischner2017.tsx b/src/pages/tools/fleischner2017.tsx index 34ec1f94..3510ce92 100644 --- a/src/pages/tools/fleischner2017.tsx +++ b/src/pages/tools/fleischner2017.tsx @@ -16,7 +16,7 @@ export const getServerSideProps: GetServerSideProps = async ({ }) => ({ props: { session: await getServerSideSession(req, res), - i18nSite: await getServerSideSiteTranslations(locale, locales), + i18nSite: await getServerSideSiteTranslations(locale, locales, ["template"]), preloadedReduxState: {}, }, }) diff --git a/src/pages/tools/gfr.tsx b/src/pages/tools/gfr.tsx index 6810dcb4..d1496e7b 100644 --- a/src/pages/tools/gfr.tsx +++ b/src/pages/tools/gfr.tsx @@ -16,7 +16,7 @@ export const getServerSideProps: GetServerSideProps = async ({ }) => ({ props: { session: await getServerSideSession(req, res), - i18nSite: await getServerSideSiteTranslations(locale, locales), + i18nSite: await getServerSideSiteTranslations(locale, locales, ["template"]), preloadedReduxState: {}, }, }) diff --git a/src/pages/tools/kidney-volume.tsx b/src/pages/tools/kidney-volume.tsx index 5f16ef67..eb3bce8a 100644 --- a/src/pages/tools/kidney-volume.tsx +++ b/src/pages/tools/kidney-volume.tsx @@ -16,7 +16,7 @@ export const getServerSideProps: GetServerSideProps = async ({ }) => ({ props: { session: await getServerSideSession(req, res), - i18nSite: await getServerSideSiteTranslations(locale, locales), + i18nSite: await getServerSideSiteTranslations(locale, locales, ["template"]), preloadedReduxState: {}, }, }) diff --git a/src/pages/tools/measurements-table.tsx b/src/pages/tools/measurements-table.tsx index 6704324d..2071ecaa 100644 --- a/src/pages/tools/measurements-table.tsx +++ b/src/pages/tools/measurements-table.tsx @@ -16,7 +16,7 @@ export const getServerSideProps: GetServerSideProps = async ({ }) => ({ props: { session: await getServerSideSession(req, res), - i18nSite: await getServerSideSiteTranslations(locale, locales), + i18nSite: await getServerSideSiteTranslations(locale, locales, ["template"]), preloadedReduxState: {}, }, }) diff --git a/src/pages/tools/sandbox.tsx b/src/pages/tools/sandbox.tsx index 1be1c6be..33ccc221 100644 --- a/src/pages/tools/sandbox.tsx +++ b/src/pages/tools/sandbox.tsx @@ -15,7 +15,7 @@ export const getServerSideProps: GetServerSideProps = async ({ }) => ({ props: { session: await getServerSideSession(req, res), - i18nSite: await getServerSideSiteTranslations(locale, locales), + i18nSite: await getServerSideSiteTranslations(locale, locales, ["template"]), preloadedReduxState: {}, }, }) diff --git a/src/server/utils/figureUtils.ts b/src/server/utils/figureUtils.ts index 23dd5bb8..39a9a663 100644 --- a/src/server/utils/figureUtils.ts +++ b/src/server/utils/figureUtils.ts @@ -1,9 +1,6 @@ -import { JSDOM } from "jsdom" import { optimize } from "svgo" -import { FigureDocument } from "~/types/resources" -import { extractMetadata } from "~/utils/figureUtils" -function optimizeSvg(source: string) { +export function optimizeSvg(source: string) { const { data } = optimize(source, { plugins: [ { @@ -20,13 +17,3 @@ function optimizeSvg(source: string) { return data } - -export function createFigureDocument(source: string): FigureDocument { - const dom = new JSDOM(source, { contentType: "image/svg+xml" }) - const meta = extractMetadata(dom.window.document, "med") - - return { - svg: optimizeSvg(source), - meta, - } -} diff --git a/src/server/utils/siteTranslations.ts b/src/server/utils/siteTranslations.ts index 8f92318e..fa1d50b1 100644 --- a/src/server/utils/siteTranslations.ts +++ b/src/server/utils/siteTranslations.ts @@ -1,6 +1,6 @@ import { Resource } from "i18next" import { GetServerSidePropsContext } from "next" -import { I18nSite, SiteLanguageOption } from "~/types/general" +import { I18nSite } from "~/types/general" import { createClient } from "./i18nServerClient" export const getServerSideSiteTranslations = async ( @@ -8,8 +8,8 @@ export const getServerSideSiteTranslations = async ( locales: GetServerSidePropsContext["locales"], additionalSiteNamespaces: string[] = [] ): Promise => { - const initialSiteLanguage = locale! as SiteLanguageOption - const supportedSiteLanguages = locales! as SiteLanguageOption[] + const initialSiteLanguage = locale! + const supportedSiteLanguages = locales! const siteNamespaces = [...additionalSiteNamespaces, "common"] const { i18n, initPromise } = createClient({ diff --git a/src/types/general.ts b/src/types/general.ts index 71d3d3e4..23dfefe0 100644 --- a/src/types/general.ts +++ b/src/types/general.ts @@ -5,17 +5,14 @@ import { NextPage } from "next" import { Session } from "next-auth" import { ReactElement, ReactNode } from "react" -export type SiteLanguage = "de" | "en" - export interface AppConfig { debugTranslations: boolean reactHookFormDevToolsEnabled: boolean } -export type SiteLanguageOption = SiteLanguage | "cimode" export interface I18nSite { - initialSiteLanguage: SiteLanguageOption - supportedSiteLanguages: SiteLanguageOption[] + initialSiteLanguage: string + supportedSiteLanguages: string[] siteNamespaces: string[] siteStore: Resource } diff --git a/src/types/resources.ts b/src/types/resources.ts deleted file mode 100644 index 6e9ee23c..00000000 --- a/src/types/resources.ts +++ /dev/null @@ -1,11 +0,0 @@ -export type FigureMetadata = { - lngs: string[] - title: { [lng: string]: string } - description: { [lng: string]: string } - options: { [id: string]: { [lng: string]: string } } -} - -export type FigureDocument = { - svg: string - meta: FigureMetadata -} diff --git a/src/utils/figureUtils.ts b/src/utils/figureUtils.ts deleted file mode 100644 index 6aa97b6c..00000000 --- a/src/utils/figureUtils.ts +++ /dev/null @@ -1,100 +0,0 @@ -import appConfig from "app.config" -import { FigureMetadata } from "~/types/resources" - -export interface TranslatedFigureMetadata { - title: string - description: string - options: { [id: string]: string } -} - -function extractText(el: Element, lng: string, ns: string = "med"): string { - const transName = ns ? `${ns}:Trans` : "Trans" - - let text = "" - for (const node of el.childNodes) { - if (node.nodeType === node.TEXT_NODE) { - text += node.textContent - } - if (node.nodeName === transName) { - const transEl = node as Element - const transLng = transEl.getAttribute("lng") - if (transLng === lng) { - text += transEl.textContent - } - } - } - - return text.trim() -} - -export function extractMetadata(doc: Document, ns: string = "med"): FigureMetadata { - let metadataEl = doc.querySelector("metadata") - if (!metadataEl) { - metadataEl = doc.createElementNS("http://www.w3.org/2000/svg", "metadata") - } - - ns = `${ns}\\:` - let figureEl = metadataEl.querySelector(`${ns}Figure`) - if (!figureEl) { - figureEl = metadataEl.querySelector("Figure") - ns = "" - } - - const lngs = figureEl - ?.getAttribute("lngs") - ?.split(",") - .map((lng) => lng.trim()) ?? ["en"] - - const meta: FigureMetadata = { - lngs, - title: {}, - description: {}, - options: {}, - } - - lngs.forEach((lng) => { - const titleEl = figureEl?.querySelector(`${ns}Title`) - meta.title[lng] = titleEl ? extractText(titleEl, lng) : "Untitled" - - const descriptionEl = figureEl?.querySelector(`${ns}Description`) - meta.description[lng] = descriptionEl ? extractText(descriptionEl, lng) : "" - - const optionEls = figureEl?.querySelectorAll(`${ns}Option`) ?? [] - for (const optionEl of optionEls) { - const optionId = optionEl.getAttribute("id") - if (!optionId) continue - - if (!(optionId in meta.options)) meta.options[optionId] = {} - meta.options[optionId][lng] = extractText(optionEl, lng) - } - }) - - return meta -} - -export function translateMetadata(meta: FigureMetadata, lng: string): TranslatedFigureMetadata { - const getTranslation = (prop: { [lng: string]: string }, defaultTranslation = ""): string => { - let trans = prop[lng] - if (!trans) { - for (const fallbackLng of appConfig.fallbackLanguages) { - trans = prop[fallbackLng] - if (trans) break - } - } - return trans ?? Object.values(prop)[0] ?? defaultTranslation - } - - const title = getTranslation(meta.title, "Untitled") - const description = getTranslation(meta.description) - const options = Object.fromEntries( - Object.entries(meta.options) - .map(([id, option]) => [id, getTranslation(option)]) - .filter(([_id, option]) => !!option) - ) - - return { - title, - description, - options, - } -} diff --git a/src/utils/localizationUtils.ts b/src/utils/localizationUtils.ts index b5a61d03..b69f8175 100644 --- a/src/utils/localizationUtils.ts +++ b/src/utils/localizationUtils.ts @@ -1,28 +1,15 @@ import DE from "dayjs/locale/de" -import EN_US from "dayjs/locale/en" import EN_GB from "dayjs/locale/en-gb" -import ES from "dayjs/locale/es" -import FR from "dayjs/locale/fr" -import IT from "dayjs/locale/it" -import NL from "dayjs/locale/nl" -import PT from "dayjs/locale/pt" -import SV from "dayjs/locale/sv" -import { SupportedLanguage } from "~/types/general" -const dateLocales: { [language in SupportedLanguage]: ILocale } = { - other: EN_GB, +const dateLocales: { [language: string]: ILocale } = { de: DE, - "en-US": EN_US, en: EN_GB, - es: ES, - fr: FR, - it: IT, - nl: NL, - pt: PT, - sv: SV, } -export function getDateLocale(language: SupportedLanguage): ILocale { +export function getDateLocale(language: string): ILocale { const dateLocale = dateLocales[language] + if (!dateLocale) { + throw new Error(`Missing date locale for language: ${language}`) + } return dateLocale }