fix: refactor dates (#1321)

## Description

Refactor the current date formatting system to utilize Lingui.

## Changes Made

- Remove redundant `LocaleData` component with Lingui dates

## Important notes

For the internal pages for certificates, default to en-US to format any
dates.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit


- **New Features**
- Enhanced internationalization support across various components by
utilizing the `i18n` object for date formatting.
- Streamlined locale management by removing cookie-based language
handling and adopting a more centralized approach.

- **Bug Fixes**
- Improved date formatting consistency by replacing the `LocaleDate`
component with direct calls to `i18n.date()` in multiple components.

- **Documentation**
- Updated localization strings in the `web.po` files to reflect recent
changes in the source code structure.

- **Chores**
- Minor formatting adjustments and code organization improvements across
various files to enhance readability and maintainability.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: github-actions <github-actions@documenso.com>
This commit is contained in:
David Nguyen
2024-09-10 12:38:08 +10:00
committed by GitHub
parent bfb09e7928
commit e81023f8d4
38 changed files with 573 additions and 712 deletions

View File

@ -5,19 +5,24 @@ import { useState } from 'react';
import { type Messages, setupI18n } from '@lingui/core';
import { I18nProvider } from '@lingui/react';
import type { I18nLocaleData } from '../../constants/i18n';
export function I18nClientProvider({
children,
initialLocale,
initialLocaleData,
initialMessages,
}: {
children: React.ReactNode;
initialLocale: string;
initialLocaleData: I18nLocaleData;
initialMessages: Messages;
}) {
const { lang, locales } = initialLocaleData;
const [i18n] = useState(() => {
return setupI18n({
locale: initialLocale,
messages: { [initialLocale]: initialMessages },
locale: lang,
locales: locales,
messages: { [lang]: initialMessages },
});
});

View File

@ -1,26 +1,26 @@
import 'server-only';
import { cookies } from 'next/headers';
import { cookies, headers } from 'next/headers';
import type { I18n, Messages } from '@lingui/core';
import { setupI18n } from '@lingui/core';
import { setI18n } from '@lingui/react/server';
import { IS_APP_WEB, IS_APP_WEB_I18N_ENABLED } from '../../constants/app';
import { IS_APP_WEB } from '../../constants/app';
import { SUPPORTED_LANGUAGE_CODES } from '../../constants/i18n';
import { extractSupportedLanguage } from '../../utils/i18n';
import { extractLocaleData } from '../../utils/i18n';
type SupportedLocales = (typeof SUPPORTED_LANGUAGE_CODES)[number];
type SupportedLanguages = (typeof SUPPORTED_LANGUAGE_CODES)[number];
async function loadCatalog(locale: SupportedLocales): Promise<{
async function loadCatalog(lang: SupportedLanguages): Promise<{
[k: string]: Messages;
}> {
const { messages } = await import(
`../../translations/${locale}/${IS_APP_WEB ? 'web' : 'marketing'}.js`
`../../translations/${lang}/${IS_APP_WEB ? 'web' : 'marketing'}.js`
);
return {
[locale]: messages,
[lang]: messages,
};
}
@ -31,18 +31,18 @@ export const allMessages = catalogs.reduce((acc, oneCatalog) => {
return { ...acc, ...oneCatalog };
}, {});
type AllI18nInstances = { [K in SupportedLocales]: I18n };
type AllI18nInstances = { [K in SupportedLanguages]: I18n };
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
export const allI18nInstances = SUPPORTED_LANGUAGE_CODES.reduce((acc, locale) => {
const messages = allMessages[locale] ?? {};
export const allI18nInstances = SUPPORTED_LANGUAGE_CODES.reduce((acc, lang) => {
const messages = allMessages[lang] ?? {};
const i18n = setupI18n({
locale,
messages: { [locale]: messages },
locale: lang,
messages: { [lang]: messages },
});
return { ...acc, [locale]: i18n };
return { ...acc, [lang]: i18n };
}, {}) as AllI18nInstances;
/**
@ -50,24 +50,23 @@ export const allI18nInstances = SUPPORTED_LANGUAGE_CODES.reduce((acc, locale) =>
*
* https://lingui.dev/tutorials/react-rsc#pages-layouts-and-lingui
*/
export const setupI18nSSR = (overrideLang?: SupportedLocales) => {
let lang =
overrideLang ||
extractSupportedLanguage({
cookies: cookies(),
});
// Override web app to be English.
if (!IS_APP_WEB_I18N_ENABLED && IS_APP_WEB) {
lang = 'en';
}
export const setupI18nSSR = () => {
const { lang, locales } = extractLocaleData({
cookies: cookies(),
headers: headers(),
});
// Get and set a ready-made i18n instance for the given language.
const i18n = allI18nInstances[lang];
// Reactivate the i18n instance with the locale for date and number formatting.
i18n.activate(lang, locales);
setI18n(i18n);
return {
lang,
locales,
i18n,
};
};

View File

@ -1,37 +0,0 @@
'use client';
import { createContext, useContext } from 'react';
export type LocaleContextValue = {
locale: string;
};
export const LocaleContext = createContext<LocaleContextValue | null>(null);
export const useLocale = () => {
const context = useContext(LocaleContext);
if (!context) {
throw new Error('useLocale must be used within a LocaleProvider');
}
return context;
};
export function LocaleProvider({
children,
locale,
}: {
children: React.ReactNode;
locale: string;
}) {
return (
<LocaleContext.Provider
value={{
locale: locale,
}}
>
{children}
</LocaleContext.Provider>
);
}