fix: refactor OverviewTableClient

This commit is contained in:
Christel Westerberg
2024-09-26 11:51:48 +02:00
parent 56cd02f90b
commit 2a5a3126fe
7 changed files with 146 additions and 133 deletions

View File

@@ -5,7 +5,7 @@ import { z } from "zod"
import { Lang } from "@/constants/languages" import { Lang } from "@/constants/languages"
import { env } from "@/env/server" import { env } from "@/env/server"
import { internalServerError } from "@/server/errors/next" import { badRequest, internalServerError, notFound } from "@/server/errors/next"
import { generateLoyaltyConfigTag } from "@/utils/generateTag" import { generateLoyaltyConfigTag } from "@/utils/generateTag"
@@ -37,15 +37,7 @@ export async function POST(request: NextRequest) {
if (secret !== env.REVALIDATE_SECRET) { if (secret !== env.REVALIDATE_SECRET) {
console.error(`Invalid Secret`) console.error(`Invalid Secret`)
console.error({ secret }) console.error({ secret })
return Response.json( return badRequest({ revalidated: false, now: Date.now() })
{
now: Date.now(),
revalidated: false,
},
{
status: 400,
}
)
} }
const data = await request.json() const data = await request.json()
@@ -85,10 +77,7 @@ export async function POST(request: NextRequest) {
) )
} else { } else {
console.error("Invalid content_type") console.error("Invalid content_type")
return Response.json( return notFound({ revalidated: false, now: Date.now() })
{ revalidated: false, now: Date.now() },
{ status: 404 }
)
} }
console.info(`Revalidating loyalty config tag: ${tag}`) console.info(`Revalidating loyalty config tag: ${tag}`)

View File

