diff --git a/.env.local.example b/.env.local.example index e1b8e182f..c6f85bec7 100644 --- a/.env.local.example +++ b/.env.local.example @@ -51,5 +51,6 @@ GOOGLE_STATIC_MAP_SIGNATURE_SECRET="" GOOGLE_STATIC_MAP_ID="" GOOGLE_DYNAMIC_MAP_ID="" -HIDE_FOR_NEXT_RELEASE="true" +HIDE_FOR_NEXT_RELEASE="false" +SHOW_SIGNUP_FLOW="true" USE_NEW_REWARDS_ENDPOINT="true" diff --git a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx index d96f10f38..215e3aec8 100644 --- a/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx +++ b/app/[lang]/(live)/(public)/[contentType]/[uid]/page.tsx @@ -1,5 +1,7 @@ +import { headers } from "next/headers" import { notFound } from "next/navigation" +import { isSignupPage } from "@/constants/routes/signup" import { env } from "@/env/server" import HotelPage from "@/components/ContentType/HotelPage" @@ -22,17 +24,33 @@ export default function ContentTypePage({ }: PageArgs) { setLang(params.lang) + const pathname = headers().get("x-pathname") || "" + switch (params.contentType) { case "collection-page": if (env.HIDE_FOR_NEXT_RELEASE) { return notFound() } return - case "content-page": + case "content-page": { + const isSignupRoute = isSignupPage(pathname) + if (env.HIDE_FOR_NEXT_RELEASE) { - return notFound() + // Hide content pages for next release for non-signup routes. + if (!isSignupRoute) { + return notFound() + } } + + if (!env.SHOW_SIGNUP_FLOW) { + // Hide content pages for signup routes when signup flow is disabled. + if (isSignupRoute) { + return notFound() + } + } + return + } case "loyalty-page": return case "hotel-page": diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.module.css b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.module.css index 89de83d4d..8bf36ee38 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.module.css +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.module.css @@ -1,21 +1,23 @@ .main { display: flex; - gap: var(--Spacing-x3); - padding: var(--Spacing-x4) var(--Spacing-x4) 0 var(--Spacing-x4); + padding: 0 var(--Spacing-x2) var(--Spacing-x3) var(--Spacing-x2); background-color: var(--Scandic-Brand-Warm-White); min-height: 100dvh; flex-direction: column; max-width: var(--max-width); margin: 0 auto; } - .header { display: flex; - margin: 0 auto; - padding: var(--Spacing-x4) var(--Spacing-x5) var(--Spacing-x3) - var(--Spacing-x5); - justify-content: space-between; - max-width: var(--max-width); + flex-direction: column; + gap: var(--Spacing-x2); + padding: var(--Spacing-x3) var(--Spacing-x2) 0 var(--Spacing-x2); +} + +.cityInformation { + display: flex; + flex-wrap: wrap; + gap: var(--Spacing-x1); } .sideBar { @@ -46,6 +48,23 @@ } @media (min-width: 768px) { + .main { + padding: var(--Spacing-x5); + } + .header { + display: block; + background-color: var(--Base-Surface-Subtle-Normal); + padding: var(--Spacing-x4) var(--Spacing-x5) var(--Spacing-x3) + var(--Spacing-x5); + } + + .title { + margin: 0 auto; + display: flex; + max-width: var(--max-width-navigation); + align-items: center; + justify-content: space-between; + } .link { display: flex; padding-bottom: var(--Spacing-x6); @@ -57,13 +76,6 @@ border-radius: var(--Corner-radius-Medium); border: 1px solid var(--Base-Border-Subtle); } - .mapLinkText { - display: flex; - align-items: center; - justify-content: center; - gap: var(--Spacing-x-half); - padding: var(--Spacing-x-one-and-half) var(--Spacing-x0); - } .main { flex-direction: row; gap: var(--Spacing-x5); diff --git a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx index 4dfefd7ac..0493c9d70 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-hotel/page.tsx @@ -18,7 +18,10 @@ import { import { ChevronRightIcon } from "@/components/Icons" import StaticMap from "@/components/Maps/StaticMap" import Alert from "@/components/TempDesignSystem/Alert" +import Button from "@/components/TempDesignSystem/Button" import Link from "@/components/TempDesignSystem/Link" +import Preamble from "@/components/TempDesignSystem/Text/Preamble" +import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import { getIntl } from "@/i18n" import { setLang } from "@/i18n/serverContext" @@ -66,8 +69,14 @@ export default async function SelectHotelPage({ return ( <>
-
{city.name}
- +
+
+ {city.name} + {hotels.length} hotels +
+ +
+
@@ -87,10 +96,14 @@ export default async function SelectHotelPage({ mapType="roadmap" altText={`Map of ${searchParams.city} city center`} /> -
- {intl.formatMessage({ id: "Show map" })} - -
+
) : ( @@ -105,7 +118,6 @@ export default async function SelectHotelPage({ /> )} -
diff --git a/components/Blocks/DynamicContent/SignUpVerification/index.tsx b/components/Blocks/DynamicContent/SignUpVerification/index.tsx index 2b182d4bf..4ae9fd899 100644 --- a/components/Blocks/DynamicContent/SignUpVerification/index.tsx +++ b/components/Blocks/DynamicContent/SignUpVerification/index.tsx @@ -1,8 +1,8 @@ import { redirect } from "next/navigation" import { overview } from "@/constants/routes/myPages" +import { getProfileSafely } from "@/lib/trpc/memoizedRequests" -import { auth } from "@/auth" import LoginButton from "@/components/LoginButton" import { getIntl } from "@/i18n" import { getLang } from "@/i18n/serverContext" @@ -14,8 +14,8 @@ import type { SignUpVerificationProps } from "@/types/components/blocks/dynamicC export default async function SignUpVerification({ dynamic_content, }: SignUpVerificationProps) { - const session = await auth() - if (session) { + const user = await getProfileSafely() + if (user) { redirect(overview[getLang()]) } const intl = await getIntl() diff --git a/components/Blocks/DynamicContent/SignupFormWrapper/index.tsx b/components/Blocks/DynamicContent/SignupFormWrapper/index.tsx index bf6af6294..7daf85588 100644 --- a/components/Blocks/DynamicContent/SignupFormWrapper/index.tsx +++ b/components/Blocks/DynamicContent/SignupFormWrapper/index.tsx @@ -1,8 +1,8 @@ import { redirect } from "next/navigation" import { overview } from "@/constants/routes/myPages" +import { getProfileSafely } from "@/lib/trpc/memoizedRequests" -import { auth } from "@/auth" import SignupForm from "@/components/Forms/Signup" import { getLang } from "@/i18n/serverContext" @@ -11,8 +11,8 @@ import { SignupFormWrapperProps } from "@/types/components/blocks/dynamicContent export default async function SignupFormWrapper({ dynamic_content, }: SignupFormWrapperProps) { - const session = await auth() - if (session) { + const user = await getProfileSafely() + if (user) { // We don't want to allow users to access signup if they are already authenticated. redirect(overview[getLang()]) } diff --git a/components/BookingWidget/Client.tsx b/components/BookingWidget/Client.tsx index 3f7bc5ca3..cb5e308b5 100644 --- a/components/BookingWidget/Client.tsx +++ b/components/BookingWidget/Client.tsx @@ -177,7 +177,7 @@ export default function BookingWidgetClient({ > -
+
diff --git a/components/DatePicker/index.tsx b/components/DatePicker/index.tsx index 962a8fc96..b115a163d 100644 --- a/components/DatePicker/index.tsx +++ b/components/DatePicker/index.tsx @@ -123,7 +123,12 @@ export default function DatePickerForm({ name = "date" }: DatePickerFormProps) { data-isopen={isOpen} ref={ref} > - ) } diff --git a/components/HotelReservation/SelectHotel/HotelSorter/hotelSorter.module.css b/components/HotelReservation/SelectHotel/HotelSorter/hotelSorter.module.css index 7c991c602..535808a35 100644 --- a/components/HotelReservation/SelectHotel/HotelSorter/hotelSorter.module.css +++ b/components/HotelReservation/SelectHotel/HotelSorter/hotelSorter.module.css @@ -1,3 +1,9 @@ .container { width: 339px; } + +@media (max-width: 768px) { + .container { + display: none; + } +} diff --git a/components/HotelReservation/SelectHotel/HotelSorter/index.tsx b/components/HotelReservation/SelectHotel/HotelSorter/index.tsx index d9a364fcd..2e48364a1 100644 --- a/components/HotelReservation/SelectHotel/HotelSorter/index.tsx +++ b/components/HotelReservation/SelectHotel/HotelSorter/index.tsx @@ -40,7 +40,7 @@ export default function HotelSorter() { ) const sortItems: SortItem[] = [ { - label: intl.formatMessage({ id: "Distance to city center" }), + label: intl.formatMessage({ id: "Distance to city centre" }), value: SortOrder.Distance, }, { label: intl.formatMessage({ id: "Name" }), value: SortOrder.Name }, diff --git a/components/Icons/Logos/ScandicLogo.tsx b/components/Icons/Logos/ScandicLogo.tsx index cdb992753..f96025768 100644 --- a/components/Icons/Logos/ScandicLogo.tsx +++ b/components/Icons/Logos/ScandicLogo.tsx @@ -11,52 +11,52 @@ export default function ScandicLogoIcon({ return ( ) diff --git a/components/TempDesignSystem/Tooltip/index.tsx b/components/TempDesignSystem/Tooltip/index.tsx index ce133b5ee..033fc9a04 100644 --- a/components/TempDesignSystem/Tooltip/index.tsx +++ b/components/TempDesignSystem/Tooltip/index.tsx @@ -1,4 +1,4 @@ -import { PropsWithChildren } from "react" +import { PropsWithChildren, useState } from "react" import Caption from "@/components/TempDesignSystem/Text/Caption" @@ -16,8 +16,20 @@ export function Tooltip

({ children, }: PropsWithChildren>) { const className = tooltipVariants({ position, arrow }) + const [isActive, setIsActive] = useState(false) + + function handleToggle() { + setIsActive(!isActive) + } + return ( -

+
{heading && ( diff --git a/components/TempDesignSystem/Tooltip/tooltip.module.css b/components/TempDesignSystem/Tooltip/tooltip.module.css index 58676e967..e25433f7c 100644 --- a/components/TempDesignSystem/Tooltip/tooltip.module.css +++ b/components/TempDesignSystem/Tooltip/tooltip.module.css @@ -140,3 +140,15 @@ border-width: 7px 8px 7px 0; border-color: transparent var(--UI-Text-Active) transparent transparent; } + +@media screen and (max-width: 768px) { + .tooltipContainer[data-active="true"] .tooltip { + visibility: visible; + opacity: 1; + } + + .tooltipContainer[data-active="false"] .tooltip { + visibility: hidden; + opacity: 0; + } +} diff --git a/constants/routes/signup.ts b/constants/routes/signup.ts index 82a39ee41..4c63cc47d 100644 --- a/constants/routes/signup.ts +++ b/constants/routes/signup.ts @@ -17,3 +17,8 @@ export const signupVerify: LangRoute = { da: `${signup.da}/bekraeft`, de: `${signup.de}/verifizieren`, } + +export function isSignupPage(path: string): boolean { + const signupPaths = [...Object.values(signup), ...Object.values(signupVerify)] + return signupPaths.some((signupPath) => signupPath.includes(path)) +} diff --git a/env/server.ts b/env/server.ts index 1f81557ce..57fc05acf 100644 --- a/env/server.ts +++ b/env/server.ts @@ -60,6 +60,13 @@ export const env = createEnv({ SEAMLESS_LOGOUT_FI: z.string(), SEAMLESS_LOGOUT_NO: z.string(), SEAMLESS_LOGOUT_SV: z.string(), + SHOW_SIGNUP_FLOW: z + .string() + // only allow "true" or "false" + .refine((s) => s === "true" || s === "false") + // transform to boolean + .transform((s) => s === "true") + .default("false"), WEBVIEW_ENCRYPTION_KEY: z.string(), BOOKING_ENCRYPTION_KEY: z.string(), GOOGLE_STATIC_MAP_KEY: z.string(), @@ -125,6 +132,7 @@ export const env = createEnv({ SEAMLESS_LOGOUT_FI: process.env.SEAMLESS_LOGOUT_FI, SEAMLESS_LOGOUT_NO: process.env.SEAMLESS_LOGOUT_NO, SEAMLESS_LOGOUT_SV: process.env.SEAMLESS_LOGOUT_SV, + SHOW_SIGNUP_FLOW: process.env.SHOW_SIGNUP_FLOW, WEBVIEW_ENCRYPTION_KEY: process.env.WEBVIEW_ENCRYPTION_KEY, BOOKING_ENCRYPTION_KEY: process.env.BOOKING_ENCRYPTION_KEY, GOOGLE_STATIC_MAP_KEY: process.env.GOOGLE_STATIC_MAP_KEY, diff --git a/i18n/dictionaries/da.json b/i18n/dictionaries/da.json index 6529382a8..47feb8b4e 100644 --- a/i18n/dictionaries/da.json +++ b/i18n/dictionaries/da.json @@ -297,6 +297,7 @@ "See details": "Se detaljer", "See hotel details": "Se hoteloplysninger", "See less FAQ": "Se mindre FAQ", + "See map": "Vis kort", "See on map": "Se på kort", "See room details": "Se værelsesdetaljer", "See rooms": "Se værelser", @@ -314,7 +315,6 @@ "Show all amenities": "Vis alle faciliteter", "Show less": "Vis mindre", "Show less rooms": "Vise færre rum", - "Show map": "Vis kort", "Show more": "Vis mere", "Show more rooms": "Vise flere rum", "Sign up bonus": "Velkomstbonus", diff --git a/i18n/dictionaries/de.json b/i18n/dictionaries/de.json index f69e9bb0e..91256509d 100644 --- a/i18n/dictionaries/de.json +++ b/i18n/dictionaries/de.json @@ -296,6 +296,7 @@ "See details": "Siehe Einzelheiten", "See hotel details": "Hotelinformationen ansehen", "See less FAQ": "Weniger anzeigen FAQ", + "See map": "Karte anzeigen", "See on map": "Karte ansehen", "See room details": "Zimmerdetails ansehen", "See rooms": "Zimmer ansehen", @@ -313,7 +314,6 @@ "Show all amenities": "Alle Annehmlichkeiten anzeigen", "Show less": "Weniger anzeigen", "Show less rooms": "Weniger Zimmer anzeigen", - "Show map": "Karte anzeigen", "Show more": "Mehr anzeigen", "Show more rooms": "Weitere Räume anzeigen", "Sign up bonus": "Anmelde-Bonus", diff --git a/i18n/dictionaries/en.json b/i18n/dictionaries/en.json index 049adce52..664069250 100644 --- a/i18n/dictionaries/en.json +++ b/i18n/dictionaries/en.json @@ -325,6 +325,7 @@ "See details": "See details", "See hotel details": "See hotel details", "See less FAQ": "See less FAQ", + "See map": "See map", "See on map": "See on map", "See room details": "See room details", "See rooms": "See rooms", @@ -343,7 +344,6 @@ "Show all amenities": "Show all amenities", "Show less": "Show less", "Show less rooms": "Show less rooms", - "Show map": "Show map", "Show more": "Show more", "Show more rooms": "Show more rooms", "Sign up bonus": "Sign up bonus", diff --git a/i18n/dictionaries/fi.json b/i18n/dictionaries/fi.json index 30b5afff0..ca9e330ea 100644 --- a/i18n/dictionaries/fi.json +++ b/i18n/dictionaries/fi.json @@ -298,6 +298,7 @@ "See details": "Katso tiedot", "See hotel details": "Katso hotellin tiedot", "See less FAQ": "Katso vähemmän UKK", + "See map": "Näytä kartta", "See on map": "Näytä kartalla", "See room details": "Katso huoneen tiedot", "See rooms": "Katso huoneet", @@ -315,7 +316,6 @@ "Show all amenities": "Näytä kaikki mukavuudet", "Show less": "Näytä vähemmän", "Show less rooms": "Näytä vähemmän huoneita", - "Show map": "Näytä kartta", "Show more": "Näytä lisää", "Show more rooms": "Näytä lisää huoneita", "Sign up bonus": "Liittymisbonus", diff --git a/i18n/dictionaries/no.json b/i18n/dictionaries/no.json index 5db8c271f..2c61f1596 100644 --- a/i18n/dictionaries/no.json +++ b/i18n/dictionaries/no.json @@ -295,6 +295,7 @@ "See details": "Se detaljer", "See hotel details": "Se hotellinformasjon", "See less FAQ": "Se mindre FAQ", + "See map": "Vis kart", "See on map": "Se på kart", "See room details": "Se detaljer om rommet", "See rooms": "Se rom", @@ -312,7 +313,6 @@ "Show all amenities": "Vis alle fasiliteter", "Show less": "Vis mindre", "Show less rooms": "Vise færre rom", - "Show map": "Vis kart", "Show more": "Vis mer", "Show more rooms": "Vise flere rom", "Sign up bonus": "Velkomstbonus", diff --git a/i18n/dictionaries/sv.json b/i18n/dictionaries/sv.json index e466c1524..911553c7b 100644 --- a/i18n/dictionaries/sv.json +++ b/i18n/dictionaries/sv.json @@ -295,6 +295,7 @@ "See details": "Se detaljer", "See hotel details": "Se hotellinformation", "See less FAQ": "See färre FAQ", + "See map": "Visa karta", "See on map": "Se på karta", "See room details": "Se rumsdetaljer", "See rooms": "Se rum", @@ -312,7 +313,6 @@ "Show all amenities": "Visa alla bekvämligheter", "Show less": "Visa mindre", "Show less rooms": "Visa färre rum", - "Show map": "Visa karta", "Show more": "Visa mer", "Show more rooms": "Visa fler rum", "Sign up bonus": "Välkomstbonus", diff --git a/types/components/form/bookingwidget.ts b/types/components/form/bookingwidget.ts index 14a548952..887c4eae2 100644 --- a/types/components/form/bookingwidget.ts +++ b/types/components/form/bookingwidget.ts @@ -1,14 +1,10 @@ -import { FormState, UseFormReturn } from "react-hook-form" - -import type { - BookingWidgetSchema, - BookingWidgetType, -} from "@/types/components/bookingWidget" +import type { BookingWidgetType } from "@/types/components/bookingWidget" import type { Location, Locations } from "@/types/trpc/routers/hotel/locations" export interface BookingWidgetFormProps { locations: Locations type?: BookingWidgetType + setIsOpen: (isOpen: boolean) => void } export interface BookingWidgetFormContentProps {