diff --git a/apps/scandic-web/actions/editProfile.ts b/apps/scandic-web/actions/editProfile.ts index e3116e4b9..a220c36f2 100644 --- a/apps/scandic-web/actions/editProfile.ts +++ b/apps/scandic-web/actions/editProfile.ts @@ -3,8 +3,8 @@ import { z } from "zod" import * as api from "@scandic-hotels/trpc/api" +import { countriesMap } from "@scandic-hotels/trpc/constants/countries" -import { countriesMap } from "@/constants/countries" import { ApiLang } from "@/constants/languages" import { getProfile } from "@/lib/trpc/memoizedRequests" import { protectedServerActionProcedure } from "@/server/trpc" diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/gla-payment-callback/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/gla-payment-callback/page.tsx index 756d028ad..f45b857a2 100644 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/gla-payment-callback/page.tsx +++ b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/gla-payment-callback/page.tsx @@ -1,11 +1,9 @@ import { notFound } from "next/navigation" import { myStay } from "@scandic-hotels/common/constants/routes/myStay" +import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode" -import { - BookingErrorCodeEnum, - PaymentCallbackStatusEnum, -} from "@/constants/booking" +import { PaymentCallbackStatusEnum } from "@/constants/booking" import { serverClient } from "@/lib/trpc/server" import GuaranteeCallback from "@/components/HotelReservation/MyStay/Ancillaries/GuaranteeCallback" diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/page.tsx index 9b7247385..32c8793f4 100644 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/page.tsx +++ b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(payment-callback)/payment-callback/page.tsx @@ -1,11 +1,9 @@ import { notFound } from "next/navigation" import { getServiceToken } from "@scandic-hotels/common/tokenManager" +import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode" -import { - BookingErrorCodeEnum, - PaymentCallbackStatusEnum, -} from "@/constants/booking" +import { PaymentCallbackStatusEnum } from "@/constants/booking" import { bookingConfirmation, details, diff --git a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx index a8a07aaba..92b3c7318 100644 --- a/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx +++ b/apps/scandic-web/app/[lang]/(live)/(public)/hotelreservation/(standard)/select-rate/page.tsx @@ -1,6 +1,8 @@ import { notFound } from "next/navigation" -import { combineRegExps, rateTypeRegex, REDEMPTION } from "@/constants/booking" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" + +import { combineRegExps, rateTypeRegex } from "@/constants/booking" import SelectRate from "@/components/HotelReservation/SelectRate" import { parseSelectRateSearchParams } from "@/utils/url" diff --git a/apps/scandic-web/auth.ts b/apps/scandic-web/auth.ts index 33e206511..fe673d163 100644 --- a/apps/scandic-web/auth.ts +++ b/apps/scandic-web/auth.ts @@ -1,10 +1,10 @@ import NextAuth, { type NextAuthConfig, type User } from "next-auth" +import { LoginTypeEnum } from "@scandic-hotels/trpc/types/loginType" + import { PRE_REFRESH_TIME_IN_SECONDS } from "@/constants/auth" import { env } from "@/env/server" -import { LoginTypeEnum } from "./types/components/tracking" - import type { JWT } from "next-auth/jwt" import type { OIDCConfig } from "next-auth/providers" diff --git a/apps/scandic-web/components/Blocks/DynamicContent/Overview/Stats/ExpiringPoints/index.tsx b/apps/scandic-web/components/Blocks/DynamicContent/Overview/Stats/ExpiringPoints/index.tsx index d408cd88e..ac41a5c1d 100644 --- a/apps/scandic-web/components/Blocks/DynamicContent/Overview/Stats/ExpiringPoints/index.tsx +++ b/apps/scandic-web/components/Blocks/DynamicContent/Overview/Stats/ExpiringPoints/index.tsx @@ -1,10 +1,10 @@ import { Lang } from "@scandic-hotels/common/constants/language" import { dt } from "@scandic-hotels/common/dt" +import { getFriendsMembership } from "@scandic-hotels/trpc/routers/user/helpers" import Body from "@/components/TempDesignSystem/Text/Body" import { getIntl } from "@/i18n" import { getLang } from "@/i18n/serverContext" -import { getFriendsMembership } from "@/utils/user" import type { UserProps } from "@/types/components/myPages/user" diff --git a/apps/scandic-web/components/Blocks/DynamicContent/Overview/Stats/Points/index.tsx b/apps/scandic-web/components/Blocks/DynamicContent/Overview/Stats/Points/index.tsx index 60b4b5fa8..df2280229 100644 --- a/apps/scandic-web/components/Blocks/DynamicContent/Overview/Stats/Points/index.tsx +++ b/apps/scandic-web/components/Blocks/DynamicContent/Overview/Stats/Points/index.tsx @@ -1,9 +1,9 @@ import { MembershipLevelEnum } from "@scandic-hotels/common/constants/membershipLevels" +import { getFriendsMembership } from "@scandic-hotels/trpc/routers/user/helpers" import { serverClient } from "@/lib/trpc/server" import { getIntl } from "@/i18n" -import { getFriendsMembership } from "@/utils/user" import PointsContainer from "./Container" import { PointsColumn } from "./PointsColumn" diff --git a/apps/scandic-web/components/Blocks/DynamicContent/SAS/LinkedAccounts/index.tsx b/apps/scandic-web/components/Blocks/DynamicContent/SAS/LinkedAccounts/index.tsx index a8c498a31..6c8c36a21 100644 --- a/apps/scandic-web/components/Blocks/DynamicContent/SAS/LinkedAccounts/index.tsx +++ b/apps/scandic-web/components/Blocks/DynamicContent/SAS/LinkedAccounts/index.tsx @@ -23,7 +23,7 @@ import { UnlinkSAS } from "./UnlinkSAS" import styles from "./linkedAccounts.module.css" -import type { UserLoyalty } from "@/types/user" +import type { UserLoyalty } from "@scandic-hotels/trpc/types/user" type Props = { title?: string diff --git a/apps/scandic-web/components/BookingWidget/Client.tsx b/apps/scandic-web/components/BookingWidget/Client.tsx index ef279f14d..db92f302d 100644 --- a/apps/scandic-web/components/BookingWidget/Client.tsx +++ b/apps/scandic-web/components/BookingWidget/Client.tsx @@ -7,8 +7,8 @@ import { FormProvider, useForm } from "react-hook-form" import { dt } from "@scandic-hotels/common/dt" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" -import { REDEMPTION } from "@/constants/booking" import { trpc } from "@/lib/trpc/client" import { StickyElementNameEnum } from "@/stores/sticky-position" diff --git a/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/index.tsx b/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/index.tsx index 474a1edbb..cb3b9139c 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/index.tsx +++ b/apps/scandic-web/components/Forms/BookingWidget/FormContent/BookingCode/index.tsx @@ -6,8 +6,7 @@ import { useMediaQuery } from "usehooks-ts" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" - -import { REDEMPTION } from "@/constants/booking" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import Modal from "@/components/Modal" import Button from "@/components/TempDesignSystem/Button" diff --git a/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/index.tsx b/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/index.tsx index 0c68634ac..4efa7afa9 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/index.tsx +++ b/apps/scandic-web/components/Forms/BookingWidget/FormContent/RewardNight/index.tsx @@ -7,8 +7,7 @@ import { useMediaQuery } from "usehooks-ts" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" - -import { REDEMPTION } from "@/constants/booking" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import Modal from "@/components/Modal" import Button from "@/components/TempDesignSystem/Button" diff --git a/apps/scandic-web/components/Forms/BookingWidget/FormContent/index.tsx b/apps/scandic-web/components/Forms/BookingWidget/FormContent/index.tsx index 9f5c7da63..8e4044bef 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/FormContent/index.tsx +++ b/apps/scandic-web/components/Forms/BookingWidget/FormContent/index.tsx @@ -7,8 +7,8 @@ import { useIntl } from "react-intl" import { dt } from "@scandic-hotels/common/dt" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" -import { REDEMPTION } from "@/constants/booking" import { hotelreservation } from "@/constants/routes/hotelReservation" import DatePicker from "@/components/DatePicker" diff --git a/apps/scandic-web/components/Forms/BookingWidget/index.tsx b/apps/scandic-web/components/Forms/BookingWidget/index.tsx index e56d3092e..106eac5db 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/index.tsx +++ b/apps/scandic-web/components/Forms/BookingWidget/index.tsx @@ -5,11 +5,12 @@ import { useTransition } from "react" import { Form as FormRAC } from "react-aria-components" import { useFormContext } from "react-hook-form" -import { REDEMPTION } from "@/constants/booking" +import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" + import { selectHotel, selectHotelMap, - selectRate, } from "@/constants/routes/hotelReservation" import useLang from "@/hooks/useLang" diff --git a/apps/scandic-web/components/Forms/BookingWidget/schema.ts b/apps/scandic-web/components/Forms/BookingWidget/schema.ts index 189cf3a49..65211c14b 100644 --- a/apps/scandic-web/components/Forms/BookingWidget/schema.ts +++ b/apps/scandic-web/components/Forms/BookingWidget/schema.ts @@ -1,9 +1,8 @@ import { z } from "zod" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum" -import { REDEMPTION } from "@/constants/booking" - export const bookingWidgetErrors = { AGE_REQUIRED: "AGE_REQUIRED", BED_CHOICE_REQUIRED: "BED_CHOICE_REQUIRED", diff --git a/apps/scandic-web/components/GuestsRoomsPicker/Form.tsx b/apps/scandic-web/components/GuestsRoomsPicker/Form.tsx index a4c6ba667..84744f2a0 100644 --- a/apps/scandic-web/components/GuestsRoomsPicker/Form.tsx +++ b/apps/scandic-web/components/GuestsRoomsPicker/Form.tsx @@ -6,8 +6,7 @@ import { useIntl } from "react-intl" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" - -import { REDEMPTION } from "@/constants/booking" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import Button from "../TempDesignSystem/Button" import { Tooltip } from "../TempDesignSystem/Tooltip" diff --git a/apps/scandic-web/components/Header/MainMenu/MyPagesMenu/index.tsx b/apps/scandic-web/components/Header/MainMenu/MyPagesMenu/index.tsx index e7dec577f..3b393a770 100644 --- a/apps/scandic-web/components/Header/MainMenu/MyPagesMenu/index.tsx +++ b/apps/scandic-web/components/Header/MainMenu/MyPagesMenu/index.tsx @@ -20,9 +20,9 @@ import MyPagesMenuContent, { useMyPagesNavigation } from "../MyPagesMenuContent" import styles from "./myPagesMenu.module.css" import type { LoyaltyLevel } from "@scandic-hotels/trpc/routers/contentstack/loyaltyLevel/output" +import type { FriendsMembership, User } from "@scandic-hotels/trpc/types/user" import { DropdownTypeEnum } from "@/types/components/dropdown/dropdown" -import type { FriendsMembership, User } from "@/types/user" export type MyPagesMenuProps = { user: Pick diff --git a/apps/scandic-web/components/HotelReservation/BookingConfirmation/PriceDetails/mapToPrice.ts b/apps/scandic-web/components/HotelReservation/BookingConfirmation/PriceDetails/mapToPrice.ts index 48c760296..0bc2f940c 100644 --- a/apps/scandic-web/components/HotelReservation/BookingConfirmation/PriceDetails/mapToPrice.ts +++ b/apps/scandic-web/components/HotelReservation/BookingConfirmation/PriceDetails/mapToPrice.ts @@ -6,8 +6,9 @@ import { packageSchema, } from "@scandic-hotels/trpc/routers/hotels/schemas/packages" +import type { Package } from "@scandic-hotels/trpc/types/packages" + import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" -import type { Package } from "@/types/requests/packages" import type { Room } from "@/types/stores/booking-confirmation" export function mapToPrice(rooms: (Room | null)[], nights: number) { diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/BedType/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/BedType/index.tsx index a7ae86d98..841540b01 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/BedType/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/BedType/index.tsx @@ -4,11 +4,7 @@ import { zodResolver } from "@hookform/resolvers/zod" import { useCallback, useEffect, useState } from "react" import { FormProvider, useForm } from "react-hook-form" -import { - BED_TYPE_ICONS, - type BedTypeEnum, - type ExtraBedTypeEnum, -} from "@/constants/booking" +import { BED_TYPE_ICONS } from "@/constants/booking" import { useEnterDetailsStore } from "@/stores/enter-details" import RadioCard from "@/components/TempDesignSystem/Form/RadioCard" @@ -20,6 +16,10 @@ import { bedTypeFormSchema } from "./schema" import styles from "./bedOptions.module.css" import type { IconProps } from "@scandic-hotels/design-system/Icons" +import type { + BedTypeEnum, + ExtraBedTypeEnum, +} from "@scandic-hotels/trpc/enums/bedType" import type { BedTypeFormSchema } from "@/types/components/hotelReservation/enterDetails/bedType" diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/Guarantee/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/Guarantee/index.tsx index 7b2004119..9326cde3f 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/Guarantee/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/Guarantee/index.tsx @@ -23,7 +23,7 @@ import PaymentOptionsGroup from "../../Payment/PaymentOptionsGroup" import styles from "./guarantee.module.css" -import type { CreditCard } from "@/types/user" +import type { CreditCard } from "@scandic-hotels/trpc/types/user" interface GuaranteeProps { savedCreditCards: CreditCard[] | null diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/index.tsx index 45a273340..ba57f4f5a 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Confirm/index.tsx @@ -11,7 +11,7 @@ import Guarantee from "./Guarantee" import styles from "./confirm.module.css" -import type { CreditCard } from "@/types/user" +import type { CreditCard } from "@scandic-hotels/trpc/types/user" interface ConfirmBookingProps { savedCreditCards: CreditCard[] | null diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/BookingAlert/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/BookingAlert/index.tsx index 48751c1d0..1ee5f05e9 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/BookingAlert/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/BookingAlert/index.tsx @@ -4,10 +4,10 @@ import { usePathname, useSearchParams } from "next/navigation" import { useEffect, useRef, useState } from "react" import { useIntl } from "react-intl" +import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation" +import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode" import { AlertTypeEnum } from "@scandic-hotels/trpc/types/alertType" -import { BookingErrorCodeEnum } from "@/constants/booking" -import { selectRate } from "@/constants/routes/hotelReservation" import { useEnterDetailsStore } from "@/stores/enter-details" import Alert from "@/components/TempDesignSystem/Alert" diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentClient.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentClient.tsx index 3565daedb..5cd879cd5 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentClient.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Payment/PaymentClient.tsx @@ -9,19 +9,15 @@ import { FormProvider, useForm } from "react-hook-form" import { useIntl } from "react-intl" import { PaymentMethodEnum } from "@scandic-hotels/common/constants/paymentMethod" +import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation" import { Button } from "@scandic-hotels/design-system/Button" import { Typography } from "@scandic-hotels/design-system/Typography" +import { bedTypeMap } from "@scandic-hotels/trpc/constants/bedTypeMap" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" -import { - BookingStatusEnum, - PAYMENT_METHOD_TITLES, - REDEMPTION, -} from "@/constants/booking" -import { - bookingConfirmation, - selectRate, -} from "@/constants/routes/hotelReservation" +import { BookingStatusEnum, PAYMENT_METHOD_TITLES } from "@/constants/booking" +import { bookingConfirmation } from "@/constants/routes/hotelReservation" import { env } from "@/env/client" import { trpc } from "@/lib/trpc/client" import { useEnterDetailsStore } from "@/stores/enter-details" @@ -38,7 +34,6 @@ import { trackPaymentEvent } from "@/utils/tracking" import { trackEvent } from "@/utils/tracking/base" import { trackGlaSaveCardAttempt } from "@/utils/tracking/myStay" -import { bedTypeMap } from "../../utils" import ConfirmBooking, { ConfirmBookingRedemption } from "../Confirm" import PriceChangeDialog from "../PriceChangeDialog" import { writeGlaToSessionStorage } from "./PaymentCallback/helpers" diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/SelectedRoom/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/SelectedRoom/index.tsx index 737e230c9..c2b3748e0 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/SelectedRoom/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/SelectedRoom/index.tsx @@ -4,10 +4,10 @@ import { useRouter } from "next/navigation" import { useTransition } from "react" import { useIntl } from "react-intl" +import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation" import { Button } from "@scandic-hotels/design-system/Button" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" -import { selectRate } from "@/constants/routes/hotelReservation" import { useEnterDetailsStore } from "@/stores/enter-details" import Footnote from "@/components/TempDesignSystem/Text/Footnote" diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Tracking/index.tsx b/apps/scandic-web/components/HotelReservation/EnterDetails/Tracking/index.tsx index 965da0a22..d9fffeaf1 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Tracking/index.tsx +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Tracking/index.tsx @@ -9,9 +9,9 @@ import { getTracking } from "./tracking" import type { Lang } from "@scandic-hotels/common/constants/language" import type { Hotel } from "@scandic-hotels/trpc/types/hotel" +import type { Room } from "@scandic-hotels/trpc/types/room" import type { DetailsBooking } from "@/types/components/hotelReservation/enterDetails/details" -import type { Room } from "@/types/providers/details/room" interface TrackingWrapperProps { booking: DetailsBooking diff --git a/apps/scandic-web/components/HotelReservation/EnterDetails/Tracking/tracking.ts b/apps/scandic-web/components/HotelReservation/EnterDetails/Tracking/tracking.ts index d7472fcc4..97bc8ed01 100644 --- a/apps/scandic-web/components/HotelReservation/EnterDetails/Tracking/tracking.ts +++ b/apps/scandic-web/components/HotelReservation/EnterDetails/Tracking/tracking.ts @@ -1,17 +1,17 @@ import { differenceInCalendarDays, format, isWeekend } from "date-fns" import { CurrencyEnum } from "@scandic-hotels/common/constants/currency" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum" import { PackageTypeEnum } from "@scandic-hotels/trpc/enums/packages" import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" -import { REDEMPTION } from "@/constants/booking" - import { sumPackages } from "@/components/HotelReservation/utils" import { getSpecialRoomType } from "@/utils/specialRoomType" import type { Lang } from "@scandic-hotels/common/constants/language" import type { Hotel } from "@scandic-hotels/trpc/types/hotel" +import type { Room } from "@scandic-hotels/trpc/types/room" import type { PriceProduct, Product, @@ -28,7 +28,6 @@ import { type TrackingSDKHotelInfo, type TrackingSDKPageData, } from "@/types/components/tracking" -import type { Room } from "@/types/providers/details/room" import type { RoomState } from "@/types/stores/enter-details" export function getTracking( diff --git a/apps/scandic-web/components/HotelReservation/HotelCard/HotelChequeCard/index.tsx b/apps/scandic-web/components/HotelReservation/HotelCard/HotelChequeCard/index.tsx index 7f44a345b..e41d689fa 100644 --- a/apps/scandic-web/components/HotelReservation/HotelCard/HotelChequeCard/index.tsx +++ b/apps/scandic-web/components/HotelReservation/HotelCard/HotelChequeCard/index.tsx @@ -7,7 +7,7 @@ import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import styles from "./hotelChequeCard.module.css" -import type { ProductTypeCheque } from "@/types/trpc/routers/hotel/availability" +import type { ProductTypeCheque } from "@scandic-hotels/trpc/types/availability" export default function HotelChequeCard({ productTypeCheque, diff --git a/apps/scandic-web/components/HotelReservation/HotelCard/HotelVoucherCard/index.tsx b/apps/scandic-web/components/HotelReservation/HotelCard/HotelVoucherCard/index.tsx index 7382c6c1c..44bfcdf24 100644 --- a/apps/scandic-web/components/HotelReservation/HotelCard/HotelVoucherCard/index.tsx +++ b/apps/scandic-web/components/HotelReservation/HotelCard/HotelVoucherCard/index.tsx @@ -7,7 +7,7 @@ import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" import styles from "./hotelVoucherCard.module.css" -import type { ProductTypeVoucher } from "@/types/trpc/routers/hotel/availability" +import type { ProductTypeVoucher } from "@scandic-hotels/trpc/types/availability" export default function HotelVoucherCard({ productTypeVoucher, diff --git a/apps/scandic-web/components/HotelReservation/HotelCard/index.tsx b/apps/scandic-web/components/HotelReservation/HotelCard/index.tsx index 421554b23..f10377cc8 100644 --- a/apps/scandic-web/components/HotelReservation/HotelCard/index.tsx +++ b/apps/scandic-web/components/HotelReservation/HotelCard/index.tsx @@ -10,11 +10,12 @@ import { import { memo } from "react" import { useIntl } from "react-intl" +import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation" import { Divider } from "@scandic-hotels/design-system/Divider" import HotelLogoIcon from "@scandic-hotels/design-system/Icons/HotelLogoIcon" import { Typography } from "@scandic-hotels/design-system/Typography" -import { selectHotelMap, selectRate } from "@/constants/routes/hotelReservation" +import { selectHotelMap } from "@/constants/routes/hotelReservation" import { useHotelsMapStore } from "@/stores/hotels-map" import BookingCodeChip from "@/components/BookingCodeChip" diff --git a/apps/scandic-web/components/HotelReservation/HotelCardDialog/ListingHotelCardDialog/index.tsx b/apps/scandic-web/components/HotelReservation/HotelCardDialog/ListingHotelCardDialog/index.tsx index 81aca7296..ef1496cc0 100644 --- a/apps/scandic-web/components/HotelReservation/HotelCardDialog/ListingHotelCardDialog/index.tsx +++ b/apps/scandic-web/components/HotelReservation/HotelCardDialog/ListingHotelCardDialog/index.tsx @@ -3,12 +3,11 @@ import { useSession } from "next-auth/react" import { useState } from "react" import { useIntl } from "react-intl" +import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation" import { IconButton } from "@scandic-hotels/design-system/IconButton" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" -import { selectRate } from "@/constants/routes/hotelReservation" - import { FacilityToIcon } from "@/components/ContentType/HotelPage/data" import Button from "@/components/TempDesignSystem/Button" import Link from "@/components/TempDesignSystem/Link" diff --git a/apps/scandic-web/components/HotelReservation/HotelCardDialog/StandaloneHotelCardDialog/index.tsx b/apps/scandic-web/components/HotelReservation/HotelCardDialog/StandaloneHotelCardDialog/index.tsx index 0237873c4..96aa74555 100644 --- a/apps/scandic-web/components/HotelReservation/HotelCardDialog/StandaloneHotelCardDialog/index.tsx +++ b/apps/scandic-web/components/HotelReservation/HotelCardDialog/StandaloneHotelCardDialog/index.tsx @@ -3,12 +3,11 @@ import { useSession } from "next-auth/react" import { useState } from "react" import { useIntl } from "react-intl" +import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation" import { IconButton } from "@scandic-hotels/design-system/IconButton" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" -import { selectRate } from "@/constants/routes/hotelReservation" - import { FacilityToIcon } from "@/components/ContentType/HotelPage/data" import Button from "@/components/TempDesignSystem/Button" import Link from "@/components/TempDesignSystem/Link" diff --git a/apps/scandic-web/components/HotelReservation/MySavedCards/index.tsx b/apps/scandic-web/components/HotelReservation/MySavedCards/index.tsx index 9616cfdd3..87a5a65c5 100644 --- a/apps/scandic-web/components/HotelReservation/MySavedCards/index.tsx +++ b/apps/scandic-web/components/HotelReservation/MySavedCards/index.tsx @@ -8,8 +8,7 @@ import PaymentOption from "../PaymentOption" import styles from "./mySavedCards.module.css" import type { PaymentMethodEnum } from "@scandic-hotels/common/constants/paymentMethod" - -import type { CreditCard } from "@/types/user" +import type { CreditCard } from "@scandic-hotels/trpc/types/user" interface MySavedCardsProps { savedCreditCards: CreditCard[] | null diff --git a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/utils.ts b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/utils.ts index 265817d1a..a53fbb49a 100644 --- a/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/utils.ts +++ b/apps/scandic-web/components/HotelReservation/MyStay/Ancillaries/utils.ts @@ -1,9 +1,10 @@ +import type { User } from "@scandic-hotels/trpc/types/user" + import type { Ancillaries, Ancillary, SelectedAncillary, } from "@/types/components/myPages/myStay/ancillaries" -import type { User } from "@/types/user" function filterPoints(ancillaries: Ancillaries, user: User | null) { return ancillaries.map((ancillary) => { diff --git a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Breakfast.tsx b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Breakfast.tsx index 736356364..f3c02d08a 100644 --- a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Breakfast.tsx +++ b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Breakfast.tsx @@ -7,8 +7,9 @@ import BoldRow from "./Row/Bold" import RegularRow from "./Row/Regular" import Tbody from "./Tbody" +import type { Child } from "@scandic-hotels/trpc/types/child" + import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" interface BreakfastProps { adults: number diff --git a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Row/Price/Packages.tsx b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Row/Price/Packages.tsx index 9d6ebfdee..8a9e48730 100644 --- a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Row/Price/Packages.tsx +++ b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Row/Price/Packages.tsx @@ -5,7 +5,7 @@ import { formatPrice } from "@/utils/numberFormatting" import RegularRow from "../Regular" -import type { Packages as PackagesType } from "@/types/requests/packages" +import type { Packages as PackagesType } from "@scandic-hotels/trpc/types/packages" interface PackagesProps { packages: PackagesType | null diff --git a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Row/Price/price.ts b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Row/Price/price.ts index 1397c76ad..535eefd10 100644 --- a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Row/Price/price.ts +++ b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/Row/Price/price.ts @@ -1,5 +1,6 @@ +import type { Packages } from "@scandic-hotels/trpc/types/packages" + import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType" -import type { Packages } from "@/types/requests/packages" export interface SharedPriceRowProps { bedType: BedTypeSchema | undefined diff --git a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/index.tsx b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/index.tsx index bf6c625ef..3924e8215 100644 --- a/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/index.tsx +++ b/apps/scandic-web/components/HotelReservation/PriceDetailsModal/PriceDetailsTable/index.tsx @@ -27,13 +27,13 @@ import Tbody from "./Tbody" import styles from "./priceDetailsTable.module.css" import type { CurrencyEnum } from "@scandic-hotels/common/constants/currency" +import type { Child } from "@scandic-hotels/trpc/types/child" +import type { Packages } from "@scandic-hotels/trpc/types/packages" import type { RateDefinition } from "@scandic-hotels/trpc/types/roomAvailability" import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType" import type { Price } from "@/types/components/hotelReservation/price" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" -import type { Packages } from "@/types/requests/packages" type RoomPrice = | CorporateChequePriceType diff --git a/apps/scandic-web/components/HotelReservation/SelectHotel/helpers.ts b/apps/scandic-web/components/HotelReservation/SelectHotel/helpers.ts index 080ce82ea..85a1d149a 100644 --- a/apps/scandic-web/components/HotelReservation/SelectHotel/helpers.ts +++ b/apps/scandic-web/components/HotelReservation/SelectHotel/helpers.ts @@ -1,17 +1,21 @@ import { AvailabilityEnum } from "@scandic-hotels/trpc/enums/selectHotel" +import { generateChildrenString } from "@scandic-hotels/trpc/routers/hotels/helpers" +import { + type AdditionalData, + type Hotel, +} from "@scandic-hotels/trpc/types/hotel" +import { + type HotelLocation, + type Location, +} from "@scandic-hotels/trpc/types/locations" import { getHotel } from "@/lib/trpc/memoizedRequests" import { serverClient } from "@/lib/trpc/server" import { getLang } from "@/i18n/serverContext" -import { generateChildrenString } from "../utils" - -import type { AdditionalData, Hotel } from "@scandic-hotels/trpc/types/hotel" -import type { - HotelLocation, - Location, -} from "@scandic-hotels/trpc/types/locations" +import type { HotelsAvailabilityItem } from "@scandic-hotels/trpc/types/availability" +import type { Child } from "@scandic-hotels/trpc/types/child" import type { AlternativeHotelsAvailabilityInput, @@ -21,8 +25,6 @@ import type { CategorizedHotelFilters, HotelFilter, } from "@/types/components/hotelReservation/selectHotel/hotelFilters" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" -import type { HotelsAvailabilityItem } from "@/types/trpc/routers/hotel/availability" interface AvailabilityResponse { availability: HotelsAvailabilityItem[] diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/AvailabilityError.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/AvailabilityError.tsx index bfa4df9a5..a58096fc9 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/AvailabilityError.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/AvailabilityError.tsx @@ -4,7 +4,7 @@ import { usePathname, useSearchParams } from "next/navigation" import { useEffect } from "react" import { useIntl } from "react-intl" -import { BookingErrorCodeEnum } from "@/constants/booking" +import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode" import { toast } from "@/components/TempDesignSystem/Toasts" diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/MobileSummary/Room/index.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/MobileSummary/Room/index.tsx index 02790944f..0d9609150 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/MobileSummary/Room/index.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/MobileSummary/Room/index.tsx @@ -14,12 +14,13 @@ import { getMemberPrice, isBookingCodeRate } from "../utils" import styles from "./room.module.css" +import type { Child } from "@scandic-hotels/trpc/types/child" +import type { Packages } from "@scandic-hotels/trpc/types/packages" + import type { RoomPrice, RoomRate, } from "@/types/components/hotelReservation/enterDetails/details" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" -import type { Packages } from "@/types/requests/packages" interface RoomProps { room: { diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/MobileSummary/mapRate.ts b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/MobileSummary/mapRate.ts index 051fd7b0e..b6db0177b 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/MobileSummary/mapRate.ts +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/MobileSummary/mapRate.ts @@ -1,11 +1,12 @@ import { CurrencyEnum } from "@scandic-hotels/common/constants/currency" +import type { Packages } from "@scandic-hotels/trpc/types/packages" + import type { Price } from "@/types/components/hotelReservation/price" import type { Rate, Room, } from "@/types/components/hotelReservation/selectRate/selectRate" -import type { Packages } from "@/types/requests/packages" export function mapRate( room: Rate, diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/utils.ts b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/utils.ts index 5c7593198..bf68ada30 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/utils.ts +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/RateSummary/utils.ts @@ -3,11 +3,11 @@ import { RateTypeEnum } from "@scandic-hotels/trpc/enums/rateType" import { sumPackages } from "@/components/HotelReservation/utils" +import type { Packages } from "@scandic-hotels/trpc/types/packages" import type { RedemptionProduct } from "@scandic-hotels/trpc/types/roomAvailability" import type { Price } from "@/types/components/hotelReservation/price" import type { Rate } from "@/types/components/hotelReservation/selectRate/selectRate" -import type { Packages } from "@/types/requests/packages" export function calculateTotalPrice( selectedRateSummary: Rate[], diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/Checkboxes/utils.ts b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/Checkboxes/utils.ts index 2dde3b87a..fb9bc282c 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/Checkboxes/utils.ts +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/Checkboxes/utils.ts @@ -1,6 +1,6 @@ import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" -import type { PackageEnum } from "@/types/requests/packages" +import type { PackageEnum } from "@scandic-hotels/trpc/types/packages" export function includesAllergyRoom(codes: PackageEnum[]) { return codes.includes(RoomPackageCodeEnum.ALLERGY_ROOM) diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/formValues.ts b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/formValues.ts index 9d71d124e..6661b636f 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/formValues.ts +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/formValues.ts @@ -1,4 +1,4 @@ -import type { PackageEnum } from "@/types/requests/packages" +import type { PackageEnum } from "@scandic-hotels/trpc/types/packages" export type FormValues = { selectedPackages: PackageEnum[] diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/index.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/index.tsx index 5a2b304df..77020b9fa 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/index.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/Form/index.tsx @@ -16,7 +16,8 @@ import Checkboxes from "./Checkboxes" import styles from "./form.module.css" -import type { PackageEnum } from "@/types/requests/packages" +import type { PackageEnum } from "@scandic-hotels/trpc/types/packages" + import type { FormValues } from "./formValues" export default function Form({ close }: { close: () => void }) { diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/index.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/index.tsx index 2b0a5d96c..aac39f179 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/index.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/index.tsx @@ -17,7 +17,7 @@ import { getIconNameByPackageCode } from "./utils" import styles from "./roomPackageFilter.module.css" -import type { PackageEnum } from "@/types/requests/packages" +import type { PackageEnum } from "@scandic-hotels/trpc/types/packages" export default function RoomPackageFilter() { const lang = useLang() diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/utils.ts b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/utils.ts index a243bc275..b4d8c64fd 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/utils.ts +++ b/apps/scandic-web/components/HotelReservation/SelectRate/RoomsContainer/Rooms/RoomsHeader/RoomPackageFilter/utils.ts @@ -1,8 +1,7 @@ import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" import type { MaterialSymbolProps } from "@scandic-hotels/design-system/Icons/MaterialIcon/MaterialSymbol" - -import type { PackageEnum } from "@/types/requests/packages" +import type { PackageEnum } from "@scandic-hotels/trpc/types/packages" export function getIconNameByPackageCode( packageCode: PackageEnum diff --git a/apps/scandic-web/components/HotelReservation/SelectRate/Tracking/index.tsx b/apps/scandic-web/components/HotelReservation/SelectRate/Tracking/index.tsx index f7b8cd613..033a40dc0 100644 --- a/apps/scandic-web/components/HotelReservation/SelectRate/Tracking/index.tsx +++ b/apps/scandic-web/components/HotelReservation/SelectRate/Tracking/index.tsx @@ -3,7 +3,7 @@ import { useSearchParams } from "next/navigation" import React from "react" -import { REDEMPTION } from "@/constants/booking" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import TrackingSDK from "@/components/TrackingSDK" import useLang from "@/hooks/useLang" diff --git a/apps/scandic-web/components/HotelReservation/utils/convertToChildType.ts b/apps/scandic-web/components/HotelReservation/utils/convertToChildType.ts index 0289ff8c1..9783f072d 100644 --- a/apps/scandic-web/components/HotelReservation/utils/convertToChildType.ts +++ b/apps/scandic-web/components/HotelReservation/utils/convertToChildType.ts @@ -1,6 +1,7 @@ import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" +import type { Child } from "@scandic-hotels/trpc/types/child" + import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation" export function convertToChildType( diff --git a/apps/scandic-web/components/HotelReservation/utils/index.tsx b/apps/scandic-web/components/HotelReservation/utils/index.tsx index 839651e91..d2f28bd65 100644 --- a/apps/scandic-web/components/HotelReservation/utils/index.tsx +++ b/apps/scandic-web/components/HotelReservation/utils/index.tsx @@ -6,14 +6,10 @@ import { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum" import { ChildBedTypeEnum } from "@scandic-hotels/trpc/enums/childBedTypeEnum" import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" +import type { Packages } from "@scandic-hotels/trpc/types/packages" import type { JSX } from "react" -import { - // RoomPackageCodeEnum, - type RoomPackageCodes, -} from "@/types/components/hotelReservation/selectRate/roomFilter" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" -import type { Packages } from "@/types/requests/packages" +import { type RoomPackageCodes } from "@/types/components/hotelReservation/selectRate/roomFilter" interface IconForFeatureCodeProps { featureCode: RoomPackageCodes @@ -33,13 +29,6 @@ export function IconForFeatureCode({ } } -export const bedTypeMap: Record = { - [ChildBedMapEnum.IN_ADULTS_BED]: ChildBedTypeEnum.ParentsBed, - [ChildBedMapEnum.IN_CRIB]: ChildBedTypeEnum.Crib, - [ChildBedMapEnum.IN_EXTRA_BED]: ChildBedTypeEnum.ExtraBed, - [ChildBedMapEnum.UNKNOWN]: ChildBedTypeEnum.Unknown, -} - export const invertedBedTypeMap: Record = { [ChildBedTypeEnum.ParentsBed]: ChildBedMapEnum[ChildBedMapEnum.IN_ADULTS_BED], [ChildBedTypeEnum.Crib]: ChildBedMapEnum[ChildBedMapEnum.IN_CRIB], @@ -47,16 +36,6 @@ export const invertedBedTypeMap: Record = { [ChildBedTypeEnum.Unknown]: ChildBedMapEnum[ChildBedMapEnum.UNKNOWN], } -export function generateChildrenString(children: Child[]): string { - return `[${children - .map((child) => { - const age = child.age - const bedType = bedTypeMap[parseInt(child.bed.toString())] - return `${age}:${bedType}` - }) - .join(",")}]` -} - export function sumPackages(packages: Packages | null) { if (!packages || !packages.length) { return { diff --git a/apps/scandic-web/components/MyPages/Avatar/index.tsx b/apps/scandic-web/components/MyPages/Avatar/index.tsx index 925e8df1f..63f0060c8 100644 --- a/apps/scandic-web/components/MyPages/Avatar/index.tsx +++ b/apps/scandic-web/components/MyPages/Avatar/index.tsx @@ -2,7 +2,7 @@ import { getInitials } from "@/utils/user" import styles from "./avatar.module.css" -import type { User } from "@/types/user" +import type { User } from "@scandic-hotels/trpc/types/user" export default function Avatar({ firstName, diff --git a/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Client.tsx b/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Client.tsx index e907e1eec..fc4c3f19c 100644 --- a/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Client.tsx +++ b/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Client.tsx @@ -15,7 +15,7 @@ import DigitalTeamMemberCardContent from "./Content" import styles from "./digitalTeamMemberCard.module.css" -import type { User } from "@/types/user" +import type { User } from "@scandic-hotels/trpc/types/user" interface DigitalTeamMemberCardClientProps { user: User diff --git a/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Content.tsx b/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Content.tsx index dad772335..b463317b3 100644 --- a/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Content.tsx +++ b/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Content.tsx @@ -9,7 +9,7 @@ import { debounce } from "@/utils/debounce" import styles from "./digitalTeamMemberCard.module.css" -import type { User } from "@/types/user" +import type { User } from "@scandic-hotels/trpc/types/user" interface DigitalTeamMemberCardCardProps { user: User diff --git a/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/index.tsx b/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/index.tsx index 00bdf018f..dd3d403f3 100644 --- a/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/index.tsx +++ b/apps/scandic-web/components/MyPages/DigitalTeamMemberCard/index.tsx @@ -2,7 +2,7 @@ import { env } from "@/env/server" import DigitalTeamMemberCardClient from "./Client" -import type { User } from "@/types/user" +import type { User } from "@scandic-hotels/trpc/types/user" interface DigitalTeamMemberCardProps { user: User diff --git a/apps/scandic-web/components/MyPages/Profile/index.tsx b/apps/scandic-web/components/MyPages/Profile/index.tsx index 019c911de..3beafd9e2 100644 --- a/apps/scandic-web/components/MyPages/Profile/index.tsx +++ b/apps/scandic-web/components/MyPages/Profile/index.tsx @@ -3,8 +3,8 @@ import { isValidLang } from "@scandic-hotels/common/utils/languages" import { Divider } from "@scandic-hotels/design-system/Divider" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" +import { countriesMap } from "@scandic-hotels/trpc/constants/countries" -import { countriesMap } from "@/constants/countries" import { languages } from "@/constants/languages" import { profileEdit } from "@/constants/routes/myPages" import { getProfile } from "@/lib/trpc/memoizedRequests" diff --git a/apps/scandic-web/components/Profile/CreditCardList/index.tsx b/apps/scandic-web/components/Profile/CreditCardList/index.tsx index e97e4739b..87a997601 100644 --- a/apps/scandic-web/components/Profile/CreditCardList/index.tsx +++ b/apps/scandic-web/components/Profile/CreditCardList/index.tsx @@ -8,7 +8,7 @@ import CreditCardRow from "../CreditCardRow" import styles from "./CreditCardList.module.css" -import type { CreditCard } from "@/types/user" +import type { CreditCard } from "@scandic-hotels/trpc/types/user" export default function CreditCardList({ initialData, diff --git a/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx b/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx index a90747a48..14d0ed0e2 100644 --- a/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx +++ b/apps/scandic-web/components/SidePeeks/BookedRoomSidePeek/index.tsx @@ -25,13 +25,13 @@ import RoomDetails from "./RoomDetails" import styles from "./bookedRoomSidePeek.module.css" +import type { Child } from "@scandic-hotels/trpc/types/child" import type { Room as HotelRoom } from "@scandic-hotels/trpc/types/hotel" +import type { Packages } from "@scandic-hotels/trpc/types/packages" import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType" import type { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" -import type { Packages } from "@/types/requests/packages" import type { BookingConfirmationSchema } from "@/types/trpc/routers/booking/confirmation" import type { SafeUser } from "@/types/user" diff --git a/apps/scandic-web/components/TempDesignSystem/Form/Country/CountryCombobox.tsx b/apps/scandic-web/components/TempDesignSystem/Form/Country/CountryCombobox.tsx index dc57b7b8e..76ccf994d 100644 --- a/apps/scandic-web/components/TempDesignSystem/Form/Country/CountryCombobox.tsx +++ b/apps/scandic-web/components/TempDesignSystem/Form/Country/CountryCombobox.tsx @@ -16,8 +16,7 @@ import { useIntl } from "react-intl" import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon" import { Typography } from "@scandic-hotels/design-system/Typography" - -import { countries } from "@/constants/countries" +import { countries } from "@scandic-hotels/trpc/constants/countries" import useLang from "@/hooks/useLang" diff --git a/apps/scandic-web/components/TempDesignSystem/Form/Country/CountrySelect.tsx b/apps/scandic-web/components/TempDesignSystem/Form/Country/CountrySelect.tsx index ab376647e..f945f2d8d 100644 --- a/apps/scandic-web/components/TempDesignSystem/Form/Country/CountrySelect.tsx +++ b/apps/scandic-web/components/TempDesignSystem/Form/Country/CountrySelect.tsx @@ -5,8 +5,7 @@ import { useController } from "react-hook-form" import { useIntl } from "react-intl" import { Select } from "@scandic-hotels/design-system/Select" - -import { countries } from "@/constants/countries" +import { countries } from "@scandic-hotels/trpc/constants/countries" import useLang from "@/hooks/useLang" diff --git a/apps/scandic-web/constants/booking.ts b/apps/scandic-web/constants/booking.ts index 25f84901d..c52ccf8b0 100644 --- a/apps/scandic-web/constants/booking.ts +++ b/apps/scandic-web/constants/booking.ts @@ -7,9 +7,14 @@ import BedSingleIcon from "@scandic-hotels/design-system/Icons/BedSingleIcon" import BedSofaExtraIcon from "@scandic-hotels/design-system/Icons/BedSofaExtraIcon" import BedTwinIcon from "@scandic-hotels/design-system/Icons/BedTwinIcon" import BedWallExtraIcon from "@scandic-hotels/design-system/Icons/BedWallExtraIcon" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import type { PaymentMethodEnum } from "@scandic-hotels/common/constants/paymentMethod" import type { IconProps } from "@scandic-hotels/design-system/Icons" +import type { + BedTypeEnum, + ExtraBedTypeEnum, +} from "@scandic-hotels/trpc/enums/bedType" import type { JSX } from "react" export enum BookingStatusEnum { @@ -31,25 +36,11 @@ export enum BookingStatusEnum { export const FamilyAndFriendsCodes = ["D000029555", "D000029271", "D000029195"] -export const REDEMPTION = "redemption" export const bookingSearchTypes = [REDEMPTION] as const export const SEARCHTYPE = "searchtype" export const MEMBERSHIP_FAILED_ERROR = "MembershipFailedError" -export enum BookingErrorCodeEnum { - InternalError = "InternalError", - ReservationError = "ReservationError", - AvailabilityError = "AvailabilityError", - BookingStatusNotFound = "BookingStatusNotFound", - TransactionAbandoned = "TransactionAbandoned", - TransactionCancelled = "TransactionCancelled", - TransactionFailed = "TransactionFailed", - BookingStateError = "BookingStateError", - MembershipFailedError = "MembershipFailedError", - NoAvailabilityForRateAndRoomType = "NoAvailabilityForRateAndRoomType", -} - export const PAYMENT_METHOD_TITLES: Record< keyof typeof PaymentMethodEnum, string @@ -100,21 +91,6 @@ export const PAYMENT_METHOD_ICONS: Record< discover: "/_static/icons/payment/discover.svg", } -export enum BedTypeEnum { - King = "King", - Queen = "Queen", - Single = "Single", - Twin = "Twin", - Other = "Other", -} - -export enum ExtraBedTypeEnum { - SofaBed = "SofaBed", - WallBed = "WallBed", - PullOutBed = "PullOutBed", - BunkBed = "BunkBed", -} - export type BedTypes = keyof typeof BedTypeEnum | keyof typeof ExtraBedTypeEnum export const BED_TYPE_ICONS: Record< diff --git a/apps/scandic-web/constants/membershipLevels.ts b/apps/scandic-web/constants/membershipLevels.ts index adfb788db..783d51e99 100644 --- a/apps/scandic-web/constants/membershipLevels.ts +++ b/apps/scandic-web/constants/membershipLevels.ts @@ -1,6 +1,6 @@ import { MembershipLevelEnum } from "@scandic-hotels/common/constants/membershipLevels" -import type { EurobonusTier } from "@/types/user" +import type { EurobonusTier } from "@scandic-hotels/trpc/types/user" export const FriendsMembershipLevels = [ "L1", diff --git a/apps/scandic-web/constants/routes/hotelReservation.js b/apps/scandic-web/constants/routes/hotelReservation.js index f9d26f90b..a5a0be3b8 100644 --- a/apps/scandic-web/constants/routes/hotelReservation.js +++ b/apps/scandic-web/constants/routes/hotelReservation.js @@ -37,13 +37,6 @@ export function selectHotelMap(lang) { return `${hotelreservation(lang)}/select-hotel/map` } -/** - * @param {Lang} lang - */ -export function selectRate(lang) { - return `${hotelreservation(lang)}/select-rate` -} - /** * @param {Lang} lang * @param {string} hotelId diff --git a/apps/scandic-web/global.d.ts b/apps/scandic-web/global.d.ts index edf0a58b3..9b2abb356 100644 --- a/apps/scandic-web/global.d.ts +++ b/apps/scandic-web/global.d.ts @@ -1,2 +1,4 @@ import "@scandic-hotels/common/global.d.ts" import "@scandic-hotels/trpc/types.d.ts" +import "@scandic-hotels/trpc/auth.d.ts" +import "@scandic-hotels/trpc/jwt.d.ts" diff --git a/apps/scandic-web/hooks/booking/useGuaranteePaymentFailedToast.ts b/apps/scandic-web/hooks/booking/useGuaranteePaymentFailedToast.ts index 661328df1..147bd1e09 100644 --- a/apps/scandic-web/hooks/booking/useGuaranteePaymentFailedToast.ts +++ b/apps/scandic-web/hooks/booking/useGuaranteePaymentFailedToast.ts @@ -4,7 +4,7 @@ import { usePathname, useRouter, useSearchParams } from "next/navigation" import { useCallback, useEffect } from "react" import { useIntl } from "react-intl" -import { BookingErrorCodeEnum } from "@/constants/booking" +import { BookingErrorCodeEnum } from "@scandic-hotels/trpc/enums/bookingErrorCode" import { toast } from "@/components/TempDesignSystem/Toasts" diff --git a/apps/scandic-web/lib/trpc/memoizedRequests/index.ts b/apps/scandic-web/lib/trpc/memoizedRequests/index.ts index 1c02bdf25..88c7aa5ab 100644 --- a/apps/scandic-web/lib/trpc/memoizedRequests/index.ts +++ b/apps/scandic-web/lib/trpc/memoizedRequests/index.ts @@ -9,18 +9,18 @@ import { serverClient } from "../server" import type { Lang } from "@scandic-hotels/common/constants/language" import type { GetHotelsByCSFilterInput } from "@scandic-hotels/trpc/routers/hotels/input" +import type { RoomsAvailabilityExtendedInputSchema } from "@scandic-hotels/trpc/types/availability" import type { Country } from "@scandic-hotels/trpc/types/country" import type { CityCoordinatesInput, HotelInput, } from "@scandic-hotels/trpc/types/hotel" - import type { AncillaryPackagesInput, BreackfastPackagesInput, PackagesInput, -} from "@/types/requests/packages" -import type { RoomsAvailabilityExtendedInputSchema } from "@/types/trpc/routers/hotel/availability" +} from "@scandic-hotels/trpc/types/packages" + import type { GetSavedPaymentCardsInput } from "@/server/routers/user/input" export const getLocations = cache(async function getMemoizedLocations() { diff --git a/apps/scandic-web/middlewares/bookingFlow.ts b/apps/scandic-web/middlewares/bookingFlow.ts index fb44a2ec9..e6b2634e6 100644 --- a/apps/scandic-web/middlewares/bookingFlow.ts +++ b/apps/scandic-web/middlewares/bookingFlow.ts @@ -1,11 +1,13 @@ import { type NextMiddleware, NextResponse } from "next/server" -import { REDEMPTION, SEARCHTYPE } from "@/constants/booking" +import { findLang } from "@scandic-hotels/common/utils/languages" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" + +import { SEARCHTYPE } from "@/constants/booking" import { login } from "@/constants/routes/handleAuth" import { getPublicNextURL } from "@/server/utils" import { auth } from "@/auth" -import { findLang } from "@scandic-hotels/common/utils/languages" import { isValidSession } from "@/utils/session" import { getDefaultRequestHeaders } from "./utils" diff --git a/apps/scandic-web/providers/MyStay.tsx b/apps/scandic-web/providers/MyStay.tsx index 81b86f187..5ecae1c7a 100644 --- a/apps/scandic-web/providers/MyStay.tsx +++ b/apps/scandic-web/providers/MyStay.tsx @@ -3,6 +3,8 @@ import { notFound } from "next/navigation" import { use, useRef } from "react" import { useIntl } from "react-intl" +import { type RoomCategories } from "@scandic-hotels/trpc/types/hotel" + import { trpc } from "@/lib/trpc/client" import { createMyStayStore } from "@/stores/my-stay" @@ -10,15 +12,14 @@ import { MyStaySkeleton } from "@/components/HotelReservation/MyStay/myStaySkele import { MyStayContext } from "@/contexts/MyStay" import type { Lang } from "@scandic-hotels/common/constants/language" +import type { CreditCard } from "@scandic-hotels/trpc/types/user" import type { Packages } from "@/types/components/myPages/myStay/ancillaries" import type { MyStayStore } from "@/types/contexts/my-stay" -import type { RoomCategories } from "@scandic-hotels/trpc/types/hotel" import type { BookingConfirmation, BookingConfirmationSchema, } from "@/types/trpc/routers/booking/confirmation" -import type { CreditCard } from "@/types/user" interface MyStayProviderProps { bookingConfirmation: BookingConfirmation diff --git a/apps/scandic-web/server/index.ts b/apps/scandic-web/server/index.ts index 5a3276256..bbd2d4ab1 100644 --- a/apps/scandic-web/server/index.ts +++ b/apps/scandic-web/server/index.ts @@ -1,10 +1,10 @@ /** Routers */ import { router } from "@scandic-hotels/trpc" import { contentstackRouter } from "@scandic-hotels/trpc/routers/contentstack" +import { hotelsRouter } from "@scandic-hotels/trpc/routers/hotels" import { autocompleteRouter } from "./routers/autocomplete" import { bookingRouter } from "./routers/booking" -import { hotelsRouter } from "./routers/hotels" import { navigationRouter } from "./routers/navigation" import { partnerRouter } from "./routers/partners" import { userRouter } from "./routers/user" diff --git a/apps/scandic-web/server/routers/hotels/utils.ts b/apps/scandic-web/server/routers/hotels/utils.ts deleted file mode 100644 index d23fb86bd..000000000 --- a/apps/scandic-web/server/routers/hotels/utils.ts +++ /dev/null @@ -1,751 +0,0 @@ -import stringify from "json-stable-stringify-without-jsonify" - -import { getCacheClient } from "@scandic-hotels/common/dataCache" -import { createCounter } from "@scandic-hotels/common/telemetry" -import * as api from "@scandic-hotels/trpc/api" -import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" -import { AvailabilityEnum } from "@scandic-hotels/trpc/enums/selectHotel" -import { badRequestError } from "@scandic-hotels/trpc/errors" -import { type RoomFeaturesInput } from "@scandic-hotels/trpc/routers/hotels/input" -import { - hotelsAvailabilitySchema, - packagesSchema, - roomFeaturesSchema, - roomsAvailabilitySchema, -} from "@scandic-hotels/trpc/routers/hotels/output" -import { toApiLang } from "@scandic-hotels/trpc/utils" -import { sortRoomConfigs } from "@scandic-hotels/trpc/utils/sortRoomConfigs" - -import { BookingErrorCodeEnum, REDEMPTION } from "@/constants/booking" -import { selectRate } from "@/constants/routes/hotelReservation" -import { env } from "@/env/server" - -import { generateChildrenString } from "@/components/HotelReservation/utils" - -import type { Room as RoomCategory } from "@scandic-hotels/trpc/types/hotel" -import type { - Product, - Products, - RateDefinition, - RedemptionsProduct, - RoomConfiguration, -} from "@scandic-hotels/trpc/types/roomAvailability" - -import type { BedTypeSelection } from "@/types/components/hotelReservation/enterDetails/bedType" -import type { PackagesOutput } from "@/types/requests/packages" -import type { - HotelsAvailabilityInputSchema, - HotelsByHotelIdsAvailabilityInputSchema, - RoomsAvailabilityExtendedInputSchema, - RoomsAvailabilityInputRoom, - RoomsAvailabilityOutputSchema, -} from "@/types/trpc/routers/hotel/availability" - -export const TWENTYFOUR_HOURS = 60 * 60 * 24 - -function findProduct(product: Products, rateDefinition: RateDefinition) { - if ("corporateCheque" in product) { - return product.corporateCheque.rateCode === rateDefinition.rateCode - } - - if (("member" in product && product.member) || "public" in product) { - let isMemberRate = false - if (product.member) { - isMemberRate = product.member.rateCode === rateDefinition.rateCode - } - let isPublicRate = false - if (product.public) { - isPublicRate = product.public.rateCode === rateDefinition.rateCode - } - return isMemberRate || isPublicRate - } - - if ("voucher" in product) { - return product.voucher.rateCode === rateDefinition.rateCode - } - - if (Array.isArray(product)) { - return product.find( - (r) => r.redemption.rateCode === rateDefinition.rateCode - ) - } -} - -export async function getHotelsAvailabilityByCity( - input: HotelsAvailabilityInputSchema, - apiLang: string, - token: string, // Either service token or user access token in case of redemption search - userPoints: number = 0 -) { - const { - cityId, - roomStayStartDate, - roomStayEndDate, - adults, - children, - bookingCode, - redemption, - } = input - - const params: Record = { - roomStayStartDate, - roomStayEndDate, - adults, - ...(children && { children }), - ...(bookingCode && { bookingCode }), - ...(redemption ? { isRedemption: "true" } : {}), - language: apiLang, - } - - const getHotelsAvailabilityByCityCounter = createCounter( - "hotel", - "getHotelsAvailabilityByCity" - ) - const metricsGetHotelsAvailabilityByCity = - getHotelsAvailabilityByCityCounter.init({ - apiLang, - cityId, - roomStayStartDate, - roomStayEndDate, - adults, - children, - bookingCode, - redemption, - }) - - metricsGetHotelsAvailabilityByCity.start() - - const apiResponse = await api.get( - api.endpoints.v1.Availability.city(cityId), - { - headers: { - Authorization: `Bearer ${token}`, - }, - }, - params - ) - if (!apiResponse.ok) { - await metricsGetHotelsAvailabilityByCity.httpError(apiResponse) - throw new Error("Failed to fetch hotels availability by city") - } - - const apiJson = await apiResponse.json() - const validateAvailabilityData = hotelsAvailabilitySchema.safeParse(apiJson) - if (!validateAvailabilityData.success) { - metricsGetHotelsAvailabilityByCity.validationError( - validateAvailabilityData.error - ) - throw badRequestError() - } - - if (redemption) { - validateAvailabilityData.data.data.forEach((data) => { - data.attributes.productType?.redemptions?.forEach((r) => { - r.hasEnoughPoints = userPoints >= r.localPrice.pointsPerStay - }) - }) - } - - const result = { - availability: validateAvailabilityData.data.data.flatMap( - (hotels) => hotels.attributes - ), - } - - metricsGetHotelsAvailabilityByCity.success() - - return result -} - -export async function getHotelsAvailabilityByHotelIds( - input: HotelsByHotelIdsAvailabilityInputSchema, - apiLang: string, - serviceToken: string -) { - const { - hotelIds, - roomStayStartDate, - roomStayEndDate, - adults, - children, - bookingCode, - } = input - - const params = new URLSearchParams([ - ["roomStayStartDate", roomStayStartDate], - ["roomStayEndDate", roomStayEndDate], - ["adults", adults.toString()], - ["children", children ?? ""], - ["bookingCode", bookingCode], - ["language", apiLang], - ]) - - const getHotelsAvailabilityByHotelIdsCounter = createCounter( - "hotel", - "getHotelsAvailabilityByHotelIds" - ) - const metricsGetHotelsAvailabilityByHotelIds = - getHotelsAvailabilityByHotelIdsCounter.init({ - apiLang, - hotelIds, - roomStayStartDate, - roomStayEndDate, - adults, - children, - bookingCode, - }) - - metricsGetHotelsAvailabilityByHotelIds.start() - - const cacheClient = await getCacheClient() - - const result = cacheClient.cacheOrGet( - `${apiLang}:hotels:availability:${hotelIds.join(",")}:${roomStayStartDate}:${roomStayEndDate}:${adults}:${children}:${bookingCode}`, - async () => { - /** - * Since API expects the params appended and not just - * a comma separated string we need to initialize the - * SearchParams with a sequence of pairs - * (hotelIds=810&hotelIds=879&hotelIds=222 etc.) - **/ - - hotelIds.forEach((hotelId) => - params.append("hotelIds", hotelId.toString()) - ) - - const apiResponse = await api.get( - api.endpoints.v1.Availability.hotels(), - { - headers: { - Authorization: `Bearer ${serviceToken}`, - }, - }, - params - ) - if (!apiResponse.ok) { - await metricsGetHotelsAvailabilityByHotelIds.httpError(apiResponse) - throw new Error("Failed to fetch hotels availability by hotelIds") - } - - const apiJson = await apiResponse.json() - const validateAvailabilityData = - hotelsAvailabilitySchema.safeParse(apiJson) - if (!validateAvailabilityData.success) { - metricsGetHotelsAvailabilityByHotelIds.validationError( - validateAvailabilityData.error - ) - throw badRequestError() - } - - return { - availability: validateAvailabilityData.data.data.flatMap( - (hotels) => hotels.attributes - ), - } - }, - env.CACHE_TIME_CITY_SEARCH - ) - - metricsGetHotelsAvailabilityByHotelIds.success() - - return result -} - -async function getRoomFeaturesInventory( - input: RoomFeaturesInput, - token: string -) { - const { - adults, - childrenInRoom, - endDate, - hotelId, - roomFeatureCodes, - startDate, - } = input - - const params = { - adults, - hotelId, - roomFeatureCode: roomFeatureCodes, - roomStayEndDate: endDate, - roomStayStartDate: startDate, - ...(childrenInRoom?.length && { - children: generateChildrenString(childrenInRoom), - }), - } - - const getRoomFeaturesInventoryCounter = createCounter( - "hotel", - "getRoomFeaturesInventory" - ) - const metricsGetRoomFeaturesInventory = - getRoomFeaturesInventoryCounter.init(params) - - metricsGetRoomFeaturesInventory.start() - - const cacheClient = await getCacheClient() - - const result = cacheClient.cacheOrGet( - stringify(input), - async function () { - const apiResponse = await api.get( - api.endpoints.v1.Availability.roomFeatures(hotelId), - { - headers: { - Authorization: `Bearer ${token}`, - }, - }, - params - ) - - if (!apiResponse.ok) { - await metricsGetRoomFeaturesInventory.httpError(apiResponse) - return null - } - - const data = await apiResponse.json() - const validatedRoomFeaturesData = roomFeaturesSchema.safeParse(data) - if (!validatedRoomFeaturesData.success) { - metricsGetRoomFeaturesInventory.validationError( - validatedRoomFeaturesData.error - ) - return null - } - - return validatedRoomFeaturesData.data - }, - "5m" - ) - - metricsGetRoomFeaturesInventory.success() - - return result -} - -export async function getPackages(input: PackagesOutput, serviceToken: string) { - const { adults, children, endDate, hotelId, lang, packageCodes, startDate } = - input - - const getPackagesCounter = createCounter("hotel", "getPackages") - const metricsGetPackages = getPackagesCounter.init({ - input, - }) - - metricsGetPackages.start() - - const cacheClient = await getCacheClient() - - const result = cacheClient.cacheOrGet( - stringify(input), - async function () { - const apiLang = toApiLang(lang) - - const searchParams = new URLSearchParams({ - adults: adults.toString(), - children: children.toString(), - endDate, - language: apiLang, - startDate, - }) - - packageCodes.forEach((code) => { - searchParams.append("packageCodes", code) - }) - - const apiResponse = await api.get( - api.endpoints.v1.Package.Packages.hotel(hotelId), - { - headers: { - Authorization: `Bearer ${serviceToken}`, - }, - }, - searchParams - ) - - if (!apiResponse.ok) { - await metricsGetPackages.httpError(apiResponse) - return null - } - - const apiJson = await apiResponse.json() - const validatedPackagesData = packagesSchema.safeParse(apiJson) - if (!validatedPackagesData.success) { - metricsGetPackages.validationError(validatedPackagesData.error) - return null - } - - return validatedPackagesData.data - }, - "3h" - ) - - metricsGetPackages.success() - - return result -} - -export async function getRoomsAvailability( - input: RoomsAvailabilityOutputSchema, - token: string, - serviceToken: string, - userPoints: number | undefined -) { - const { - booking: { bookingCode, fromDate, hotelId, rooms, searchType, toDate }, - lang, - } = input - - const redemption = searchType === REDEMPTION - - const getRoomsAvailabilityCounter = createCounter( - "hotel", - "getRoomsAvailability" - ) - const metricsGetRoomsAvailability = getRoomsAvailabilityCounter.init({ - input, - redemption, - }) - - metricsGetRoomsAvailability.start() - - const apiLang = toApiLang(lang) - - const baseCacheKey = { - bookingCode, - fromDate, - hotelId, - lang, - searchType, - toDate, - } - - const cacheClient = await getCacheClient() - const availabilityResponses = await Promise.allSettled( - rooms.map((room: RoomsAvailabilityInputRoom) => { - const cacheKey = { - ...baseCacheKey, - room, - } - const result = cacheClient.cacheOrGet( - stringify(cacheKey), - async function () { - { - const params = { - adults: room.adults, - language: apiLang, - roomStayStartDate: fromDate, - roomStayEndDate: toDate, - ...(room.childrenInRoom?.length && { - children: generateChildrenString(room.childrenInRoom), - }), - ...(room.bookingCode && { bookingCode: room.bookingCode }), - ...(redemption && { isRedemption: "true" }), - } - - const apiResponse = await api.get( - api.endpoints.v1.Availability.hotel(hotelId), - { - cache: undefined, // overwrite default - headers: { - Authorization: `Bearer ${token}`, - }, - }, - params - ) - - if (!apiResponse.ok) { - await metricsGetRoomsAvailability.httpError(apiResponse) - const text = await apiResponse.text() - return { error: "http_error", details: text } - } - - const apiJson = await apiResponse.json() - const validateAvailabilityData = - roomsAvailabilitySchema.safeParse(apiJson) - if (!validateAvailabilityData.success) { - metricsGetRoomsAvailability.validationError( - validateAvailabilityData.error - ) - - return { - error: "validation_error", - details: validateAvailabilityData.error, - } - } - - if (redemption) { - for (const roomConfig of validateAvailabilityData.data - .roomConfigurations) { - for (const product of roomConfig.redemptions) { - if (userPoints) { - product.redemption.hasEnoughPoints = - userPoints >= product.redemption.localPrice.pointsPerStay - } - } - } - } - - const roomFeatures = await getPackages( - { - adults: room.adults, - children: room.childrenInRoom?.length || 0, - endDate: input.booking.toDate, - hotelId: input.booking.hotelId, - lang, - packageCodes: [ - RoomPackageCodeEnum.ACCESSIBILITY_ROOM, - RoomPackageCodeEnum.ALLERGY_ROOM, - RoomPackageCodeEnum.PET_ROOM, - ], - startDate: input.booking.fromDate, - }, - serviceToken - ) - - if (roomFeatures) { - validateAvailabilityData.data.packages = roomFeatures - } - - // Fetch packages - if (room.packages?.length) { - const roomFeaturesInventory = await getRoomFeaturesInventory( - { - adults: room.adults, - childrenInRoom: room.childrenInRoom, - endDate: input.booking.toDate, - hotelId: input.booking.hotelId, - lang, - roomFeatureCodes: room.packages, - startDate: input.booking.fromDate, - }, - serviceToken - ) - - if (roomFeaturesInventory) { - const features = roomFeaturesInventory.reduce< - Record - >((fts, feat) => { - fts[feat.roomTypeCode] = feat.features?.[0]?.inventory ?? 0 - return fts - }, {}) - - const updatedRoomConfigurations = - validateAvailabilityData.data.roomConfigurations - // This filter is needed since we can get availability - // back from roomFeatures yet the availability call - // says there are no rooms left... - .filter((rc) => rc.roomsLeft) - .filter((rc) => features?.[rc.roomTypeCode]) - .map((rc) => ({ - ...rc, - roomsLeft: features[rc.roomTypeCode], - status: AvailabilityEnum.Available, - })) - - validateAvailabilityData.data.roomConfigurations = - updatedRoomConfigurations - } - } - - return validateAvailabilityData.data - } - }, - "1m" - ) - - return result - }) - ) - - const data = availabilityResponses.map((availability) => { - if (availability.status === "fulfilled") { - return availability.value - } - return { - details: availability.reason, - error: "request_failure", - } - }) - - metricsGetRoomsAvailability.success() - - return data -} - -export function getSelectedRoomAvailability( - rateCode: string, - rateDefinitions: RateDefinition[], - roomConfigurations: RoomConfiguration[], - roomTypeCode: string, - userPoints: number | undefined -) { - const rateDefinition = rateDefinitions.find((rd) => rd.rateCode === rateCode) - if (!rateDefinition) { - return null - } - - const selectedRoom = roomConfigurations.find( - (room) => - room.roomTypeCode === roomTypeCode && - room.products.find((product) => findProduct(product, rateDefinition)) - ) - - if (!selectedRoom) { - return null - } - - let product: Product | RedemptionsProduct | undefined = - selectedRoom.products.find((product) => - findProduct(product, rateDefinition) - ) - - if (!product) { - return null - } - - if (Array.isArray(product)) { - const redemptionProduct = userPoints - ? product.find( - (r) => - r.redemption.rateCode === rateDefinition.rateCode && - r.redemption.localPrice.pointsPerStay <= userPoints - ) - : undefined - if (!redemptionProduct) { - return null - } - product = redemptionProduct - } - - return { - rateDefinition, - rateDefinitions, - rooms: roomConfigurations, - product, - selectedRoom, - } -} - -export function getBedTypes( - rooms: RoomConfiguration[], - roomType: string, - roomCategories?: RoomCategory[] -) { - if (!roomCategories) { - return [] - } - - return rooms - .filter( - (room) => room.status === AvailabilityEnum.Available || room.roomsLeft > 0 - ) - .filter((room) => room.roomType === roomType) - .map((availRoom) => { - const matchingRoom = roomCategories - ?.find((room) => - room.roomTypes - .map((roomType) => roomType.code) - .includes(availRoom.roomTypeCode) - ) - ?.roomTypes.find((roomType) => roomType.code === availRoom.roomTypeCode) - - if (matchingRoom) { - return { - description: matchingRoom.description, - size: matchingRoom.mainBed.widthRange, - value: matchingRoom.code, - type: matchingRoom.mainBed.type, - roomsLeft: availRoom.roomsLeft, - extraBed: matchingRoom.fixedExtraBed - ? { - type: matchingRoom.fixedExtraBed.type, - description: matchingRoom.fixedExtraBed.description, - } - : undefined, - } - } - }) - .filter((bed): bed is BedTypeSelection => Boolean(bed)) -} - -export function mergeRoomTypes(roomConfigurations: RoomConfiguration[]) { - // Initial sort to guarantee if one bed is NotAvailable and whereas - // the other is Available to make sure data is added to the correct - // roomConfig - roomConfigurations.sort(sortRoomConfigs) - - const roomConfigs = new Map() - for (const roomConfig of roomConfigurations) { - if (roomConfigs.has(roomConfig.roomType)) { - const currentRoomConf = roomConfigs.get(roomConfig.roomType) - if (currentRoomConf) { - currentRoomConf.features = roomConfig.features.reduce( - (feats, feature) => { - const currentFeatureIndex = feats.findIndex( - (f) => f.code === feature.code - ) - if (currentFeatureIndex !== -1) { - feats[currentFeatureIndex].inventory = - feats[currentFeatureIndex].inventory + feature.inventory - } else { - feats.push(feature) - } - return feats - }, - currentRoomConf.features - ) - currentRoomConf.roomsLeft = - currentRoomConf.roomsLeft + roomConfig.roomsLeft - roomConfigs.set(currentRoomConf.roomType, currentRoomConf) - } - } else { - roomConfigs.set(roomConfig.roomType, roomConfig) - } - } - return Array.from(roomConfigs.values()) -} - -export function selectRateRedirectURL( - input: RoomsAvailabilityExtendedInputSchema, - selectedRooms: boolean[] -) { - const searchParams = new URLSearchParams({ - errorCode: BookingErrorCodeEnum.AvailabilityError, - fromdate: input.booking.fromDate, - hotel: input.booking.hotelId, - todate: input.booking.toDate, - }) - if (input.booking.searchType) { - searchParams.set("searchtype", input.booking.searchType) - } - for (const [idx, room] of input.booking.rooms.entries()) { - searchParams.set(`room[${idx}].adults`, room.adults.toString()) - - if (selectedRooms[idx]) { - if (room.counterRateCode) { - searchParams.set(`room[${idx}].counterratecode`, room.counterRateCode) - } - searchParams.set(`room[${idx}].ratecode`, room.rateCode) - searchParams.set(`room[${idx}].roomtype`, room.roomTypeCode) - } else { - if (!searchParams.has("modifyRateIndex")) { - searchParams.set("modifyRateIndex", idx.toString()) - } - } - if (room.bookingCode) { - searchParams.set(`room[${idx}].bookingCode`, room.bookingCode) - } - if (room.packages) { - searchParams.set(`room[${idx}].packages`, room.packages.join(",")) - } - if (room.childrenInRoom?.length) { - for (const [i, kid] of room.childrenInRoom.entries()) { - searchParams.set(`room[${idx}].child[${i}].age`, kid.age.toString()) - searchParams.set(`room[${idx}].child[${i}].bed`, kid.bed.toString()) - } - } - } - - return `${selectRate(input.lang)}?${searchParams.toString()}` -} diff --git a/apps/scandic-web/server/routers/navigation/mypages/getPrimaryLinks.ts b/apps/scandic-web/server/routers/navigation/mypages/getPrimaryLinks.ts index dbb8addb0..0643178f2 100644 --- a/apps/scandic-web/server/routers/navigation/mypages/getPrimaryLinks.ts +++ b/apps/scandic-web/server/routers/navigation/mypages/getPrimaryLinks.ts @@ -9,8 +9,8 @@ import { getIntl } from "@/i18n" import { getEurobonusMembership } from "@/utils/user" import type { Lang } from "@scandic-hotels/common/constants/language" +import type { UserLoyalty } from "@scandic-hotels/trpc/types/user" -import type { UserLoyalty } from "@/types/user" import type { MyPagesLink } from "./MyPagesLink" export const getPrimaryLinks = cache( diff --git a/apps/scandic-web/server/routers/navigation/mypages/index.ts b/apps/scandic-web/server/routers/navigation/mypages/index.ts index 6b7fea898..2f8e5dcb8 100644 --- a/apps/scandic-web/server/routers/navigation/mypages/index.ts +++ b/apps/scandic-web/server/routers/navigation/mypages/index.ts @@ -3,8 +3,7 @@ import { z } from "zod" import { Lang } from "@scandic-hotels/common/constants/language" import { safeProtectedProcedure } from "@scandic-hotels/trpc/procedures" - -import { getVerifiedUser } from "@/server/routers/user/utils" +import { getVerifiedUser } from "@scandic-hotels/trpc/routers/user/utils" import { isValidSession } from "@/utils/session" diff --git a/apps/scandic-web/server/routers/partners/sas/performLevelUpgrade.ts b/apps/scandic-web/server/routers/partners/sas/performLevelUpgrade.ts index 966cde952..8603c2541 100644 --- a/apps/scandic-web/server/routers/partners/sas/performLevelUpgrade.ts +++ b/apps/scandic-web/server/routers/partners/sas/performLevelUpgrade.ts @@ -4,13 +4,12 @@ import { z } from "zod" import * as api from "@scandic-hotels/trpc/api" import { protectedProcedure } from "@scandic-hotels/trpc/procedures" +import { getUserSchema } from "@scandic-hotels/trpc/routers/user/output" +import { getVerifiedUser } from "@scandic-hotels/trpc/routers/user/utils" import { FriendsMembershipLevels } from "@/constants/membershipLevels" -import { getUserSchema } from "../../user/output" -import { getVerifiedUser } from "../../user/utils" - -import type { FriendsTier } from "@/types/user" +import type { FriendsTier } from "@scandic-hotels/trpc/types/user" const matchedSchema = z.object({ tierMatchState: z.enum(["matched"]), diff --git a/apps/scandic-web/server/routers/user/output.ts b/apps/scandic-web/server/routers/user/output.ts index c01236949..8bf0d3e5a 100644 --- a/apps/scandic-web/server/routers/user/output.ts +++ b/apps/scandic-web/server/routers/user/output.ts @@ -2,122 +2,6 @@ import { z } from "zod" import { imageSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/image" -import { countriesMap } from "@/constants/countries" - -import { getFriendsMembership } from "@/utils/user" - -const scandicFriendsTier = z.enum(["L1", "L2", "L3", "L4", "L5", "L6", "L7"]) -const sasEurobonusTier = z.enum(["EBB", "EBS", "EBG", "EBD", "EBP"]) - -const commonMembershipSchema = z.object({ - membershipNumber: z.string(), - tierExpires: z.string().nullish().default(null), - memberSince: z.string().nullish(), -}) - -// This prevents validation errors if the API returns an unhandled membership type -const otherMembershipSchema = z - .object({ - // This ensures that `type` won't widen into "string", losing the literal types, when used in a union - type: z.string().refine((val): val is string & {} => true), - }) - .merge(commonMembershipSchema) - -export const sasMembershipSchema = z - .object({ - type: z.literal("SAS_EB"), - tier: sasEurobonusTier, - nextTier: sasEurobonusTier.nullish(), - spendablePoints: z.number().nullish(), - boostedByScandic: z.boolean().nullish(), - boostedTier: sasEurobonusTier.nullish(), - boostedTierExpires: z.string().nullish().default(null), - }) - .merge(commonMembershipSchema) - .transform((response) => { - return { - ...response, - tierExpires: - // SAS API returns 1900-01-01 for non-expiring tiers - response.tierExpires === "1900-01-01" ? null : response.tierExpires, - } - }) - -export const friendsMembershipSchema = z - .object({ - type: z.literal("SCANDIC_NATIVE"), - tier: scandicFriendsTier, - nextTier: scandicFriendsTier.nullish(), - pointsToNextTier: z.number().nullish(), - nightsToTopTier: z.number().nullish(), - }) - .merge(commonMembershipSchema) - -export const membershipSchema = z.union([ - friendsMembershipSchema, - sasMembershipSchema, - otherMembershipSchema, -]) - -const pointExpirationSchema = z.object({ - points: z.number().int(), - expires: z.string(), -}) - -export const userLoyaltySchema = z.object({ - memberships: z.array(membershipSchema), - points: z.object({ - spendable: z.number().int(), - earned: z.number().int(), - spent: z.number().int(), - }), - tier: scandicFriendsTier, - tierExpires: z.string(), - tierBoostedBy: z.string().nullish(), - pointExpirations: z.array(pointExpirationSchema), -}) - -export const getUserSchema = z - .object({ - data: z.object({ - attributes: z.object({ - dateOfBirth: z.string().optional().default("1900-01-01"), - email: z.string().email(), - firstName: z.string(), - language: z - .string() - // Preserve Profile v1 formatting for now so it matches ApiLang enum - .transform((s) => s.charAt(0).toUpperCase() + s.slice(1)) - .optional(), - lastName: z.string(), - phoneNumber: z.string().optional(), - profileId: z.string(), - membershipNumber: z.string(), - address: z - .object({ - city: z.string().optional(), - country: z.string().optional(), - countryCode: z.nativeEnum(countriesMap).optional(), - streetAddress: z.string().optional(), - zipCode: z.string().optional(), - }) - .optional() - .nullable(), - loyalty: userLoyaltySchema.optional(), - }), - type: z.string(), - }), - }) - .transform((apiResponse) => { - return { - ...apiResponse.data.attributes, - membership: apiResponse.data.attributes.loyalty - ? getFriendsMembership(apiResponse.data.attributes.loyalty) - : null, - name: `${apiResponse.data.attributes.firstName} ${apiResponse.data.attributes.lastName}`, - } - }) - // Schema is the same for upcoming and previous stays endpoints export const getStaysSchema = z.object({ data: z.array( @@ -234,35 +118,6 @@ type GetFriendTransactionsData = z.infer export type FriendTransaction = GetFriendTransactionsData["data"][number] -export const creditCardSchema = z - .object({ - attribute: z.object({ - cardName: z.string().optional(), - alias: z.string(), - truncatedNumber: z.string().transform((s) => s.slice(-4)), - expirationDate: z.string(), - cardType: z - .string() - .transform((s) => s.charAt(0).toLowerCase() + s.slice(1)), - }), - id: z.string(), - type: z.string(), - }) - .transform((apiResponse) => { - return { - id: apiResponse.id, - type: apiResponse.attribute.cardType, - truncatedNumber: apiResponse.attribute.truncatedNumber, - alias: apiResponse.attribute.alias, - expirationDate: apiResponse.attribute.expirationDate, - cardType: apiResponse.attribute.cardType, - } - }) - -export const creditCardsSchema = z.object({ - data: z.array(creditCardSchema), -}) - export const initiateSaveCardSchema = z.object({ data: z.object({ attribute: z.object({ diff --git a/apps/scandic-web/server/routers/user/query.ts b/apps/scandic-web/server/routers/user/query.ts index 699edb51f..68608182b 100644 --- a/apps/scandic-web/server/routers/user/query.ts +++ b/apps/scandic-web/server/routers/user/query.ts @@ -6,10 +6,12 @@ import { protectedProcedure, safeProtectedProcedure, } from "@scandic-hotels/trpc/procedures" +import { getFriendsMembership } from "@scandic-hotels/trpc/routers/user/helpers" +import { getVerifiedUser } from "@scandic-hotels/trpc/routers/user/utils" import { toApiLang } from "@scandic-hotels/trpc/utils" import { isValidSession } from "@/utils/session" -import { getFriendsMembership, getMembershipCards } from "@/utils/user" +import { getMembershipCards } from "@/utils/user" import { friendTransactionsInput, @@ -22,13 +24,14 @@ import { getCreditCards, getPreviousStays, getUpcomingStays, - getVerifiedUser, parsedUser, updateStaysBookingUrl, } from "./utils" +import type { LoginType } from "@scandic-hotels/trpc/types/loginType" + import type { - LoginType, + // LoginType, TrackingSDKUserData, } from "@/types/components/tracking" import { Transactions } from "@/types/enums/transactions" diff --git a/apps/scandic-web/server/routers/user/utils.ts b/apps/scandic-web/server/routers/user/utils.ts index ff596c704..8c3c914c0 100644 --- a/apps/scandic-web/server/routers/user/utils.ts +++ b/apps/scandic-web/server/routers/user/utils.ts @@ -2,9 +2,12 @@ import { myStay } from "@scandic-hotels/common/constants/routes/myStay" import { dt } from "@scandic-hotels/common/dt" import { createCounter } from "@scandic-hotels/common/telemetry" import * as api from "@scandic-hotels/trpc/api" +import { countries } from "@scandic-hotels/trpc/constants/countries" +import { getFriendsMembership } from "@scandic-hotels/trpc/routers/user/helpers" +import { creditCardsSchema } from "@scandic-hotels/trpc/routers/user/output" +import { getVerifiedUser } from "@scandic-hotels/trpc/routers/user/utils" import { toApiLang } from "@scandic-hotels/trpc/utils" -import { countries } from "@/constants/countries" import { myBookingPath } from "@/constants/myBooking" import { env } from "@/env/server" @@ -13,93 +16,13 @@ import { encrypt } from "@/utils/encryption" import * as maskValue from "@/utils/maskValue" import { isValidSession } from "@/utils/session" import { getCurrentWebUrl } from "@/utils/url" -import { getFriendsMembership } from "@/utils/user" -import { - creditCardsSchema, - type FriendTransaction, - getStaysSchema, - getUserSchema, - type Stay, -} from "./output" +import { type FriendTransaction, getStaysSchema, type Stay } from "./output" import type { Lang } from "@scandic-hotels/common/constants/language" +import type { User } from "@scandic-hotels/trpc/types/user" import type { Session } from "next-auth" -import type { User } from "@/types/user" - -export const getVerifiedUser = cache( - async ({ - session, - includeExtendedPartnerData, - }: { - session: Session - includeExtendedPartnerData?: boolean - }) => { - const getVerifiedUserCounter = createCounter("user", "getVerifiedUser") - const metricsGetVerifiedUser = getVerifiedUserCounter.init() - - metricsGetVerifiedUser.start() - - const now = Date.now() - if (session.token.expires_at && session.token.expires_at < now) { - metricsGetVerifiedUser.dataError(`Token expired`) - return { error: true, cause: "token_expired" } as const - } - - const apiResponse = await api.get( - api.endpoints.v2.Profile.profile, - { - headers: { - Authorization: `Bearer ${session.token.access_token}`, - }, - }, - includeExtendedPartnerData - ? { includes: "extendedPartnerInformation" } - : {} - ) - - if (!apiResponse.ok) { - await metricsGetVerifiedUser.httpError(apiResponse) - - if (apiResponse.status === 401) { - return { error: true, cause: "unauthorized" } as const - } else if (apiResponse.status === 403) { - return { error: true, cause: "forbidden" } as const - } else if (apiResponse.status === 404) { - return { error: true, cause: "notfound" } as const - } - - return { - error: true, - cause: "unknown", - status: apiResponse.status, - } as const - } - - const apiJson = await apiResponse.json() - if (!apiJson.data?.attributes) { - metricsGetVerifiedUser.dataError( - `Missing data attributes in API response`, - { - data: apiJson, - } - ) - return null - } - - const verifiedData = getUserSchema.safeParse(apiJson) - if (!verifiedData.success) { - metricsGetVerifiedUser.validationError(verifiedData.error) - return null - } - - metricsGetVerifiedUser.success() - - return verifiedData - } -) - export async function getMembershipNumber( session: Session | null ): Promise { diff --git a/apps/scandic-web/stores/enter-details/helpers.ts b/apps/scandic-web/stores/enter-details/helpers.ts index 9a79a8821..369c48623 100644 --- a/apps/scandic-web/stores/enter-details/helpers.ts +++ b/apps/scandic-web/stores/enter-details/helpers.ts @@ -11,6 +11,7 @@ import { import { detailsStorageName } from "." +import type { Packages } from "@scandic-hotels/trpc/types/packages" import type { CorporateChequeProduct, PriceProduct, @@ -22,7 +23,6 @@ import type { BreakfastPackage } from "@/types/components/hotelReservation/break import { type RoomRate } from "@/types/components/hotelReservation/enterDetails/details" import type { Price } from "@/types/components/hotelReservation/price" import type { SelectRateBooking } from "@/types/components/hotelReservation/selectRate/selectRate" -import type { Packages } from "@/types/requests/packages" import type { PersistedState, RoomState } from "@/types/stores/enter-details" import type { SafeUser } from "@/types/user" diff --git a/apps/scandic-web/stores/select-rate/index.ts b/apps/scandic-web/stores/select-rate/index.ts index 500abae37..fa31a6f2a 100644 --- a/apps/scandic-web/stores/select-rate/index.ts +++ b/apps/scandic-web/stores/select-rate/index.ts @@ -2,11 +2,10 @@ import { produce } from "immer" import { useContext } from "react" import { create, useStore } from "zustand" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" import { AvailabilityEnum } from "@scandic-hotels/trpc/enums/selectHotel" -import { REDEMPTION } from "@/constants/booking" - import { RatesContext } from "@/contexts/Rates" import { serializeBookingSearchParams } from "@/utils/url" @@ -16,10 +15,10 @@ import { findSelectedRate, } from "./helpers" +import type { Package, Packages } from "@scandic-hotels/trpc/types/packages" import type { PriceProduct } from "@scandic-hotels/trpc/types/roomAvailability" import { BookingCodeFilterEnum } from "@/types/enums/bookingCodeFilter" -import type { Package, Packages } from "@/types/requests/packages" import type { InitialState, RatesState } from "@/types/stores/rates" export function createRatesStore({ diff --git a/apps/scandic-web/types/components/bookingWidget/guestsRoomsPicker.ts b/apps/scandic-web/types/components/bookingWidget/guestsRoomsPicker.ts index f1c4d2f0f..1d05de862 100644 --- a/apps/scandic-web/types/components/bookingWidget/guestsRoomsPicker.ts +++ b/apps/scandic-web/types/components/bookingWidget/guestsRoomsPicker.ts @@ -1,4 +1,4 @@ -import type { Child } from "../hotelReservation/selectRate/selectRate" +import type { Child } from "@scandic-hotels/trpc/types/child" export type ChildBed = { label: string diff --git a/apps/scandic-web/types/components/current/header/mainMenu.ts b/apps/scandic-web/types/components/current/header/mainMenu.ts index 7dc36c422..19291834c 100644 --- a/apps/scandic-web/types/components/current/header/mainMenu.ts +++ b/apps/scandic-web/types/components/current/header/mainMenu.ts @@ -1,10 +1,10 @@ import type { Image } from "@scandic-hotels/trpc/types/image" +import type { User } from "@scandic-hotels/trpc/types/user" import type { CurrentHeaderLink, TopMenuHeaderLink, } from "@/types/requests/currentHeader" -import type { User } from "@/types/user" export type MainMenuProps = { frontpageLinkText: string diff --git a/apps/scandic-web/types/components/hotelPage/meetingRooms.ts b/apps/scandic-web/types/components/hotelPage/meetingRooms.ts index 5fdf95f56..3402c7400 100644 --- a/apps/scandic-web/types/components/hotelPage/meetingRooms.ts +++ b/apps/scandic-web/types/components/hotelPage/meetingRooms.ts @@ -1,7 +1,6 @@ +import type { meetingRoomsSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/meetingRoom" import type { z } from "zod" -import type { meetingRoomsSchema } from "@/server/routers/hotels/schemas/meetingRoom" - export type MeetingRoomData = z.output export type MeetingRooms = MeetingRoomData["data"] export type MeetingRoom = MeetingRooms[number]["attributes"] diff --git a/apps/scandic-web/types/components/hotelReservation/enterDetails/bedType.ts b/apps/scandic-web/types/components/hotelReservation/enterDetails/bedType.ts index a80c55d46..2524d217d 100644 --- a/apps/scandic-web/types/components/hotelReservation/enterDetails/bedType.ts +++ b/apps/scandic-web/types/components/hotelReservation/enterDetails/bedType.ts @@ -4,24 +4,6 @@ import type { bedTypeFormSchema, bedTypeSchema, } from "@/components/HotelReservation/EnterDetails/BedType/schema" -import type { BedTypeEnum, ExtraBedTypeEnum } from "@/constants/booking" - -export type BedTypeSelection = { - description: string - size: { - min: number - max: number - } - value: string - type: BedTypeEnum - roomsLeft: number - extraBed: - | { - description: string - type: ExtraBedTypeEnum - } - | undefined -} export interface BedTypeFormSchema extends z.output {} diff --git a/apps/scandic-web/types/components/hotelReservation/enterDetails/details.ts b/apps/scandic-web/types/components/hotelReservation/enterDetails/details.ts index 56c7e049e..e9df833cf 100644 --- a/apps/scandic-web/types/components/hotelReservation/enterDetails/details.ts +++ b/apps/scandic-web/types/components/hotelReservation/enterDetails/details.ts @@ -1,17 +1,17 @@ +import type { productTypePointsSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/productTypePrice" +import type { Child } from "@scandic-hotels/trpc/types/child" +import type { PackageEnum } from "@scandic-hotels/trpc/types/packages" +import type { Product } from "@scandic-hotels/trpc/types/roomAvailability" import type { z } from "zod" -import type { PackageEnum } from "@/types/requests/packages" -import type { Product } from "@scandic-hotels/trpc/types/roomAvailability" import type { SafeUser } from "@/types/user" import type { getMultiroomDetailsSchema } from "@/components/HotelReservation/EnterDetails/Details/Multiroom/schema" import type { guestDetailsSchema, signedInDetailsSchema, } from "@/components/HotelReservation/EnterDetails/Details/RoomOne/schema" -import type { productTypePointsSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/productTypePrice" import type { BookingSearchType } from "../booking" import type { Price } from "../price" -import type { Child } from "../selectRate/selectRate" export type DetailsSchema = z.output export type MultiroomDetailsSchema = z.output< diff --git a/apps/scandic-web/types/components/hotelReservation/enterDetails/payment.ts b/apps/scandic-web/types/components/hotelReservation/enterDetails/payment.ts index 9716b20e4..dff23595a 100644 --- a/apps/scandic-web/types/components/hotelReservation/enterDetails/payment.ts +++ b/apps/scandic-web/types/components/hotelReservation/enterDetails/payment.ts @@ -1,6 +1,5 @@ import type { PaymentMethodEnum } from "@scandic-hotels/common/constants/paymentMethod" - -import type { CreditCard } from "@/types/user" +import type { CreditCard } from "@scandic-hotels/trpc/types/user" export interface PaymentProps { otherPaymentOptions: PaymentMethodEnum[] diff --git a/apps/scandic-web/types/components/hotelReservation/selectHotel/hotelCardListingProps.ts b/apps/scandic-web/types/components/hotelReservation/selectHotel/hotelCardListingProps.ts index b1019bc5c..4f9908792 100644 --- a/apps/scandic-web/types/components/hotelReservation/selectHotel/hotelCardListingProps.ts +++ b/apps/scandic-web/types/components/hotelReservation/selectHotel/hotelCardListingProps.ts @@ -1,5 +1,6 @@ +import type { ProductType } from "@scandic-hotels/trpc/types/availability" import type { Hotel } from "@scandic-hotels/trpc/types/hotel" -import type { ProductType } from "@/types/trpc/routers/hotel/availability" + import type { HotelResponse } from "@/components/HotelReservation/SelectHotel/helpers" export enum HotelCardListingTypeEnum { diff --git a/apps/scandic-web/types/components/hotelReservation/selectHotel/map.ts b/apps/scandic-web/types/components/hotelReservation/selectHotel/map.ts index 0fdd1e173..fa36cb0e8 100644 --- a/apps/scandic-web/types/components/hotelReservation/selectHotel/map.ts +++ b/apps/scandic-web/types/components/hotelReservation/selectHotel/map.ts @@ -1,9 +1,9 @@ import type { imageSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/image" +import type { ProductTypeCheque } from "@scandic-hotels/trpc/types/availability" import type { Amenities } from "@scandic-hotels/trpc/types/hotel" import type { z } from "zod" import type { Coordinates } from "@/types/components/maps/coordinates" -import type { ProductTypeCheque } from "@/types/trpc/routers/hotel/availability" import type { HotelResponse } from "@/components/HotelReservation/SelectHotel/helpers" import type { CategorizedHotelFilters } from "./hotelFilters" import type { SelectHotelBooking } from "./selectHotel" diff --git a/apps/scandic-web/types/components/hotelReservation/selectHotel/priceCardProps.ts b/apps/scandic-web/types/components/hotelReservation/selectHotel/priceCardProps.ts index 1f95c1248..5e7cbeeca 100644 --- a/apps/scandic-web/types/components/hotelReservation/selectHotel/priceCardProps.ts +++ b/apps/scandic-web/types/components/hotelReservation/selectHotel/priceCardProps.ts @@ -2,7 +2,7 @@ import type { ProductTypeCheque, ProductTypePrices, ProductTypeVoucher, -} from "@/types/trpc/routers/hotel/availability" +} from "@scandic-hotels/trpc/types/availability" export type PriceCardProps = { productTypePrices: ProductTypePrices diff --git a/apps/scandic-web/types/components/hotelReservation/selectHotel/selectHotel.ts b/apps/scandic-web/types/components/hotelReservation/selectHotel/selectHotel.ts index dc8072ed7..c65673042 100644 --- a/apps/scandic-web/types/components/hotelReservation/selectHotel/selectHotel.ts +++ b/apps/scandic-web/types/components/hotelReservation/selectHotel/selectHotel.ts @@ -1,6 +1,7 @@ +import type { Child } from "@scandic-hotels/trpc/types/child" import type { Hotel } from "@scandic-hotels/trpc/types/hotel" + import type { BookingSearchType } from "../booking" -import type { Child } from "../selectRate/selectRate" import type { SidePeekEnum } from "../sidePeek" export interface ReadMoreProps { diff --git a/apps/scandic-web/types/components/hotelReservation/selectRate/roomListItem.ts b/apps/scandic-web/types/components/hotelReservation/selectRate/roomListItem.ts index 91a3b45ed..d36aed65a 100644 --- a/apps/scandic-web/types/components/hotelReservation/selectRate/roomListItem.ts +++ b/apps/scandic-web/types/components/hotelReservation/selectRate/roomListItem.ts @@ -1,4 +1,4 @@ -import type { Package } from "@/types/requests/packages" +import type { Package } from "@scandic-hotels/trpc/types/packages" import type { RoomConfiguration } from "@scandic-hotels/trpc/types/roomAvailability" export type RoomListItemProps = { diff --git a/apps/scandic-web/types/components/hotelReservation/selectRate/selectRate.ts b/apps/scandic-web/types/components/hotelReservation/selectRate/selectRate.ts index 1b465ef41..54753d87b 100644 --- a/apps/scandic-web/types/components/hotelReservation/selectRate/selectRate.ts +++ b/apps/scandic-web/types/components/hotelReservation/selectRate/selectRate.ts @@ -1,18 +1,13 @@ -import type { ChildBedMapEnum } from "@scandic-hotels/trpc/enums/childBedMapEnum" import type { RateEnum } from "@scandic-hotels/trpc/enums/rate" +import type { Child } from "@scandic-hotels/trpc/types/child" +import type { PackageEnum, Packages } from "@scandic-hotels/trpc/types/packages" import type { Product, RoomConfiguration, } from "@scandic-hotels/trpc/types/roomAvailability" -import type { PackageEnum, Packages } from "@/types/requests/packages" import type { BookingSearchType } from "../booking" -export interface Child { - bed: ChildBedMapEnum - age: number -} - export interface Room { adults: number childrenInRoom?: Child[] diff --git a/apps/scandic-web/types/components/hotelReservation/summary.ts b/apps/scandic-web/types/components/hotelReservation/summary.ts index 6b600d309..b438b3f10 100644 --- a/apps/scandic-web/types/components/hotelReservation/summary.ts +++ b/apps/scandic-web/types/components/hotelReservation/summary.ts @@ -1,5 +1,7 @@ import type { CurrencyEnum } from "@scandic-hotels/common/constants/currency" -import type { Packages } from "@/types/requests/packages" +import type { Child } from "@scandic-hotels/trpc/types/child" +import type { Packages } from "@scandic-hotels/trpc/types/packages" + import type { RoomState } from "@/types/stores/enter-details" import type { DetailsBooking, @@ -7,7 +9,7 @@ import type { RoomRate, } from "./enterDetails/details" import type { Price } from "./price" -import type { Child, SelectRateBooking } from "./selectRate/selectRate" +import type { SelectRateBooking } from "./selectRate/selectRate" export type RoomsData = { rateDetails: string[] | undefined diff --git a/apps/scandic-web/types/components/myPages/friend.ts b/apps/scandic-web/types/components/myPages/friend.ts index acb93c2f5..5cce78b4b 100644 --- a/apps/scandic-web/types/components/myPages/friend.ts +++ b/apps/scandic-web/types/components/myPages/friend.ts @@ -1,4 +1,4 @@ -import type { User } from "@/types/user" +import type { User } from "@scandic-hotels/trpc/types/user" export interface FriendProps extends React.PropsWithChildren> {} diff --git a/apps/scandic-web/types/components/myPages/membershipNumber.ts b/apps/scandic-web/types/components/myPages/membershipNumber.ts index cdd8c81c8..b9e8a4bd2 100644 --- a/apps/scandic-web/types/components/myPages/membershipNumber.ts +++ b/apps/scandic-web/types/components/myPages/membershipNumber.ts @@ -1,6 +1,6 @@ +import type { User } from "@scandic-hotels/trpc/types/user" import type { VariantProps } from "class-variance-authority" -import type { User } from "@/types/user" import type { membershipNumberVariants } from "@/components/Blocks/DynamicContent/Overview/Friend/MembershipNumber/membershipNumberVariants" export interface MembershipNumberProps diff --git a/apps/scandic-web/types/components/myPages/myProfile/creditCards.ts b/apps/scandic-web/types/components/myPages/myProfile/creditCards.ts index 6290f5288..6fd2b8974 100644 --- a/apps/scandic-web/types/components/myPages/myProfile/creditCards.ts +++ b/apps/scandic-web/types/components/myPages/myProfile/creditCards.ts @@ -1,4 +1,4 @@ -import type { CreditCard } from "@/types/user" +import type { CreditCard } from "@scandic-hotels/trpc/types/user" export type CreditCardRowProps = { card: CreditCard diff --git a/apps/scandic-web/types/components/myPages/myProfile/edit.ts b/apps/scandic-web/types/components/myPages/myProfile/edit.ts index cfb61b658..5350984d3 100644 --- a/apps/scandic-web/types/components/myPages/myProfile/edit.ts +++ b/apps/scandic-web/types/components/myPages/myProfile/edit.ts @@ -1,4 +1,4 @@ -import type { User } from "@/types/user" +import type { User } from "@scandic-hotels/trpc/types/user" export type EditFormProps = { user: User diff --git a/apps/scandic-web/types/components/myPages/myStay/ancillaries.ts b/apps/scandic-web/types/components/myPages/myStay/ancillaries.ts index 5504172f1..b8011ca89 100644 --- a/apps/scandic-web/types/components/myPages/myStay/ancillaries.ts +++ b/apps/scandic-web/types/components/myPages/myStay/ancillaries.ts @@ -1,11 +1,11 @@ -import type { z } from "zod" - -import type { Room } from "@/types/stores/my-stay" -import type { CreditCard, User } from "@/types/user" import type { ancillaryPackagesSchema, packagesSchema, } from "@scandic-hotels/trpc/routers/hotels/output" +import type { CreditCard, User } from "@scandic-hotels/trpc/types/user" +import type { z } from "zod" + +import type { Room } from "@/types/stores/my-stay" export type Ancillaries = z.output export type Ancillary = Ancillaries[number] diff --git a/apps/scandic-web/types/components/myPages/user.ts b/apps/scandic-web/types/components/myPages/user.ts index 825c0a42c..25f6406ec 100644 --- a/apps/scandic-web/types/components/myPages/user.ts +++ b/apps/scandic-web/types/components/myPages/user.ts @@ -1,4 +1,5 @@ -import type { User } from "@/types/user" +import type { User } from "@scandic-hotels/trpc/types/user" + import type { userQueryRouter } from "@/server/routers/user/query" export type UserQueryRouter = typeof userQueryRouter diff --git a/apps/scandic-web/types/components/tracking.ts b/apps/scandic-web/types/components/tracking.ts index 0555bd136..d28c82842 100644 --- a/apps/scandic-web/types/components/tracking.ts +++ b/apps/scandic-web/types/components/tracking.ts @@ -1,6 +1,7 @@ import type { Lang } from "@scandic-hotels/common/constants/language" import type { MembershipLevel } from "@scandic-hotels/common/constants/membershipLevels" import type { RateEnum } from "@scandic-hotels/trpc/enums/rate" +import type { LoginType } from "@scandic-hotels/trpc/types/loginType" export enum TrackingChannelEnum { "scandic-friends" = "scandic-friends", @@ -31,14 +32,6 @@ export type TrackingSDKPageData = { sessionId?: string | null } -export enum LoginTypeEnum { - email = "email", - "membership number" = "membership number", - "email link" = "email link", - "dtmc" = "dtmc", -} -export type LoginType = keyof typeof LoginTypeEnum - export type TrackingSDKUserData = | { loginStatus: "logged in" diff --git a/apps/scandic-web/types/contexts/select-rate/room.ts b/apps/scandic-web/types/contexts/select-rate/room.ts index c3a0b4fa9..bd0767c05 100644 --- a/apps/scandic-web/types/contexts/select-rate/room.ts +++ b/apps/scandic-web/types/contexts/select-rate/room.ts @@ -1,4 +1,5 @@ -import type { Package } from "@/types/requests/packages" +import type { Package } from "@scandic-hotels/trpc/types/packages" + import type { RatesState, SelectedRoom } from "@/types/stores/rates" export interface RoomContextValue extends Omit { diff --git a/apps/scandic-web/types/providers/details/room.ts b/apps/scandic-web/types/providers/details/room.ts index 0f0df5334..b18c6466e 100644 --- a/apps/scandic-web/types/providers/details/room.ts +++ b/apps/scandic-web/types/providers/details/room.ts @@ -1,29 +1,4 @@ -import type { RateEnum } from "@scandic-hotels/trpc/enums/rate" - -import type { BedTypeSelection } from "@/types/components/hotelReservation/enterDetails/bedType" -import type { RoomRate } from "@/types/components/hotelReservation/enterDetails/details" -import type { Package } from "@/types/requests/packages" - -export interface Room { - bedTypes: BedTypeSelection[] - breakfastIncluded: boolean - cancellationRule: string - cancellationText: string - mustBeGuaranteed: boolean - memberMustBeGuaranteed: boolean | undefined - packages: Package[] - rate: RateEnum - rateDefinitionTitle: string - rateDetails: string[] - memberRateDetails: string[] | undefined - rateTitle: string | undefined - rateType: string - roomRate: RoomRate - roomType: string - roomTypeCode: string - isAvailable: boolean - isFlexRate: boolean -} +import type { Room } from "@scandic-hotels/trpc/types/room" export interface RoomProviderProps extends React.PropsWithChildren { idx: number diff --git a/apps/scandic-web/types/providers/enter-details.ts b/apps/scandic-web/types/providers/enter-details.ts index 73e74987e..3b6b957e2 100644 --- a/apps/scandic-web/types/providers/enter-details.ts +++ b/apps/scandic-web/types/providers/enter-details.ts @@ -1,4 +1,5 @@ -import type { Room } from "@/types/providers/details/room" +import type { Room } from "@scandic-hotels/trpc/types/room" + import type { SafeUser } from "@/types/user" import type { Lang } from "@/constants/routes/hotelReservation" import type { BreakfastPackages } from "../components/hotelReservation/breakfast" diff --git a/apps/scandic-web/types/stores/enter-details.ts b/apps/scandic-web/types/stores/enter-details.ts index d51899675..aced9125c 100644 --- a/apps/scandic-web/types/stores/enter-details.ts +++ b/apps/scandic-web/types/stores/enter-details.ts @@ -1,11 +1,13 @@ +import type { CurrencyEnum } from "@scandic-hotels/common/constants/currency" +import type { BedTypeSelection } from "@scandic-hotels/trpc/types/bedTypeSelection" +import type { Child } from "@scandic-hotels/trpc/types/child" +import type { Packages } from "@scandic-hotels/trpc/types/packages" + import type { BreakfastPackage, BreakfastPackages, } from "@/types/components/hotelReservation/breakfast" -import type { - BedTypeSchema, - BedTypeSelection, -} from "@/types/components/hotelReservation/enterDetails/bedType" +import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType" import type { DetailsBooking, DetailsSchema, @@ -14,11 +16,8 @@ import type { RoomRate, SignedInDetailsSchema, } from "@/types/components/hotelReservation/enterDetails/details" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" import type { StepEnum } from "@/types/enums/step" import type { Price } from "../components/hotelReservation/price" -import type { CurrencyEnum } from "../../../../packages/common/constants/currency" -import type { Packages } from "../requests/packages" export interface InitialRoomData { // used when there is only one bedtype to preselect it diff --git a/apps/scandic-web/types/stores/my-stay.ts b/apps/scandic-web/types/stores/my-stay.ts index 16dba3ce0..97b340371 100644 --- a/apps/scandic-web/types/stores/my-stay.ts +++ b/apps/scandic-web/types/stores/my-stay.ts @@ -1,18 +1,18 @@ +import type { Child } from "@scandic-hotels/trpc/types/child" import type { Hotel, Room as HotelRoom, RoomCategories, } from "@scandic-hotels/trpc/types/hotel" +import type { CreditCard } from "@scandic-hotels/trpc/types/user" import type { IntlShape } from "react-intl" import type { BreakfastPackage } from "@/types/components/hotelReservation/breakfast" import type { BedTypeSchema } from "@/types/components/hotelReservation/enterDetails/bedType" import type { RoomPrice } from "@/types/components/hotelReservation/enterDetails/details" import type { PriceTypeEnum } from "@/types/components/hotelReservation/myStay/myStay" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" import type { Packages } from "@/types/components/myPages/myStay/ancillaries" import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation" -import type { CreditCard } from "@/types/user" export type Room = Omit< BookingConfirmation["booking"], diff --git a/apps/scandic-web/types/stores/rates.ts b/apps/scandic-web/types/stores/rates.ts index 78ccbf10b..526a42924 100644 --- a/apps/scandic-web/types/stores/rates.ts +++ b/apps/scandic-web/types/stores/rates.ts @@ -1,6 +1,7 @@ import type { CurrencyEnum } from "@scandic-hotels/common/constants/currency" import type { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" import type { Room } from "@scandic-hotels/trpc/types/hotel" +import type { Package, PackageEnum } from "@scandic-hotels/trpc/types/packages" import type { Product, RoomConfiguration, @@ -12,7 +13,6 @@ import type { Room as RoomBooking, SelectRateBooking, } from "@/types/components/hotelReservation/selectRate/selectRate" -import type { Package, PackageEnum } from "@/types/requests/packages" import type { BookingCodeFilterEnum } from "../enums/bookingCodeFilter" export interface AvailabilityError { diff --git a/apps/scandic-web/types/user.ts b/apps/scandic-web/types/user.ts index be06d7118..e23f8f89e 100644 --- a/apps/scandic-web/types/user.ts +++ b/apps/scandic-web/types/user.ts @@ -1,32 +1,3 @@ -import type { z } from "zod" - import type { RouterOutput } from "@/lib/trpc/client" -import type { - creditCardSchema, - friendsMembershipSchema, - getUserSchema, - sasMembershipSchema, - userLoyaltySchema, -} from "@/server/routers/user/output" -import type { getFriendsMembership } from "@/utils/user" - -/** - * All extended field needs to be added by API team to response or - * we have to get the values from elsewhere - */ -export interface User extends z.output {} export type SafeUser = RouterOutput["user"]["getSafely"] - -export type CreditCard = z.output - -export type UserLoyalty = z.output - -export type Membership = UserLoyalty["memberships"][number] -export type NativeFriendsMembership = z.output -export type EurobonusMembership = z.output - -export type FriendsMembership = ReturnType - -export type EurobonusTier = EurobonusMembership["tier"] -export type FriendsTier = NativeFriendsMembership["tier"] diff --git a/apps/scandic-web/utils/countries.ts b/apps/scandic-web/utils/countries.ts index 6d6e408f3..321281cb5 100644 --- a/apps/scandic-web/utils/countries.ts +++ b/apps/scandic-web/utils/countries.ts @@ -1,4 +1,4 @@ -import { countriesMap } from "@/constants/countries" +import { countriesMap } from "@scandic-hotels/trpc/constants/countries" export function isValidCountry( country: string diff --git a/apps/scandic-web/utils/hotelSearchDetails.ts b/apps/scandic-web/utils/hotelSearchDetails.ts index fb3c9f238..66b07df88 100644 --- a/apps/scandic-web/utils/hotelSearchDetails.ts +++ b/apps/scandic-web/utils/hotelSearchDetails.ts @@ -1,19 +1,19 @@ import { notFound } from "next/navigation" import { safeTry } from "@scandic-hotels/common/utils/safeTry" +import { REDEMPTION } from "@scandic-hotels/trpc/constants/booking" +import { generateChildrenString } from "@scandic-hotels/trpc/routers/hotels/helpers" import { type HotelLocation, isHotelLocation, type Location, } from "@scandic-hotels/trpc/types/locations" -import { REDEMPTION } from "@/constants/booking" import { getLocations } from "@/lib/trpc/memoizedRequests" -import { generateChildrenString } from "@/components/HotelReservation/utils" +import type { Child } from "@scandic-hotels/trpc/types/child" import type { BookingSearchType } from "@/types/components/hotelReservation/booking" -import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate" export type ChildrenInRoom = (Child[] | null)[] | null export type ChildrenInRoomString = (string | null)[] | null diff --git a/apps/scandic-web/utils/specialRoomType.ts b/apps/scandic-web/utils/specialRoomType.ts index 62e175401..041397bc1 100644 --- a/apps/scandic-web/utils/specialRoomType.ts +++ b/apps/scandic-web/utils/specialRoomType.ts @@ -1,5 +1,7 @@ import { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" -import type { Packages } from "@/types/requests/packages" + +import type { Packages } from "@scandic-hotels/trpc/types/packages" + import type { BookingConfirmation } from "@/types/trpc/routers/booking/confirmation" export function getSpecialRoomType( diff --git a/apps/scandic-web/utils/tracking/myStay.ts b/apps/scandic-web/utils/tracking/myStay.ts index b514fd07d..c731cff2a 100644 --- a/apps/scandic-web/utils/tracking/myStay.ts +++ b/apps/scandic-web/utils/tracking/myStay.ts @@ -3,10 +3,11 @@ import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast" import { trackEvent } from "./base" +import type { CreditCard } from "@scandic-hotels/trpc/types/user" + import type { SelectedAncillary } from "@/types/components/myPages/myStay/ancillaries" import type { Room } from "@/types/stores/my-stay" import type { PackageSchema } from "@/types/trpc/routers/booking/confirmation" -import type { CreditCard } from "@/types/user" import type { BreakfastData } from "@/stores/my-stay/add-ancillary-flow" export function trackCancelStay(hotelId: string, bnr: string) { diff --git a/apps/scandic-web/utils/user.ts b/apps/scandic-web/utils/user.ts index 1ffd87549..3e0f8bbd6 100644 --- a/apps/scandic-web/utils/user.ts +++ b/apps/scandic-web/utils/user.ts @@ -2,56 +2,14 @@ import { type MembershipLevel, MembershipLevelEnum, } from "@scandic-hotels/common/constants/membershipLevels" +import { scandicMembershipTypes } from "@scandic-hotels/trpc/routers/user/helpers" import type { EurobonusMembership, Membership, - NativeFriendsMembership, User, UserLoyalty, -} from "@/types/user" - -export enum scandicMembershipTypes { - SCANDIC_NATIVE = "SCANDIC_NATIVE", - SAS_EB = "SAS_EB", -} - -export function isScandicNativeMembership( - membership: Membership -): membership is NativeFriendsMembership { - return membership.type === scandicMembershipTypes.SCANDIC_NATIVE -} - -export function getFriendsMembership(userLoyalty: UserLoyalty) { - const { memberships, ...loyalty } = userLoyalty - - const friendsMembership = memberships.find(isScandicNativeMembership) - - if (!friendsMembership) return null - - const pointExpiration = loyalty.pointExpirations - .sort( - (a, b) => new Date(a.expires).getTime() - new Date(b.expires).getTime() - ) - .at(0) - - // Map to the same format that was used with Profile V1 to avoid larger changes for now. - const result = { - membershipType: friendsMembership.type, - membershipNumber: friendsMembership.membershipNumber, - membershipLevel: loyalty.tier, - nextLevel: friendsMembership.nextTier, - currentPoints: loyalty.points.spendable, - expirationDate: loyalty.tierExpires, - nightsToTopTier: friendsMembership.nightsToTopTier, - pointsRequiredToNextlevel: friendsMembership.pointsToNextTier, - tierExpirationDate: loyalty.tierExpires, - pointsExpiryDate: pointExpiration?.expires, - pointsToExpire: pointExpiration?.points, - memberSince: friendsMembership.memberSince, - } - return result -} +} from "@scandic-hotels/trpc/types/user" function isEurobonusMembership( membership: Membership diff --git a/packages/common/constants/routes/hotelReservation.ts b/packages/common/constants/routes/hotelReservation.ts new file mode 100644 index 000000000..6214340ef --- /dev/null +++ b/packages/common/constants/routes/hotelReservation.ts @@ -0,0 +1,5 @@ +import type { Lang } from "../language" + +export function selectRate(lang: Lang) { + return `/${lang}/hotelreservation/select-rate` +} diff --git a/apps/scandic-web/types/auth.d.ts b/packages/trpc/auth.d.ts similarity index 86% rename from apps/scandic-web/types/auth.d.ts rename to packages/trpc/auth.d.ts index 3c7f8fb02..66e129e96 100644 --- a/apps/scandic-web/types/auth.d.ts +++ b/packages/trpc/auth.d.ts @@ -1,6 +1,7 @@ +// TODO might just want to duplicate this file in each package that needs it import type { JWT } from "next-auth/jwt" -import type { RefreshTokenError } from "./authError" +import type { RefreshTokenError } from "./lib/types/authError" // Module augmentation // https://authjs.dev/getting-started/typescript#popular-interfaces-to-augment diff --git a/packages/trpc/env/server.ts b/packages/trpc/env/server.ts index fac7b4d76..6dca8fc40 100644 --- a/packages/trpc/env/server.ts +++ b/packages/trpc/env/server.ts @@ -22,6 +22,10 @@ export const env = createEnv({ .transform((val) => process.env.CMS_ENVIRONMENT === "test" ? 5 * 60 : val ), + CACHE_TIME_CITY_SEARCH: z.coerce + .number() + .default(10 * 60) + .transform((val) => (process.env.CMS_ENVIRONMENT === "test" ? 60 : val)), NODE_ENV: z.enum(["development", "test", "production"]), CMS_ACCESS_TOKEN: z.string(), CMS_BRANCH: z.enum(["development", "production"]), @@ -40,6 +44,7 @@ export const env = createEnv({ runtimeEnv: { API_BASEURL: process.env.API_BASEURL, CACHE_TIME_HOTELS: process.env.CACHE_TIME_HOTELS, + CACHE_TIME_CITY_SEARCH: process.env.CACHE_TIME_CITY_SEARCH, NODE_ENV: process.env.NODE_ENV, CMS_ACCESS_TOKEN: process.env.CMS_ACCESS_TOKEN, CMS_BRANCH: process.env.CMS_BRANCH, diff --git a/apps/scandic-web/types/jwt.d.ts b/packages/trpc/jwt.d.ts similarity index 71% rename from apps/scandic-web/types/jwt.d.ts rename to packages/trpc/jwt.d.ts index d3019dc12..ddb9bfc3a 100644 --- a/apps/scandic-web/types/jwt.d.ts +++ b/packages/trpc/jwt.d.ts @@ -1,7 +1,8 @@ +// TODO might just want to duplicate this file in each package that needs it import type { DefaultJWT } from "next-auth/jwt" -import type { RefreshTokenError } from "./authError" -import type { LoginType } from "./components/tracking" +import type { RefreshTokenError } from "./lib/types/authError" +import type { LoginType } from "./lib/types/loginType" // Module augmentation // https://authjs.dev/getting-started/typescript#popular-interfaces-to-augment diff --git a/packages/trpc/lib/constants/bedTypeMap.ts b/packages/trpc/lib/constants/bedTypeMap.ts new file mode 100644 index 000000000..39e141638 --- /dev/null +++ b/packages/trpc/lib/constants/bedTypeMap.ts @@ -0,0 +1,9 @@ +import { ChildBedMapEnum } from "../enums/childBedMapEnum" +import { ChildBedTypeEnum } from "../enums/childBedTypeEnum" + +export const bedTypeMap: Record = { + [ChildBedMapEnum.IN_ADULTS_BED]: ChildBedTypeEnum.ParentsBed, + [ChildBedMapEnum.IN_CRIB]: ChildBedTypeEnum.Crib, + [ChildBedMapEnum.IN_EXTRA_BED]: ChildBedTypeEnum.ExtraBed, + [ChildBedMapEnum.UNKNOWN]: ChildBedTypeEnum.Unknown, +} diff --git a/packages/trpc/lib/constants/booking.ts b/packages/trpc/lib/constants/booking.ts new file mode 100644 index 000000000..01ca41429 --- /dev/null +++ b/packages/trpc/lib/constants/booking.ts @@ -0,0 +1,2 @@ +// TODO better name? +export const REDEMPTION = "redemption" diff --git a/apps/scandic-web/constants/countries.ts b/packages/trpc/lib/constants/countries.ts similarity index 100% rename from apps/scandic-web/constants/countries.ts rename to packages/trpc/lib/constants/countries.ts diff --git a/packages/trpc/lib/enums/bedType.ts b/packages/trpc/lib/enums/bedType.ts new file mode 100644 index 000000000..36766127a --- /dev/null +++ b/packages/trpc/lib/enums/bedType.ts @@ -0,0 +1,14 @@ +export enum BedTypeEnum { + King = "King", + Queen = "Queen", + Single = "Single", + Twin = "Twin", + Other = "Other", +} + +export enum ExtraBedTypeEnum { + SofaBed = "SofaBed", + WallBed = "WallBed", + PullOutBed = "PullOutBed", + BunkBed = "BunkBed", +} diff --git a/packages/trpc/lib/enums/bookingErrorCode.ts b/packages/trpc/lib/enums/bookingErrorCode.ts new file mode 100644 index 000000000..6dc1beee1 --- /dev/null +++ b/packages/trpc/lib/enums/bookingErrorCode.ts @@ -0,0 +1,12 @@ +export enum BookingErrorCodeEnum { + InternalError = "InternalError", + ReservationError = "ReservationError", + AvailabilityError = "AvailabilityError", + BookingStatusNotFound = "BookingStatusNotFound", + TransactionAbandoned = "TransactionAbandoned", + TransactionCancelled = "TransactionCancelled", + TransactionFailed = "TransactionFailed", + BookingStateError = "BookingStateError", + MembershipFailedError = "MembershipFailedError", + NoAvailabilityForRateAndRoomType = "NoAvailabilityForRateAndRoomType", +} diff --git a/packages/trpc/lib/routers/contentstack/metadata/query.ts b/packages/trpc/lib/routers/contentstack/metadata/query.ts index 46dbd9704..3d353a31b 100644 --- a/packages/trpc/lib/routers/contentstack/metadata/query.ts +++ b/packages/trpc/lib/routers/contentstack/metadata/query.ts @@ -91,7 +91,6 @@ export const metadataQueryRouter = router({ } let data: unknown = null - switch (ctx.contentType) { case PageContentTypeEnum.accountPage: const accountPageResponse = await fetchMetadata<{ diff --git a/packages/trpc/lib/routers/hotels/helpers.ts b/packages/trpc/lib/routers/hotels/helpers.ts new file mode 100644 index 000000000..e6476d70e --- /dev/null +++ b/packages/trpc/lib/routers/hotels/helpers.ts @@ -0,0 +1,13 @@ +import { bedTypeMap } from "../../constants/bedTypeMap" + +import type { Child } from "../../types/child" + +export function generateChildrenString(children: Child[]): string { + return `[${children + .map((child) => { + const age = child.age + const bedType = bedTypeMap[parseInt(child.bed.toString())] + return `${age}:${bedType}` + }) + .join(",")}]` +} diff --git a/apps/scandic-web/server/routers/hotels/index.ts b/packages/trpc/lib/routers/hotels/index.ts similarity index 66% rename from apps/scandic-web/server/routers/hotels/index.ts rename to packages/trpc/lib/routers/hotels/index.ts index eb748fabd..26480d08c 100644 --- a/apps/scandic-web/server/routers/hotels/index.ts +++ b/packages/trpc/lib/routers/hotels/index.ts @@ -1,5 +1,4 @@ -import { mergeRouters } from "@scandic-hotels/trpc" - +import { mergeRouters } from "../.." import { hotelQueryRouter } from "./query" export const hotelsRouter = mergeRouters(hotelQueryRouter) diff --git a/apps/scandic-web/server/routers/hotels/query.ts b/packages/trpc/lib/routers/hotels/query.ts similarity index 97% rename from apps/scandic-web/server/routers/hotels/query.ts rename to packages/trpc/lib/routers/hotels/query.ts index f40af9a56..f91494458 100644 --- a/apps/scandic-web/server/routers/hotels/query.ts +++ b/packages/trpc/lib/routers/hotels/query.ts @@ -2,21 +2,6 @@ import { Lang } from "@scandic-hotels/common/constants/language" import { getCacheClient } from "@scandic-hotels/common/dataCache" import { dt } from "@scandic-hotels/common/dt" import { createCounter } from "@scandic-hotels/common/telemetry" -import { router } from "@scandic-hotels/trpc" -import * as api from "@scandic-hotels/trpc/api" -import { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast" -import { RateEnum } from "@scandic-hotels/trpc/enums/rate" -import { RateTypeEnum } from "@scandic-hotels/trpc/enums/rateType" -import { AvailabilityEnum } from "@scandic-hotels/trpc/enums/selectHotel" -import { badRequestError, unauthorizedError } from "@scandic-hotels/trpc/errors" -import { - contentStackBaseWithServiceProcedure, - publicProcedure, - safeProtectedServiceProcedure, - serviceProcedure, -} from "@scandic-hotels/trpc/procedures" -import { getCityPageUrls } from "@scandic-hotels/trpc/routers/contentstack/destinationCityPage/utils" -import { getHotelPageUrls } from "@scandic-hotels/trpc/routers/contentstack/hotelPage/utils" import { ancillaryPackageInputSchema, breakfastPackageInputSchema, @@ -45,27 +30,39 @@ import { getNearbyHotelIdsSchema, } from "@scandic-hotels/trpc/routers/hotels/output" import { additionalDataSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/hotel/include/additionalData" + +import { env } from "../../../env/server" +import { router } from "../.." +import * as api from "../../api" +import { REDEMPTION } from "../../constants/booking" +import { BreakfastPackageEnum } from "../../enums/breakfast" +import { RateEnum } from "../../enums/rate" +import { RateTypeEnum } from "../../enums/rateType" +import { AvailabilityEnum } from "../../enums/selectHotel" +import { badRequestError, unauthorizedError } from "../../errors" import { + contentStackBaseWithServiceProcedure, + publicProcedure, + safeProtectedServiceProcedure, + serviceProcedure, +} from "../../procedures" +import { getCityPageUrls } from "../../routers/contentstack/destinationCityPage/utils" +import { getHotelPageUrls } from "../../routers/contentstack/hotelPage/utils" +import { toApiLang } from "../../utils" +import { getVerifiedUser } from "../user/utils" +import { meetingRoomsSchema } from "./schemas/meetingRoom" +import { + getBedTypes, getCitiesByCountry, getCountries, getHotel, getHotelIdsByCityId, getHotelIdsByCityIdentifier, getHotelIdsByCountry, - getHotelsByHotelIds, - getLocations, -} from "@scandic-hotels/trpc/routers/hotels/utils" -import { toApiLang } from "@scandic-hotels/trpc/utils" - -import { REDEMPTION } from "@/constants/booking" -import { env } from "@/env/server" -import { getVerifiedUser } from "@/server/routers/user/utils" - -import { meetingRoomsSchema } from "./schemas/meetingRoom" -import { - getBedTypes, getHotelsAvailabilityByCity, getHotelsAvailabilityByHotelIds, + getHotelsByHotelIds, + getLocations, getPackages, getRoomsAvailability, getSelectedRoomAvailability, @@ -76,10 +73,9 @@ import { import type { DestinationPagesHotelData, HotelDataWithUrl, -} from "@scandic-hotels/trpc/types/hotel" -import type { CityLocation } from "@scandic-hotels/trpc/types/locations" - -import type { Room } from "@/types/providers/details/room" +} from "../../types/hotel" +import type { CityLocation } from "../../types/locations" +import type { Room } from "../../types/room" export const hotelQueryRouter = router({ availability: router({ diff --git a/apps/scandic-web/server/routers/hotels/schemas/meetingRoom.ts b/packages/trpc/lib/routers/hotels/schemas/meetingRoom.ts similarity index 100% rename from apps/scandic-web/server/routers/hotels/schemas/meetingRoom.ts rename to packages/trpc/lib/routers/hotels/schemas/meetingRoom.ts diff --git a/packages/trpc/lib/routers/hotels/utils.ts b/packages/trpc/lib/routers/hotels/utils.ts index c03919e51..1621a0854 100644 --- a/packages/trpc/lib/routers/hotels/utils.ts +++ b/packages/trpc/lib/routers/hotels/utils.ts @@ -1,17 +1,31 @@ import deepmerge from "deepmerge" +import stringify from "json-stable-stringify-without-jsonify" import { Lang } from "@scandic-hotels/common/constants/language" +import { selectRate } from "@scandic-hotels/common/constants/routes/hotelReservation" import { getCacheClient } from "@scandic-hotels/common/dataCache" import { createCounter } from "@scandic-hotels/common/telemetry" import { chunk } from "@scandic-hotels/common/utils/chunk" +import { + hotelsAvailabilitySchema, + packagesSchema, + roomFeaturesSchema, + roomsAvailabilitySchema, +} from "@scandic-hotels/trpc/routers/hotels/output" +import { sortRoomConfigs } from "@scandic-hotels/trpc/utils/sortRoomConfigs" import { env } from "../../../env/server" import * as api from "../../api" +import { REDEMPTION } from "../../constants/booking" import { cache } from "../../DUPLICATED/cache" +import { BookingErrorCodeEnum } from "../../enums/bookingErrorCode" import { HotelTypeEnum } from "../../enums/hotelType" +import { RoomPackageCodeEnum } from "../../enums/roomFilter" +import { AvailabilityEnum } from "../../enums/selectHotel" import { badRequestError } from "../../errors" import { toApiLang } from "../../utils" import { getHotelPageUrls } from "../contentstack/hotelPage/utils" +import { generateChildrenString } from "./helpers" import { citiesByCountrySchema, citiesSchema, @@ -21,14 +35,32 @@ import { locationsSchema, } from "./output" +import type { Room as RoomCategory } from "@scandic-hotels/trpc/types/hotel" +import type { + Product, + Products, + RateDefinition, + RedemptionsProduct, + RoomConfiguration, +} from "@scandic-hotels/trpc/types/roomAvailability" import type { z } from "zod" import type { Endpoint } from "../../api/endpoints" +import type { + HotelsAvailabilityInputSchema, + HotelsByHotelIdsAvailabilityInputSchema, + RoomsAvailabilityExtendedInputSchema, + RoomsAvailabilityInputRoom, + RoomsAvailabilityOutputSchema, +} from "../../types/availability" +import type { BedTypeSelection } from "../../types/bedTypeSelection" import type { DestinationPagesHotelData, HotelInput } from "../../types/hotel" import type { CitiesGroupedByCountry, CityLocation, } from "../../types/locations" +import type { PackagesOutput } from "../../types/packages" +import type { RoomFeaturesInput } from "./input" import type { Cities } from "./output" export const locationsAffix = "locations" @@ -594,3 +626,712 @@ export async function getCity({ "1d" ) } + +export const TWENTYFOUR_HOURS = 60 * 60 * 24 + +function findProduct(product: Products, rateDefinition: RateDefinition) { + if ("corporateCheque" in product) { + return product.corporateCheque.rateCode === rateDefinition.rateCode + } + + if (("member" in product && product.member) || "public" in product) { + let isMemberRate = false + if (product.member) { + isMemberRate = product.member.rateCode === rateDefinition.rateCode + } + let isPublicRate = false + if (product.public) { + isPublicRate = product.public.rateCode === rateDefinition.rateCode + } + return isMemberRate || isPublicRate + } + + if ("voucher" in product) { + return product.voucher.rateCode === rateDefinition.rateCode + } + + if (Array.isArray(product)) { + return product.find( + (r) => r.redemption.rateCode === rateDefinition.rateCode + ) + } +} + +export async function getHotelsAvailabilityByCity( + input: HotelsAvailabilityInputSchema, + apiLang: string, + token: string, // Either service token or user access token in case of redemption search + userPoints: number = 0 +) { + const { + cityId, + roomStayStartDate, + roomStayEndDate, + adults, + children, + bookingCode, + redemption, + } = input + + const params: Record = { + roomStayStartDate, + roomStayEndDate, + adults, + ...(children && { children }), + ...(bookingCode && { bookingCode }), + ...(redemption ? { isRedemption: "true" } : {}), + language: apiLang, + } + + const getHotelsAvailabilityByCityCounter = createCounter( + "hotel", + "getHotelsAvailabilityByCity" + ) + const metricsGetHotelsAvailabilityByCity = + getHotelsAvailabilityByCityCounter.init({ + apiLang, + cityId, + roomStayStartDate, + roomStayEndDate, + adults, + children, + bookingCode, + redemption, + }) + + metricsGetHotelsAvailabilityByCity.start() + + const apiResponse = await api.get( + api.endpoints.v1.Availability.city(cityId), + { + headers: { + Authorization: `Bearer ${token}`, + }, + }, + params + ) + if (!apiResponse.ok) { + await metricsGetHotelsAvailabilityByCity.httpError(apiResponse) + throw new Error("Failed to fetch hotels availability by city") + } + + const apiJson = await apiResponse.json() + const validateAvailabilityData = hotelsAvailabilitySchema.safeParse(apiJson) + if (!validateAvailabilityData.success) { + metricsGetHotelsAvailabilityByCity.validationError( + validateAvailabilityData.error + ) + throw badRequestError() + } + + if (redemption) { + validateAvailabilityData.data.data.forEach((data) => { + data.attributes.productType?.redemptions?.forEach((r) => { + r.hasEnoughPoints = userPoints >= r.localPrice.pointsPerStay + }) + }) + } + + const result = { + availability: validateAvailabilityData.data.data.flatMap( + (hotels) => hotels.attributes + ), + } + + metricsGetHotelsAvailabilityByCity.success() + + return result +} + +export async function getHotelsAvailabilityByHotelIds( + input: HotelsByHotelIdsAvailabilityInputSchema, + apiLang: string, + serviceToken: string +) { + const { + hotelIds, + roomStayStartDate, + roomStayEndDate, + adults, + children, + bookingCode, + } = input + + const params = new URLSearchParams([ + ["roomStayStartDate", roomStayStartDate], + ["roomStayEndDate", roomStayEndDate], + ["adults", adults.toString()], + ["children", children ?? ""], + ["bookingCode", bookingCode], + ["language", apiLang], + ]) + + const getHotelsAvailabilityByHotelIdsCounter = createCounter( + "hotel", + "getHotelsAvailabilityByHotelIds" + ) + const metricsGetHotelsAvailabilityByHotelIds = + getHotelsAvailabilityByHotelIdsCounter.init({ + apiLang, + hotelIds, + roomStayStartDate, + roomStayEndDate, + adults, + children, + bookingCode, + }) + + metricsGetHotelsAvailabilityByHotelIds.start() + + const cacheClient = await getCacheClient() + + const result = cacheClient.cacheOrGet( + `${apiLang}:hotels:availability:${hotelIds.join(",")}:${roomStayStartDate}:${roomStayEndDate}:${adults}:${children}:${bookingCode}`, + async () => { + /** + * Since API expects the params appended and not just + * a comma separated string we need to initialize the + * SearchParams with a sequence of pairs + * (hotelIds=810&hotelIds=879&hotelIds=222 etc.) + **/ + + hotelIds.forEach((hotelId) => + params.append("hotelIds", hotelId.toString()) + ) + + const apiResponse = await api.get( + api.endpoints.v1.Availability.hotels(), + { + headers: { + Authorization: `Bearer ${serviceToken}`, + }, + }, + params + ) + if (!apiResponse.ok) { + await metricsGetHotelsAvailabilityByHotelIds.httpError(apiResponse) + throw new Error("Failed to fetch hotels availability by hotelIds") + } + + const apiJson = await apiResponse.json() + const validateAvailabilityData = + hotelsAvailabilitySchema.safeParse(apiJson) + if (!validateAvailabilityData.success) { + metricsGetHotelsAvailabilityByHotelIds.validationError( + validateAvailabilityData.error + ) + throw badRequestError() + } + + return { + availability: validateAvailabilityData.data.data.flatMap( + (hotels) => hotels.attributes + ), + } + }, + env.CACHE_TIME_CITY_SEARCH + ) + + metricsGetHotelsAvailabilityByHotelIds.success() + + return result +} + +async function getRoomFeaturesInventory( + input: RoomFeaturesInput, + token: string +) { + const { + adults, + childrenInRoom, + endDate, + hotelId, + roomFeatureCodes, + startDate, + } = input + + const params = { + adults, + hotelId, + roomFeatureCode: roomFeatureCodes, + roomStayEndDate: endDate, + roomStayStartDate: startDate, + ...(childrenInRoom?.length && { + children: generateChildrenString(childrenInRoom), + }), + } + + const getRoomFeaturesInventoryCounter = createCounter( + "hotel", + "getRoomFeaturesInventory" + ) + const metricsGetRoomFeaturesInventory = + getRoomFeaturesInventoryCounter.init(params) + + metricsGetRoomFeaturesInventory.start() + + const cacheClient = await getCacheClient() + + const result = cacheClient.cacheOrGet( + stringify(input), + async function () { + const apiResponse = await api.get( + api.endpoints.v1.Availability.roomFeatures(hotelId), + { + headers: { + Authorization: `Bearer ${token}`, + }, + }, + params + ) + + if (!apiResponse.ok) { + await metricsGetRoomFeaturesInventory.httpError(apiResponse) + return null + } + + const data = await apiResponse.json() + const validatedRoomFeaturesData = roomFeaturesSchema.safeParse(data) + if (!validatedRoomFeaturesData.success) { + metricsGetRoomFeaturesInventory.validationError( + validatedRoomFeaturesData.error + ) + return null + } + + return validatedRoomFeaturesData.data + }, + "5m" + ) + + metricsGetRoomFeaturesInventory.success() + + return result +} + +export async function getPackages(input: PackagesOutput, serviceToken: string) { + const { adults, children, endDate, hotelId, lang, packageCodes, startDate } = + input + + const getPackagesCounter = createCounter("hotel", "getPackages") + const metricsGetPackages = getPackagesCounter.init({ + input, + }) + + metricsGetPackages.start() + + const cacheClient = await getCacheClient() + + const result = cacheClient.cacheOrGet( + stringify(input), + async function () { + const apiLang = toApiLang(lang) + + const searchParams = new URLSearchParams({ + adults: adults.toString(), + children: children.toString(), + endDate, + language: apiLang, + startDate, + }) + + packageCodes.forEach((code) => { + searchParams.append("packageCodes", code) + }) + + const apiResponse = await api.get( + api.endpoints.v1.Package.Packages.hotel(hotelId), + { + headers: { + Authorization: `Bearer ${serviceToken}`, + }, + }, + searchParams + ) + + if (!apiResponse.ok) { + await metricsGetPackages.httpError(apiResponse) + return null + } + + const apiJson = await apiResponse.json() + const validatedPackagesData = packagesSchema.safeParse(apiJson) + if (!validatedPackagesData.success) { + metricsGetPackages.validationError(validatedPackagesData.error) + return null + } + + return validatedPackagesData.data + }, + "3h" + ) + + metricsGetPackages.success() + + return result +} + +export async function getRoomsAvailability( + input: RoomsAvailabilityOutputSchema, + token: string, + serviceToken: string, + userPoints: number | undefined +) { + const { + booking: { bookingCode, fromDate, hotelId, rooms, searchType, toDate }, + lang, + } = input + + const redemption = searchType === REDEMPTION + + const getRoomsAvailabilityCounter = createCounter( + "hotel", + "getRoomsAvailability" + ) + const metricsGetRoomsAvailability = getRoomsAvailabilityCounter.init({ + input, + redemption, + }) + + metricsGetRoomsAvailability.start() + + const apiLang = toApiLang(lang) + + const baseCacheKey = { + bookingCode, + fromDate, + hotelId, + lang, + searchType, + toDate, + } + + const cacheClient = await getCacheClient() + const availabilityResponses = await Promise.allSettled( + rooms.map((room: RoomsAvailabilityInputRoom) => { + const cacheKey = { + ...baseCacheKey, + room, + } + const result = cacheClient.cacheOrGet( + stringify(cacheKey), + async function () { + { + const params = { + adults: room.adults, + language: apiLang, + roomStayStartDate: fromDate, + roomStayEndDate: toDate, + ...(room.childrenInRoom?.length && { + children: generateChildrenString(room.childrenInRoom), + }), + ...(room.bookingCode && { bookingCode: room.bookingCode }), + ...(redemption && { isRedemption: "true" }), + } + + const apiResponse = await api.get( + api.endpoints.v1.Availability.hotel(hotelId), + { + cache: undefined, // overwrite default + headers: { + Authorization: `Bearer ${token}`, + }, + }, + params + ) + + if (!apiResponse.ok) { + await metricsGetRoomsAvailability.httpError(apiResponse) + const text = await apiResponse.text() + return { error: "http_error", details: text } + } + + const apiJson = await apiResponse.json() + const validateAvailabilityData = + roomsAvailabilitySchema.safeParse(apiJson) + if (!validateAvailabilityData.success) { + metricsGetRoomsAvailability.validationError( + validateAvailabilityData.error + ) + + return { + error: "validation_error", + details: validateAvailabilityData.error, + } + } + + if (redemption) { + for (const roomConfig of validateAvailabilityData.data + .roomConfigurations) { + for (const product of roomConfig.redemptions) { + if (userPoints) { + product.redemption.hasEnoughPoints = + userPoints >= product.redemption.localPrice.pointsPerStay + } + } + } + } + + const roomFeatures = await getPackages( + { + adults: room.adults, + children: room.childrenInRoom?.length || 0, + endDate: input.booking.toDate, + hotelId: input.booking.hotelId, + lang, + packageCodes: [ + RoomPackageCodeEnum.ACCESSIBILITY_ROOM, + RoomPackageCodeEnum.ALLERGY_ROOM, + RoomPackageCodeEnum.PET_ROOM, + ], + startDate: input.booking.fromDate, + }, + serviceToken + ) + + if (roomFeatures) { + validateAvailabilityData.data.packages = roomFeatures + } + + // Fetch packages + if (room.packages?.length) { + const roomFeaturesInventory = await getRoomFeaturesInventory( + { + adults: room.adults, + childrenInRoom: room.childrenInRoom, + endDate: input.booking.toDate, + hotelId: input.booking.hotelId, + lang, + roomFeatureCodes: room.packages, + startDate: input.booking.fromDate, + }, + serviceToken + ) + + if (roomFeaturesInventory) { + const features = roomFeaturesInventory.reduce< + Record + >((fts, feat) => { + fts[feat.roomTypeCode] = feat.features?.[0]?.inventory ?? 0 + return fts + }, {}) + + const updatedRoomConfigurations = + validateAvailabilityData.data.roomConfigurations + // This filter is needed since we can get availability + // back from roomFeatures yet the availability call + // says there are no rooms left... + .filter((rc) => rc.roomsLeft) + .filter((rc) => features?.[rc.roomTypeCode]) + .map((rc) => ({ + ...rc, + roomsLeft: features[rc.roomTypeCode], + status: AvailabilityEnum.Available, + })) + + validateAvailabilityData.data.roomConfigurations = + updatedRoomConfigurations + } + } + + return validateAvailabilityData.data + } + }, + "1m" + ) + + return result + }) + ) + + const data = availabilityResponses.map((availability) => { + if (availability.status === "fulfilled") { + return availability.value + } + return { + details: availability.reason, + error: "request_failure", + } + }) + + metricsGetRoomsAvailability.success() + + return data +} + +export function getSelectedRoomAvailability( + rateCode: string, + rateDefinitions: RateDefinition[], + roomConfigurations: RoomConfiguration[], + roomTypeCode: string, + userPoints: number | undefined +) { + const rateDefinition = rateDefinitions.find((rd) => rd.rateCode === rateCode) + if (!rateDefinition) { + return null + } + + const selectedRoom = roomConfigurations.find( + (room) => + room.roomTypeCode === roomTypeCode && + room.products.find((product) => findProduct(product, rateDefinition)) + ) + + if (!selectedRoom) { + return null + } + + let product: Product | RedemptionsProduct | undefined = + selectedRoom.products.find((product) => + findProduct(product, rateDefinition) + ) + + if (!product) { + return null + } + + if (Array.isArray(product)) { + const redemptionProduct = userPoints + ? product.find( + (r) => + r.redemption.rateCode === rateDefinition.rateCode && + r.redemption.localPrice.pointsPerStay <= userPoints + ) + : undefined + if (!redemptionProduct) { + return null + } + product = redemptionProduct + } + + return { + rateDefinition, + rateDefinitions, + rooms: roomConfigurations, + product, + selectedRoom, + } +} + +export function getBedTypes( + rooms: RoomConfiguration[], + roomType: string, + roomCategories?: RoomCategory[] +) { + if (!roomCategories) { + return [] + } + + return rooms + .filter( + (room) => room.status === AvailabilityEnum.Available || room.roomsLeft > 0 + ) + .filter((room) => room.roomType === roomType) + .map((availRoom) => { + const matchingRoom = roomCategories + ?.find((room) => + room.roomTypes + .map((roomType) => roomType.code) + .includes(availRoom.roomTypeCode) + ) + ?.roomTypes.find((roomType) => roomType.code === availRoom.roomTypeCode) + + if (matchingRoom) { + return { + description: matchingRoom.description, + size: matchingRoom.mainBed.widthRange, + value: matchingRoom.code, + type: matchingRoom.mainBed.type, + roomsLeft: availRoom.roomsLeft, + extraBed: matchingRoom.fixedExtraBed + ? { + type: matchingRoom.fixedExtraBed.type, + description: matchingRoom.fixedExtraBed.description, + } + : undefined, + } + } + }) + .filter((bed): bed is BedTypeSelection => Boolean(bed)) +} + +export function mergeRoomTypes(roomConfigurations: RoomConfiguration[]) { + // Initial sort to guarantee if one bed is NotAvailable and whereas + // the other is Available to make sure data is added to the correct + // roomConfig + roomConfigurations.sort(sortRoomConfigs) + + const roomConfigs = new Map() + for (const roomConfig of roomConfigurations) { + if (roomConfigs.has(roomConfig.roomType)) { + const currentRoomConf = roomConfigs.get(roomConfig.roomType) + if (currentRoomConf) { + currentRoomConf.features = roomConfig.features.reduce( + (feats, feature) => { + const currentFeatureIndex = feats.findIndex( + (f) => f.code === feature.code + ) + if (currentFeatureIndex !== -1) { + feats[currentFeatureIndex].inventory = + feats[currentFeatureIndex].inventory + feature.inventory + } else { + feats.push(feature) + } + return feats + }, + currentRoomConf.features + ) + currentRoomConf.roomsLeft = + currentRoomConf.roomsLeft + roomConfig.roomsLeft + roomConfigs.set(currentRoomConf.roomType, currentRoomConf) + } + } else { + roomConfigs.set(roomConfig.roomType, roomConfig) + } + } + return Array.from(roomConfigs.values()) +} + +export function selectRateRedirectURL( + input: RoomsAvailabilityExtendedInputSchema, + selectedRooms: boolean[] +) { + const searchParams = new URLSearchParams({ + errorCode: BookingErrorCodeEnum.AvailabilityError, + fromdate: input.booking.fromDate, + hotel: input.booking.hotelId, + todate: input.booking.toDate, + }) + if (input.booking.searchType) { + searchParams.set("searchtype", input.booking.searchType) + } + for (const [idx, room] of input.booking.rooms.entries()) { + searchParams.set(`room[${idx}].adults`, room.adults.toString()) + + if (selectedRooms[idx]) { + if (room.counterRateCode) { + searchParams.set(`room[${idx}].counterratecode`, room.counterRateCode) + } + searchParams.set(`room[${idx}].ratecode`, room.rateCode) + searchParams.set(`room[${idx}].roomtype`, room.roomTypeCode) + } else { + if (!searchParams.has("modifyRateIndex")) { + searchParams.set("modifyRateIndex", idx.toString()) + } + } + if (room.bookingCode) { + searchParams.set(`room[${idx}].bookingCode`, room.bookingCode) + } + if (room.packages) { + searchParams.set(`room[${idx}].packages`, room.packages.join(",")) + } + if (room.childrenInRoom?.length) { + for (const [i, kid] of room.childrenInRoom.entries()) { + searchParams.set(`room[${idx}].child[${i}].age`, kid.age.toString()) + searchParams.set(`room[${idx}].child[${i}].bed`, kid.bed.toString()) + } + } + } + + return `${selectRate(input.lang)}?${searchParams.toString()}` +} diff --git a/packages/trpc/lib/routers/user/helpers.ts b/packages/trpc/lib/routers/user/helpers.ts new file mode 100644 index 000000000..ac36627a7 --- /dev/null +++ b/packages/trpc/lib/routers/user/helpers.ts @@ -0,0 +1,47 @@ +import type { + Membership, + NativeFriendsMembership, + UserLoyalty, +} from "../../types/user" + +export enum scandicMembershipTypes { + SCANDIC_NATIVE = "SCANDIC_NATIVE", + SAS_EB = "SAS_EB", +} + +export function isScandicNativeMembership( + membership: Membership +): membership is NativeFriendsMembership { + return membership.type === scandicMembershipTypes.SCANDIC_NATIVE +} + +export function getFriendsMembership(userLoyalty: UserLoyalty) { + const { memberships, ...loyalty } = userLoyalty + + const friendsMembership = memberships.find(isScandicNativeMembership) + + if (!friendsMembership) return null + + const pointExpiration = loyalty.pointExpirations + .sort( + (a, b) => new Date(a.expires).getTime() - new Date(b.expires).getTime() + ) + .at(0) + + // Map to the same format that was used with Profile V1 to avoid larger changes for now. + const result = { + membershipType: friendsMembership.type, + membershipNumber: friendsMembership.membershipNumber, + membershipLevel: loyalty.tier, + nextLevel: friendsMembership.nextTier, + currentPoints: loyalty.points.spendable, + expirationDate: loyalty.tierExpires, + nightsToTopTier: friendsMembership.nightsToTopTier, + pointsRequiredToNextlevel: friendsMembership.pointsToNextTier, + tierExpirationDate: loyalty.tierExpires, + pointsExpiryDate: pointExpiration?.expires, + pointsToExpire: pointExpiration?.points, + memberSince: friendsMembership.memberSince, + } + return result +} diff --git a/packages/trpc/lib/routers/user/output.ts b/packages/trpc/lib/routers/user/output.ts new file mode 100644 index 000000000..01569916b --- /dev/null +++ b/packages/trpc/lib/routers/user/output.ts @@ -0,0 +1,145 @@ +import { z } from "zod" + +import { countriesMap } from "../../constants/countries" +import { getFriendsMembership } from "./helpers" + +const scandicFriendsTier = z.enum(["L1", "L2", "L3", "L4", "L5", "L6", "L7"]) +const sasEurobonusTier = z.enum(["EBB", "EBS", "EBG", "EBD", "EBP"]) + +const commonMembershipSchema = z.object({ + membershipNumber: z.string(), + tierExpires: z.string().nullish().default(null), + memberSince: z.string().nullish(), +}) + +// This prevents validation errors if the API returns an unhandled membership type +const otherMembershipSchema = z + .object({ + // This ensures that `type` won't widen into "string", losing the literal types, when used in a union + type: z.string().refine((val): val is string & {} => true), + }) + .merge(commonMembershipSchema) + +export const sasMembershipSchema = z + .object({ + type: z.literal("SAS_EB"), + tier: sasEurobonusTier, + nextTier: sasEurobonusTier.nullish(), + spendablePoints: z.number().nullish(), + boostedByScandic: z.boolean().nullish(), + boostedTier: sasEurobonusTier.nullish(), + boostedTierExpires: z.string().nullish().default(null), + }) + .merge(commonMembershipSchema) + .transform((response) => { + return { + ...response, + tierExpires: + // SAS API returns 1900-01-01 for non-expiring tiers + response.tierExpires === "1900-01-01" ? null : response.tierExpires, + } + }) + +export const friendsMembershipSchema = z + .object({ + type: z.literal("SCANDIC_NATIVE"), + tier: scandicFriendsTier, + nextTier: scandicFriendsTier.nullish(), + pointsToNextTier: z.number().nullish(), + nightsToTopTier: z.number().nullish(), + }) + .merge(commonMembershipSchema) + +export const membershipSchema = z.union([ + friendsMembershipSchema, + sasMembershipSchema, + otherMembershipSchema, +]) + +const pointExpirationSchema = z.object({ + points: z.number().int(), + expires: z.string(), +}) + +export const userLoyaltySchema = z.object({ + memberships: z.array(membershipSchema), + points: z.object({ + spendable: z.number().int(), + earned: z.number().int(), + spent: z.number().int(), + }), + tier: scandicFriendsTier, + tierExpires: z.string(), + tierBoostedBy: z.string().nullish(), + pointExpirations: z.array(pointExpirationSchema), +}) + +export const getUserSchema = z + .object({ + data: z.object({ + attributes: z.object({ + dateOfBirth: z.string().optional().default("1900-01-01"), + email: z.string().email(), + firstName: z.string(), + language: z + .string() + // Preserve Profile v1 formatting for now so it matches ApiLang enum + .transform((s) => s.charAt(0).toUpperCase() + s.slice(1)) + .optional(), + lastName: z.string(), + phoneNumber: z.string().optional(), + profileId: z.string(), + membershipNumber: z.string(), + address: z + .object({ + city: z.string().optional(), + country: z.string().optional(), + countryCode: z.nativeEnum(countriesMap).optional(), + streetAddress: z.string().optional(), + zipCode: z.string().optional(), + }) + .optional() + .nullable(), + loyalty: userLoyaltySchema.optional(), + }), + type: z.string(), + }), + }) + .transform((apiResponse) => { + return { + ...apiResponse.data.attributes, + membership: apiResponse.data.attributes.loyalty + ? getFriendsMembership(apiResponse.data.attributes.loyalty) + : null, + name: `${apiResponse.data.attributes.firstName} ${apiResponse.data.attributes.lastName}`, + } + }) + +export const creditCardSchema = z + .object({ + attribute: z.object({ + cardName: z.string().optional(), + alias: z.string(), + truncatedNumber: z.string().transform((s) => s.slice(-4)), + expirationDate: z.string(), + cardType: z + .string() + .transform((s) => s.charAt(0).toLowerCase() + s.slice(1)), + }), + id: z.string(), + type: z.string(), + }) + .transform((apiResponse) => { + return { + id: apiResponse.id, + type: apiResponse.attribute.cardType, + truncatedNumber: apiResponse.attribute.truncatedNumber, + alias: apiResponse.attribute.alias, + expirationDate: apiResponse.attribute.expirationDate, + cardType: apiResponse.attribute.cardType, + } + }) + +export const creditCardsSchema = z.object({ + data: z.array(creditCardSchema), +}) diff --git a/packages/trpc/lib/routers/user/utils.ts b/packages/trpc/lib/routers/user/utils.ts new file mode 100644 index 000000000..3e6abc25c --- /dev/null +++ b/packages/trpc/lib/routers/user/utils.ts @@ -0,0 +1,79 @@ +import { createCounter } from "@scandic-hotels/common/telemetry" + +import * as api from "../../api" +import { cache } from "../../DUPLICATED/cache" +import { getUserSchema } from "./output" + +import type { Session } from "next-auth" + +export const getVerifiedUser = cache( + async ({ + session, + includeExtendedPartnerData, + }: { + session: Session + includeExtendedPartnerData?: boolean + }) => { + const getVerifiedUserCounter = createCounter("user", "getVerifiedUser") + const metricsGetVerifiedUser = getVerifiedUserCounter.init() + + metricsGetVerifiedUser.start() + + const now = Date.now() + if (session.token.expires_at && session.token.expires_at < now) { + metricsGetVerifiedUser.dataError(`Token expired`) + return { error: true, cause: "token_expired" } as const + } + + const apiResponse = await api.get( + api.endpoints.v2.Profile.profile, + { + headers: { + Authorization: `Bearer ${session.token.access_token}`, + }, + }, + includeExtendedPartnerData + ? { includes: "extendedPartnerInformation" } + : {} + ) + + if (!apiResponse.ok) { + await metricsGetVerifiedUser.httpError(apiResponse) + + if (apiResponse.status === 401) { + return { error: true, cause: "unauthorized" } as const + } else if (apiResponse.status === 403) { + return { error: true, cause: "forbidden" } as const + } else if (apiResponse.status === 404) { + return { error: true, cause: "notfound" } as const + } + + return { + error: true, + cause: "unknown", + status: apiResponse.status, + } as const + } + + const apiJson = await apiResponse.json() + if (!apiJson.data?.attributes) { + metricsGetVerifiedUser.dataError( + `Missing data attributes in API response`, + { + data: apiJson, + } + ) + return null + } + + const verifiedData = getUserSchema.safeParse(apiJson) + if (!verifiedData.success) { + metricsGetVerifiedUser.validationError(verifiedData.error) + return null + } + + metricsGetVerifiedUser.success() + + return verifiedData + } +) diff --git a/apps/scandic-web/types/authError.ts b/packages/trpc/lib/types/authError.ts similarity index 100% rename from apps/scandic-web/types/authError.ts rename to packages/trpc/lib/types/authError.ts diff --git a/apps/scandic-web/types/trpc/routers/hotel/availability.ts b/packages/trpc/lib/types/availability.ts similarity index 82% rename from apps/scandic-web/types/trpc/routers/hotel/availability.ts rename to packages/trpc/lib/types/availability.ts index ab16d9cb1..ea0eb3d0d 100644 --- a/apps/scandic-web/types/trpc/routers/hotel/availability.ts +++ b/packages/trpc/lib/types/availability.ts @@ -1,18 +1,19 @@ +import type { z } from "zod" + import type { enterDetailsRoomsAvailabilityInputSchema, getHotelsByHotelIdsAvailabilityInputSchema, hotelsAvailabilityInputSchema, selectRateRoomsAvailabilityInputSchema, -} from "@scandic-hotels/trpc/routers/hotels/input" -import type { hotelsAvailabilitySchema } from "@scandic-hotels/trpc/routers/hotels/output" -import type { productTypeSchema } from "@scandic-hotels/trpc/routers/hotels/schemas/availability/productType" +} from "../routers/hotels/input" +import type { hotelsAvailabilitySchema } from "../routers/hotels/output" +import type { productTypeSchema } from "../routers/hotels/schemas/availability/productType" import type { productTypeCorporateChequeSchema, productTypePointsSchema, productTypePriceSchema, productTypeVoucherSchema, -} from "@scandic-hotels/trpc/routers/hotels/schemas/productTypePrice" -import type { z } from "zod" +} from "../routers/hotels/schemas/productTypePrice" export type HotelsAvailability = z.output export type HotelsAvailabilityInputSchema = z.output< diff --git a/packages/trpc/lib/types/bedTypeSelection.ts b/packages/trpc/lib/types/bedTypeSelection.ts new file mode 100644 index 000000000..dd981c7b4 --- /dev/null +++ b/packages/trpc/lib/types/bedTypeSelection.ts @@ -0,0 +1,18 @@ +import type { BedTypeEnum, ExtraBedTypeEnum } from "../enums/bedType" + +export type BedTypeSelection = { + description: string + size: { + min: number + max: number + } + value: string + type: BedTypeEnum + roomsLeft: number + extraBed: + | { + description: string + type: ExtraBedTypeEnum + } + | undefined +} diff --git a/packages/trpc/lib/types/child.ts b/packages/trpc/lib/types/child.ts new file mode 100644 index 000000000..5821a01d0 --- /dev/null +++ b/packages/trpc/lib/types/child.ts @@ -0,0 +1,6 @@ +import type { ChildBedMapEnum } from "../enums/childBedMapEnum" + +export interface Child { + bed: ChildBedMapEnum + age: number +} diff --git a/packages/trpc/lib/types/loginType.ts b/packages/trpc/lib/types/loginType.ts new file mode 100644 index 000000000..b505272b8 --- /dev/null +++ b/packages/trpc/lib/types/loginType.ts @@ -0,0 +1,7 @@ +export enum LoginTypeEnum { + email = "email", + "membership number" = "membership number", + "email link" = "email link", + "dtmc" = "dtmc", +} +export type LoginType = keyof typeof LoginTypeEnum diff --git a/apps/scandic-web/types/requests/packages.ts b/packages/trpc/lib/types/packages.ts similarity index 69% rename from apps/scandic-web/types/requests/packages.ts rename to packages/trpc/lib/types/packages.ts index 944dcaf84..20d9802b6 100644 --- a/apps/scandic-web/types/requests/packages.ts +++ b/packages/trpc/lib/types/packages.ts @@ -1,12 +1,13 @@ -import type { BreakfastPackageEnum } from "@scandic-hotels/trpc/enums/breakfast" -import type { RoomPackageCodeEnum } from "@scandic-hotels/trpc/enums/roomFilter" +import type { z } from "zod" + +import type { BreakfastPackageEnum } from "../enums/breakfast" +import type { RoomPackageCodeEnum } from "../enums/roomFilter" import type { ancillaryPackageInputSchema, breakfastPackageInputSchema, roomPackagesInputSchema, -} from "@scandic-hotels/trpc/routers/hotels/input" -import type { packagesSchema } from "@scandic-hotels/trpc/routers/hotels/output" -import type { z } from "zod" +} from "../routers/hotels/input" +import type { packagesSchema } from "../routers/hotels/output" export interface BreackfastPackagesInput extends z.input {} diff --git a/packages/trpc/lib/types/room.ts b/packages/trpc/lib/types/room.ts new file mode 100644 index 000000000..4330005e0 --- /dev/null +++ b/packages/trpc/lib/types/room.ts @@ -0,0 +1,25 @@ +import type { RateEnum } from "../enums/rate" +import type { BedTypeSelection } from "./bedTypeSelection" +import type { Package } from "./packages" +import type { Product } from "./roomAvailability" + +export interface Room { + bedTypes: BedTypeSelection[] + breakfastIncluded: boolean + cancellationRule: string + cancellationText: string + mustBeGuaranteed: boolean + memberMustBeGuaranteed: boolean | undefined + packages: Package[] + rate: RateEnum + rateDefinitionTitle: string + rateDetails: string[] + memberRateDetails: string[] | undefined + rateTitle: string | undefined + rateType: string + roomRate: Product + roomType: string + roomTypeCode: string + isAvailable: boolean + isFlexRate: boolean +} diff --git a/packages/trpc/lib/types/user.ts b/packages/trpc/lib/types/user.ts new file mode 100644 index 000000000..2bad5cd9c --- /dev/null +++ b/packages/trpc/lib/types/user.ts @@ -0,0 +1,29 @@ +import type { z } from "zod" + +import type { getFriendsMembership } from "../routers/user/helpers" +import type { + creditCardSchema, + friendsMembershipSchema, + getUserSchema, + sasMembershipSchema, + userLoyaltySchema, +} from "../routers/user/output" + +/** + * All extended field needs to be added by API team to response or + * we have to get the values from elsewhere + */ +export interface User extends z.output {} + +export type CreditCard = z.output + +export type UserLoyalty = z.output + +export type Membership = UserLoyalty["memberships"][number] +export type NativeFriendsMembership = z.output +export type EurobonusMembership = z.output + +export type FriendsMembership = ReturnType + +export type EurobonusTier = EurobonusMembership["tier"] +export type FriendsTier = NativeFriendsMembership["tier"] diff --git a/packages/trpc/package.json b/packages/trpc/package.json index 9d915bca6..4247b152d 100644 --- a/packages/trpc/package.json +++ b/packages/trpc/package.json @@ -21,13 +21,19 @@ "./routers/*": "./lib/routers/*/index.ts", "./routers/contentstack/*": "./lib/routers/contentstack/*.ts", "./routers/hotels/*": "./lib/routers/hotels/*.ts", + "./routers/booking/*": "./lib/routers/booking/*.ts", + "./routers/user/*": "./lib/routers/user/*.ts", "./enums/*": "./lib/enums/*.ts", "./types/*": "./lib/types/*.ts", + "./constants/*": "./lib/constants/*.ts", "./api": "./lib/api/index.ts", "./utils": "./lib/utils.ts", "./utils/*": "./lib/utils/*.ts", "./cms/*": "./lib/services/cms/*.ts", "./previewContext": "./lib/previewContext.ts", + "./FIX-BELOW": "./unused", + "./jwt.d.ts": "./jwt.d.ts", + "./auth.d.ts": "./auth.d.ts", "./graphql/Query/Current/CurrentBlockPage.graphql": "./lib/graphql/Query/Current/CurrentBlockPage.graphql", "./graphql/Query/Current/CurrentBlockPageTrackingData.graphql": "./lib/graphql/Query/Current/CurrentBlockPageTrackingData.graphql" },