@@ -10,10 +10,10 @@ import {
import MembershipLevelIcon from "@/components/Levels/Icon" import MembershipLevelIcon from "@/components/Levels/Icon"
import Select from "@/components/TempDesignSystem/Select" import Select from "@/components/TempDesignSystem/Select"
import { getSteppedUpLevel } from "@/utils/user"
import LargeTable from "./LargeTable" import LargeTable from "./LargeTable"
import LevelSummary from "./LevelSummary" import LevelSummary from "./LevelSummary"
import { getInitialState, getLevel, reducer } from "./reducer"
import RewardList from "./RewardList" import RewardList from "./RewardList"
import YourLevel from "./YourLevelScript" import YourLevel from "./YourLevelScript"
@@ -24,11 +24,9 @@ import type { Key } from "react-aria-components"
import { import {
ComparisonLevel, ComparisonLevel,
DesktopSelectColumns, DesktopSelectColumns,
LevelWithRewards,
type MobileColumnHeaderProps, type MobileColumnHeaderProps,
OverviewTableActionsEnum, OverviewTableActionsEnum,
type OverviewTableClientProps, type OverviewTableClientProps,
OverviewTableReducerAction,
} from "@/types/components/overviewTable" } from "@/types/components/overviewTable"
function getLevelNamesForSelect(level: MembershipLevel, levelName: string) { function getLevelNamesForSelect(level: MembershipLevel, levelName: string) {
@@ -36,89 +34,7 @@ function getLevelNamesForSelect(level: MembershipLevel, levelName: string) {
return [levelToNumber, levelName].join(" - ") return [levelToNumber, levelName].join(" - ")
} }
function getLevel( export default function OverviewTableClient({
membershipLevel: MembershipLevel,
levels: LevelWithRewards[]
) {
return levels.find((level) => level.level_id === membershipLevel)!
}
function getInitialState({
activeMembership,
levels,
}: OverviewTableClientProps) {
if (!activeMembership) {
return {
selectedLevelAMobile: getLevel(MembershipLevelEnum.L1, levels),
selectedLevelBMobile: getLevel(MembershipLevelEnum.L2, levels),
selectedLevelADesktop: getLevel(MembershipLevelEnum.L1, levels),
selectedLevelBDesktop: getLevel(MembershipLevelEnum.L2, levels),
selectedLevelCDesktop: getLevel(MembershipLevelEnum.L3, levels),
}
}
const level = MembershipLevelEnum[activeMembership]
switch (level) {
case MembershipLevelEnum.L6:
return {
selectedLevelAMobile: getLevel(MembershipLevelEnum.L6, levels),
selectedLevelBMobile: getLevel(MembershipLevelEnum.L7, levels),
selectedLevelADesktop: getLevel(MembershipLevelEnum.L5, levels),
selectedLevelBDesktop: getLevel(MembershipLevelEnum.L6, levels),
selectedLevelCDesktop: getLevel(MembershipLevelEnum.L7, levels),
}
case MembershipLevelEnum.L7:
return {
selectedLevelAMobile: getLevel(MembershipLevelEnum.L6, levels),
selectedLevelBMobile: getLevel(MembershipLevelEnum.L7, levels),
selectedLevelADesktop: getLevel(MembershipLevelEnum.L6, levels),
selectedLevelBDesktop: getLevel(MembershipLevelEnum.L7, levels),
selectedLevelCDesktop: getLevel(MembershipLevelEnum.L1, levels),
}
default:
return {
selectedLevelAMobile: getLevel(level, levels),
selectedLevelBMobile: getLevel(getSteppedUpLevel(level, 1), levels),
selectedLevelADesktop: getLevel(level, levels),
selectedLevelBDesktop: getLevel(getSteppedUpLevel(level, 1), levels),
selectedLevelCDesktop: getLevel(getSteppedUpLevel(level, 2), levels),
}
}
}
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({
activeMembership, activeMembership,
levels, levels,
}: OverviewTableClientProps) { }: OverviewTableClientProps) {

View File

@@ -22,7 +22,7 @@ export default function LargeTable({
activeLevel, activeLevel,
Select, Select,
}: LargeTableProps) { }: LargeTableProps) {
const groupedRewards = getGroupedRewards(levels) const keyedGroupedRewards = getGroupedRewards(levels)
return ( return (
<table className={styles.table}> <table className={styles.table}>
@@ -32,27 +32,34 @@ export default function LargeTable({
Select={Select} Select={Select}
/> />
<tbody className={styles.tbody}> <tbody className={styles.tbody}>
{Object.entries(groupedRewards).map(([key, groupedRewards], idx) => { {Object.entries(keyedGroupedRewards).map(
const { label, description } = ([key, groupedRewards], idx) => {
getGroupedLabelAndDescription(groupedRewards) const { label, description } =
getGroupedLabelAndDescription(groupedRewards)
return ( return (
<tr key={key + idx} className={styles.tr}> <tr key={key + idx} className={styles.tr}>
<th scope={"row"} className={styles.rewardTh}> <th scope={"row"} className={styles.rewardTh}>
<RewardTableHeader name={label} description={description} /> <RewardTableHeader name={label} description={description} />
</th> </th>
{levels.map((level, idx) => { {levels.map((level, idx) => {
const rewardIdsInGroup = groupedRewards.map((b) => b.reward_id) const rewardIdsInGroup = groupedRewards.map(
const reward = findAvailableRewards(rewardIdsInGroup, level) (b) => b.reward_id
return ( )
<td key={`${reward?.reward_id}-${idx}`} className={styles.td}> const reward = findAvailableRewards(rewardIdsInGroup, level)
<RewardValue reward={reward} /> return (
</td> <td
) key={`${reward?.reward_id}-${idx}`}
})} className={styles.td}
</tr> >
) <RewardValue reward={reward} />
})} </td>
)
})}
</tr>
)
}
)}
</tbody> </tbody>
</table> </table>
) )

View File

@@ -11,9 +11,9 @@ import styles from "./rewardList.module.css"
import type { RewardListProps } from "@/types/components/overviewTable" import type { RewardListProps } from "@/types/components/overviewTable"
export default function RewardList({ levels }: RewardListProps) { export default function RewardList({ levels }: RewardListProps) {
const groupedRewards = getGroupedRewards(levels) const keyedGroupedRewards = getGroupedRewards(levels)
return Object.values(groupedRewards).map((groupedRewards) => { return Object.values(keyedGroupedRewards).map((groupedRewards) => {
const rewardIdsInGroup = groupedRewards.map((b) => b.reward_id) const rewardIdsInGroup = groupedRewards.map((b) => b.reward_id)
const { label, description } = getGroupedLabelAndDescription(groupedRewards) const { label, description } = getGroupedLabelAndDescription(groupedRewards)

View File

@@ -0,0 +1,95 @@
import {
type MembershipLevel,
MembershipLevelEnum,
} from "@/constants/membershipLevels"
import { getSteppedUpLevel } from "@/utils/user"
import {
type LevelWithRewards,
OverviewTableActionsEnum,
type OverviewTableClientProps,
OverviewTableReducerAction,
} from "@/types/components/overviewTable"
export function getLevel(
membershipLevel: MembershipLevel,
levels: LevelWithRewards[]
) {
return levels.find((level) => level.level_id === membershipLevel)!
}
export function getInitialState({
activeMembership,
levels,
}: OverviewTableClientProps) {
if (!activeMembership) {
return {
selectedLevelAMobile: getLevel(MembershipLevelEnum.L1, levels),
selectedLevelBMobile: getLevel(MembershipLevelEnum.L2, levels),
selectedLevelADesktop: getLevel(MembershipLevelEnum.L1, levels),
selectedLevelBDesktop: getLevel(MembershipLevelEnum.L2, levels),
selectedLevelCDesktop: getLevel(MembershipLevelEnum.L3, levels),
}
}
const level = MembershipLevelEnum[activeMembership]
switch (level) {
case MembershipLevelEnum.L6:
return {
selectedLevelAMobile: getLevel(MembershipLevelEnum.L6, levels),
selectedLevelBMobile: getLevel(MembershipLevelEnum.L7, levels),
selectedLevelADesktop: getLevel(MembershipLevelEnum.L5, levels),
selectedLevelBDesktop: getLevel(MembershipLevelEnum.L6, levels),
selectedLevelCDesktop: getLevel(MembershipLevelEnum.L7, levels),
}
case MembershipLevelEnum.L7:
return {
selectedLevelAMobile: getLevel(MembershipLevelEnum.L6, levels),
selectedLevelBMobile: getLevel(MembershipLevelEnum.L7, levels),
selectedLevelADesktop: getLevel(MembershipLevelEnum.L6, levels),
selectedLevelBDesktop: getLevel(MembershipLevelEnum.L7, levels),
selectedLevelCDesktop: getLevel(MembershipLevelEnum.L1, levels),
}
default:
return {
selectedLevelAMobile: getLevel(level, levels),
selectedLevelBMobile: getLevel(getSteppedUpLevel(level, 1), levels),
selectedLevelADesktop: getLevel(level, levels),
selectedLevelBDesktop: getLevel(getSteppedUpLevel(level, 1), levels),
selectedLevelCDesktop: getLevel(getSteppedUpLevel(level, 2), levels),
}
}
}
export 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
}
}

View File

@@ -40,9 +40,16 @@ export default function ClientCurrentRewards({
const filteredRewards = const filteredRewards =
data?.pages.filter((page) => page && page.rewards) ?? [] data?.pages.filter((page) => page && page.rewards) ?? []
const rewards = filteredRewards.flatMap((page) => page?.rewards) as Reward[] const rewards = filteredRewards.flatMap((page) => page?.rewards) as Reward[]
return isLoading ? (
<LoadingSpinner /> if (isLoading) {
) : rewards.length ? ( return <LoadingSpinner />
}
if (!rewards.length) {
return null
}
return (
<div> <div>
<Grids.Stackable> <Grids.Stackable>
{rewards.map((reward, idx) => ( {rewards.map((reward, idx) => (
@@ -58,13 +65,12 @@ export default function ClientCurrentRewards({
</article> </article>
))} ))}
</Grids.Stackable> </Grids.Stackable>
{hasNextPage ? ( {hasNextPage &&
isFetching ? ( (isFetching ? (
<LoadingSpinner /> <LoadingSpinner />
) : ( ) : (
<ShowMoreButton disabled={isFetching} loadMoreData={loadMoreData} /> <ShowMoreButton loadMoreData={loadMoreData} />
) ))}
) : null}
</div> </div>
) : null )
} }

View File

@@ -13,7 +13,7 @@ export const rewardsAllInput = z
.default({ unique: false }) .default({ unique: false })
export const rewardsCurrentInput = z.object({ export const rewardsCurrentInput = z.object({
limit: z.number().min(0).default(3), limit: z.number().min(1).default(3),
cursor: z.number().optional().default(0), cursor: z.number().optional().default(0),
lang: z.nativeEnum(Lang).optional(), lang: z.nativeEnum(Lang).optional(),
}) })