Files
web/apps/scandic-web/utils/rewards.ts
Christian Andolf f272dde1ef chore: remove unused filter modal
remove old cms model

refactor reward types
2025-03-26 09:55:26 +01:00

125 lines
3.3 KiB
TypeScript

import { RESTAURANT_REWARD_IDS, REWARD_IDS } from "@/constants/rewards"
import { dt } from "@/lib/dt"
import type { Dayjs } from "dayjs"
import type {
RestaurantRewardId,
RewardId,
} from "@/types/components/myPages/rewards"
import type {
ApiReward,
RedeemableCoupon,
RedeemLocation,
SurpriseReward,
} from "@/types/trpc/routers/contentstack/reward"
export {
getEarliestExpirationDate,
getFirstRedeemableCoupon,
getRedeemableRewards,
getReedemableCoupons,
getUnwrappedSurpriseRewards,
isOnSiteTierReward,
isRestaurantOnSiteTierReward,
isRestaurantReward,
isSurpriseReward,
isTierType,
isValidRewardId,
redeemLocationIsOnSite,
}
function isValidRewardId(id: string): id is RewardId {
return Object.values<string>(REWARD_IDS).includes(id)
}
function isRestaurantReward(rewardId: string): rewardId is RestaurantRewardId {
return RESTAURANT_REWARD_IDS.some((id) => id === rewardId)
}
function redeemLocationIsOnSite(
location: RedeemLocation
): location is "On-site" {
return location === "On-site"
}
function isTierType(type: string): type is "Tier" {
return type === "Tier"
}
function isOnSiteTierReward(reward: ApiReward): boolean {
return (
redeemLocationIsOnSite(reward.redeemLocation) &&
isTierType(reward.rewardType)
)
}
function isRestaurantOnSiteTierReward(reward: ApiReward): boolean {
return isOnSiteTierReward(reward) && isRestaurantReward(reward.rewardId)
}
function getReedemableCoupons(reward: ApiReward): RedeemableCoupon[] {
if ("coupon" in reward) {
return reward.coupon.filter(
(coupon): coupon is RedeemableCoupon => coupon.state !== "redeemed"
)
}
return []
}
function getFirstRedeemableCoupon(reward: ApiReward): RedeemableCoupon {
const sortedCoupons = getReedemableCoupons(reward).sort((a, b) => {
// null values used instead of undefined, otherwise it will return current time
return dt(a.expiresAt ?? null).valueOf() - dt(b.expiresAt ?? null).valueOf()
})
return sortedCoupons[0]
}
function getEarliestExpirationDate(reward: ApiReward) {
return getReedemableCoupons(reward)
.map(({ expiresAt }) => expiresAt)
.filter((expiresAt): expiresAt is string => !!expiresAt)
.reduce((earliestDate: Dayjs | null, expiresAt) => {
const expiresAtDate = dt(expiresAt)
if (!earliestDate) {
return expiresAtDate
}
return earliestDate.isBefore(expiresAtDate) ? earliestDate : expiresAtDate
}, null)
}
function isSurpriseReward(reward: ApiReward): reward is SurpriseReward {
return reward.rewardType === "Surprise"
}
function getUnwrappedSurpriseRewards(rewards: ApiReward[]) {
return rewards
.filter(isSurpriseReward)
.filter((reward) => getReedemableCoupons(reward).length)
.filter((reward) => {
const unwrappedCoupons =
reward.coupon.filter((coupon) => !coupon.unwrapped) || []
return unwrappedCoupons.length
})
}
function getRedeemableRewards(rewards: ApiReward[]) {
return rewards
.filter((reward) => {
if ("coupon" in reward && reward.coupon.length > 0) {
if (reward.coupon.every((coupon) => coupon.state === "redeemed")) {
return false
}
}
return true
})
.filter((reward) => {
if (isSurpriseReward(reward)) {
return !reward.coupon.some(({ unwrapped }) => !unwrapped)
}
return true
})
}