Files
web/components/Loyalty/Blocks/DynamicContent/OverviewTable/index.tsx
2024-06-20 15:26:55 +02:00

356 lines
11 KiB
TypeScript

"use client"
import { useParams } from "next/navigation"
import { useReducer } from "react"
import { type Key } from "react-aria-components"
import { useIntl } from "react-intl"
import { Lang } from "@/constants/languages"
import { membershipLevels } from "@/constants/membershipLevels"
import Image from "@/components/Image"
import Select from "@/components/TempDesignSystem/Select"
import { getMembership } from "@/utils/user"
import DA from "./data/DA.json"
import DE from "./data/DE.json"
import EN from "./data/EN.json"
import FI from "./data/FI.json"
import NO from "./data/NO.json"
import SV from "./data/SV.json"
import BenefitList from "./BenefitList"
import LargeTable from "./LargeTable"
import LevelSummary from "./LevelSummary"
import OverviewTableTitle from "./Title"
import styles from "./overviewTable.module.css"
import {
ComparisonLevel,
overviewTableActionsEnum,
OverviewTableProps,
OverviewTableReducerAction,
} from "@/types/components/loyalty/blocks"
import { LangParams } from "@/types/params"
import { User } from "@/types/user"
const levelsTranslations = {
[Lang.en]: EN,
[Lang.sv]: SV,
[Lang.no]: NO,
[Lang.da]: DA,
[Lang.fi]: FI,
[Lang.de]: DE,
}
// These should ultimately be fetched from Contentstack
const titleTranslations = {
[Lang.en]: [
{ text: "7 delightful levels", highlight: true },
{ text: "of friendship", highlight: false },
],
// TODO: Add translations for the following languages
[Lang.da]: [
{ text: "7 delightful levels", highlight: true },
{ text: "of friendship", highlight: false },
],
[Lang.no]: [
{ text: "7 delightful levels", highlight: true },
{ text: "of friendship", highlight: false },
],
[Lang.sv]: [
{ text: "7 delightful levels", highlight: true },
{ text: "of friendship", highlight: false },
],
[Lang.fi]: [
{ text: "7 delightful levels", highlight: true },
{ text: "of friendship", highlight: false },
],
[Lang.de]: [
{ text: "7 delightful levels", highlight: true },
{ text: "of friendship", highlight: false },
],
}
function getTranslatedLevelByTier(tier: membershipLevels, lang: Lang) {
return levelsTranslations[lang].levels.find(
(level) => level.tier === tier
) as ComparisonLevel
}
function getInitialState({ user, lang }: { user?: User; lang: Lang }) {
const membership = user?.memberships ? getMembership(user.memberships) : null
if (!membership?.membershipLevel) {
return {
selectedLevelAMobile: getTranslatedLevelByTier(1, lang),
selectedLevelBMobile: getTranslatedLevelByTier(2, lang),
selectedLevelADesktop: getTranslatedLevelByTier(1, lang),
selectedLevelBDesktop: getTranslatedLevelByTier(2, lang),
selectedLevelCDesktop: getTranslatedLevelByTier(3, lang),
}
}
if (!membership.membershipLevel) return null
const tier = membershipLevels[membership.membershipLevel]
switch (tier) {
case 6:
return {
selectedLevelAMobile: getTranslatedLevelByTier(6, lang),
selectedLevelBMobile: getTranslatedLevelByTier(7, lang),
selectedLevelADesktop: getTranslatedLevelByTier(5, lang),
selectedLevelBDesktop: getTranslatedLevelByTier(6, lang),
selectedLevelCDesktop: getTranslatedLevelByTier(7, lang),
}
case 7:
return {
selectedLevelAMobile: getTranslatedLevelByTier(6, lang),
selectedLevelBMobile: getTranslatedLevelByTier(7, lang),
selectedLevelADesktop: getTranslatedLevelByTier(6, lang),
selectedLevelBDesktop: getTranslatedLevelByTier(7, lang),
selectedLevelCDesktop: getTranslatedLevelByTier(1, lang),
}
default:
return {
selectedLevelAMobile: getTranslatedLevelByTier(tier, lang),
selectedLevelBMobile: getTranslatedLevelByTier(tier + 1, lang),
selectedLevelADesktop: getTranslatedLevelByTier(tier, lang),
selectedLevelBDesktop: getTranslatedLevelByTier(tier + 1, lang),
selectedLevelCDesktop: getTranslatedLevelByTier(tier + 2, lang),
}
}
}
function reducer(state: any, action: OverviewTableReducerAction) {
switch (action.type) {
case overviewTableActionsEnum.SET_SELECTED_LEVEL_A_MOBILE:
return {
...state,
selectedLevelAMobile: action.payload,
}
case overviewTableActionsEnum.SET_SELECTED_LEVEL_B_MOBILE:
return {
...state,
selectedLevelBMobile: action.payload,
}
case overviewTableActionsEnum.SET_SELECTED_LEVEL_A_DESKTOP:
return {
...state,
selectedLevelADesktop: action.payload,
}
case overviewTableActionsEnum.SET_SELECTED_LEVEL_B_DESKTOP:
return {
...state,
selectedLevelBDesktop: action.payload,
}
case overviewTableActionsEnum.SET_SELECTED_LEVEL_C_DESKTOP:
return {
...state,
selectedLevelCDesktop: action.payload,
}
default:
return state
}
}
export default function OverviewTable({ user }: OverviewTableProps) {
const intl = useIntl()
const params = useParams<LangParams>()
const levelsData = levelsTranslations[params.lang]
const [selectionState, dispatch] = useReducer(
reducer,
{ user, lang: params.lang },
getInitialState
)
function handleSelectChange(actionType: overviewTableActionsEnum) {
return (key: Key) => {
if (typeof key === "number") {
dispatch({
payload: getTranslatedLevelByTier(key, params.lang),
type: actionType,
})
}
}
}
const levelOptions = levelsData.levels.map((level) => ({
label: level.name,
value: level.tier,
}))
return (
<div className={styles.container}>
<div className={styles.intro}>
<OverviewTableTitle texts={titleTranslations[Lang.en]} />
<p className={styles.preamble}>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Arcu risus
quis varius quam quisque id diam vel. Rhoncus urna neque viverra
justo. Mattis aliquam faucibus purus in massa. Id cursus metus aliquam
eleifend mi in nulla posuere.
</p>
</div>
<div className={styles.mobileColumns}>
<div className={styles.columnHeaderContainer}>
<div className={styles.columnHeader}>
<Select
name="benefitA"
label={intl.formatMessage({ id: "Level" })}
items={levelOptions}
value={selectionState.selectedLevelAMobile.tier}
onSelect={handleSelectChange(
overviewTableActionsEnum.SET_SELECTED_LEVEL_A_MOBILE
)}
/>
<Image
className={styles.icon}
src={selectionState.selectedLevelAMobile.icon}
alt={selectionState.selectedLevelAMobile.name}
height={50}
width={100}
/>
<LevelSummary
level={
levelsData.levels.find(
(level) =>
level.tier === selectionState.selectedLevelAMobile.tier
) as ComparisonLevel
}
/>
</div>
<div className={styles.columnHeader}>
<Select
name="benefitB"
label={intl.formatMessage({ id: "Level" })}
items={levelOptions}
value={selectionState.selectedLevelBMobile.tier}
onSelect={handleSelectChange(
overviewTableActionsEnum.SET_SELECTED_LEVEL_B_MOBILE
)}
/>
<Image
className={styles.icon}
src={selectionState.selectedLevelBMobile.icon}
alt={selectionState.selectedLevelBMobile.name}
height={50}
width={100}
/>
<LevelSummary
level={
levelsData.levels.find(
(level) =>
level.tier === selectionState.selectedLevelBMobile.tier
) as ComparisonLevel
}
/>
</div>
</div>
<BenefitList
levels={[
selectionState.selectedLevelAMobile,
selectionState.selectedLevelBMobile,
]}
/>
</div>
<div className={styles.columns}>
<div className={styles.columnHeaderContainer}>
<div className={styles.columnHeader}>
<Select
name="benefitA"
label={intl.formatMessage({ id: "Level" })}
items={levelOptions}
value={selectionState.selectedLevelADesktop.tier}
onSelect={handleSelectChange(
overviewTableActionsEnum.SET_SELECTED_LEVEL_A_DESKTOP
)}
/>
<Image
className={styles.icon}
src={selectionState.selectedLevelADesktop.icon}
alt={selectionState.selectedLevelADesktop.name}
height={50}
width={100}
/>
<LevelSummary
level={
levelsData.levels.find(
(level) =>
level.tier === selectionState.selectedLevelADesktop.tier
) as ComparisonLevel
}
/>
</div>
<div className={styles.columnHeader}>
<Select
name="benefitB"
label={intl.formatMessage({ id: "Level" })}
items={levelOptions}
value={selectionState.selectedLevelBDesktop.tier}
onSelect={handleSelectChange(
overviewTableActionsEnum.SET_SELECTED_LEVEL_B_DESKTOP
)}
/>
<Image
className={styles.icon}
src={selectionState.selectedLevelBDesktop.icon}
alt={selectionState.selectedLevelBDesktop.name}
height={50}
width={100}
/>
<LevelSummary
level={
levelsData.levels.find(
(level) =>
level.tier === selectionState.selectedLevelBDesktop.tier
) as ComparisonLevel
}
/>
</div>
<div className={styles.columnHeader}>
<Select
name="benefitC"
label={intl.formatMessage({ id: "Level" })}
items={levelOptions}
value={selectionState.selectedLevelCDesktop.tier}
onSelect={handleSelectChange(
overviewTableActionsEnum.SET_SELECTED_LEVEL_C_DESKTOP
)}
/>
<Image
className={styles.icon}
src={selectionState.selectedLevelCDesktop.icon}
alt={selectionState.selectedLevelCDesktop.name}
height={50}
width={100}
/>
<LevelSummary
level={
levelsData.levels.find(
(level) =>
level.tier === selectionState.selectedLevelCDesktop.tier
) as ComparisonLevel
}
/>
</div>
</div>
<BenefitList
levels={[
selectionState.selectedLevelADesktop,
selectionState.selectedLevelBDesktop,
selectionState.selectedLevelCDesktop,
]}
/>
</div>
<div className={styles.largeTableContainer}>
{/* Remove `as` once we have real data */}
<LargeTable levels={levelsData.levels as ComparisonLevel[]} />
</div>
</div>
)
}