import { cx } from "class-variance-authority"
import { type ReactNode, Suspense } from "react"
import { Typography } from "@scandic-hotels/design-system/Typography"
import { TIER_TO_FRIEND_MAP } from "@/constants/membershipLevels"
import { env } from "@/env/server"
import { getProfile } from "@/lib/trpc/memoizedRequests"
import { DiamondIcon, InfoCircleIcon, LinkIcon } from "@/components/Icons"
import SectionContainer from "@/components/Section/Container"
import SectionHeader from "@/components/Section/Header"
import SectionLink from "@/components/Section/Link"
import SkeletonShimmer from "@/components/SkeletonShimmer"
import { getIntl } from "@/i18n"
import {
getEurobonusMembership,
getFriendsMembership,
scandicMemberships,
} from "@/utils/user"
import { UnlinkSAS } from "./UnlinkSAS"
import styles from "./linkedAccounts.module.css"
import type { Membership } from "@/types/user"
type Props = {
title?: string
link?: { href: string; text: string }
subtitle?: string
}
export default async function SASLinkedAccount({
title,
subtitle,
link,
}: Props) {
if (!env.SAS_ENABLED) {
return null
}
const intl = await getIntl()
return (
{intl.formatMessage({
id: "Changes in tier match can take up to 24 hours to be displayed.",
})}
)
}
async function MatchedAccountInfo() {
const user = await getProfile()
if (!user || "error" in user) {
return null
}
const intl = await getIntl()
const eurobonusMembership = getEurobonusMembership(user.memberships)
const friendsMembership = user.membership
if (!eurobonusMembership || !friendsMembership) {
return null
}
const sasLevelName = eurobonusMembership.membershipLevel || "-"
const sasMembershipNumber = eurobonusMembership.membershipNumber
const sasTierExpirationDate = eurobonusMembership.tierExpirationDate
const scandicLevelName = TIER_TO_FRIEND_MAP[friendsMembership.membershipLevel]
const scandicExpirationDate = friendsMembership.tierExpirationDate
const matchState = calculateMatchState(user.memberships)
return (
SAS EuroBonus
{sasLevelName}
EB{sasMembershipNumber}
)
}
async function MatchedAccountInfoSkeleton() {
const intl = await getIntl()
return (
SAS EuroBonus
)
}
type TierMatchMessageProps = {
matchState: MatchState
scandicLevelName: string
sasLevelName: string
}
async function TierMatchMessage({
matchState,
sasLevelName,
scandicLevelName,
}: TierMatchMessageProps) {
const intl = await getIntl()
const messageValues = {
sasLevelName: sasLevelName,
scandicLevelName: scandicLevelName,
sasMark: (text: ReactNode) => (
{text}
),
scandicMark: (text: ReactNode) => (
{text}
),
}
const messageMap: Record = {
boostedBySAS: intl.formatMessage(
{
id: "SAS {sasLevelName} has upgraded your Scandic Friends level to {scandicLevelName}.",
},
messageValues
),
boostedByScandic: intl.formatMessage(
{
id: "Scandic {scandicLevelName} has upgraded you to {sasLevelName}.",
},
messageValues
),
noBoost: intl.formatMessage(
{
id: "SAS {sasLevelName} and {scandicLevelName} are equally matched tiers. Level up one of your memberships for a chance of an upgrade!",
},
messageValues
),
}
const iconMap: Record = {
boostedBySAS: (
),
boostedByScandic: (
),
noBoost: ,
}
return (
{iconMap[matchState]}
{messageMap[matchState]}
)
}
async function TierMatchMessageSkeleton() {
const intl = await getIntl()
return (
)
}
type TierMatchExpirationProps = {
matchState: MatchState
sasExpirationDate: string | undefined
scandicExpirationDate: string | undefined
}
async function TierMatchExpiration({
matchState,
sasExpirationDate,
scandicExpirationDate,
}: TierMatchExpirationProps) {
if (matchState === "noBoost") {
return null
}
const intl = await getIntl()
return (
{matchState === "boostedBySAS"
? scandicExpirationDate
: sasExpirationDate}
)
}
function Label({ children }: { children: ReactNode }) {
return (
{children}
)
}
type MatchState = "boostedBySAS" | "boostedByScandic" | "noBoost"
function calculateMatchState(memberships: Membership[]): MatchState {
const eurobonusMembership = getEurobonusMembership(memberships)
const friendsMembership = getFriendsMembership(memberships)
const nativeMembership = memberships.find(
(x) => x.membershipType === scandicMemberships.scandic_native_tiers
)
if (!eurobonusMembership || !friendsMembership || !nativeMembership) {
return "noBoost"
}
const nativeLevel = nativeMembership.membershipLevel
const friendsLevel = friendsMembership.membershipLevel
if (nativeLevel !== friendsLevel) {
return "boostedBySAS"
}
// TODO check if SAS have been boosted by Scandic when API is available
const isBoostedByScandic = false
if (isBoostedByScandic) {
return "boostedByScandic"
}
return "noBoost"
}