-
- {heading}
-
- {benefits?.length ? (
-
- {benefits.map((benefit) => (
- -
-
-
- {benefit}
-
-
- ))}
-
- ) : null}
+
+
+ {heading}
+
+ {benefits?.length ? (
+
+ {benefits.map((benefit) => (
+ -
+
+
+ {benefit}
+
+
+ ))}
+
+ ) : null}
+
- {isLoggedIn && (
-
- {/* TODO: Account for more activation states. */}
-
-
- )}
+ {isLoggedIn &&
+ (isEligible ?
:
)}
{!isLoggedIn && (
diff --git a/apps/scandic-web/components/ContentType/PromoCampaignPage/Hero/utils.ts b/apps/scandic-web/components/ContentType/PromoCampaignPage/Hero/utils.ts
new file mode 100644
index 000000000..ed2e84164
--- /dev/null
+++ b/apps/scandic-web/components/ContentType/PromoCampaignPage/Hero/utils.ts
@@ -0,0 +1,18 @@
+import type { MembershipLevel } from "@scandic-hotels/common/constants/membershipLevels"
+
+/**
+ * Checks if a user's membership level is eligible for a promotional campaign.
+ * @param userLevel - The user's current membership level
+ * @param eligibleLevels - Array of membership levels eligible for the promo
+ * @returns true if user is eligible, false otherwise
+ */
+export function isUserEligibleForPromo(
+ userLevel: MembershipLevel | undefined,
+ eligibleLevels: MembershipLevel[]
+): boolean {
+ if (!userLevel || eligibleLevels.length === 0) {
+ return false
+ }
+
+ return eligibleLevels.includes(userLevel)
+}
diff --git a/apps/scandic-web/components/ContentType/PromoCampaignPage/index.tsx b/apps/scandic-web/components/ContentType/PromoCampaignPage/index.tsx
index 07e93a0e0..992a98ab8 100644
--- a/apps/scandic-web/components/ContentType/PromoCampaignPage/index.tsx
+++ b/apps/scandic-web/components/ContentType/PromoCampaignPage/index.tsx
@@ -18,9 +18,10 @@ export default async function PromoCampaignPage() {
if (!pageData) {
notFound()
}
- //const isUserLoggedIn = await isLoggedInUser()
const { promo_campaign_page, tracking } = pageData
- const { heading, subheading, enddate, promo_hero } = promo_campaign_page
+
+ const { heading, subheading, enddate, promo_hero, eligibleLevels } =
+ promo_campaign_page
const isCampaignExpired = enddate
? dt().isAfter(dt(enddate).endOf("day"))
@@ -30,7 +31,14 @@ export default async function PromoCampaignPage() {
<>
}>
-
+ {isCampaignExpired ? (
+
+ ) : (
+
+ )}
@@ -43,7 +51,6 @@ export default async function PromoCampaignPage() {
) : null}
- {isCampaignExpired ?
: null}
diff --git a/apps/scandic-web/utils/membershipLevels.ts b/apps/scandic-web/utils/membershipLevels.ts
deleted file mode 100644
index 2599caf2c..000000000
--- a/apps/scandic-web/utils/membershipLevels.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { MembershipLevelEnum } from "@scandic-hotels/common/constants/membershipLevels"
-
-export function isMembershipLevel(value: string): value is MembershipLevelEnum {
- return Object.values(MembershipLevelEnum).some((level) => level === value)
-}
diff --git a/packages/common/package.json b/packages/common/package.json
index 5ecd2c549..5b394d44f 100644
--- a/packages/common/package.json
+++ b/packages/common/package.json
@@ -54,6 +54,7 @@
"./utils/isValidJson": "./utils/isValidJson.ts",
"./utils/languages": "./utils/languages.ts",
"./utils/maskValue": "./utils/maskValue.ts",
+ "./utils/membershipLevels": "./utils/membershipLevels.ts",
"./utils/numberFormatting": "./utils/numberFormatting.ts",
"./utils/rangeArray": "./utils/rangeArray.ts",
"./utils/safeTry": "./utils/safeTry.ts",
diff --git a/packages/common/utils/membershipLevels.ts b/packages/common/utils/membershipLevels.ts
new file mode 100644
index 000000000..7cfb36c03
--- /dev/null
+++ b/packages/common/utils/membershipLevels.ts
@@ -0,0 +1,10 @@
+import { MembershipLevelEnum } from "../constants/membershipLevels"
+
+/**
+ * Type guard to check if a string value is a valid MembershipLevel
+ * @param value - The string value to check
+ * @returns true if the value is a valid MembershipLevel, false otherwise
+ */
+export function isMembershipLevel(value: string): value is MembershipLevelEnum {
+ return Object.values(MembershipLevelEnum).some((level) => level === value)
+}
diff --git a/packages/trpc/lib/graphql/Query/PromoCampaignPage/PromoCampaignPage.graphql b/packages/trpc/lib/graphql/Query/PromoCampaignPage/PromoCampaignPage.graphql
index 09e54a7ea..debe92057 100644
--- a/packages/trpc/lib/graphql/Query/PromoCampaignPage/PromoCampaignPage.graphql
+++ b/packages/trpc/lib/graphql/Query/PromoCampaignPage/PromoCampaignPage.graphql
@@ -25,6 +25,7 @@ query GetPromoCampaignPage($locale: String!, $uid: String!) {
promo_code
startdate
enddate
+ level_selection
system {
...System
created_at
diff --git a/packages/trpc/lib/routers/contentstack/promoCampaignPage/output.ts b/packages/trpc/lib/routers/contentstack/promoCampaignPage/output.ts
index c4e85ebbd..4654851cd 100644
--- a/packages/trpc/lib/routers/contentstack/promoCampaignPage/output.ts
+++ b/packages/trpc/lib/routers/contentstack/promoCampaignPage/output.ts
@@ -1,6 +1,7 @@
import { z } from "zod"
import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault"
+import { isMembershipLevel } from "@scandic-hotels/common/utils/membershipLevels"
import { nullableStringValidator } from "@scandic-hotels/common/utils/zod/stringValidator"
import { systemSchema } from "../schemas/system"
@@ -35,6 +36,13 @@ export const promoCampaignPageSchema = z
promo_code: z.string(),
startdate: nullableStringValidator,
enddate: nullableStringValidator,
+ level_selection: z
+ .array(z.string())
+ .nullish()
+ .transform((data) => {
+ if (!data) return []
+ return data.filter(isMembershipLevel)
+ }),
system: systemSchema.merge(
z.object({
created_at: z.string(),
@@ -47,13 +55,15 @@ export const promoCampaignPageSchema = z
}),
})
.transform(({ promo_campaign_page, ...data }) => {
- const { page_settings, ...promoCampaignPageData } = promo_campaign_page
+ const { page_settings, level_selection, ...promoCampaignPageData } =
+ promo_campaign_page
const bookingCode = page_settings?.booking_code || null
return {
...data,
promo_campaign_page: {
bookingCode,
+ eligibleLevels: level_selection,
...promoCampaignPageData,
},
}