feat(WEB-220): label translations

This commit is contained in:
Simon Emanuelsson
2024-05-22 10:27:16 +02:00
parent 125998efcf
commit de79c2dc80
80 changed files with 1104 additions and 460 deletions

View File

@@ -8,8 +8,7 @@ import Shortcuts from "@/components/MyPages/Blocks/Shortcuts"
import PreviousStays from "@/components/MyPages/Blocks/Stays/Previous"
import SoonestStays from "@/components/MyPages/Blocks/Stays/Soonest"
import UpcomingStays from "@/components/MyPages/Blocks/Stays/Upcoming"
import { ExpiringPoints } from "../Blocks/Points/ExpiringPoints"
import { removeMultipleSlashes } from "@/utils/url"
import {
AccountPageContentProps,
@@ -56,7 +55,9 @@ export default function Content({ lang, content }: ContentProps) {
href:
item.dynamic_content.link.linkConnection.edges[0].node
.original_url ||
`/${lang}${item.dynamic_content.link.linkConnection.edges[0].node.url}`,
removeMultipleSlashes(
`/${lang}/${item.dynamic_content.link.linkConnection.edges[0].node.url}`
),
text: item.dynamic_content.link.link_text,
}
: null

View File

@@ -23,19 +23,16 @@
}
.card {
flex: 1 1 0px;
text-decoration: none;
align-items: center;
background-color: var(--UI-Grey-10);
border-radius: 4px;
color: var(--Theme-Primary-Light-On-Surface-Text);
display: flex;
flex: 1 1 0px;
flex-direction: column;
gap: 10px;
min-height: 280px;
background-color: var(--UI-Grey-10);
justify-content: center;
align-items: center;
min-height: 280px;
padding: 30px;
border-radius: 4px;
text-decoration: none;
text-align: center;
color: var(--Theme-Primary-Light-On-Surface-Text);
}

View File

@@ -1,10 +1,9 @@
import Link from "next/link"
import { Lang } from "@/constants/languages"
import { serverClient } from "@/lib/trpc/server"
import Header from "@/components/MyPages/Blocks/Header"
import CardGrid from "@/components/TempDesignSystem/CardGrid"
import Link from "@/components/TempDesignSystem/Link"
import Title from "@/components/TempDesignSystem/Text/Title"
import levelsData from "../data"

View File

