feat(SW-66, SW-348): search functionality and ui
This commit is contained in:
@@ -584,3 +584,192 @@ const rate = z.object({
|
||||
|
||||
export const getRatesSchema = z.array(rate)
|
||||
export type Rate = z.infer<typeof rate>
|
||||
|
||||
const hotelFilter = z.object({
|
||||
roomFacilities: z.array(z.string()),
|
||||
hotelFacilities: z.array(z.string()),
|
||||
hotelSurroundings: z.array(z.string()),
|
||||
})
|
||||
|
||||
export const getFiltersSchema = hotelFilter
|
||||
export type HotelFilter = z.infer<typeof hotelFilter>
|
||||
|
||||
export const apiCitiesByCountrySchema = z.object({
|
||||
data: z.array(
|
||||
z
|
||||
.object({
|
||||
attributes: z.object({
|
||||
cityIdentifier: z.string().optional(),
|
||||
name: z.string(),
|
||||
keywords: z.array(z.string()).optional(),
|
||||
timeZoneId: z.string().optional(),
|
||||
ianaTimeZoneId: z.string().optional(),
|
||||
isPublished: z.boolean().optional().default(false),
|
||||
}),
|
||||
id: z.string(),
|
||||
type: z.literal("cities"),
|
||||
})
|
||||
.transform((data) => {
|
||||
return {
|
||||
...data.attributes,
|
||||
id: data.id,
|
||||
type: data.type,
|
||||
}
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
export interface CitiesByCountry
|
||||
extends z.output<typeof apiCitiesByCountrySchema> {}
|
||||
export type CitiesGroupedByCountry = Record<string, CitiesByCountry["data"]>
|
||||
|
||||
export const apiCountriesSchema = z.object({
|
||||
data: z
|
||||
.array(
|
||||
z.object({
|
||||
attributes: z.object({
|
||||
currency: z.string().optional(),
|
||||
name: z.string(),
|
||||
}),
|
||||
hotelInformationSystemId: z.number().optional(),
|
||||
id: z.string().optional(),
|
||||
language: z.string().optional(),
|
||||
type: z.literal("countries"),
|
||||
})
|
||||
)
|
||||
.transform((data) => {
|
||||
return data.map((country) => {
|
||||
return {
|
||||
...country.attributes,
|
||||
hotelInformationSystemId: country.hotelInformationSystemId,
|
||||
id: country.id,
|
||||
language: country.language,
|
||||
type: country.type,
|
||||
}
|
||||
})
|
||||
}),
|
||||
})
|
||||
|
||||
export interface Countries extends z.output<typeof apiCountriesSchema> {}
|
||||
|
||||
export const apiLocationCitySchema = z.object({
|
||||
attributes: z.object({
|
||||
cityIdentifier: z.string().optional(),
|
||||
keyWords: z.array(z.string()).optional(),
|
||||
name: z.string().optional().default(""),
|
||||
}),
|
||||
country: z.string().optional().default(""),
|
||||
id: z.string().optional().default(""),
|
||||
type: z.literal("cities"),
|
||||
})
|
||||
|
||||
export const apiCitySchema = z
|
||||
.object({
|
||||
data: z.array(
|
||||
z.object({
|
||||
attributes: z.object({
|
||||
cityIdentifier: z.string().optional(),
|
||||
name: z.string(),
|
||||
keywords: z.array(z.string()),
|
||||
timeZoneId: z.string().optional(),
|
||||
ianaTimeZoneId: z.string().optional(),
|
||||
isPublished: z.boolean().optional().default(false),
|
||||
}),
|
||||
id: z.string().optional(),
|
||||
type: z.literal("cities"),
|
||||
})
|
||||
),
|
||||
})
|
||||
.transform(({ data }) => {
|
||||
if (data.length) {
|
||||
const city = data[0]
|
||||
return {
|
||||
...city.attributes,
|
||||
id: city.id,
|
||||
type: city.type,
|
||||
}
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
export const apiLocationHotelSchema = z.object({
|
||||
attributes: z.object({
|
||||
distanceToCentre: z.number().optional(),
|
||||
images: z
|
||||
.object({
|
||||
large: z.string().optional(),
|
||||
medium: z.string().optional(),
|
||||
small: z.string().optional(),
|
||||
tiny: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
keyWords: z.array(z.string()).optional(),
|
||||
name: z.string().optional().default(""),
|
||||
operaId: z.string().optional(),
|
||||
}),
|
||||
id: z.string().optional().default(""),
|
||||
relationships: z
|
||||
.object({
|
||||
city: z
|
||||
.object({
|
||||
links: z
|
||||
.object({
|
||||
related: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.optional(),
|
||||
type: z.literal("hotels"),
|
||||
})
|
||||
|
||||
export const apiLocationsSchema = z.object({
|
||||
data: z
|
||||
.array(
|
||||
z
|
||||
.discriminatedUnion("type", [
|
||||
apiLocationCitySchema,
|
||||
apiLocationHotelSchema,
|
||||
])
|
||||
.transform((location) => {
|
||||
if (location.type === "cities") {
|
||||
return {
|
||||
...location.attributes,
|
||||
country: location?.country ?? "",
|
||||
id: location.id,
|
||||
type: location.type,
|
||||
}
|
||||
}
|
||||
return {
|
||||
...location.attributes,
|
||||
id: location.id,
|
||||
relationships: {
|
||||
city: {
|
||||
cityIdentifier: "",
|
||||
ianaTimeZoneId: "",
|
||||
id: "",
|
||||
isPublished: false,
|
||||
keywords: [],
|
||||
name: "",
|
||||
timeZoneId: "",
|
||||
type: "cities",
|
||||
url: location?.relationships?.city?.links?.related ?? "",
|
||||
},
|
||||
},
|
||||
type: location.type,
|
||||
}
|
||||
})
|
||||
)
|
||||
.transform((data) =>
|
||||
data
|
||||
.filter((node) => !!node)
|
||||
.sort((a, b) => {
|
||||
if (a.type === b.type) {
|
||||
return a.name.localeCompare(b.name)
|
||||
} else {
|
||||
return a.type === "cities" ? -1 : 1
|
||||
}
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user