feat: SW-276 Implemented Guests and rooms picker

This commit is contained in:
Hrishikesh Vaipurkar
2024-09-12 11:30:56 +02:00
parent f4be831a78
commit 24f7bc290d
19 changed files with 605 additions and 4 deletions

View File

@@ -7,6 +7,7 @@ import { dt } from "@/lib/dt"
import DatePicker from "@/components/DatePicker" import DatePicker from "@/components/DatePicker"
import { SearchIcon } from "@/components/Icons" import { SearchIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button" import Button from "@/components/TempDesignSystem/Button"
import GuestsRoomsPickerForm from "@/components/GuestsRoomsPicker"
import Caption from "@/components/TempDesignSystem/Text/Caption" import Caption from "@/components/TempDesignSystem/Text/Caption"
import Input from "./Input" import Input from "./Input"
@@ -51,7 +52,7 @@ export default function FormContent({
{rooms} {rooms}
</Caption> </Caption>
</label> </label>
<Input type="text" placeholder={rooms} /> <GuestsRoomsPickerForm />
</div> </div>
</div> </div>
<div className={styles.voucherContainer}> <div className={styles.voucherContainer}>

View File

@@ -26,7 +26,6 @@ export const bookingWidgetSchema = z.object({
), ),
redemption: z.boolean().default(false), redemption: z.boolean().default(false),
rooms: z.array( rooms: z.array(
// This will be updated when working in guests component
z.object({ z.object({
adults: z.number().default(1), adults: z.number().default(1),
children: z.array( children: z.array(

View File

@@ -0,0 +1,9 @@
.container {
display: grid;
grid-template-columns: auto auto auto auto;
align-items: center;
}
.textCenter {
text-align: center;
}

View File

@@ -0,0 +1,44 @@
import { useIntl } from "react-intl"
import Button from "@/components/TempDesignSystem/Button"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import styles from "./adult-selector.module.css"
import { AdultSelectorProps } from "@/types/components/bookingWidget/guestsRoomsPicker"
export default function AdultSelector({
adults = 1,
updateAdults = (count: number) => {},
}: AdultSelectorProps) {
const intl = useIntl()
const adultsLabel = intl.formatMessage({ id: "Adults" })
function decreaseAdults() {
if (adults <= 1) {
return
}
adults = adults - 1
updateAdults(adults)
}
function increaseAdults() {
if (adults > 5) {
return
}
adults = adults + 1
updateAdults(adults)
}
return (
<section className={styles.container}>
<Caption>{adultsLabel}</Caption>
<Button onClick={decreaseAdults} intent="text" size="small">
-
</Button>
<span className={styles.textCenter}>{adults}</span>
<Button onClick={increaseAdults} intent="text" size="small">
+
</Button>
</section>
)
}

View File

@@ -0,0 +1,83 @@
import { useIntl } from "react-intl"
import Select from "@/components/TempDesignSystem/Select"
import {
Child,
ChildBed,
} from "@/types/components/bookingWidget/guestsRoomsPicker"
type ChildSelectorProps = {
child: Child
index: number
availableBedTypes?: ChildBed[]
updateChild: (child: Child, index: number) => void
}
export default function ChildInfoSelector({
child = { age: -1, bed: -1 },
index = 0,
availableBedTypes = [
{ label: "In adults bed", value: 0 },
{ label: "In crib", value: 1 },
{ label: "In extra bed", value: 2 },
],
updateChild = (child: Child, index: number) => {},
}: ChildSelectorProps) {
const intl = useIntl()
const ageLabel = intl.formatMessage({ id: "Age" })
const bedLabel = intl.formatMessage({ id: "Bed" })
const ageList = [
{ label: "0", value: 0 },
{ label: "1", value: 1 },
{ label: "2", value: 2 },
{ label: "3", value: 3 },
{ label: "4", value: 4 },
{ label: "5", value: 5 },
{ label: "6", value: 6 },
{ label: "7", value: 7 },
{ label: "8", value: 8 },
{ label: "9", value: 9 },
{ label: "10", value: 10 },
{ label: "11", value: 11 },
{ label: "12", value: 12 },
]
function handleOnSelect(selectedKey: any, childInfo: string) {
if (childInfo == "age") {
child.age = selectedKey
} else if (childInfo == "bed") {
child.bed = selectedKey
}
updateChild(child, index)
}
return (
<>
<Select
size={2}
items={ageList}
label={ageLabel}
aria-label={ageLabel}
value={child.age}
onSelect={(key) => {
handleOnSelect(key, "age")
}}
name="age"
/>
{child.age !== -1 ? (
<Select
items={availableBedTypes}
label={bedLabel}
aria-label={bedLabel}
value={child.bed}
onSelect={(key) => {
handleOnSelect(key, "bed")
}}
name="bed"
/>
) : null}
</>
)
}

View File

@@ -0,0 +1,14 @@
.container {
display: grid;
grid-template-columns: auto auto auto auto;
align-items: center;
}
.childInfoContainer {
display: flex;
gap: 20px;
}
.textCenter {
text-align: center;
}

View File

@@ -0,0 +1,101 @@
import { useIntl } from "react-intl"
import Button from "@/components/TempDesignSystem/Button"
import Caption from "@/components/TempDesignSystem/Text/Caption"
import ChildInfoSelector from "./ChildInfoSelector"
import styles from "./child-selector.module.css"
import {
Child,
ChildBed,
ChildSelectorProps,
} from "@/types/components/bookingWidget/guestsRoomsPicker"
export default function ChildSelector({
roomChildren = [],
adultCount = 1,
updateChildren = (children: Child[]) => {},
}: ChildSelectorProps) {
const intl = useIntl()
const childrenLabel = intl.formatMessage({ id: "Children" })
function decreaseChildren() {
if (roomChildren.length < 1) {
return
}
roomChildren.pop()
updateChildren(roomChildren)
}
function increaseChildren() {
if (roomChildren.length > 5) {
return
}
roomChildren.push({ age: -1, bed: -1 })
updateChildren(roomChildren)
}
function updateChildInfo(child: Child, index: number) {
roomChildren[index] = child
updateChildren(roomChildren)
}
const childInAdultsBedIndices: number[] = []
let availableInAdultsBed = adultCount
const availableBedTypes: ChildBed[] = [
{ label: intl.formatMessage({ id: "In adults bed" }), value: 0 },
{ label: intl.formatMessage({ id: "In crib" }), value: 1 },
{ label: intl.formatMessage({ id: "In extra bed" }), value: 2 },
]
const childBedTypes: ChildBed[][] = []
for (let i = 0; i < roomChildren.length; i++) {
if (roomChildren[i].bed == 0 && availableInAdultsBed > 0) {
childInAdultsBedIndices.push(i)
availableInAdultsBed = availableInAdultsBed - 1
}
}
roomChildren.forEach((child, index) => {
let types: typeof availableBedTypes = []
if (
child.age <= 5 &&
(availableInAdultsBed > 0 || childInAdultsBedIndices.indexOf(index) != -1)
) {
types.push(availableBedTypes[0])
}
if (child.age < 3) {
types.push(availableBedTypes[1])
}
if (child.age > 2) {
types.push(availableBedTypes[2])
}
childBedTypes[index] = types
})
return (
<>
<section className={styles.container}>
<Caption>{childrenLabel}</Caption>
<Button intent="text" size="small" onClick={decreaseChildren}>
-
</Button>
<span className={styles.textCenter}>{roomChildren.length}</span>
<Button intent="text" size="small" onClick={increaseChildren}>
+
</Button>
</section>
{roomChildren.map((child, index) => (
<div key={index} className={styles.childInfoContainer}>
<ChildInfoSelector
index={index}
child={child}
availableBedTypes={childBedTypes[index]}
updateChild={updateChildInfo}
/>
</div>
))}
</>
)
}

View File

@@ -0,0 +1,6 @@
.container {
width: 280px;
display: grid;
gap: var(--Spacing-x2);
padding-bottom: var(--Spacing-x1);
}

View File

@@ -0,0 +1,47 @@
import { useIntl } from "react-intl"
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
import AdultSelector from "./AdultSelector"
import ChildSelector from "./ChildSelector"
import styles from "./guests-room-picker.module.css"
import {
Child,
GuestsRoom,
GuestsRoomPickerProps,
} from "@/types/components/bookingWidget/guestsRoomsPicker"
export default function GuestsRoomPicker({
handleOnSelect = (selected: GuestsRoom, index: number) => {},
room = { adults: 1, children: [] },
index = 1,
}: GuestsRoomPickerProps) {
const intl = useIntl()
const roomLabel = intl.formatMessage({ id: "Room" })
function updateAdults(count: number) {
room.adults = count
handleOnSelect(room, index)
}
function updateChildren(children: Child[]) {
room.children = children
handleOnSelect(room, index)
}
return (
<section className={styles.container}>
<Subtitle>
{roomLabel} {index + 1}
</Subtitle>
<AdultSelector adults={room.adults} updateAdults={updateAdults} />
<ChildSelector
roomChildren={room.children}
adultCount={room.adults}
updateChildren={updateChildren}
/>
</section>
)
}

View File

@@ -0,0 +1,89 @@
"use client"
import { useState } from "react"
import useLang from "@/hooks/useLang"
import Button from "../TempDesignSystem/Button"
import Divider from "../TempDesignSystem/Divider"
import GuestsRoomPicker from "./GuestsRoomPicker"
import styles from "./guests-rooms-picker.module.css"
import {
GuestsRoom,
GuestsRoomsPickerProps,
} from "@/types/components/bookingWidget/guestsRoomsPicker"
export default function GuestsRoomsPicker({
handleOnSelect,
initialSelected = [
{
adults: 1,
children: [],
},
],
closePicker,
}: GuestsRoomsPickerProps) {
const lang = useLang()
const [selectedGuests, setSelectedGuests] =
useState<GuestsRoom[]>(initialSelected)
function handleSelectRoomGuests(
selectedGuestsRoom: GuestsRoom,
index: number
) {
let updatedSelectedGuests = JSON.parse(JSON.stringify(selectedGuests))
updatedSelectedGuests[index] = selectedGuestsRoom
handleOnSelect(updatedSelectedGuests)
setSelectedGuests(updatedSelectedGuests)
}
function addRoom() {
if (selectedGuests.length < 4) {
let updatedSelectedGuests = JSON.parse(JSON.stringify(selectedGuests))
updatedSelectedGuests.push({
adults: 1,
children: [],
})
setSelectedGuests(updatedSelectedGuests)
handleOnSelect(updatedSelectedGuests)
}
}
function removeRoom(index: number) {
if (selectedGuests.length > 1) {
let updatedSelectedGuests = JSON.parse(JSON.stringify(selectedGuests))
updatedSelectedGuests.splice(index, 1)
setSelectedGuests(updatedSelectedGuests)
handleOnSelect(updatedSelectedGuests)
}
}
return (
<>
{selectedGuests.map((room, index) => (
<section key={index}>
<GuestsRoomPicker
room={room}
handleOnSelect={handleSelectRoomGuests}
index={index}
/>
<Divider></Divider>
{index > 0 ? (
<Button intent="text" onClick={() => removeRoom(index)}>
Remove Room
</Button>
) : null}
</section>
))}
<div className={styles.footer}>
{selectedGuests.length < 4 ? (
<Button intent="text" onClick={addRoom}>
Add Room
</Button>
) : null}
<Button onClick={closePicker}>Done</Button>
</div>
</>
)
}

View File

@@ -0,0 +1,34 @@
.container {
overflow: hidden;
position: relative;
z-index: 10;
&[data-isopen="true"] {
overflow: visible;
}
}
.hideWrapper {
background-color: var(--Main-Grey-White);
border-radius: var(--Corner-radius-Medium);
box-shadow: 0px 16px 24px 0px rgba(0, 0, 0, 0.08);
padding: var(--Spacing-x-one-and-half);
position: absolute;
/** BookingWidget padding + border-width */
top: calc(100% + var(--Spacing-x2) + 1px);
}
.btn {
background: none;
border: none;
cursor: pointer;
outline: none;
padding: 0;
width: 100%;
}
.body {
opacity: 0.8;
}
.footer {
display: grid;
gap: 20px;
grid-template-columns: auto auto;
margin: 10px 0 0;
}

View File

@@ -0,0 +1,85 @@
"use client"
import { useEffect, useRef, useState } from "react"
import { useFormContext, useWatch } from "react-hook-form"
import { useIntl } from "react-intl"
import Body from "@/components/TempDesignSystem/Text/Body"
import GuestsRoomsPicker from "./GuestsRoomsPicker"
import styles from "./guests-rooms-picker.module.css"
import {
GuestsRoom,
GuestsRoomsFormProps,
} from "@/types/components/bookingWidget/guestsRoomsPicker"
export default function GuestsRoomsPickerForm({
name = "rooms",
}: GuestsRoomsFormProps) {
const intl = useIntl()
const [isOpen, setIsOpen] = useState(false)
const selectedGuests = useWatch({ name })
const { register, setValue } = useFormContext()
const ref = useRef<HTMLDivElement | null>(null)
function handleOnClick() {
setIsOpen((prevIsOpen) => !prevIsOpen)
}
function handleSelectGuest(selected: GuestsRoom[]) {
setValue(name, selected)
}
useEffect(() => {
function handleClickOutside(evt: Event) {
const target = evt.target as HTMLElement
if (ref.current && target && !ref.current.contains(target)) {
setIsOpen(false)
}
}
document.addEventListener("click", handleClickOutside)
return () => {
document.removeEventListener("click", handleClickOutside)
}
}, [setIsOpen])
let selectedAdultsCount = 0
let selectedChildrenCount = 0
selectedGuests.forEach((room: GuestsRoom) => {
selectedAdultsCount = selectedAdultsCount + room.adults
selectedChildrenCount =
selectedChildrenCount + (room.children ? room.children.length : 0)
})
const selectedRoomsCount = selectedGuests.length
const childCountLabel =
(selectedChildrenCount > 1
? intl.formatMessage({ id: "Children" })
: intl.formatMessage({ id: "Child" })) + ", "
return (
<div className={styles.container} data-isopen={isOpen} ref={ref}>
<button className={styles.btn} onClick={handleOnClick} type="button">
<Body className={styles.body}>
{selectedAdultsCount}{" "}
{selectedAdultsCount > 1
? intl.formatMessage({ id: "Adults" })
: intl.formatMessage({ id: "Adult" })}{" "}
{", "}
{selectedChildrenCount > 0
? selectedChildrenCount + " " + childCountLabel
: null}
{selectedRoomsCount}{" "}
{selectedRoomsCount > 1
? intl.formatMessage({ id: "Rooms" })
: intl.formatMessage({ id: "Room" })}
</Body>
</button>
<div aria-modal className={styles.hideWrapper} role="dialog">
<GuestsRoomsPicker
handleOnSelect={handleSelectGuest}
initialSelected={selectedGuests}
closePicker={handleOnClick}
/>
</div>
</div>
)
}

View File

@@ -9,6 +9,8 @@
"Add new card": "Tilføj nyt kort", "Add new card": "Tilføj nyt kort",
"Address": "Adresse", "Address": "Adresse",
"Airport": "Lufthavn", "Airport": "Lufthavn",
"Adult": "Voksen",
"Adults": "voksne",
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle vores morgenmadsbuffeter tilbyder glutenfrie, veganske og allergivenlige muligheder.", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle vores morgenmadsbuffeter tilbyder glutenfrie, veganske og allergivenlige muligheder.",
"Already a friend?": "Allerede en ven?", "Already a friend?": "Allerede en ven?",
"Amenities": "Faciliteter", "Amenities": "Faciliteter",
@@ -44,6 +46,8 @@
"Check in": "Check ind", "Check in": "Check ind",
"Check out": "Check ud", "Check out": "Check ud",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tjek de kreditkort, der er gemt på din profil. Betal med et gemt kort, når du er logget ind for en mere jævn weboplevelse.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tjek de kreditkort, der er gemt på din profil. Betal med et gemt kort, når du er logget ind for en mere jævn weboplevelse.",
"Child": "Barn",
"Children": "børn",
"Choose room": "Vælg rum", "Choose room": "Vælg rum",
"Cities": "Byer", "Cities": "Byer",
"City": "By", "City": "By",
@@ -123,6 +127,9 @@
"How it works": "Hvordan det virker", "How it works": "Hvordan det virker",
"I would like to get my booking confirmation via sms": "Jeg vil gerne få min booking bekræftelse via SMS", "I would like to get my booking confirmation via sms": "Jeg vil gerne få min booking bekræftelse via SMS",
"Image gallery": "Billedgalleri", "Image gallery": "Billedgalleri",
"In adults bed": "i de voksnes seng",
"In crib": "i tremmeseng",
"In extra bed": "i ekstra seng",
"Included": "Inkluderet", "Included": "Inkluderet",
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det er ikke muligt at administrere dine kommunikationspræferencer lige nu, prøv venligst igen senere eller kontakt support, hvis problemet fortsætter.", "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det er ikke muligt at administrere dine kommunikationspræferencer lige nu, prøv venligst igen senere eller kontakt support, hvis problemet fortsætter.",
"Join Scandic Friends": "Tilmeld dig Scandic Friends", "Join Scandic Friends": "Tilmeld dig Scandic Friends",
@@ -224,6 +231,7 @@
"Retype new password": "Gentag den nye adgangskode", "Retype new password": "Gentag den nye adgangskode",
"Room & Terms": "Værelse & Vilkår", "Room & Terms": "Værelse & Vilkår",
"Room facilities": "Værelsesfaciliteter", "Room facilities": "Værelsesfaciliteter",
"Room": "Værelse",
"Rooms": "Værelser", "Rooms": "Værelser",
"Rooms & Guests": "Værelser & gæster", "Rooms & Guests": "Værelser & gæster",
"Sauna and gym": "Sauna and gym", "Sauna and gym": "Sauna and gym",

View File

@@ -9,6 +9,8 @@
"Add new card": "Neue Karte hinzufügen", "Add new card": "Neue Karte hinzufügen",
"Address": "Adresse", "Address": "Adresse",
"Airport": "Flughafen", "Airport": "Flughafen",
"Adult": "Erwachsener",
"Adults": "Erwachsene",
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle unsere Frühstücksbuffets bieten glutenfreie, vegane und allergikerfreundliche Speisen.", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle unsere Frühstücksbuffets bieten glutenfreie, vegane und allergikerfreundliche Speisen.",
"Already a friend?": "Sind wir schon Freunde?", "Already a friend?": "Sind wir schon Freunde?",
"Amenities": "Annehmlichkeiten", "Amenities": "Annehmlichkeiten",
@@ -44,6 +46,8 @@
"Check in": "Einchecken", "Check in": "Einchecken",
"Check out": "Auschecken", "Check out": "Auschecken",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sehen Sie sich die in Ihrem Profil gespeicherten Kreditkarten an. Bezahlen Sie mit einer gespeicherten Karte, wenn Sie angemeldet sind, für ein reibungsloseres Web-Erlebnis.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sehen Sie sich die in Ihrem Profil gespeicherten Kreditkarten an. Bezahlen Sie mit einer gespeicherten Karte, wenn Sie angemeldet sind, für ein reibungsloseres Web-Erlebnis.",
"Child": "Kind",
"Children": "Kinder",
"Choose room": "Zimmer wählen", "Choose room": "Zimmer wählen",
"Cities": "Städte", "Cities": "Städte",
"City": "Stadt", "City": "Stadt",
@@ -123,6 +127,9 @@
"How it works": "Wie es funktioniert", "How it works": "Wie es funktioniert",
"I would like to get my booking confirmation via sms": "Ich möchte meine Buchungsbestätigung per SMS erhalten", "I would like to get my booking confirmation via sms": "Ich möchte meine Buchungsbestätigung per SMS erhalten",
"Image gallery": "Bildergalerie", "Image gallery": "Bildergalerie",
"In adults bed": "Im Bett der Eltern",
"In crib": "im Kinderbett",
"In extra bed": "im zusätzlichen Bett",
"Included": "Iinklusive", "Included": "Iinklusive",
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Es ist derzeit nicht möglich, Ihre Kommunikationseinstellungen zu verwalten. Bitte versuchen Sie es später erneut oder wenden Sie sich an den Support, wenn das Problem weiterhin besteht.", "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Es ist derzeit nicht möglich, Ihre Kommunikationseinstellungen zu verwalten. Bitte versuchen Sie es später erneut oder wenden Sie sich an den Support, wenn das Problem weiterhin besteht.",
"Join Scandic Friends": "Treten Sie Scandic Friends bei", "Join Scandic Friends": "Treten Sie Scandic Friends bei",
@@ -225,6 +232,7 @@
"Room & Terms": "Zimmer & Bedingungen", "Room & Terms": "Zimmer & Bedingungen",
"Room facilities": "Zimmerausstattung", "Room facilities": "Zimmerausstattung",
"Rooms": "Räume", "Rooms": "Räume",
"Room": "Zimmer",
"Rooms & Guests": "Zimmer & Gäste", "Rooms & Guests": "Zimmer & Gäste",
"Sauna and gym": "Sauna and gym", "Sauna and gym": "Sauna and gym",
"Save": "Speichern", "Save": "Speichern",

View File

@@ -9,6 +9,9 @@
"Add new card": "Add new card", "Add new card": "Add new card",
"Address": "Address", "Address": "Address",
"Airport": "Airport", "Airport": "Airport",
"Adult": "Adult",
"Adults": "Adults",
"Age": "Age",
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.",
"Already a friend?": "Already a friend?", "Already a friend?": "Already a friend?",
"Amenities": "Amenities", "Amenities": "Amenities",
@@ -27,6 +30,7 @@
"Attractions": "Attractions", "Attractions": "Attractions",
"Back to scandichotels.com": "Back to scandichotels.com", "Back to scandichotels.com": "Back to scandichotels.com",
"Bar": "Bar", "Bar": "Bar",
"Bed": "Bed",
"Bed type": "Bed type", "Bed type": "Bed type",
"Birth date": "Birth date", "Birth date": "Birth date",
"Book": "Book", "Book": "Book",
@@ -44,6 +48,8 @@
"Check in": "Check in", "Check in": "Check in",
"Check out": "Check out", "Check out": "Check out",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.",
"Child": "Child",
"Children": "Children",
"Choose room": "Choose room", "Choose room": "Choose room",
"Cities": "Cities", "Cities": "Cities",
"City": "City", "City": "City",
@@ -123,6 +129,9 @@
"How it works": "How it works", "How it works": "How it works",
"I would like to get my booking confirmation via sms": "I would like to get my booking confirmation via sms", "I would like to get my booking confirmation via sms": "I would like to get my booking confirmation via sms",
"Image gallery": "Image gallery", "Image gallery": "Image gallery",
"In adults bed": "In adults bed",
"In crib": "In crib",
"In extra bed": "In extra bed",
"Included": "Included", "Included": "Included",
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.", "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.",
"Join Scandic Friends": "Join Scandic Friends", "Join Scandic Friends": "Join Scandic Friends",
@@ -224,6 +233,7 @@
"Retype new password": "Retype new password", "Retype new password": "Retype new password",
"Room & Terms": "Room & Terms", "Room & Terms": "Room & Terms",
"Room facilities": "Room facilities", "Room facilities": "Room facilities",
"Room": "Room",
"Rooms": "Rooms", "Rooms": "Rooms",
"Rooms & Guests": "Rooms & Guests", "Rooms & Guests": "Rooms & Guests",
"Sauna and gym": "Sauna and gym", "Sauna and gym": "Sauna and gym",

View File

@@ -9,6 +9,8 @@
"Add new card": "Lisää uusi kortti", "Add new card": "Lisää uusi kortti",
"Address": "Osoite", "Address": "Osoite",
"Airport": "Lentokenttä", "Airport": "Lentokenttä",
"Adult": "Aikuinen",
"Adults": "Aikuista",
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Kaikki aamiaisbuffettimme tarjoavat gluteenittomia, vegaanisia ja allergiaystävällisiä vaihtoehtoja.", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Kaikki aamiaisbuffettimme tarjoavat gluteenittomia, vegaanisia ja allergiaystävällisiä vaihtoehtoja.",
"Already a friend?": "Oletko jo ystävä?", "Already a friend?": "Oletko jo ystävä?",
"Amenities": "Mukavuudet", "Amenities": "Mukavuudet",
@@ -44,6 +46,8 @@
"Check in": "Sisäänkirjautuminen", "Check in": "Sisäänkirjautuminen",
"Check out": "Uloskirjautuminen", "Check out": "Uloskirjautuminen",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tarkista profiiliisi tallennetut luottokortit. Maksa tallennetulla kortilla kirjautuneena, jotta verkkokokemus on sujuvampi.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Tarkista profiiliisi tallennetut luottokortit. Maksa tallennetulla kortilla kirjautuneena, jotta verkkokokemus on sujuvampi.",
"Child": "Lapsi",
"Children": "Lasta",
"Choose room": "Valitse huone", "Choose room": "Valitse huone",
"Cities": "Kaupungit", "Cities": "Kaupungit",
"City": "Kaupunki", "City": "Kaupunki",
@@ -123,6 +127,9 @@
"How it works": "Kuinka se toimii", "How it works": "Kuinka se toimii",
"I would like to get my booking confirmation via sms": "Haluan saada varauksen vahvistuksen SMS-viestillä", "I would like to get my booking confirmation via sms": "Haluan saada varauksen vahvistuksen SMS-viestillä",
"Image gallery": "Kuvagalleria", "Image gallery": "Kuvagalleria",
"In adults bed": "Aikuisten vuoteessa",
"In crib": "Pinnasängyssä",
"In extra bed": "Oma vuodepaikka",
"Included": "Sisälly hintaan", "Included": "Sisälly hintaan",
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Viestintäasetuksiasi ei voi hallita juuri nyt. Yritä myöhemmin uudelleen tai ota yhteyttä tukeen, jos ongelma jatkuu.", "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Viestintäasetuksiasi ei voi hallita juuri nyt. Yritä myöhemmin uudelleen tai ota yhteyttä tukeen, jos ongelma jatkuu.",
"Join Scandic Friends": "Liity jäseneksi", "Join Scandic Friends": "Liity jäseneksi",
@@ -224,6 +231,7 @@
"Retype new password": "Kirjoita uusi salasana uudelleen", "Retype new password": "Kirjoita uusi salasana uudelleen",
"Room & Terms": "Huone & Ehdot", "Room & Terms": "Huone & Ehdot",
"Room facilities": "Huoneen varustelu", "Room facilities": "Huoneen varustelu",
"Room": "Huone",
"Rooms": "Huoneet", "Rooms": "Huoneet",
"Rooms & Guests": "Huoneet & Vieraat", "Rooms & Guests": "Huoneet & Vieraat",
"Rooms & Guestss": "Huoneet & Vieraat", "Rooms & Guestss": "Huoneet & Vieraat",

View File

@@ -9,6 +9,8 @@
"Add new card": "Legg til nytt kort", "Add new card": "Legg til nytt kort",
"Address": "Adresse", "Address": "Adresse",
"Airport": "Flyplass", "Airport": "Flyplass",
"Adult": "Voksen",
"Adults": "Voksne",
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle våre frokostbufféer tilbyr glutenfrie, veganske og allergivennlige alternativer.", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle våre frokostbufféer tilbyr glutenfrie, veganske og allergivennlige alternativer.",
"Already a friend?": "Allerede Friend?", "Already a friend?": "Allerede Friend?",
"Amenities": "Fasiliteter", "Amenities": "Fasiliteter",
@@ -44,6 +46,8 @@
"Check in": "Sjekk inn", "Check in": "Sjekk inn",
"Check out": "Sjekk ut", "Check out": "Sjekk ut",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sjekk ut kredittkortene som er lagret på profilen din. Betal med et lagret kort når du er pålogget for en jevnere nettopplevelse.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Sjekk ut kredittkortene som er lagret på profilen din. Betal med et lagret kort når du er pålogget for en jevnere nettopplevelse.",
"Child": "Barn",
"Children": "Barn",
"Choose room": "Velg rom", "Choose room": "Velg rom",
"Cities": "Byer", "Cities": "Byer",
"City": "By", "City": "By",
@@ -121,6 +125,9 @@
"How do you want to sleep?": "Hvordan vil du sove?", "How do you want to sleep?": "Hvordan vil du sove?",
"How it works": "Hvordan det fungerer", "How it works": "Hvordan det fungerer",
"Image gallery": "Bildegalleri", "Image gallery": "Bildegalleri",
"In adults bed": "i voksnes seng",
"In crib": "i sprinkelseng",
"In extra bed": "i ekstraseng",
"Included": "Inkludert", "Included": "Inkludert",
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det er ikke mulig å administrere kommunikasjonspreferansene dine akkurat nå, prøv igjen senere eller kontakt support hvis problemet vedvarer.", "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det er ikke mulig å administrere kommunikasjonspreferansene dine akkurat nå, prøv igjen senere eller kontakt support hvis problemet vedvarer.",
"Join Scandic Friends": "Bli med i Scandic Friends", "Join Scandic Friends": "Bli med i Scandic Friends",
@@ -222,6 +229,7 @@
"Retype new password": "Skriv inn nytt passord på nytt", "Retype new password": "Skriv inn nytt passord på nytt",
"Room & Terms": "Rom & Vilkår", "Room & Terms": "Rom & Vilkår",
"Room facilities": "Romfasiliteter", "Room facilities": "Romfasiliteter",
"Room": "Rom",
"Rooms": "Rom", "Rooms": "Rom",
"Rooms & Guests": "Rom og gjester", "Rooms & Guests": "Rom og gjester",
"Sauna and gym": "Sauna and gym", "Sauna and gym": "Sauna and gym",

View File

@@ -9,6 +9,8 @@
"Add new card": "Lägg till nytt kort", "Add new card": "Lägg till nytt kort",
"Address": "Adress", "Address": "Adress",
"Airport": "Flygplats", "Airport": "Flygplats",
"Adult": "Vuxen",
"Adults": "Vuxna",
"All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alla våra frukostbufféer erbjuder glutenfria, veganska och allergivänliga alternativ.", "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alla våra frukostbufféer erbjuder glutenfria, veganska och allergivänliga alternativ.",
"Already a friend?": "Är du redan en vän?", "Already a friend?": "Är du redan en vän?",
"Amenities": "Bekvämligheter", "Amenities": "Bekvämligheter",
@@ -44,6 +46,8 @@
"Check in": "Checka in", "Check in": "Checka in",
"Check out": "Checka ut", "Check out": "Checka ut",
"Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Kolla in kreditkorten som sparats i din profil. Betala med ett sparat kort när du är inloggad för en smidigare webbupplevelse.", "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.": "Kolla in kreditkorten som sparats i din profil. Betala med ett sparat kort när du är inloggad för en smidigare webbupplevelse.",
"Child": "Barn",
"Children": "Barn",
"Choose room": "Välj rum", "Choose room": "Välj rum",
"Cities": "Städer", "Cities": "Städer",
"City": "Ort", "City": "Ort",
@@ -121,6 +125,9 @@
"How do you want to sleep?": "Hur vill du sova?", "How do you want to sleep?": "Hur vill du sova?",
"How it works": "Hur det fungerar", "How it works": "Hur det fungerar",
"Image gallery": "Bildgalleri", "Image gallery": "Bildgalleri",
"In adults bed": "I vuxens säng",
"In crib": "I spjälsäng",
"In extra bed": "Egen sängplats",
"Included": "Inkluderad", "Included": "Inkluderad",
"It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det gick inte att hantera dina kommunikationsinställningar just nu, försök igen senare eller kontakta supporten om problemet kvarstår.", "It is not posible to manage your communication preferences right now, please try again later or contact support if the problem persists.": "Det gick inte att hantera dina kommunikationsinställningar just nu, försök igen senare eller kontakta supporten om problemet kvarstår.",
"Join Scandic Friends": "Gå med i Scandic Friends", "Join Scandic Friends": "Gå med i Scandic Friends",
@@ -222,6 +229,7 @@
"Retype new password": "Upprepa nytt lösenord", "Retype new password": "Upprepa nytt lösenord",
"Room & Terms": "Rum & Villkor", "Room & Terms": "Rum & Villkor",
"Room facilities": "Rumfaciliteter", "Room facilities": "Rumfaciliteter",
"Room": "Rum",
"Rooms": "Rum", "Rooms": "Rum",
"Rooms & Guests": "Rum och gäster", "Rooms & Guests": "Rum och gäster",
"Sauna and gym": "Sauna and gym", "Sauna and gym": "Sauna and gym",
@@ -315,7 +323,6 @@
"Zoo": "Djurpark", "Zoo": "Djurpark",
"Zoom in": "Zooma in", "Zoom in": "Zooma in",
"Zoom out": "Zooma ut", "Zoom out": "Zooma ut",
"as of today": "från och med idag",
"booking.adults": "{totalAdults, plural, one {# vuxen} other {# vuxna}}", "booking.adults": "{totalAdults, plural, one {# vuxen} other {# vuxna}}",
"booking.guests": "Max {nrOfGuests, plural, one {# gäst} other {# gäster}}", "booking.guests": "Max {nrOfGuests, plural, one {# gäst} other {# gäster}}",
"booking.nights": "{totalNights, plural, one {# natt} other {# nätter}}", "booking.nights": "{totalNights, plural, one {# natt} other {# nätter}}",
@@ -340,7 +347,6 @@
"special character": "speciell karaktär", "special character": "speciell karaktär",
"spendable points expiring by": "{points} poäng förfaller {date}", "spendable points expiring by": "{points} poäng förfaller {date}",
"to": "till", "to": "till",
"uppercase letter": "stor bokstav",
"{amount} {currency}": "{amount} {currency}", "{amount} {currency}": "{amount} {currency}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}", "{difference}{amount} {currency}": "{difference}{amount} {currency}",
"{width} cm × {length} cm": "{width} cm × {length} cm" "{width} cm × {length} cm": "{width} cm × {length} cm"

View File

@@ -0,0 +1,41 @@
export type ChildBed = {
label: string
value: number
}
export type Child = {
age: number
bed: number
}
export type GuestsRoom = {
adults: number
children: Child[]
}
export type GuestsRoomsFormProps = {
name?: string
}
export interface GuestsRoomsPickerProps {
handleOnSelect: (selected: GuestsRoom[]) => void
initialSelected?: GuestsRoom[]
closePicker: () => void
}
export type GuestsRoomPickerProps = {
handleOnSelect: (selected: GuestsRoom, index: number) => void
room: GuestsRoom
index: number
}
export type AdultSelectorProps = {
adults: number
updateAdults: (count: number) => void
}
export type ChildSelectorProps = {
roomChildren: Child[]
adultCount: number
updateChildren: (children: Child[]) => void
}