@@ -1,4 +1,3 @@
import Link from "next/link"
import { Lock } from "react-feather"
import { serverClient } from "@/lib/trpc/server"
@@ -6,6 +5,8 @@ import { serverClient } from "@/lib/trpc/server"
import Header from "@/components/MyPages/Blocks/Header"
import Button from "@/components/TempDesignSystem/Button"
import CardGrid from "@/components/TempDesignSystem/CardGrid"
import Link from "@/components/TempDesignSystem/Link"
import { getIntl } from "@/i18n"
import styles from "./next.module.css"
@@ -17,7 +18,7 @@ export default async function NextLevelBenefitsBlock({
link,
}: AccountPageComponentProps) {
const { nextLevel, perks } = await serverClient().user.benefits.nextLevel()
const { formatMessage } = await getIntl()
return (
<section className={styles.container}>
<Header title={title} subtitle={subtitle} link={link} />
@@ -26,7 +27,7 @@ export default async function NextLevelBenefitsBlock({
<article key={perk.id} className={styles.card}>
<Button type="button" disabled>
<Lock height={16} />
Level up to unlock
{formatMessage({ id: "Level up to unlock" })}
</Button>
<div>
<span className={styles.level}>As our {nextLevel}</span>{" "}
@@ -36,9 +37,9 @@ export default async function NextLevelBenefitsBlock({
))}
</CardGrid>
<div className={styles.buttonContainer}>
<Button intent="primary" asChild>
<Link href="#" className={styles.buttonText}>
Explore all levels and benefits
<Button asChild intent="primary">
<Link href="#">
{formatMessage({ id: "Explore all levels and benefits" })}
</Link>
</Button>
</div>

View File

@@ -45,20 +45,11 @@
justify-content: center;
}
.buttonText {
text-decoration: none;
}
@media screen and (min-width: 1367px) {
@media screen and (min-width: 950px) {
.cardContainer {
grid-template-columns: 1fr 1fr 1fr;
}
.level {
font-size: var(--typography-Script-Desktop-fontSize);
font-weight: var(--typography-Script-Desktop-fontWeight);
}
.cardSubtitle {
font-size: var(--typography-Subtitle-Desktop-fontSize, 18px);
}

View File

@@ -1,21 +1,26 @@
import { _ } from "@/lib/translation"
import Image from "@/components/Image"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import styles from "./challenges.module.css"
import type { ChallengesProps } from "@/types/components/myPages/myPage/challenges"
export default function Challenges({ journeys, victories }: ChallengesProps) {
export default async function Challenges({
journeys,
victories,
}: ChallengesProps) {
const { formatMessage } = await getIntl()
return (
<section className={styles.challenges}>
<header className={styles.header}>
<Title level="h2">{_("Your Challenges Conquer & Earn!")}</Title>
<Title level="h2">
{formatMessage({ id: "Your Challenges Conquer & Earn!" })}
</Title>
</header>
<section className={styles.section}>
<header>
<Title level="h3">{_("On your journey")}</Title>
<Title level="h3">{formatMessage({ id: "On your journey" })}</Title>
</header>
<section className={styles.journeys}>
{journeys.map((journey) => (
@@ -28,7 +33,9 @@ export default function Challenges({ journeys, victories }: ChallengesProps) {
</section>
<aside className={styles.aside}>
<header>
<Title level="h3">{_("Previous victories")}</Title>
<Title level="h3">
{formatMessage({ id: "Previous victories" })}
</Title>
</header>
<section className={styles.victories}>
{victories.map((victory) => (

View File

@@ -22,7 +22,7 @@ export default function Header({
{title}
</Title>
{link && (
<Link className={styles.link} href={link.href}>
<Link className={styles.link} href={link.href} variant="myPage">
{link.text}
</Link>
)}

View File

@@ -1,22 +0,0 @@
"use client"
import Image from "@/components/Image"
import Button from "@/components/TempDesignSystem/Button"
import styles from "./btn.module.css"
export default function MembershipCardButton() {
function handleShowMembershipCard() {
console.log(`Showing membership card`)
}
return (
<Button
className={styles.membershipBtn}
onClick={handleShowMembershipCard}
type="button"
>
<span>Membership Card</span>
<Image alt="QR icon" height={20} src="/_static/icons/qr.svg" width={20} />
</Button>
)
}

View File

@@ -1,19 +1,19 @@
import { _ } from "@/lib/translation"
import { GoodFriend } from "@/components/Levels"
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import styles from "./friend.module.css"
import type { UserProps } from "@/types/components/myPages/user"
export default function Friend({ user }: UserProps) {
export default async function Friend({ user }: UserProps) {
const { formatMessage } = await getIntl()
return (
<section className={styles.friend}>
<header className={styles.header}>
<BiroScript className={styles.levelLabel} color="pale">
Current level:
{formatMessage({ id: "Current level" })}:
</BiroScript>
<GoodFriend className={styles.level} color="pale" />
</header>
@@ -22,7 +22,9 @@ export default function Friend({ user }: UserProps) {
{user.name}
</Title>
<div className={styles.membershipContainer}>
<p className={styles.membershipId}>{_("Membership ID:")}</p>
<p className={styles.membershipId}>
{formatMessage({ id: "Membership ID" })}:
</p>
<p className={styles.membershipId}>
{user.membership ? user.membership.membershipNumber : "N/A"}
</p>

View File

@@ -1,7 +1,6 @@
import { _ } from "@/lib/translation"
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import Label from "../Label"
@@ -9,13 +8,14 @@ import styles from "./nextLevel.module.css"
import type { UserProps } from "@/types/components/myPages/user"
export default function NextLevel({}: UserProps) {
export default async function NextLevel({}: UserProps) {
const { formatMessage } = await getIntl()
return (
<section>
<Label>{_("Next level")}:</Label>
<Label>{formatMessage({ id: "Next level" })}:</Label>
<Title className={styles.nextLevel} color="pale" level="h3">
{_("Close friend")}
<BiroScript>{_("Coming up")}!</BiroScript>
N/A
<BiroScript>{formatMessage({ id: "Coming up" })}!</BiroScript>
</Title>
</section>
)

View File

@@ -7,6 +7,7 @@
@media screen and (min-width: 768px) {
.nextLevel {
gap: var(--Spacing-x1);
grid-template-columns: 1fr auto;
grid-template-columns: auto auto;
justify-content: flex-start;
}
}

View File

@@ -1,4 +1,5 @@
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import Label from "../Label"
@@ -6,17 +7,18 @@ import styles from "./totalPoints.module.css"
import type { UserProps } from "@/types/components/myPages/user"
export default function Points({ user }: UserProps) {
export default async function Points({ user }: UserProps) {
const { formatMessage } = await getIntl()
return (
<section className={styles.points}>
<article>
<Label>Total Points</Label>
<Label>{formatMessage({ id: "Total Points" })}</Label>
<Title color="pale" level="h2">
{user.membership ? user.membership.currentPoints : "N/A"}
</Title>
</article>
<article>
<Label>Points until next level</Label>
<Label>{formatMessage({ id: "Points until next level" })}</Label>
<Title color="pale" level="h2">
{user.membership ? user.membership.currentPoints : "N/A"}
</Title>

View File

@@ -1,7 +1,7 @@
import { _ } from "@/lib/translation"
import { serverClient } from "@/lib/trpc/server"
import Header from "@/components/MyPages/Blocks/Header"
import { getIntl } from "@/i18n"
import styles from "./currentPointsBalance.module.css"
@@ -14,17 +14,18 @@ async function CurrentPointsBalance({
lang,
}: AccountPageComponentProps) {
const user = await serverClient().user.get()
const { formatMessage } = await getIntl()
return (
<div>
<Header title={title} link={link} subtitle={subtitle} />
<div className={styles.card}>
<h2>{`${_("Total points")}*`}</h2>
<h2>{`${formatMessage({ id: "Total points" })}*`}</h2>
<p
className={styles.points}
>{`${_("Points")}: ${user.membership?.currentPoints || "N/A"}`}</p>
>{`${formatMessage({ id: "Points" })}: ${user.membership?.currentPoints || "N/A"}`}</p>
<p className={styles.disclaimer}>
{`*${_("Points may take up to 10 days to be displayed.")}`}
{`*${formatMessage({ id: "Points may take up to 10 days to be displayed." })}`}
</p>
</div>
</div>

View File

@@ -1,11 +1,10 @@
"use client"
import { useIntl } from "react-intl"
import { dt } from "@/lib/dt"
import { _ } from "@/lib/translation"
import { trpc } from "@/lib/trpc/client"
import Header from "@/components/MyPages/Blocks/Header"
import Button from "@/components/TempDesignSystem/Button"
import styles from "./earnAndBurn.module.css"
@@ -13,11 +12,11 @@ import { AccountPageComponentProps } from "@/types/components/myPages/myPage/acc
import { Page, RowProps } from "@/types/components/myPages/myPage/earnAndBurn"
const tableHeadings = [
_("Arrival date"),
_("Description"),
_("Booking number"),
_("Transaction date"),
_("Points"),
"Arrival date",
"Description",
"Booking number",
"Transaction date",
"Points",
]
function EarnAndBurn({
@@ -26,7 +25,8 @@ function EarnAndBurn({
subtitle,
link,
}: AccountPageComponentProps) {
const { data, hasNextPage, isFetching, fetchNextPage } =
const intl = useIntl()
const { data, hasNextPage, fetchNextPage } =
trpc.user.transaction.friendTransactions.useInfiniteQuery(
{ limit: 5 },
{
@@ -49,8 +49,12 @@ function EarnAndBurn({
<table className={styles.mobileTable}>
<thead className={styles.mobileThead}>
<tr>
<th className={styles.mobileTh}>{_("Transactions")}</th>
<th className={styles.mobileTh}>{_("Points")}</th>
<th className={styles.mobileTh}>
{intl.formatMessage({ id: "Transactions" })}
</th>
<th className={styles.mobileTh}>
{intl.formatMessage({ id: "Points" })}
</th>
</tr>
</thead>
<tbody>
@@ -72,7 +76,7 @@ function EarnAndBurn({
<span>{`${transaction.hotelName}, ${transaction.city}`}</span>
) : null}
<span>
{`${transaction.nights} ${_(transaction.nights === 1 ? "night" : "nights")}`}
{`${transaction.nights} ${intl.formatMessage({ id: transaction.nights === 1 ? "night" : "nights" })}`}
</span>
</td>
<td
@@ -85,7 +89,7 @@ function EarnAndBurn({
) : (
<tr>
<td className={styles.mobilePlaceholder} colSpan={2}>
Empty
{intl.formatMessage({ id: "Empty" })}
</td>
</tr>
)}
@@ -99,7 +103,7 @@ function EarnAndBurn({
<tr>
{tableHeadings.map((heading) => (
<th key={heading} className={styles.th}>
{heading}
{intl.formatMessage({ id: heading })}
</th>
))}
</tr>
@@ -123,7 +127,7 @@ function EarnAndBurn({
// type="button"
// onClick={loadMoreData}
// >
// {_("See more transactions")}
// {intl.formatMessage({id:"See more transactions"})}
// </Button>
<table className={styles.table}>
<thead className={styles.thead}>
@@ -141,7 +145,7 @@ function EarnAndBurn({
colSpan={tableHeadings.length}
className={styles.placeholder}
>
{_("No transactions available")}
{intl.formatMessage({ id: "No transactions available" })}
</td>
</tr>
</tbody>
@@ -153,10 +157,11 @@ function EarnAndBurn({
}
function Row({ transaction, lang }: RowProps) {
const intl = useIntl()
const description =
transaction.hotelName && transaction.city
? `${_(transaction.hotelName)}, ${transaction.city} ${transaction.nights} ${_("nights")}`
: `${transaction.nights} ${_("nights")}`
? `${intl.formatMessage({ id: transaction.hotelName })}, ${transaction.city} ${transaction.nights} ${intl.formatMessage({ id: "nights" })}`
: `${transaction.nights} ${intl.formatMessage({ id: "nights" })}`
const arrival = dt(transaction.checkinDate).locale(lang).format("DD MMM YYYY")
const departure = dt(transaction.checkoutDate)
.locale(lang)

View File

@@ -1,14 +1,15 @@
import { _ } from "@/lib/translation"
import { getIntl } from "@/i18n"
import styles from "./expiringPoints.module.css"
export function ExpiringPoints() {
export async function ExpiringPoints() {
const { formatMessage } = await getIntl()
return (
<table className={styles.table}>
<thead className={styles.thead}>
<tr>
<th className={styles.th}>{_("Arrival date")}</th>
<th className={styles.th}>{_("Points")}</th>
<th className={styles.th}>{formatMessage({ id: "Arrival date" })}</th>
<th className={styles.th}>{formatMessage({ id: "Points" })}</th>
</tr>
</thead>
<tbody>

View File

@@ -1,14 +1,15 @@
import { _ } from "@/lib/translation"
import { useIntl } from "react-intl"
import Title from "@/components/TempDesignSystem/Text/Title"
import styles from "./emptyPreviousStays.module.css"
export default function EmptyPreviousStaysBlock() {
const { formatMessage } = useIntl()
return (
<section className={styles.container}>
<Title as="h5" level="h3">
{_("You have no previous stays.")}
{formatMessage({ id: "You have no previous stays." })}
</Title>
</section>
)

View File

@@ -1,3 +1,7 @@
"use client"
import { useIntl } from "react-intl"
import Button from "@/components/TempDesignSystem/Button"
import styles from "./button.module.css"
@@ -8,16 +12,17 @@ export default function ShowMoreButton({
disabled,
loadMoreData,
}: ShowMoreButtonParams) {
const { formatMessage } = useIntl()
return (
<div className={styles.container}>
<Button
disabled={disabled}
intent="primary"
theme="primaryDark"
type="button"
onClick={loadMoreData}
theme="secondaryDark"
type="button"
>
Show more
{formatMessage({ id: "Show more" })}
</Button>
</div>
)

View File

@@ -1,24 +1,24 @@
import { _ } from "@/lib/translation"
import Button from "@/components/TempDesignSystem/Button"
import Link from "@/components/TempDesignSystem/Link"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import styles from "./emptyUpcomingStays.module.css"
export default function EmptyUpcomingStaysBlock() {
export default async function EmptyUpcomingStaysBlock() {
const { formatMessage } = await getIntl()
return (
<section className={styles.container}>
<Title as="h5" level="h3">
{_("You have no upcoming stays.")}
{formatMessage({ id: "You have no upcoming stays." })}
<span className={styles.grayTitle}>
{" "}
{_("Where should you go next?")}
{formatMessage({ id: "Where should you go next?" })}
</span>
</Title>
<Button intent="primary" asChild type="button">
<Button asChild intent="primary" type="button">
<Link className={styles.link} href="#" key="getInspired">
{_("Get inspired")}
{formatMessage({ id: "Get inspired" })}
</Link>
</Button>
</section>

View File

@@ -1,6 +1,5 @@
import { serverClient } from "@/lib/trpc/server"
import MaxWidth from "@/components/MaxWidth"
import CardGrid from "@/components/TempDesignSystem/CardGrid"
import Header from "../../Header"

View File

@@ -1,4 +1,4 @@
import { _ } from "@/lib/translation"
import { useIntl } from "react-intl"
import Button from "@/components/TempDesignSystem/Button"
import Link from "@/components/TempDesignSystem/Link"
@@ -7,18 +7,19 @@ import Title from "@/components/TempDesignSystem/Text/Title"
import styles from "./emptyUpcomingStays.module.css"
export default function EmptyUpcomingStaysBlock() {
const { formatMessage } = useIntl()
return (
<section className={styles.container}>
<Title as="h5" level="h3">
{_("You have no upcoming stays.")}
{formatMessage({ id: "You have no upcoming stays." })}
<span className={styles.grayTitle}>
{" "}
{_("Where should you go next?")}
{formatMessage({ id: "Where should you go next?" })}
</span>
</Title>
<Button intent="primary" asChild type="button">
<Button asChild intent="primary" type="button">
<Link className={styles.link} href="#" key="getInspired">
{_("Get inspired")}
{formatMessage({ id: "Get inspired" })}
</Link>
</Button>
</section>

View File

@@ -1,6 +1,5 @@
"use client"
import { _ } from "@/lib/translation"
import { trpc } from "@/lib/trpc/client"
import LoadingSpinner from "@/components/LoadingSpinner"

View File

@@ -1,4 +1,3 @@
import { _ } from "@/lib/translation"
import { serverClient } from "@/lib/trpc/server"
import Breadcrumb from "./Breadcrumb"

View File

@@ -1,43 +0,0 @@
.user {
align-items: center;
background-color: var(--some-black-color, #000);
border-radius: 50%;
color: var(--some-white-color, #fff);
display: flex;
font-family: var(--typography-Body-Regular-fontFamily);
font-size: 1.2rem;
font-weight: 600;
height: 3.5rem;
justify-content: center;
position: relative;
width: 3.5rem;
}
.alert {
align-items: center;
background-color: var(--some-red-color, #ed2027);
border-radius: 50%;
display: flex;
font-size: 1rem;
height: 2rem;
justify-content: center;
position: absolute;
right: -1rem;
top: -0.5rem;
width: 2rem;
}
@media screen and (min-width: 1367px) {
.user {
height: 2.8rem;
width: 2.8rem;
}
.alert {
font-size: 0.6rem;
height: 1rem;
right: -0.2rem;
top: -0.1rem;
width: 1rem;
}
}

View File

@@ -6,6 +6,7 @@ import { serverClient } from "@/lib/trpc/server"
import Link from "@/components/TempDesignSystem/Link"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
import styles from "./sidebar.module.css"
@@ -13,6 +14,7 @@ import { LangParams } from "@/types/params"
export default async function Sidebar({ lang }: LangParams) {
const navigation = await serverClient().contentstack.myPages.navigation.get()
const { formatMessage } = await getIntl()
return (
<aside className={styles.sidebar}>
@@ -29,21 +31,21 @@ export default async function Sidebar({ lang }: LangParams) {
</Link>
{item.subItems
? item.subItems.map((subItem) => (
<Link
key={subItem.uid}
href={subItem.originalUrl || subItem.url}
partialMatch
variant="sidebar"
>
{subItem.linkText}
</Link>
))
<Link
key={subItem.uid}
href={subItem.originalUrl || subItem.url}
partialMatch
variant="sidebar"
>
{subItem.linkText}
</Link>
))
: null}
</Fragment>
))}
<Link prefetch={false} href={logout[lang]} variant="sidebar">
Log out <LogOut height={16} width={16} />
{formatMessage({ id: "Log out" })} <LogOut height={16} width={16} />
</Link>
</nav>
</aside>