-
+
diff --git a/components/MyPages/Blocks/Stays/StayCard/stay.module.css b/components/MyPages/Blocks/Stays/StayCard/stay.module.css
index c27472ce8..6e6b22158 100644
--- a/components/MyPages/Blocks/Stays/StayCard/stay.module.css
+++ b/components/MyPages/Blocks/Stays/StayCard/stay.module.css
@@ -36,4 +36,4 @@
align-items: center;
display: flex;
gap: var(--Spacing-x-half);
-}
\ No newline at end of file
+}
diff --git a/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/emptyUpcomingStays.module.css b/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/emptyUpcomingStays.module.css
index 941f3be5e..438b06f54 100644
--- a/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/emptyUpcomingStays.module.css
+++ b/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/emptyUpcomingStays.module.css
@@ -1,18 +1,32 @@
.container {
+ display: grid;
+ grid-template-rows: 1fr min(50px);
+ background-color: var(--Base-Surface-Primary-Normal);
+ border-radius: var(--Corner-radius-Medium);
+ min-height: 250px;
+ margin-bottom: var(--Spacing-x-half);
+ overflow: hidden;
+}
+
+.titleContainer {
+ display: flex;
+ justify-content: center;
align-items: center;
background-color: var(--Scandic-Brand-Pale-Peach);
- border-radius: var(--Corner-radius-Medium);
+}
+
+.title {
display: flex;
- gap: var(--Spacing-x3);
flex-direction: column;
- justify-content: center;
- margin-bottom: var(--Spacing-x-half);
- min-height: 250px;
- padding: var(--Spacing-x0) var(--Spacing-x3);
+ align-items: center;
}
.burgundyTitle {
color: var(--Scandic-Brand-Burgundy);
- display: block;
- text-align: center;
+}
+
+.link {
+ display: flex;
+ justify-content: center;
+ align-items: center;
}
diff --git a/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/index.tsx b/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/index.tsx
index a6799c7b9..4e1e5d6e8 100644
--- a/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/index.tsx
+++ b/components/MyPages/Blocks/Stays/Upcoming/EmptyUpcomingStays/index.tsx
@@ -1,7 +1,7 @@
import { homeHrefs } from "@/constants/homeHrefs"
import { env } from "@/env/server"
-import Button from "@/components/TempDesignSystem/Button"
+import { ArrowRightIcon } from "@/components/Icons"
import Link from "@/components/TempDesignSystem/Link"
import Title from "@/components/TempDesignSystem/Text/Title"
import { getIntl } from "@/i18n"
@@ -14,18 +14,22 @@ export default async function EmptyUpcomingStaysBlock({ lang }: LangParams) {
const { formatMessage } = await getIntl()
return (
-
- {formatMessage({ id: "You have no upcoming stays." })}
-
- {" "}
- {formatMessage({ id: "Where will you go next?" })}
-
-
-
+
+
+ {formatMessage({ id: "You have no upcoming stays." })}
+
+ {formatMessage({ id: "Where will you go next?" })}
+
+
+
+
+ {formatMessage({ id: "Get inspired" })}
+
+
)
}
diff --git a/components/Section/Header/index.tsx b/components/Section/Header/index.tsx
index 0537b526a..925deb330 100644
--- a/components/Section/Header/index.tsx
+++ b/components/Section/Header/index.tsx
@@ -16,7 +16,7 @@ export default function SectionHeader({
return (
diff --git a/components/TempDesignSystem/Button/button.module.css b/components/TempDesignSystem/Button/button.module.css
index 0de3dbc29..6b01a8529 100644
--- a/components/TempDesignSystem/Button/button.module.css
+++ b/components/TempDesignSystem/Button/button.module.css
@@ -41,6 +41,12 @@ a.inverted {
border: none;
}
+.text,
+a.text {
+ background: none;
+ border: none;
+}
+
/* VARIANTS */
.default,
a.default {
@@ -50,7 +56,9 @@ a.default {
}
.icon {
- align-items: baseline;
+ display: flex;
+ align-items: center;
+ gap: var(--Spacing-x-half);
}
/* SIZES */
@@ -97,6 +105,25 @@ a.default {
color: var(--Base-Button-Primary-On-Fill-Disabled);
}
+.icon.basePrimary svg,
+.icon.basePrimary svg * {
+ fill: var(--Base-Button-Primary-On-Fill-Normal);
+}
+
+.icon.basePrimary:active svg,
+.icon.basePrimary:focus svg,
+.icon.basePrimary:hover svg,
+.icon.basePrimary:active svg *,
+.icon.basePrimary:focus svg *,
+.icon.basePrimary:hover svg * {
+ fill: var(--Base-Button-Primary-On-Fill-Hover);
+}
+
+.icon.basePrimary:disabled *,
+.icon.basePrimary:disabled svg * {
+ fill: var(--Base-Button-Primary-On-Fill-Disabled);
+}
+
.baseSecondary {
background-color: var(--Base-Button-Secondary-Fill-Normal);
border-color: var(--Base-Button-Secondary-Border-Normal);
@@ -117,6 +144,25 @@ a.default {
color: var(--Base-Button-Secondary-On-Fill-Disabled);
}
+.icon.baseSecondary svg,
+.icon.baseSecondary svg * {
+ fill: var(--Base-Button-Secondary-On-Fill-Normal);
+}
+
+.icon.baseSecondary:active svg,
+.icon.baseSecondary:focus svg,
+.icon.baseSecondary:hover svg,
+.icon.baseSecondary:active svg *,
+.icon.baseSecondary:focus svg *,
+.icon.baseSecondary:hover svg * {
+ fill: var(--Base-Button-Secondary-On-Fill-Hover);
+}
+
+.icon.baseSecondary:disabled svg,
+.icon.baseSecondary:disabled svg * {
+ fill: var(--Base-Button-Secondary-On-Fill-Disabled);
+}
+
.baseTertiary {
background-color: var(--Base-Button-Tertiary-Fill-Normal);
color: var(--Base-Button-Tertiary-On-Fill-Normal);
@@ -134,6 +180,25 @@ a.default {
color: var(--Base-Button-Tertiary-On-Fill-Disabled);
}
+.icon.baseTertiary svg,
+.icon.baseTertiary svg * {
+ fill: var(--Base-Button-Tertiary-On-Fill-Normal);
+}
+
+.icon.baseTertiary:active svg,
+.icon.baseTertiary:focus svg,
+.icon.baseTertiary:hover svg,
+.icon.baseTertiary:active svg *,
+.icon.baseTertiary:focus svg *,
+.icon.baseTertiary:hover svg * {
+ fill: var(--Base-Button-Tertiary-On-Fill-Hover);
+}
+
+.icon.baseTertiary:disabled svg,
+.icon.baseTertiary:disabled svg * {
+ fill: var(--Base-Button-Tertiary-On-Fill-Disabled);
+}
+
.baseInverted {
background-color: var(--Base-Button-Inverted-Fill-Normal);
color: var(--Base-Button-Inverted-On-Fill-Normal);
@@ -151,6 +216,60 @@ a.default {
color: var(--Base-Button-Inverted-On-Fill-Disabled);
}
+.icon.baseInverted svg,
+.icon.baseInverted svg * {
+ fill: var(--Base-Button-Inverted-On-Fill-Normal);
+}
+
+.icon.baseInverted:active svg,
+.icon.baseInverted:focus svg,
+.icon.baseInverted:hover svg,
+.icon.baseInverted:active svg *,
+.icon.baseInverted:focus svg *,
+.icon.baseInverted:hover svg * {
+ fill: var(--Base-Button-Inverted-On-Fill-Hover);
+}
+
+.icon.baseInverted:disabled svg,
+.icon.baseInverted:disabled svg * {
+ fill: var(--Base-Button-Inverted-On-Fill-Disabled);
+}
+
+.baseText {
+ color: var(--Base-Button-Text-On-Fill-Normal);
+}
+
+.baseText:active,
+.baseText:focus,
+.baseText:hover {
+ color: var(--Base-Button-Text-On-Fill-Hover);
+ text-decoration: underline;
+}
+
+.baseText:disabled {
+ color: var(--Base-Button-Text-On-Fill-Disabled);
+}
+
+.icon.baseText svg,
+.icon.baseText svg * {
+ fill: var(--Base-Button-Text-On-Fill-Normal);
+}
+
+.icon.baseText:active svg,
+.icon.baseText:focus svg,
+.icon.baseText:hover svg,
+.icon.baseText:active svg *,
+.icon.baseText:focus svg *,
+.icon.baseText:hover svg * {
+ fill: var(--Base-Button-Text-On-Fill-Hover);
+ text-decoration: underline;
+}
+
+.icon.baseText:disabled svg,
+.icon.baseText:disabled svg * {
+ fill: var(--Base-Button-Text-On-Fill-Disabled);
+}
+
.primaryStrongPrimary {
background-color: var(--Theme-Primary-Strong-Button-Primary-Fill-Normal);
color: var(--Theme-Primary-Strong-Button-Primary-On-Fill-Normal);
@@ -168,6 +287,25 @@ a.default {
color: var(--Theme-Primary-Strong-Button-Primary-On-Fill-Disabled);
}
+.icon.primaryStrongPrimary svg,
+.icon.primaryStrongPrimary svg * {
+ fill: var(--Theme-Primary-Strong-Button-Primary-On-Fill-Normal);
+}
+
+.icon.primaryStrongPrimary:active svg,
+.icon.primaryStrongPrimary:focus svg,
+.icon.primaryStrongPrimary:hover svg,
+.icon.primaryStrongPrimary:active svg *,
+.icon.primaryStrongPrimary:focus svg *,
+.icon.primaryStrongPrimary:hover svg * {
+ fill: var(--Theme-Primary-Strong-Button-Primary-On-Fill-Hover);
+}
+
+.icon.primaryStrongPrimary:disabled svg,
+.icon.primaryStrongPrimary:disabled svg * {
+ fill: var(--Theme-Primary-Strong-Button-Primary-On-Fill-Disabled);
+}
+
.primaryStrongSecondary {
background-color: var(--Theme-Primary-Strong-Button-Secondary-Fill-Normal);
border-color: var(--Theme-Primary-Strong-Button-Secondary-Border-Normal);
@@ -188,6 +326,25 @@ a.default {
color: var(--Theme-Primary-Strong-Button-Secondary-On-Fill-Disabled);
}
+.icon.primaryStrongSecondary svg,
+.icon.primaryStrongSecondary svg * {
+ fill: var(--Theme-Primary-Strong-Button-Secondary-On-Fill-Normal);
+}
+
+.icon.primaryStrongSecondary:active svg,
+.icon.primaryStrongSecondary:focus svg,
+.icon.primaryStrongSecondary:hover svg,
+.icon.primaryStrongSecondary:active svg *,
+.icon.primaryStrongSecondary:focus svg *,
+.icon.primaryStrongSecondary:hover svg * {
+ fill: var(--Theme-Primary-Strong-Button-Secondary-On-Fill-Hover);
+}
+
+.icon.primaryStrongSecondary:disabled svg,
+.icon.primaryStrongSecondary:disabled svg * {
+ fill: var(--Theme-Primary-Strong-Button-Secondary-On-Fill-Disabled);
+}
+
.primaryDarkPrimary {
background-color: var(--Theme-Primary-Dark-Button-Primary-Fill-Normal);
color: var(--Theme-Primary-Dark-Button-Primary-On-Fill-Normal);
@@ -205,6 +362,25 @@ a.default {
color: var(--Theme-Primary-Dark-Button-Primary-On-Fill-Disabled);
}
+.icon.primaryDarkPrimary svg,
+.icon.primaryDarkPrimary svg * {
+ fill: var(--Theme-Primary-Dark-Button-Primary-On-Fill-Normal);
+}
+
+.icon.primaryDarkPrimary:active svg,
+.icon.primaryDarkPrimary:focus svg,
+.icon.primaryDarkPrimary:hover svg,
+.icon.primaryDarkPrimary:active svg *,
+.icon.primaryDarkPrimary:focus svg *,
+.icon.primaryDarkPrimary:hover svg * {
+ fill: var(--Theme-Primary-Dark-Button-Primary-On-Fill-Hover);
+}
+
+.icon.primaryDarkPrimary:disabled svg,
+.icon.primaryDarkPrimary:disabled svg * {
+ fill: var(--Theme-Primary-Dark-Button-Primary-On-Fill-Disabled);
+}
+
.primaryDarkSecondary {
background-color: var(--Theme-Primary-Dark-Button-Secondary-Fill-Normal);
border-color: var(--Theme-Primary-Dark-Button-Secondary-Border-Normal);
@@ -225,6 +401,25 @@ a.default {
color: var(--Theme-Primary-Dark-Button-Secondary-On-Fill-Disabled);
}
+.icon.primaryDarkSecondary svg,
+.icon.primaryDarkSecondary svg * {
+ fill: var(--Theme-Primary-Dark-Button-Secondary-On-Fill-Normal);
+}
+
+.icon.primaryDarkSecondary:active svg,
+.icon.primaryDarkSecondary:focus svg,
+.icon.primaryDarkSecondary:hover svg,
+.icon.primaryDarkSecondary:active svg *,
+.icon.primaryDarkSecondary:focus svg *,
+.icon.primaryDarkSecondary:hover svg * {
+ fill: var(--Theme-Primary-Dark-Button-Secondary-On-Fill-Hover);
+}
+
+.icon.primaryDarkSecondary:disabled svg,
+.icon.primaryDarkSecondary:disabled svg * {
+ fill: var(--Theme-Primary-Dark-Button-Secondary-On-Fill-Disabled);
+}
+
.primaryLightPrimary {
background-color: var(--Theme-Primary-Light-Button-Primary-Fill-Normal);
color: var(--Theme-Primary-Light-Button-Primary-On-Fill-Normal);
@@ -242,6 +437,25 @@ a.default {
color: var(--Theme-Primary-Light-Button-Primary-On-Fill-Disabled);
}
+.icon.primaryLightPrimary svg,
+.icon.primaryLightPrimary svg * {
+ fill: var(--Theme-Primary-Light-Button-Primary-On-Fill-Normal);
+}
+
+.icon.primaryLightPrimary:active svg,
+.icon.primaryLightPrimary:focus svg,
+.icon.primaryLightPrimary:hover svg,
+.icon.primaryLightPrimary:active svg *,
+.icon.primaryLightPrimary:focus svg *,
+.icon.primaryLightPrimary:hover svg * {
+ fill: var(--Theme-Primary-Light-Button-Primary-On-Fill-Hover);
+}
+
+.icon.primaryLightPrimary:disabled svg,
+.icon.primaryLightPrimary:disabled svg * {
+ fill: var(--Theme-Primary-Light-Button-Primary-On-Fill-Disabled);
+}
+
.primaryLightSecondary {
background-color: var(--Theme-Primary-Light-Button-Secondary-Fill-Normal);
border-color: var(--Theme-Primary-Light-Button-Secondary-Border-Normal);
@@ -262,6 +476,25 @@ a.default {
color: var(--Theme-Primary-Light-Button-Secondary-On-Fill-Disabled);
}
+.icon.primaryLightSecondary svg,
+.icon.primaryLightSecondary svg * {
+ fill: var(--Theme-Primary-Light-Button-Secondary-On-Fill-Normal);
+}
+
+.icon.primaryLightSecondary:active svg,
+.icon.primaryLightSecondary:focus svg,
+.icon.primaryLightSecondary:hover svg,
+.icon.primaryLightSecondary:active svg *,
+.icon.primaryLightSecondary:focus svg *,
+.icon.primaryLightSecondary:hover svg * {
+ fill: var(--Theme-Primary-Light-Button-Secondary-On-Fill-Hover);
+}
+
+.icon.primaryLightSecondary:disabled svg,
+.icon.primaryLightSecondary:disabled svg * {
+ fill: var(--Theme-Primary-Light-Button-Secondary-On-Fill-Disabled);
+}
+
.secondaryDarkPrimary {
background-color: var(--Theme-Secondary-Dark-Button-Primary-Fill-Normal);
color: var(--Theme-Secondary-Dark-Button-Primary-On-Fill-Normal);
@@ -279,6 +512,25 @@ a.default {
color: var(--Theme-Secondary-Dark-Button-Primary-On-Fill-Disabled);
}
+.icon.secondaryDarkPrimary svg,
+.icon.secondaryDarkPrimary svg * {
+ fill: var(--Theme-Secondary-Dark-Button-Primary-On-Fill-Normal);
+}
+
+.icon.secondaryDarkPrimary:active svg,
+.icon.secondaryDarkPrimary:focus svg,
+.icon.secondaryDarkPrimary:hover svg,
+.icon.secondaryDarkPrimary:active svg *,
+.icon.secondaryDarkPrimary:focus svg *,
+.icon.secondaryDarkPrimary:hover svg * {
+ fill: var(--Theme-Secondary-Dark-Button-Primary-On-Fill-Hover);
+}
+
+.icon.secondaryDarkPrimary:disabled svg,
+.icon.secondaryDarkPrimary:disabled svg * {
+ fill: var(--Theme-Secondary-Dark-Button-Primary-On-Fill-Disabled);
+}
+
.secondaryDarkSecondary {
background-color: var(--Theme-Secondary-Dark-Button-Secondary-Fill-Normal);
border-color: var(--Theme-Secondary-Dark-Button-Secondary-Border-Normal);
@@ -299,6 +551,25 @@ a.default {
color: var(--Theme-Secondary-Dark-Button-Secondary-On-Fill-Disabled);
}
+.icon.secondaryDarkSecondary svg,
+.icon.secondaryDarkSecondary svg * {
+ fill: var(--Theme-Secondary-Dark-Button-Secondary-On-Fill-Normal);
+}
+
+.icon.secondaryDarkSecondary:active svg,
+.icon.secondaryDarkSecondary:focus svg,
+.icon.secondaryDarkSecondary:hover svg,
+.icon.secondaryDarkSecondary:active svg *,
+.icon.secondaryDarkSecondary:focus svg *,
+.icon.secondaryDarkSecondary:hover svg * {
+ fill: var(--Theme-Secondary-Dark-Button-Secondary-On-Fill-Hover);
+}
+
+.icon.secondaryDarkSecondary:disabled svg,
+.icon.secondaryDarkSecondary:disabled svg * {
+ fill: var(--Theme-Secondary-Dark-Button-Secondary-On-Fill-Disabled);
+}
+
.secondaryLightPrimary {
background-color: var(--Theme-Secondary-Light-Button-Primary-Fill-Normal);
color: var(--Theme-Secondary-Light-Button-Primary-On-Fill-Normal);
@@ -316,6 +587,25 @@ a.default {
color: var(--Theme-Secondary-Light-Button-Primary-On-Fill-Disabled);
}
+.icon.secondaryLightPrimary svg,
+.icon.secondaryLightPrimary svg * {
+ fill: var(--Theme-Secondary-Light-Button-Primary-On-Fill-Normal);
+}
+
+.icon.secondaryLightPrimary:active svg,
+.icon.secondaryLightPrimary:focus svg,
+.icon.secondaryLightPrimary:hover svg,
+.icon.secondaryLightPrimary:active svg *,
+.icon.secondaryLightPrimary:focus svg *,
+.icon.secondaryLightPrimary:hover svg * {
+ fill: var(--Theme-Secondary-Light-Button-Primary-On-Fill-Hover);
+}
+
+.icon.secondaryLightPrimary:disabled svg,
+.icon.secondaryLightPrimary:disabled svg * {
+ fill: var(--Theme-Secondary-Light-Button-Primary-On-Fill-Disabled);
+}
+
.secondaryLightSecondary {
background-color: var(--Theme-Secondary-Light-Button-Secondary-Fill-Normal);
border-color: var(--Theme-Secondary-Light-Button-Secondary-Border-Normal);
@@ -336,6 +626,25 @@ a.default {
color: var(--Theme-Secondary-Light-Button-Secondary-On-Fill-Disabled);
}
+.icon.secondaryLightSecondary svg,
+.icon.secondaryLightSecondary svg * {
+ fill: var(--Theme-Secondary-Light-Button-Secondary-On-Fill-Normal);
+}
+
+.icon.secondaryLightSecondary:active svg,
+.icon.secondaryLightSecondary:focus svg,
+.icon.secondaryLightSecondary:hover svg,
+.icon.secondaryLightSecondary:active svg *,
+.icon.secondaryLightSecondary:focus svg *,
+.icon.secondaryLightSecondary:hover svg * {
+ fill: var(--Theme-Secondary-Light-Button-Secondary-On-Fill-Hover);
+}
+
+.icon.secondaryLightSecondary:disabled svg,
+.icon.secondaryLightSecondary:disabled svg * {
+ fill: var(--Theme-Secondary-Light-Button-Secondary-On-Fill-Disabled);
+}
+
.tertiaryDarkPrimary {
background-color: var(--Theme-Tertiary-Dark-Button-Primary-Fill-Normal);
color: var(--Theme-Tertiary-Dark-Button-Primary-On-Fill-Normal);
@@ -353,6 +662,25 @@ a.default {
color: var(--Theme-Tertiary-Dark-Button-Primary-On-Fill-Disabled);
}
+.icon.tertiaryDarkPrimary svg,
+.icon.tertiaryDarkPrimary svg * {
+ fill: var(--Theme-Tertiary-Dark-Button-Primary-On-Fill-Normal);
+}
+
+.icon.tertiaryDarkPrimary:active svg,
+.icon.tertiaryDarkPrimary:focus svg,
+.icon.tertiaryDarkPrimary:hover svg,
+.icon.tertiaryDarkPrimary:active svg *,
+.icon.tertiaryDarkPrimary:focus svg *,
+.icon.tertiaryDarkPrimary:hover svg * {
+ fill: var(--Theme-Tertiary-Dark-Button-Primary-On-Fill-Hover);
+}
+
+.icon.tertiaryDarkPrimary:disabled svg,
+.icon.tertiaryDarkPrimary:disabled svg * {
+ fill: var(--Theme-Tertiary-Dark-Button-Primary-On-Fill-Disabled);
+}
+
.tertiaryDarkSecondary {
background-color: var(--Theme-Tertiary-Dark-Button-Secondary-Fill-Normal);
border-color: var(--Theme-Tertiary-Dark-Button-Secondary-Border-Normal);
@@ -373,6 +701,25 @@ a.default {
color: var(--Theme-Tertiary-Dark-Button-Secondary-On-Fill-Disabled);
}
+.icon.tertiaryDarkSecondary svg,
+.icon.tertiaryDarkSecondary svg * {
+ fill: var(--Theme-Tertiary-Dark-Button-Secondary-On-Fill-Normal);
+}
+
+.icon.tertiaryDarkSecondary:active svg,
+.icon.tertiaryDarkSecondary:focus svg,
+.icon.tertiaryDarkSecondary:hover svg,
+.icon.tertiaryDarkSecondary:active svg *,
+.icon.tertiaryDarkSecondary:focus svg *,
+.icon.tertiaryDarkSecondary:hover svg * {
+ fill: var(--Theme-Tertiary-Dark-Button-Secondary-On-Fill-Hover);
+}
+
+.icon.tertiaryDarkSecondary:disabled svg,
+.icon.tertiaryDarkSecondary:disabled svg * {
+ fill: var(--Theme-Tertiary-Dark-Button-Secondary-On-Fill-Disabled);
+}
+
.tertiaryLightPrimary {
background-color: var(--Theme-Tertiary-Light-Button-Primary-Fill-Normal);
color: var(--Theme-Tertiary-Light-Button-Primary-On-Fill-Normal);
@@ -390,6 +737,25 @@ a.default {
color: var(--Theme-Tertiary-Light-Button-Primary-On-Fill-Disabled);
}
+.icon.tertiaryLightPrimary svg,
+.icon.tertiaryLightPrimary svg * {
+ fill: var(--Theme-Tertiary-Light-Button-Primary-On-Fill-Normal);
+}
+
+.icon.tertiaryLightPrimary:active svg,
+.icon.tertiaryLightPrimary:focus svg,
+.icon.tertiaryLightPrimary:hover svg,
+.icon.tertiaryLightPrimary:active svg *,
+.icon.tertiaryLightPrimary:focus svg *,
+.icon.tertiaryLightPrimary:hover svg * {
+ fill: var(--Theme-Tertiary-Light-Button-Primary-On-Fill-Hover);
+}
+
+.icon.tertiaryLightPrimary:disabled svg,
+.icon.tertiaryLightPrimary:disabled svg * {
+ fill: var(--Theme-Tertiary-Light-Button-Primary-On-Fill-Disabled);
+}
+
.tertiaryLightSecondary {
background-color: var(--Tertiary-Light-Button-Secondary-Fill-Normal);
border-color: var(--Tertiary-Light-Button-Secondary-Border-Normal);
@@ -409,3 +775,22 @@ a.default {
border-color: var(--Tertiary-Light-Button-Secondary-Border-Disabled);
color: var(--Tertiary-Light-Button-Secondary-On-Fill-Disabled);
}
+
+.icon.tertiaryLightSecondary svg,
+.icon.tertiaryLightSecondary svg * {
+ fill: var(--Tertiary-Light-Button-Secondary-On-Fill-Normal);
+}
+
+.icon.tertiaryLightSecondary:active svg,
+.icon.tertiaryLightSecondary:focus svg,
+.icon.tertiaryLightSecondary:hover svg,
+.icon.tertiaryLightSecondary:active svg *,
+.icon.tertiaryLightSecondary:focus svg *,
+.icon.tertiaryLightSecondary:hover svg * {
+ fill: var(--Tertiary-Light-Button-Secondary-On-Fill-Hover);
+}
+
+.icon.tertiaryLightSecondary:disabled svg,
+.icon.tertiaryLightSecondary:disabled svg * {
+ fill: var(--Tertiary-Light-Button-Secondary-On-Fill-Disabled);
+}
diff --git a/components/TempDesignSystem/Button/variants.ts b/components/TempDesignSystem/Button/variants.ts
index 71757fcfe..217d14b51 100644
--- a/components/TempDesignSystem/Button/variants.ts
+++ b/components/TempDesignSystem/Button/variants.ts
@@ -9,6 +9,7 @@ export const buttonVariants = cva(styles.btn, {
primary: styles.primary,
secondary: styles.secondary,
tertiary: styles.tertiary,
+ text: styles.text,
},
size: {
small: styles.small,
@@ -128,5 +129,10 @@ export const buttonVariants = cva(styles.btn, {
intent: "secondary",
theme: "tertiaryLight",
},
+ {
+ className: styles.baseText,
+ intent: "text",
+ theme: "base",
+ },
],
})
diff --git a/components/TempDesignSystem/Card/index.tsx b/components/TempDesignSystem/Card/index.tsx
index 32ff9d292..8c51da7aa 100644
--- a/components/TempDesignSystem/Card/index.tsx
+++ b/components/TempDesignSystem/Card/index.tsx
@@ -1,5 +1,4 @@
import Button from "@/components/TempDesignSystem/Button"
-import Divider from "@/components/TempDesignSystem/Divider"
import Link from "@/components/TempDesignSystem/Link"
import BiroScript from "@/components/TempDesignSystem/Text/BiroScript"
import Body from "@/components/TempDesignSystem/Text/Body"
@@ -47,7 +46,6 @@ export default function Card({
{scriptedTopTitle}
-
) : null}
diff --git a/components/TempDesignSystem/Link/link.module.css b/components/TempDesignSystem/Link/link.module.css
index 84fcf30be..bcf90ec33 100644
--- a/components/TempDesignSystem/Link/link.module.css
+++ b/components/TempDesignSystem/Link/link.module.css
@@ -17,7 +17,7 @@
.icon {
align-items: center;
display: flex;
- gap: var(--Spacing-x1);
+ gap: var(--Spacing-x-half);
}
.myPage {
@@ -102,6 +102,10 @@
color: var(--Scandic-Peach-80);
}
+.white {
+ color: var(--Base-Button-Primary-On-Fill-Normal);
+}
+
.regular {
font-family: var(--typography-Body-Regular-fontFamily);
font-size: var(--typography-Body-Regular-fontSize);
diff --git a/components/TempDesignSystem/Link/variants.ts b/components/TempDesignSystem/Link/variants.ts
index c943da924..cffb3dda4 100644
--- a/components/TempDesignSystem/Link/variants.ts
+++ b/components/TempDesignSystem/Link/variants.ts
@@ -13,6 +13,7 @@ export const linkVariants = cva(styles.link, {
none: "",
pale: styles.pale,
peach80: styles.peach80,
+ white: styles.white,
},
size: {
small: styles.small,
diff --git a/components/TempDesignSystem/LoyaltyCard/index.tsx b/components/TempDesignSystem/LoyaltyCard/index.tsx
new file mode 100644
index 000000000..db060ef42
--- /dev/null
+++ b/components/TempDesignSystem/LoyaltyCard/index.tsx
@@ -0,0 +1,66 @@
+import ArrowRight from "@/components/Icons/ArrowRight"
+import Image from "@/components/Image"
+import Link from "@/components/TempDesignSystem/Link"
+import Body from "@/components/TempDesignSystem/Text/Body"
+import Title from "@/components/TempDesignSystem/Text/Title"
+
+import { loyaltyCardVariants } from "./variants"
+
+import styles from "./loyaltyCard.module.css"
+
+import type { LoyaltyCardProps } from "./loyaltyCard"
+
+export default function LoyaltyCard({
+ link,
+ image,
+ heading,
+ bodyText,
+ theme = "white",
+ className,
+}: LoyaltyCardProps) {
+ return (
+
+ {image ? (
+
+ ) : null}
+
+ {heading}
+
+ {bodyText ? (
+
+ {bodyText}
+
+ ) : null}
+
+ {link ? (
+
+
+ {link.title}
+
+ ) : null}
+
+
+ )
+}
diff --git a/components/TempDesignSystem/LoyaltyCard/loyaltyCard.module.css b/components/TempDesignSystem/LoyaltyCard/loyaltyCard.module.css
new file mode 100644
index 000000000..bc83ef0b7
--- /dev/null
+++ b/components/TempDesignSystem/LoyaltyCard/loyaltyCard.module.css
@@ -0,0 +1,38 @@
+.container {
+ align-items: center;
+ display: grid;
+ border-radius: var(--Corner-radius-xLarge);
+ gap: var(--Spacing-x2);
+ height: 480px;
+ justify-content: space-between;
+ margin-right: var(--Spacing-x2);
+ padding: var(--Spacing-x4) var(--Spacing-x3);
+ text-align: center;
+ width: 100%;
+}
+
+.image {
+ object-fit: contain;
+ height: 160px;
+ width: auto;
+ justify-self: center;
+}
+
+.white {
+ background-color: var(--Main-Grey-White);
+}
+
+.buttonContainer {
+ display: flex;
+ gap: var(--Spacing-x1);
+ justify-content: center;
+}
+
+.link {
+ display: flex;
+ align-items: center;
+}
+
+.icon {
+ align-self: center;
+}
diff --git a/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts b/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts
new file mode 100644
index 000000000..784d643ad
--- /dev/null
+++ b/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts
@@ -0,0 +1,20 @@
+import { loyaltyCardVariants } from "./variants"
+
+import type { VariantProps } from "class-variance-authority"
+
+import { ImageVaultAsset } from "@/types/components/imageVaultImage"
+
+export interface LoyaltyCardProps
+ extends React.HTMLAttributes,
+ VariantProps {
+ link?: {
+ href: string
+ title: string
+ openInNewTab?: boolean
+ isExternal: boolean
+ }
+ image?: ImageVaultAsset
+ heading?: string | null
+ bodyText?: string | null
+ backgroundImage?: { url: string }
+}
diff --git a/components/TempDesignSystem/LoyaltyCard/variants.ts b/components/TempDesignSystem/LoyaltyCard/variants.ts
new file mode 100644
index 000000000..7fb16df0a
--- /dev/null
+++ b/components/TempDesignSystem/LoyaltyCard/variants.ts
@@ -0,0 +1,14 @@
+import { cva } from "class-variance-authority"
+
+import styles from "./loyaltyCard.module.css"
+
+export const loyaltyCardVariants = cva(styles.container, {
+ variants: {
+ theme: {
+ white: styles.white,
+ },
+ },
+ defaultVariants: {
+ theme: "white",
+ },
+})
diff --git a/components/TempDesignSystem/Text/BiroScript/biroScript.module.css b/components/TempDesignSystem/Text/BiroScript/biroScript.module.css
index 1c7cc7774..9c0ed4aaf 100644
--- a/components/TempDesignSystem/Text/BiroScript/biroScript.module.css
+++ b/components/TempDesignSystem/Text/BiroScript/biroScript.module.css
@@ -26,6 +26,14 @@
line-height: var(--typography-Script-2-lineHeight);
}
+.tiltedSmall {
+ transform: rotate(-2deg);
+}
+
+.tiltedLarge {
+ transform: rotate(-13deg) translate(0px, -15px);
+}
+
.center {
text-align: center;
}
diff --git a/components/TempDesignSystem/Text/BiroScript/index.tsx b/components/TempDesignSystem/Text/BiroScript/index.tsx
index 13e0b0252..095bec4f7 100644
--- a/components/TempDesignSystem/Text/BiroScript/index.tsx
+++ b/components/TempDesignSystem/Text/BiroScript/index.tsx
@@ -10,6 +10,7 @@ export default function BiroScript({
color,
textAlign,
type,
+ tilted,
...props
}: BiroScriptProps) {
const Comp = asChild ? Slot : "span"
@@ -18,6 +19,7 @@ export default function BiroScript({
color,
textAlign,
type,
+ tilted,
})
return
}
diff --git a/components/TempDesignSystem/Text/BiroScript/variants.ts b/components/TempDesignSystem/Text/BiroScript/variants.ts
index df1bec379..570af1c0c 100644
--- a/components/TempDesignSystem/Text/BiroScript/variants.ts
+++ b/components/TempDesignSystem/Text/BiroScript/variants.ts
@@ -19,6 +19,10 @@ const config = {
one: styles.one,
two: styles.two,
},
+ tilted: {
+ small: styles.tiltedSmall,
+ large: styles.tiltedLarge,
+ },
},
defaultVariants: {
type: "one",
diff --git a/components/TempDesignSystem/Text/Caption/caption.module.css b/components/TempDesignSystem/Text/Caption/caption.module.css
index 21e846236..09361d5bf 100644
--- a/components/TempDesignSystem/Text/Caption/caption.module.css
+++ b/components/TempDesignSystem/Text/Caption/caption.module.css
@@ -36,3 +36,15 @@
.pale {
color: var(--Scandic-Brand-Pale-Peach);
}
+
+.textMediumContrast {
+ color: var(--Base-Text-UI-Medium-contrast);
+}
+
+.center {
+ text-align: center;
+}
+
+.left {
+ text-align: left;
+}
diff --git a/components/TempDesignSystem/Text/Caption/index.tsx b/components/TempDesignSystem/Text/Caption/index.tsx
index a63680d98..0e43263c6 100644
--- a/components/TempDesignSystem/Text/Caption/index.tsx
+++ b/components/TempDesignSystem/Text/Caption/index.tsx
@@ -9,19 +9,21 @@ export default function Caption({
className = "",
color,
fontOnly = false,
+ textAlign,
textTransform,
...props
}: CaptionProps) {
const Comp = asChild ? Slot : "p"
const classNames = fontOnly
? fontOnlycaptionVariants({
- className,
- textTransform,
- })
+ className,
+ textTransform,
+ })
: captionVariants({
- className,
- color,
- textTransform,
- })
+ className,
+ color,
+ textTransform,
+ textAlign,
+ })
return
}
diff --git a/components/TempDesignSystem/Text/Caption/variants.ts b/components/TempDesignSystem/Text/Caption/variants.ts
index d4a4f14b0..a0188ffee 100644
--- a/components/TempDesignSystem/Text/Caption/variants.ts
+++ b/components/TempDesignSystem/Text/Caption/variants.ts
@@ -8,11 +8,16 @@ const config = {
black: styles.black,
burgundy: styles.burgundy,
pale: styles.pale,
+ textMediumContrast: styles.textMediumContrast,
},
textTransform: {
bold: styles.bold,
regular: styles.regular,
},
+ textAlign: {
+ center: styles.center,
+ left: styles.left,
+ },
},
defaultVariants: {
color: "black",
diff --git a/components/TempDesignSystem/Text/Footnote/footnote.module.css b/components/TempDesignSystem/Text/Footnote/footnote.module.css
index f9f8e044b..bf4aff206 100644
--- a/components/TempDesignSystem/Text/Footnote/footnote.module.css
+++ b/components/TempDesignSystem/Text/Footnote/footnote.module.css
@@ -43,4 +43,8 @@
.pale {
color: var(--Scandic-Brand-Pale-Peach);
-}
\ No newline at end of file
+}
+
+.textMediumContrast {
+ color: var(--Base-Text-UI-Medium-contrast);
+}
diff --git a/components/TempDesignSystem/Text/Footnote/variants.ts b/components/TempDesignSystem/Text/Footnote/variants.ts
index d791045a6..eb2040177 100644
--- a/components/TempDesignSystem/Text/Footnote/variants.ts
+++ b/components/TempDesignSystem/Text/Footnote/variants.ts
@@ -8,6 +8,7 @@ const config = {
black: styles.black,
burgundy: styles.burgundy,
pale: styles.pale,
+ textMediumContrast: styles.textMediumContrast,
},
textAlign: {
center: styles.center,
diff --git a/env/server.ts b/env/server.ts
index 7a01807d8..4c6d79ad1 100644
--- a/env/server.ts
+++ b/env/server.ts
@@ -9,7 +9,9 @@ export const env = createEnv({
*/
isServer: typeof window === "undefined" || "Deno" in window,
server: {
+ APPLICATION_INSIGHTS_CONNECTION_STRING: z.string().optional(),
ADOBE_SCRIPT_SRC: z.string().optional(),
+ ADOBE_SDK_SCRIPT_SRC: z.string().optional(),
API_BASEURL: z.string(),
BUILD_ID: z.string().default("64rYXBu8o2eHp0Jf"),
CMS_ACCESS_TOKEN: z.string(),
@@ -58,7 +60,10 @@ export const env = createEnv({
},
emptyStringAsUndefined: true,
runtimeEnv: {
+ APPLICATION_INSIGHTS_CONNECTION_STRING:
+ process.env.APPLICATION_INSIGHTS_CONNECTION_STRING,
ADOBE_SCRIPT_SRC: process.env.ADOBE_SCRIPT_SRC,
+ ADOBE_SDK_SCRIPT_SRC: process.env.ADOBE_SDK_SCRIPT_SRC,
API_BASEURL: process.env.API_BASEURL,
BUILD_ID: process.env.BUILD_ID,
CMS_ACCESS_TOKEN: process.env.CMS_ACCESS_TOKEN,
diff --git a/instrumentation.ts b/instrumentation.ts
new file mode 100644
index 000000000..ac09da613
--- /dev/null
+++ b/instrumentation.ts
@@ -0,0 +1,21 @@
+import { env } from "./env/server"
+
+export async function register() {
+ if (
+ process.env.NEXT_RUNTIME === "nodejs" &&
+ env.APPLICATION_INSIGHTS_CONNECTION_STRING
+ ) {
+ const { AzureMonitorTraceExporter } = await import(
+ "@azure/monitor-opentelemetry-exporter"
+ )
+ const { registerOTel } = await import("@vercel/otel")
+
+ const connectionString = env.APPLICATION_INSIGHTS_CONNECTION_STRING
+ const traceExporter = new AzureMonitorTraceExporter({ connectionString })
+
+ registerOTel({
+ serviceName: "scandic-web",
+ traceExporter,
+ })
+ }
+}
diff --git a/lib/graphql/Fragments/Blocks/LoyaltyCard.graphql b/lib/graphql/Fragments/Blocks/LoyaltyCard.graphql
new file mode 100644
index 000000000..fcd19ea65
--- /dev/null
+++ b/lib/graphql/Fragments/Blocks/LoyaltyCard.graphql
@@ -0,0 +1,28 @@
+fragment LoyaltyCardBlock on LoyaltyCard {
+ heading
+ body_text
+ image
+ title
+ link {
+ cta_text
+ open_in_new_tab
+ external_link {
+ title
+ href
+ }
+ linkConnection {
+ edges {
+ node {
+ __typename
+ ...LoyaltyPageLink
+ ...ContentPageLink
+ ...AccountPageLink
+ }
+ }
+ }
+ }
+ system {
+ locale
+ uid
+ }
+}
diff --git a/lib/graphql/Fragments/Blocks/Refs/Card.graphql b/lib/graphql/Fragments/Blocks/Refs/Card.graphql
index 3b3c33a9a..138a45b5e 100644
--- a/lib/graphql/Fragments/Blocks/Refs/Card.graphql
+++ b/lib/graphql/Fragments/Blocks/Refs/Card.graphql
@@ -1,4 +1,5 @@
fragment CardBlockRef on Card {
+ __typename
secondary_button {
linkConnection {
edges {
diff --git a/lib/graphql/Fragments/Blocks/Refs/LoyaltyCard.graphql b/lib/graphql/Fragments/Blocks/Refs/LoyaltyCard.graphql
new file mode 100644
index 000000000..2bb847c8c
--- /dev/null
+++ b/lib/graphql/Fragments/Blocks/Refs/LoyaltyCard.graphql
@@ -0,0 +1,18 @@
+fragment LoyaltyCardBlockRef on LoyaltyCard {
+ __typename
+ link {
+ linkConnection {
+ edges {
+ node {
+ __typename
+ ...LoyaltyPageRef
+ ...ContentPageRef
+ ...AccountPageRef
+ }
+ }
+ }
+ }
+ system {
+ ...System
+ }
+}
diff --git a/lib/graphql/Query/LoyaltyPage.graphql b/lib/graphql/Query/LoyaltyPage.graphql
index 668640ae0..1749eaac5 100644
--- a/lib/graphql/Query/LoyaltyPage.graphql
+++ b/lib/graphql/Query/LoyaltyPage.graphql
@@ -1,6 +1,10 @@
#import "../Fragments/Image.graphql"
#import "../Fragments/Blocks/Card.graphql"
+#import "../Fragments/Blocks/LoyaltyCard.graphql"
+
#import "../Fragments/Blocks/Refs/Card.graphql"
+#import "../Fragments/Blocks/Refs/LoyaltyCard.graphql"
+
#import "../Fragments/LoyaltyPage/Breadcrumbs.graphql"
#import "../Fragments/PageLink/AccountPageLink.graphql"
#import "../Fragments/PageLink/ContentPageLink.graphql"
@@ -83,7 +87,9 @@ query GetLoyaltyPage($locale: String!, $uid: String!) {
cardConnection(limit: 10) {
edges {
node {
+ __typename
...CardBlock
+ ...LoyaltyCardBlock
}
}
}
@@ -94,6 +100,11 @@ query GetLoyaltyPage($locale: String!, $uid: String!) {
heading
sidebar {
__typename
+ ... on LoyaltyPageSidebarDynamicContent {
+ dynamic_content {
+ component
+ }
+ }
... on LoyaltyPageSidebarJoinLoyaltyContact {
join_loyalty_contact {
title
@@ -104,6 +115,7 @@ query GetLoyaltyPage($locale: String!, $uid: String!) {
contact {
display_text
contact_field
+ footnote
}
}
}
@@ -206,6 +218,7 @@ query GetLoyaltyPageRefs($locale: String!, $uid: String!) {
edges {
node {
...CardBlockRef
+ ...LoyaltyCardBlockRef
}
}
}
diff --git a/next.config.js b/next.config.js
index 484a8fd94..921e1d3dc 100644
--- a/next.config.js
+++ b/next.config.js
@@ -13,6 +13,7 @@ const nextConfig = {
eslint: { ignoreDuringBuilds: true },
trailingSlash: false,
experimental: {
+ instrumentationHook: true,
serverActions: {
allowedOrigins: [
"*--web-scandic-hotels.netlify.app",
diff --git a/package-lock.json b/package-lock.json
index 250fa8c2c..88676b645 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.1.0",
"hasInstallScript": true,
"dependencies": {
+ "@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.24",
"@contentstack/live-preview-utils": "^1.4.0",
"@hookform/error-message": "^2.0.1",
"@hookform/resolvers": "^3.3.4",
@@ -20,6 +21,7 @@
"@trpc/client": "^11.0.0-next-beta.318",
"@trpc/react-query": "^11.0.0-next-beta.318",
"@trpc/server": "^11.0.0-next-beta.318",
+ "@vercel/otel": "^1.9.1",
"class-variance-authority": "^0.7.0",
"clean-deep": "^3.4.0",
"dayjs": "^1.11.10",
@@ -130,6 +132,156 @@
}
}
},
+ "node_modules/@azure/abort-controller": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
+ "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/core-auth": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.7.2.tgz",
+ "integrity": "sha512-Igm/S3fDYmnMq1uKS38Ae1/m37B3zigdlZw+kocwEhh5GjyKjPrXKO2J6rzpC1wAxrNil/jX9BJRqBshyjnF3g==",
+ "dependencies": {
+ "@azure/abort-controller": "^2.0.0",
+ "@azure/core-util": "^1.1.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/core-client": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.2.tgz",
+ "integrity": "sha512-kRdry/rav3fUKHl/aDLd/pDLcB+4pOFwPPTVEExuMyaI5r+JBbMWqRbCY1pn5BniDaU3lRxO9eaQ1AmSMehl/w==",
+ "dependencies": {
+ "@azure/abort-controller": "^2.0.0",
+ "@azure/core-auth": "^1.4.0",
+ "@azure/core-rest-pipeline": "^1.9.1",
+ "@azure/core-tracing": "^1.0.0",
+ "@azure/core-util": "^1.6.1",
+ "@azure/logger": "^1.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/core-rest-pipeline": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.16.1.tgz",
+ "integrity": "sha512-ExPSbgjwCoht6kB7B4MeZoBAxcQSIl29r/bPeazZJx50ej4JJCByimLOrZoIsurISNyJQQHf30b3JfqC3Hb88A==",
+ "dependencies": {
+ "@azure/abort-controller": "^2.0.0",
+ "@azure/core-auth": "^1.4.0",
+ "@azure/core-tracing": "^1.0.1",
+ "@azure/core-util": "^1.9.0",
+ "@azure/logger": "^1.0.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/core-rest-pipeline/node_modules/agent-base": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
+ "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
+ "dependencies": {
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@azure/core-rest-pipeline/node_modules/http-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@azure/core-rest-pipeline/node_modules/https-proxy-agent": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
+ "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/@azure/core-tracing": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.1.2.tgz",
+ "integrity": "sha512-dawW9ifvWAWmUm9/h+/UQ2jrdvjCJ7VJEuCJ6XVNudzcOwm53BFZH4Q845vjfgoUAM8ZxokvVNxNxAITc502YA==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/core-util": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.9.0.tgz",
+ "integrity": "sha512-AfalUQ1ZppaKuxPPMsFEUdX6GZPB3d9paR9d/TTL7Ow2De8cJaC7ibi7kWVlFAVPCYo31OcnGymc0R89DX8Oaw==",
+ "dependencies": {
+ "@azure/abort-controller": "^2.0.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/logger": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.2.tgz",
+ "integrity": "sha512-l170uE7bsKpIU6B/giRc9i4NI0Mj+tANMMMxf7Zi/5cKzEqPayP7+X1WPrG7e+91JgY8N+7K7nF2WOi7iVhXvg==",
+ "dependencies": {
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@azure/monitor-opentelemetry-exporter": {
+ "version": "1.0.0-beta.24",
+ "resolved": "https://registry.npmjs.org/@azure/monitor-opentelemetry-exporter/-/monitor-opentelemetry-exporter-1.0.0-beta.24.tgz",
+ "integrity": "sha512-oEYmQxfa40Rcqh358GeVd9MPQd9dHOxQJBsH1BwXW1aZ4cd9QwylEzAMrLvwJiHmaq0g4CzPnbtlpwxfb758Qg==",
+ "dependencies": {
+ "@azure/core-auth": "^1.3.0",
+ "@azure/core-client": "^1.0.0",
+ "@azure/core-rest-pipeline": "^1.1.0",
+ "@opentelemetry/api": "^1.9.0",
+ "@opentelemetry/api-logs": "^0.52.0",
+ "@opentelemetry/core": "^1.25.0",
+ "@opentelemetry/resources": "^1.25.0",
+ "@opentelemetry/sdk-logs": "^0.52.0",
+ "@opentelemetry/sdk-metrics": "^1.25.0",
+ "@opentelemetry/sdk-trace-base": "^1.25.0",
+ "@opentelemetry/semantic-conventions": "^1.25.0",
+ "tslib": "^2.6.2"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.24.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
@@ -3396,6 +3548,130 @@
"node": ">= 8"
}
},
+ "node_modules/@opentelemetry/api": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
+ "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@opentelemetry/api-logs": {
+ "version": "0.52.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.52.1.tgz",
+ "integrity": "sha512-qnSqB2DQ9TPP96dl8cDubDvrUyWc0/sK81xHTK8eSUspzDM3bsewX903qclQFvVhgStjRWdC5bLb3kQqMkfV5A==",
+ "dependencies": {
+ "@opentelemetry/api": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@opentelemetry/core": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-1.25.1.tgz",
+ "integrity": "sha512-GeT/l6rBYWVQ4XArluLVB6WWQ8flHbdb6r2FCHC3smtdOAbrJBIv35tpV/yp9bmYUJf+xmZpu9DRTIeJVhFbEQ==",
+ "dependencies": {
+ "@opentelemetry/semantic-conventions": "1.25.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/instrumentation": {
+ "version": "0.52.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.52.1.tgz",
+ "integrity": "sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw==",
+ "peer": true,
+ "dependencies": {
+ "@opentelemetry/api-logs": "0.52.1",
+ "@types/shimmer": "^1.0.2",
+ "import-in-the-middle": "^1.8.1",
+ "require-in-the-middle": "^7.1.1",
+ "semver": "^7.5.2",
+ "shimmer": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.3.0"
+ }
+ },
+ "node_modules/@opentelemetry/resources": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-1.25.1.tgz",
+ "integrity": "sha512-pkZT+iFYIZsVn6+GzM0kSX+u3MSLCY9md+lIJOoKl/P+gJFfxJte/60Usdp8Ce4rOs8GduUpSPNe1ddGyDT1sQ==",
+ "dependencies": {
+ "@opentelemetry/core": "1.25.1",
+ "@opentelemetry/semantic-conventions": "1.25.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-logs": {
+ "version": "0.52.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.52.1.tgz",
+ "integrity": "sha512-MBYh+WcPPsN8YpRHRmK1Hsca9pVlyyKd4BxOC4SsgHACnl/bPp4Cri9hWhVm5+2tiQ9Zf4qSc1Jshw9tOLGWQA==",
+ "dependencies": {
+ "@opentelemetry/api-logs": "0.52.1",
+ "@opentelemetry/core": "1.25.1",
+ "@opentelemetry/resources": "1.25.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.4.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-metrics": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-1.25.1.tgz",
+ "integrity": "sha512-9Mb7q5ioFL4E4dDrc4wC/A3NTHDat44v4I3p2pLPSxRvqUbDIQyMVr9uK+EU69+HWhlET1VaSrRzwdckWqY15Q==",
+ "dependencies": {
+ "@opentelemetry/core": "1.25.1",
+ "@opentelemetry/resources": "1.25.1",
+ "lodash.merge": "^4.6.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.3.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/sdk-trace-base": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.25.1.tgz",
+ "integrity": "sha512-C8k4hnEbc5FamuZQ92nTOp8X/diCY56XUTnMiv9UTuJitCzaNNHAVsdm5+HLCdI8SLQsLWIrG38tddMxLVoftw==",
+ "dependencies": {
+ "@opentelemetry/core": "1.25.1",
+ "@opentelemetry/resources": "1.25.1",
+ "@opentelemetry/semantic-conventions": "1.25.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": ">=1.0.0 <1.10.0"
+ }
+ },
+ "node_modules/@opentelemetry/semantic-conventions": {
+ "version": "1.25.1",
+ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.25.1.tgz",
+ "integrity": "sha512-ZDjMJJQRlyk8A1KZFCc+bCbsyrn1wTwdNt56F7twdfUfnHUZUq77/WfONCj8p72NZOyP7pNTdUWSTYC3GTbuuQ==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@panva/hkdf": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz",
@@ -5868,6 +6144,12 @@
"@types/node": "*"
}
},
+ "node_modules/@types/shimmer": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@types/shimmer/-/shimmer-1.0.5.tgz",
+ "integrity": "sha512-9Hp0ObzwwO57DpLFF0InUjUm/II8GmKAvzbefxQTihCb7KI6yc9yzf0nLc4mVdby5N4DRCgQM2wCup9KTieeww==",
+ "peer": true
+ },
"node_modules/@types/sinonjs__fake-timers": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
@@ -6050,6 +6332,23 @@
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
"dev": true
},
+ "node_modules/@vercel/otel": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/@vercel/otel/-/otel-1.9.1.tgz",
+ "integrity": "sha512-ZSTqgvd+w/lcB1nxEW8EHSBBqd4ZdeJ1t5op1CFo/nKFdG/EshwMon0qKc2ZxVEZXOZJI/x+LKf8Y5/Y/VHqEA==",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.7.0",
+ "@opentelemetry/api-logs": ">=0.46.0 && <1.0.0",
+ "@opentelemetry/instrumentation": ">=0.46.0 && <1.0.0",
+ "@opentelemetry/resources": "^1.19.0",
+ "@opentelemetry/sdk-logs": ">=0.46.0 && <1.0.0",
+ "@opentelemetry/sdk-metrics": "^1.19.0",
+ "@opentelemetry/sdk-trace-base": "^1.19.0"
+ }
+ },
"node_modules/abab": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
@@ -6074,7 +6373,6 @@
"version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
- "dev": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -6092,6 +6390,15 @@
"acorn-walk": "^8.0.2"
}
},
+ "node_modules/acorn-import-attributes": {
+ "version": "1.9.5",
+ "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
+ "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
+ "peer": true,
+ "peerDependencies": {
+ "acorn": "^8"
+ }
+ },
"node_modules/acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
@@ -7236,8 +7543,7 @@
"node_modules/cjs-module-lexer": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz",
- "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==",
- "dev": true
+ "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q=="
},
"node_modules/class-variance-authority": {
"version": "0.7.0",
@@ -8104,7 +8410,6 @@
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "dev": true,
"dependencies": {
"ms": "2.1.2"
},
@@ -9661,7 +9966,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -10108,7 +10412,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
- "dev": true,
"dependencies": {
"function-bind": "^1.1.2"
},
@@ -10340,6 +10643,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/import-in-the-middle": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-1.8.1.tgz",
+ "integrity": "sha512-yhRwoHtiLGvmSozNOALgjRPFI6uYsds60EoMqqnXyyv+JOIW/BrrLejuTGBt+bq0T5tLzOHrN0T7xYTm4Qt/ng==",
+ "peer": true,
+ "dependencies": {
+ "acorn": "^8.8.2",
+ "acorn-import-attributes": "^1.9.5",
+ "cjs-module-lexer": "^1.2.2",
+ "module-details-from-path": "^1.0.3"
+ }
+ },
"node_modules/import-local": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
@@ -10543,7 +10858,6 @@
"version": "2.13.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
"integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
- "dev": true,
"dependencies": {
"hasown": "^2.0.0"
},
@@ -13262,8 +13576,7 @@
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
},
"node_modules/lodash.once": {
"version": "4.1.1",
@@ -13820,6 +14133,12 @@
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
"dev": true
},
+ "node_modules/module-details-from-path": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz",
+ "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==",
+ "peer": true
+ },
"node_modules/morgan": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
@@ -13871,8 +14190,7 @@
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "dev": true
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/mustache": {
"version": "4.2.0",
@@ -14594,8 +14912,7 @@
"node_modules/path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"node_modules/path-scurry": {
"version": "1.10.2",
@@ -15635,6 +15952,20 @@
"node": ">=0.10.0"
}
},
+ "node_modules/require-in-the-middle": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-7.3.0.tgz",
+ "integrity": "sha512-nQFEv9gRw6SJAwWD2LrL0NmQvAcO7FBwJbwmr2ttPAacfy0xuiOjE5zt+zM4xDyuyvUaxBi/9gb2SoCyNEVJcw==",
+ "peer": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "module-details-from-path": "^1.0.3",
+ "resolve": "^1.22.1"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -15651,7 +15982,6 @@
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
- "dev": true,
"dependencies": {
"is-core-module": "^2.13.0",
"path-parse": "^1.0.7",
@@ -15978,7 +16308,6 @@
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
- "dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
@@ -15993,7 +16322,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -16134,6 +16462,12 @@
"node": ">=8"
}
},
+ "node_modules/shimmer": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz",
+ "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==",
+ "peer": true
+ },
"node_modules/side-channel": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
@@ -16759,7 +17093,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
"engines": {
"node": ">= 0.4"
},
@@ -17981,8 +18314,7 @@
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/yaml": {
"version": "2.3.4",
diff --git a/package.json b/package.json
index 39570cd65..04649dc82 100644
--- a/package.json
+++ b/package.json
@@ -25,6 +25,7 @@
"test:unit:watch": "jest --watch"
},
"dependencies": {
+ "@azure/monitor-opentelemetry-exporter": "^1.0.0-beta.24",
"@contentstack/live-preview-utils": "^1.4.0",
"@hookform/error-message": "^2.0.1",
"@hookform/resolvers": "^3.3.4",
@@ -36,6 +37,7 @@
"@trpc/client": "^11.0.0-next-beta.318",
"@trpc/react-query": "^11.0.0-next-beta.318",
"@trpc/server": "^11.0.0-next-beta.318",
+ "@vercel/otel": "^1.9.1",
"class-variance-authority": "^0.7.0",
"clean-deep": "^3.4.0",
"dayjs": "^1.11.10",
diff --git a/server/routers/contentstack/base/output.ts b/server/routers/contentstack/base/output.ts
index ce217f241..3c81aae88 100644
--- a/server/routers/contentstack/base/output.ts
+++ b/server/routers/contentstack/base/output.ts
@@ -59,6 +59,7 @@ export type ContactConfig = ContactConfigData["all_contact_config"]["items"][0]
export type ContactFields = {
display_text: string | null
contact_field: string
+ footnote: string | null
}
export const validateHeaderConfigSchema = z.object({
diff --git a/server/routers/contentstack/loyaltyPage/output.ts b/server/routers/contentstack/loyaltyPage/output.ts
index 2cd7dd427..83a5ac8d0 100644
--- a/server/routers/contentstack/loyaltyPage/output.ts
+++ b/server/routers/contentstack/loyaltyPage/output.ts
@@ -2,10 +2,13 @@ import { z } from "zod"
import { Lang } from "@/constants/languages"
+import { ImageVaultAsset } from "@/types/components/imageVaultImage"
import {
JoinLoyaltyContactTypenameEnum,
LoyaltyBlocksTypenameEnum,
+ LoyaltyCardsGridEnum,
LoyaltyComponentEnum,
+ LoyaltySidebarDynamicComponentEnum,
SidebarTypenameEnum,
} from "@/types/components/loyalty/enums"
import { Embeds } from "@/types/requests/embeds"
@@ -47,6 +50,7 @@ const loyaltyPageShortcuts = z.object({
})
const cardBlock = z.object({
+ __typename: z.literal(LoyaltyCardsGridEnum.Card),
heading: z.string().nullable(),
body_text: z.string().nullable(),
background_image: z.any(),
@@ -73,6 +77,30 @@ const cardBlock = z.object({
}),
})
+const loyaltyCardBlock = z.object({
+ __typename: z.literal(LoyaltyCardsGridEnum.LoyaltyCard),
+ heading: z.string().nullable(),
+ body_text: z.string().nullable(),
+ image: z.any(),
+ link: z
+ .object({
+ openInNewTab: z.boolean(),
+ title: z.string(),
+ href: z.string(),
+ isExternal: z.boolean(),
+ })
+ .optional(),
+ system: z.object({
+ locale: z.nativeEnum(Lang),
+ uid: z.string(),
+ }),
+})
+
+const loyaltyPageCardsItems = z.discriminatedUnion("__typename", [
+ loyaltyCardBlock,
+ cardBlock,
+])
+
const loyaltyPageCards = z.object({
__typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid),
cards_grid: z.object({
@@ -80,7 +108,7 @@ const loyaltyPageCards = z.object({
preamble: z.string().nullable(),
layout: z.enum(["twoColumnGrid", "threeColumnGrid", "twoPlusOne"]),
theme: z.enum(["one", "two", "three"]).nullable(),
- cards: z.array(cardBlock),
+ cards: z.array(loyaltyPageCardsItems),
}),
})
@@ -132,14 +160,23 @@ const loyaltyPageJoinLoyaltyContact = z.object({
contact: z.object({
display_text: z.string().nullable(),
contact_field: z.string(),
+ footnote: z.string().nullable(),
}),
})
),
}),
})
+const loyaltyPageSidebarDynamicContent = z.object({
+ __typename: z.literal(SidebarTypenameEnum.LoyaltyPageSidebarDynamicContent),
+ dynamic_content: z.object({
+ component: z.nativeEnum(LoyaltySidebarDynamicComponentEnum),
+ }),
+})
+
const loyaltyPageSidebarItem = z.discriminatedUnion("__typename", [
loyaltyPageSidebarTextContent,
+ loyaltyPageSidebarDynamicContent,
loyaltyPageJoinLoyaltyContact,
])
@@ -151,7 +188,6 @@ export const validateLoyaltyPageSchema = z.object({
})
// Block types
-
export type DynamicContent = z.infer
type BlockContentRaw = z.infer
@@ -164,11 +200,25 @@ export interface RteBlockContent extends BlockContentRaw {
}
}
+type LoyaltyCardRaw = z.infer
+
+type LoyaltyCard = Omit & {
+ image?: ImageVaultAsset
+}
+
+type CardRaw = z.infer
+
+type Card = Omit & {
+ backgroundImage?: ImageVaultAsset
+}
+
type CardsGridRaw = z.infer
-export type CardsRaw = CardsGridRaw["cards_grid"]["cards"][number]
+export type CardsGrid = Omit & {
+ cards: (LoyaltyCard | Card)[]
+}
-export type CardsGrid = z.infer
+export type CardsRaw = CardsGrid["cards_grid"]["cards"][number]
export type Shortcuts = z.infer
@@ -185,8 +235,13 @@ export type RteSidebarContent = Omit & {
}
}
}
+type SideBarDynamicContent = z.infer
+
export type JoinLoyaltyContact = z.infer
-export type Sidebar = JoinLoyaltyContact | RteSidebarContent
+export type Sidebar =
+ | JoinLoyaltyContact
+ | RteSidebarContent
+ | SideBarDynamicContent
type LoyaltyPageDataRaw = z.infer
export type LoyaltyPage = Omit & {
@@ -210,6 +265,7 @@ const pageConnectionRefs = z.object({
})
const cardBlockRefs = z.object({
+ __typename: z.literal(LoyaltyCardsGridEnum.Card),
primary_button: z
.object({
linkConnection: pageConnectionRefs,
@@ -227,13 +283,32 @@ const cardBlockRefs = z.object({
}),
})
+const loyaltyCardBlockRefs = z.object({
+ __typename: z.literal(LoyaltyCardsGridEnum.LoyaltyCard),
+ link: z
+ .object({
+ linkConnection: pageConnectionRefs,
+ })
+ .nullable(),
+
+ system: z.object({
+ content_type_uid: z.string(),
+ uid: z.string(),
+ }),
+})
+
+const cardGridCardsRef = z.discriminatedUnion("__typename", [
+ loyaltyCardBlockRefs,
+ cardBlockRefs,
+])
+
const loyaltyPageCardsRefs = z.object({
__typename: z.literal(LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid),
cards_grid: z.object({
cardConnection: z.object({
edges: z.array(
z.object({
- node: cardBlockRefs,
+ node: cardGridCardsRef,
})
),
}),
diff --git a/server/routers/contentstack/loyaltyPage/query.ts b/server/routers/contentstack/loyaltyPage/query.ts
index dcd711b65..c4d3c0bff 100644
--- a/server/routers/contentstack/loyaltyPage/query.ts
+++ b/server/routers/contentstack/loyaltyPage/query.ts
@@ -11,6 +11,7 @@ import {
generateTag,
generateTags,
} from "@/utils/generateTag"
+import { insertResponseToImageVaultAsset } from "@/utils/imageVault"
import { removeMultipleSlashes } from "@/utils/url"
import { removeEmptyObjects } from "../../utils"
@@ -22,7 +23,17 @@ import {
} from "./output"
import { getConnections } from "./utils"
-import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
+import { InsertResponse } from "@/types/components/imageVaultImage"
+import {
+ LoyaltyBlocksTypenameEnum,
+ LoyaltyCardsGridEnum,
+} from "@/types/components/loyalty/enums"
+
+function makeImageVaultImage(image: any) {
+ return image && !!Object.keys(image).length
+ ? insertResponseToImageVaultAsset(image as InsertResponse)
+ : undefined
+}
function makeButtonObject(button: any) {
return {
@@ -35,9 +46,9 @@ function makeButtonObject(button: any) {
href:
button.is_contentstack_link && button.linkConnection.edges.length
? button.linkConnection.edges[0].node.web?.original_url ||
- removeMultipleSlashes(
- `/${button.linkConnection.edges[0].node.system.locale}/${button.linkConnection.edges[0].node.url}`
- )
+ removeMultipleSlashes(
+ `/${button.linkConnection.edges[0].node.system.locale}/${button.linkConnection.edges[0].node.url}`
+ )
: button.external_link.href,
isExternal: !button.is_contentstack_link,
}
@@ -96,66 +107,82 @@ export const loyaltyPageQueryRouter = router({
const blocks = response.data.loyalty_page.blocks
? response.data.loyalty_page.blocks.map((block: any) => {
- switch (block.__typename) {
- case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent:
- return {
- ...block,
- dynamic_content: {
- ...block.dynamic_content,
- link: block.dynamic_content.link.pageConnection.edges.length
- ? {
- text: block.dynamic_content.link.text,
- href: removeMultipleSlashes(
- `/${block.dynamic_content.link.pageConnection.edges[0].node.system.locale}/${block.dynamic_content.link.pageConnection.edges[0].node.url}`
- ),
- title:
- block.dynamic_content.link.pageConnection.edges[0]
- .node.title,
- }
- : undefined,
- },
- }
- case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
- return {
- ...block,
- shortcuts: {
- ...block.shortcuts,
- shortcuts: block.shortcuts.shortcuts.map((shortcut: any) => ({
- text: shortcut.text,
- openInNewTab: shortcut.open_in_new_tab,
- ...shortcut.linkConnection.edges[0].node,
- url:
- shortcut.linkConnection.edges[0].node.web?.original_url ||
- removeMultipleSlashes(
- `/${shortcut.linkConnection.edges[0].node.system.locale}/${shortcut.linkConnection.edges[0].node.url}`
- ),
- })),
- },
- }
- case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid:
- return {
- ...block,
- cards_grid: {
- ...block.cards_grid,
- cards: block.cards_grid.cardConnection.edges.map(
- ({ node: card }: { node: any }) => {
- return {
- ...card,
- primaryButton: card.has_primary_button
- ? makeButtonObject(card.primary_button)
- : undefined,
- secondaryButton: card.has_secondary_button
- ? makeButtonObject(card.secondary_button)
- : undefined,
+ switch (block.__typename) {
+ case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksDynamicContent:
+ return {
+ ...block,
+ dynamic_content: {
+ ...block.dynamic_content,
+ link: block.dynamic_content.link.pageConnection.edges.length
+ ? {
+ text: block.dynamic_content.link.text,
+ href: removeMultipleSlashes(
+ `/${block.dynamic_content.link.pageConnection.edges[0].node.system.locale}/${block.dynamic_content.link.pageConnection.edges[0].node.url}`
+ ),
+ title:
+ block.dynamic_content.link.pageConnection.edges[0]
+ .node.title,
+ }
+ : undefined,
+ },
+ }
+ case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts:
+ return {
+ ...block,
+ shortcuts: {
+ ...block.shortcuts,
+ shortcuts: block.shortcuts.shortcuts.map((shortcut: any) => ({
+ text: shortcut.text,
+ openInNewTab: shortcut.open_in_new_tab,
+ ...shortcut.linkConnection.edges[0].node,
+ url:
+ shortcut.linkConnection.edges[0].node.web?.original_url ||
+ removeMultipleSlashes(
+ `/${shortcut.linkConnection.edges[0].node.system.locale}/${shortcut.linkConnection.edges[0].node.url}`
+ ),
+ })),
+ },
+ }
+ case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid:
+ return {
+ ...block,
+ cards_grid: {
+ ...block.cards_grid,
+ cards: block.cards_grid.cardConnection.edges.map(
+ ({ node: card }: { node: any }) => {
+ switch (card.__typename) {
+ case LoyaltyCardsGridEnum.LoyaltyCard:
+ return {
+ ...card,
+ image: makeImageVaultImage(card.image),
+ link: makeButtonObject({
+ ...card.link,
+ is_contentstack_link:
+ !!card.link.linkConnection.edges.length,
+ }),
+ }
+ case LoyaltyCardsGridEnum.Card:
+ return {
+ ...card,
+ backgroundImage: makeImageVaultImage(
+ card.background_image
+ ),
+ primaryButton: card.has_primary_button
+ ? makeButtonObject(card.primary_button)
+ : undefined,
+ secondaryButton: card.has_secondary_button
+ ? makeButtonObject(card.secondary_button)
+ : undefined,
+ }
+ }
}
- }
- ),
- },
- }
- default:
- return block
- }
- })
+ ),
+ },
+ }
+ default:
+ return block
+ }
+ })
: null
const loyaltyPage = {
diff --git a/server/routers/contentstack/loyaltyPage/utils.ts b/server/routers/contentstack/loyaltyPage/utils.ts
index e56207061..409ebadef 100644
--- a/server/routers/contentstack/loyaltyPage/utils.ts
+++ b/server/routers/contentstack/loyaltyPage/utils.ts
@@ -1,6 +1,9 @@
import { LoyaltyPageRefsDataRaw } from "./output"
-import { LoyaltyBlocksTypenameEnum } from "@/types/components/loyalty/enums"
+import {
+ LoyaltyBlocksTypenameEnum,
+ LoyaltyCardsGridEnum,
+} from "@/types/components/loyalty/enums"
import type { Edges } from "@/types/requests/utils/edges"
import type { NodeRefs } from "@/types/requests/utils/refs"
@@ -18,13 +21,23 @@ export function getConnections(refs: LoyaltyPageRefsDataRaw) {
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksCardsGrid: {
connections.push(item.cards_grid.cardConnection)
item.cards_grid.cardConnection.edges.forEach((card) => {
- if (card.node.primary_button) {
- connections.push(card.node.primary_button?.linkConnection)
- } else if (card.node.secondary_button) {
- connections.push(card.node.secondary_button?.linkConnection)
+ switch (card.node.__typename) {
+ case LoyaltyCardsGridEnum.LoyaltyCard: {
+ if (card.node.link) {
+ connections.push(card.node.link?.linkConnection)
+ }
+ break
+ }
+ case LoyaltyCardsGridEnum.Card: {
+ if (card.node.primary_button) {
+ connections.push(card.node.primary_button?.linkConnection)
+ } else if (card.node.secondary_button) {
+ connections.push(card.node.secondary_button?.linkConnection)
+ }
+ break
+ }
}
})
-
break
}
case LoyaltyBlocksTypenameEnum.LoyaltyPageBlocksShortcuts: {
diff --git a/types/components/loyalty/blocks.ts b/types/components/loyalty/blocks.ts
index c06475cb1..f9f337344 100644
--- a/types/components/loyalty/blocks.ts
+++ b/types/components/loyalty/blocks.ts
@@ -24,7 +24,9 @@ export type DynamicComponentProps = {
component: DynamicContent["dynamic_content"]["component"]
}
-export type CardsGridProps = Pick
+export type CardsGridProps = Pick & {
+ firstItem?: boolean
+}
export type Content = { content: RteBlockContent["content"]["content"] }
diff --git a/types/components/loyalty/enums.ts b/types/components/loyalty/enums.ts
index 077c439cb..4859d23eb 100644
--- a/types/components/loyalty/enums.ts
+++ b/types/components/loyalty/enums.ts
@@ -13,10 +13,15 @@ export type JoinLoyaltyContactContact = Typename<
export enum SidebarTypenameEnum {
LoyaltyPageSidebarJoinLoyaltyContact = "LoyaltyPageSidebarJoinLoyaltyContact",
LoyaltyPageSidebarContent = "LoyaltyPageSidebarContent",
+ LoyaltyPageSidebarDynamicContent = "LoyaltyPageSidebarDynamicContent",
}
export type SidebarTypename = keyof typeof SidebarTypenameEnum
+export enum LoyaltySidebarDynamicComponentEnum {
+ my_pages_navigation = "my_pages_navigation",
+}
+
export enum LoyaltyComponentEnum {
loyalty_levels = "loyalty_levels",
how_it_works = "how_it_works",
@@ -31,3 +36,8 @@ export enum LoyaltyBlocksTypenameEnum {
LoyaltyPageBlocksShortcuts = "LoyaltyPageBlocksShortcuts",
LoyaltyPageBlocksCardsGrid = "LoyaltyPageBlocksCardsGrid",
}
+
+export enum LoyaltyCardsGridEnum {
+ LoyaltyCard = "LoyaltyCard",
+ Card = "Card",
+}