fix(i18n): prepare for Lokalise

This commit is contained in:
Michael Zetterberg
2025-01-03 14:54:46 +01:00
parent cbc17e2c5b
commit d2ce9c0d7c
120 changed files with 1703 additions and 1042 deletions

View File

@@ -5,11 +5,13 @@ import { overview } from "@/constants/routes/myPages"
import { getProfile } from "@/lib/trpc/memoizedRequests"
import { auth } from "@/auth"
import { getIntl } from "@/i18n"
import { getLang } from "@/i18n/serverContext"
export default async function ProtectedLayout({
children,
}: React.PropsWithChildren) {
const intl = await getIntl()
const session = await auth()
/**
* Fallback to make sure every route nested in the
@@ -54,7 +56,7 @@ export default async function ProtectedLayout({
console.error(`[layout:protected] unhandled user loading error`)
break
}
return <p>Something went wrong!</p>
return <p>{intl.formatMessage({ id: "Something went wrong!" })}</p>
}
if (!user) {

View File

@@ -1,12 +1,16 @@
"use client"
import * as Sentry from "@sentry/nextjs"
import { useEffect } from "react"
import { useIntl } from "react-intl"
export default function Error({
error,
}: {
error: Error & { digest?: string }
}) {
const intl = useIntl()
useEffect(() => {
if (!error) return
@@ -17,7 +21,12 @@ export default function Error({
return (
<p>
<strong>
Breadcrumbs failed for this page ({error.digest}@{Date.now()})
{intl.formatMessage(
{ id: "Breadcrumbs failed for this page ({errorId})" },
{
errorId: `${error.digest}@${Date.now()}`,
}
)}
</strong>
</p>
)

View File

@@ -2,12 +2,15 @@
import * as Sentry from "@sentry/nextjs"
import { useEffect } from "react"
import { useIntl } from "react-intl"
export default function Error({
error,
}: {
error: Error & { digest?: string }
}) {
const intl = useIntl()
useEffect(() => {
if (!error) return
@@ -18,7 +21,12 @@ export default function Error({
return (
<p>
<strong>
Error loading this page ({error.digest}@{Date.now()})
{intl.formatMessage(
{ id: "Error loading this page ({errorId})" },
{
errorId: `${error.digest}@${Date.now()}`,
}
)}
</strong>
</p>
)

View File

@@ -30,12 +30,43 @@ export default async function MembershipCardSlot({
membershipCards.map((card, idx) => (
<div className={styles.card} key={idx}>
<Subtitle className={styles.subTitle}>
Name: {card.membershipType}
{intl.formatMessage(
{ id: "Name: {cardMembershipType}" },
{
cardMembershipType: card.membershipType,
}
)}
</Subtitle>
<span> Current Points: {card.currentPoints} </span>
<span> Member Since: {card.memberSince}</span>
<span> Number: {card.membershipNumber}</span>
<span>Expiration Date: {card.expirationDate.split("T")[0]}</span>
<span>
{intl.formatMessage(
{ id: "Current Points {points, number}" },
{ points: card.currentPoints }
)}
</span>
<span>
{intl.formatMessage(
{ id: "Member Since: {value}" },
{
value: card.memberSince,
}
)}
</span>
<span>
{intl.formatMessage(
{ id: "Number: {membershipNumber}" },
{
membershipNumber: card.membershipNumber,
}
)}
</span>
<span>
{intl.formatMessage(
{ id: "Expiration Date: {expirationDate}" },
{
expirationDate: card.expirationDate.split("T")[0],
}
)}
</span>
</div>
))}
<Link href="#" variant="icon">

View File

@@ -2,10 +2,13 @@
import * as Sentry from "@sentry/nextjs"
import { useEffect } from "react"
import { useIntl } from "react-intl"
import type { ErrorPage } from "@/types/next/error"
export default function ProfileError({ error }: ErrorPage) {
const intl = useIntl()
useEffect(() => {
if (!error) return
@@ -13,5 +16,5 @@ export default function ProfileError({ error }: ErrorPage) {
Sentry.captureException(error)
}, [error])
return <h1>Error happened, Profile</h1>
return <h1>{intl.formatMessage({ id: "Error happened, Profile" })}</h1>
}

View File

@@ -30,6 +30,24 @@ export default async function Profile({ params }: PageArgs<LangParams>) {
return null
}
const addressParts = []
if (user.address.streetAddress) {
addressParts.push(user.address.streetAddress)
}
if (user.address.city) {
addressParts.push(user.address.city)
}
if (user.address.country) {
addressParts.push(user.address.country)
}
const addressOutput =
addressParts.length > 0
? addressParts.join(", ")
: intl.formatMessage({ id: "N/A" })
const defaultLanguage = languages[params.lang]
const language = languageSelect.find((l) => l.value === user.language)
return (
@@ -90,18 +108,7 @@ export default async function Profile({ params }: PageArgs<LangParams>) {
<Body color="burgundy" textTransform="bold">
{intl.formatMessage({ id: "Address" })}
</Body>
<Body color="burgundy">
{user.address.streetAddress
? `${user.address.streetAddress}, `
: ""}
{user.address.city ? `${user.address.city}, ` : ""}
{user.address.country ? `${user.address.country}` : ""}
{!user.address.streetAddress &&
!user.address.city &&
!user.address.country
? "N/A"
: null}
</Body>
<Body color="burgundy">{addressOutput}</Body>
</div>
<div className={styles.item}>
<LockIcon color="burgundy" />

View File

@@ -1,19 +1,13 @@
"use client" // Error components must be Client Components
"use client"
import * as Sentry from "@sentry/nextjs"
import {
useParams,
usePathname,
useRouter,
useSearchParams,
} from "next/navigation"
import { useParams, useRouter, useSearchParams } from "next/navigation"
import { startTransition, useEffect, useRef } from "react"
import { useIntl } from "react-intl"
import { login } from "@/constants/routes/handleAuth"
import { SESSION_EXPIRED } from "@/server/errors/trpc"
import { findLang } from "@/utils/languages"
import styles from "./error.module.css"
import type { LangParams } from "@/types/params"
@@ -63,13 +57,10 @@ export default function Error({
currentSearchParamsRef.current = currentSearchParams
}, [searchParams, reset, router])
const pathname = usePathname()
const lang = findLang(pathname)
return (
<section className={styles.layout}>
<div className={styles.content}>
{lang}: {intl.formatMessage({ id: "Something went wrong!" })}
{intl.formatMessage({ id: "Something went wrong!" })}
</div>
</section>
)

View File

@@ -1,17 +1,26 @@
import { getIntl } from "@/i18n"
import { setLang } from "@/i18n/serverContext"
import styles from "./page.module.css"
import type { LangParams, LayoutArgs, StatusParams } from "@/types/params"
export default function MiddlewareError({
export default async function MiddlewareError({
params,
}: LayoutArgs<LangParams & StatusParams>) {
setLang(params.lang)
const intl = await getIntl()
return (
<div className={styles.layout}>
Middleware Error {params.lang}: {params.status}
{intl.formatMessage(
{ id: "Middleware error {lang}: {status}" },
{
lang: params.lang,
status: params.status,
}
)}
</div>
)
}

View File

@@ -5,6 +5,7 @@ import { getProfile } from "@/lib/trpc/memoizedRequests"
import AccountPage from "@/components/Webviews/AccountPage"
import LoyaltyPage from "@/components/Webviews/LoyaltyPage"
import { getIntl } from "@/i18n"
import { setLang } from "@/i18n/serverContext"
import type {
@@ -18,11 +19,12 @@ export default async function ContentTypePage({
params,
}: PageArgs<LangParams & ContentTypeWebviewParams & UIDParams, {}>) {
setLang(params.lang)
const intl = await getIntl()
const user = await getProfile()
if (!user) {
console.log(`[webview:page] unable to load user`)
return <p>Error: No user could be loaded</p>
return <p>{intl.formatMessage({ id: "Error: No user could be loaded" })}</p>
}
if ("error" in user) {
@@ -36,9 +38,13 @@ export default async function ContentTypePage({
console.log(`[webview:page] user error, redirecting to: ${redirectURL}`)
redirect(redirectURL)
case "notfound":
return <p>Error: user not found</p>
return <p>{intl.formatMessage({ id: "Error: user not found" })}</p>
case "unknown":
return <p>Unknown error occurred loading user</p>
return (
<p>
{intl.formatMessage({ id: "Unknown error occurred loading user" })}
</p>
)
default:
const u: never = user
console.log(`[webview:page] unhandled user loading error`)