feat: SW-2028 Updated validations at trpc query level
This commit is contained in:
@@ -44,7 +44,6 @@ function HotelCard({
|
||||
state = "default",
|
||||
type = HotelCardListingTypeEnum.PageListing,
|
||||
bookingCode = "",
|
||||
userPoints,
|
||||
}: HotelCardProps) {
|
||||
const params = useParams()
|
||||
const lang = params.lang as Lang
|
||||
@@ -74,13 +73,7 @@ function HotelCard({
|
||||
availability.productType?.member?.rateType === RateTypeEnum.Regular
|
||||
const price = availability.productType
|
||||
|
||||
const userHasEnoughPoints =
|
||||
userPoints !== undefined
|
||||
? !!price?.redemptions?.some(
|
||||
(r) => r.localPrice.pointsPerStay < userPoints
|
||||
)
|
||||
: false
|
||||
|
||||
const userHasEnoughPoints = price?.redemptions?.some((r) => r.hasEnoughPoints)
|
||||
const notEnoughPointsLabel = intl.formatMessage({ id: "Not enough points" })
|
||||
|
||||
return (
|
||||
@@ -218,7 +211,7 @@ function HotelCard({
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
{userPoints !== undefined && !userHasEnoughPoints ? (
|
||||
{price?.redemptions?.length && !userHasEnoughPoints ? (
|
||||
<Tooltip
|
||||
arrow="left"
|
||||
position="bottom"
|
||||
|
||||
@@ -30,7 +30,6 @@ import { RateTypeEnum } from "@/types/enums/rateType"
|
||||
export default function HotelCardListing({
|
||||
hotelData,
|
||||
type = HotelCardListingTypeEnum.PageListing,
|
||||
userPoints,
|
||||
}: HotelCardListingProps) {
|
||||
const { data: session } = useSession()
|
||||
const isUserLoggedIn = isValidClientSession(session)
|
||||
@@ -122,7 +121,6 @@ export default function HotelCardListing({
|
||||
}
|
||||
type={type}
|
||||
bookingCode={bookingCode}
|
||||
userPoints={userPoints}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
|
||||
@@ -246,14 +246,6 @@ export async function getHotels(
|
||||
return hotels
|
||||
}
|
||||
|
||||
export async function getUserPoints() {
|
||||
const membershipCard = await serverClient().user.safeMembershipLevel()
|
||||
if (!membershipCard) {
|
||||
return undefined
|
||||
}
|
||||
return membershipCard.currentPoints
|
||||
}
|
||||
|
||||
const hotelSurroundingsFilterNames = [
|
||||
"Hotel surroundings",
|
||||
"Hotel omgivelser",
|
||||
|
||||
@@ -23,7 +23,7 @@ import { convertObjToSearchParams } from "@/utils/url"
|
||||
|
||||
import HotelCardListing from "../HotelCardListing"
|
||||
import BookingCodeFilter from "./BookingCodeFilter"
|
||||
import { getFiltersFromHotels, getHotels, getUserPoints } from "./helpers"
|
||||
import { getFiltersFromHotels, getHotels } from "./helpers"
|
||||
import HotelCount from "./HotelCount"
|
||||
import HotelFilter from "./HotelFilter"
|
||||
import HotelSorter from "./HotelSorter"
|
||||
@@ -76,11 +76,6 @@ export default async function SelectHotel({
|
||||
!!redemption
|
||||
)
|
||||
|
||||
let userPoints
|
||||
if (redemption) {
|
||||
userPoints = await getUserPoints()
|
||||
}
|
||||
|
||||
const arrivalDate = new Date(selectHotelParams.fromDate)
|
||||
const departureDate = new Date(selectHotelParams.toDate)
|
||||
|
||||
@@ -252,10 +247,7 @@ export default async function SelectHotel({
|
||||
isAllUnavailable={isAllUnavailable}
|
||||
operaId={hotels?.[0]?.hotel.operaId}
|
||||
/>
|
||||
<HotelCardListing
|
||||
hotelData={hotels}
|
||||
userPoints={userPoints ? userPoints : undefined}
|
||||
/>
|
||||
<HotelCardListing hotelData={hotels} />
|
||||
</div>
|
||||
</main>
|
||||
<Suspense key={`${suspenseKey}-tracking`} fallback={null}>
|
||||
|
||||
@@ -67,6 +67,8 @@ import {
|
||||
getSelectedRoomAvailability,
|
||||
} from "./utils"
|
||||
|
||||
import type { Session } from "next-auth"
|
||||
|
||||
import type { BedTypeSelection } from "@/types/components/hotelReservation/enterDetails/bedType"
|
||||
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
|
||||
import { HotelTypeEnum } from "@/types/enums/hotelType"
|
||||
@@ -209,7 +211,8 @@ export const getHotel = cache(
|
||||
export const getHotelsAvailabilityByCity = async (
|
||||
input: HotelsAvailabilityInputSchema,
|
||||
apiLang: string,
|
||||
token: string // Either service token or user access token in case of redemption search
|
||||
token: string, // Either service token or user access token in case of redemption search
|
||||
session?: Session
|
||||
) => {
|
||||
const {
|
||||
cityId,
|
||||
@@ -222,7 +225,7 @@ export const getHotelsAvailabilityByCity = async (
|
||||
} = input
|
||||
const cacheClient = await getCacheClient()
|
||||
return await cacheClient.cacheOrGet(
|
||||
`${cityId}:${roomStayStartDate}:${roomStayEndDate}:${adults}:${children}:${bookingCode}`,
|
||||
`${cityId}:${roomStayStartDate}:${roomStayEndDate}:${adults}:${children}:${bookingCode}:${redemption ? "isRedemption" : ""}`,
|
||||
async () => {
|
||||
const params: Record<string, string | number> = {
|
||||
roomStayStartDate,
|
||||
@@ -325,6 +328,18 @@ export const getHotelsAvailabilityByCity = async (
|
||||
query: { cityId, params: params },
|
||||
})
|
||||
)
|
||||
if (redemption && session) {
|
||||
const verifiedUser = await getVerifiedUser({ session })
|
||||
if (!verifiedUser?.error) {
|
||||
const userPoints = verifiedUser?.data.membership?.currentPoints ?? 0
|
||||
validateAvailabilityData.data.data.forEach((data) => {
|
||||
data.attributes.productType?.redemptions?.forEach((r) => {
|
||||
r.hasEnoughPoints = userPoints >= r.localPrice.pointsPerStay
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
availability: validateAvailabilityData.data.data.flatMap(
|
||||
(hotels) => hotels.attributes
|
||||
@@ -487,7 +502,8 @@ export const hotelQueryRouter = router({
|
||||
return getHotelsAvailabilityByCity(
|
||||
input,
|
||||
apiLang,
|
||||
ctx.session.token.access_token
|
||||
ctx.session.token.access_token,
|
||||
ctx.session,
|
||||
)
|
||||
}),
|
||||
hotelsByHotelIds: serviceProcedure
|
||||
@@ -606,6 +622,18 @@ export const hotelQueryRouter = router({
|
||||
)?.mustBeGuaranteed
|
||||
}
|
||||
|
||||
if (redemption && ctx.session) {
|
||||
const verifiedUser = await getVerifiedUser({ session: ctx.session })
|
||||
if (!verifiedUser?.error) {
|
||||
const userPoints = verifiedUser?.data.membership?.currentPoints ?? 0
|
||||
validateAvailabilityData.data.roomConfigurations.forEach((data) => {
|
||||
data.redemptions?.forEach(r => {
|
||||
r.redemption.hasEnoughPoints = userPoints >= r.redemption.localPrice.pointsPerStay
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return validateAvailabilityData.data
|
||||
})
|
||||
)
|
||||
|
||||
@@ -66,6 +66,7 @@ export const productTypePointsSchema = z
|
||||
.object({
|
||||
localPrice: redemptionSchema,
|
||||
requestedPrice: redemptionSchema.nullish(),
|
||||
hasEnoughPoints: z.boolean().optional().default(false),
|
||||
})
|
||||
.merge(partialPriceSchema)
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ export type HotelData = {
|
||||
export type HotelCardListingProps = {
|
||||
hotelData: HotelResponse[]
|
||||
type?: HotelCardListingTypeEnum
|
||||
userPoints?: number
|
||||
}
|
||||
|
||||
export interface NullableHotelData extends Omit<HotelData, "hotelData"> {
|
||||
|
||||
@@ -7,5 +7,4 @@ export type HotelCardProps = {
|
||||
type?: HotelCardListingTypeEnum
|
||||
state?: "default" | "active"
|
||||
bookingCode?: string | null
|
||||
userPoints?: number
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user