Merged in feat/SW-431-payment-flow (pull request #635)
Feat/SW-431 payment flow * feat(SW-431): Update mock hotel data * feat(SW-431): Added route handler and trpc routes * feat(SW-431): List payment methods and handle booking status and redirection * feat(SW-431): Updated booking page to poll for booking status * feat(SW-431): Updated create booking contract * feat(SW-431): small fix * fix(SW-431): Added intl string and sorted dictionaries * fix(SW-431): Changes from PR * fix(SW-431): fixes from PR * fix(SW-431): add todo comments * fix(SW-431): update schema prop Approved-by: Simon.Emanuelsson
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
|
import { notFound } from "next/navigation"
|
||||||
|
|
||||||
import { serverClient } from "@/lib/trpc/server"
|
import { serverClient } from "@/lib/trpc/server"
|
||||||
import { getHotelDataSchema } from "@/server/routers/hotels/output"
|
|
||||||
import tempHotelData from "@/server/routers/hotels/tempHotelData.json"
|
|
||||||
|
|
||||||
import HotelSelectionHeader from "@/components/HotelReservation/HotelSelectionHeader"
|
import HotelSelectionHeader from "@/components/HotelReservation/HotelSelectionHeader"
|
||||||
import BedSelection from "@/components/HotelReservation/SelectRate/BedSelection"
|
import BedSelection from "@/components/HotelReservation/SelectRate/BedSelection"
|
||||||
@@ -80,12 +80,19 @@ export default async function SectionsPage({
|
|||||||
}: PageArgs<LangParams & { section: string }, SectionPageProps>) {
|
}: PageArgs<LangParams & { section: string }, SectionPageProps>) {
|
||||||
setLang(params.lang)
|
setLang(params.lang)
|
||||||
|
|
||||||
// TODO: Use real endpoint.
|
const hotel = await serverClient().hotel.hotelData.get({
|
||||||
const hotel = getHotelDataSchema.parse(tempHotelData)
|
hotelId: "811",
|
||||||
|
language: params.lang,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!hotel) {
|
||||||
|
// TODO: handle case with hotel missing
|
||||||
|
return notFound()
|
||||||
|
}
|
||||||
|
|
||||||
const rooms = await serverClient().hotel.rates.get({
|
const rooms = await serverClient().hotel.rates.get({
|
||||||
// TODO: pass the correct hotel ID and all other parameters that should be included in the search
|
// TODO: pass the correct hotel ID and all other parameters that should be included in the search
|
||||||
hotelId: "1",
|
hotelId: hotel.data.id,
|
||||||
})
|
})
|
||||||
const intl = await getIntl()
|
const intl = await getIntl()
|
||||||
|
|
||||||
@@ -170,7 +177,9 @@ export default async function SectionsPage({
|
|||||||
header={intl.formatMessage({ id: "Payment info" })}
|
header={intl.formatMessage({ id: "Payment info" })}
|
||||||
path={`payment?${currentSearchParams}`}
|
path={`payment?${currentSearchParams}`}
|
||||||
>
|
>
|
||||||
{params.section === "payment" && <Payment />}
|
{params.section === "payment" && (
|
||||||
|
<Payment hotel={hotel.data.attributes} />
|
||||||
|
)}
|
||||||
</SectionAccordion>
|
</SectionAccordion>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.summary}>
|
<div className={styles.summary}>
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||||
|
|
||||||
|
export default function Loading() {
|
||||||
|
return <LoadingSpinner />
|
||||||
|
}
|
||||||
@@ -1,20 +1,67 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { useMemo } from "react"
|
||||||
|
|
||||||
|
import {
|
||||||
|
BOOKING_CONFIRMATION_NUMBER,
|
||||||
|
BookingStatusEnum,
|
||||||
|
} from "@/constants/booking"
|
||||||
|
|
||||||
import IntroSection from "@/components/HotelReservation/BookingConfirmation/IntroSection"
|
import IntroSection from "@/components/HotelReservation/BookingConfirmation/IntroSection"
|
||||||
import StaySection from "@/components/HotelReservation/BookingConfirmation/StaySection"
|
import StaySection from "@/components/HotelReservation/BookingConfirmation/StaySection"
|
||||||
import SummarySection from "@/components/HotelReservation/BookingConfirmation/SummarySection"
|
import SummarySection from "@/components/HotelReservation/BookingConfirmation/SummarySection"
|
||||||
import { tempConfirmationData } from "@/components/HotelReservation/BookingConfirmation/tempConfirmationData"
|
import { tempConfirmationData } from "@/components/HotelReservation/BookingConfirmation/tempConfirmationData"
|
||||||
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||||
|
import { useHandleBookingStatus } from "@/hooks/booking/useHandleBookingStatus"
|
||||||
|
|
||||||
import styles from "./page.module.css"
|
import styles from "./page.module.css"
|
||||||
|
|
||||||
|
const maxRetries = 10
|
||||||
|
const retryInterval = 2000
|
||||||
|
|
||||||
export default function BookingConfirmationPage() {
|
export default function BookingConfirmationPage() {
|
||||||
const { email, hotel, stay, summary } = tempConfirmationData
|
const { email, hotel, stay, summary } = tempConfirmationData
|
||||||
|
|
||||||
return (
|
const confirmationNumber = useMemo(() => {
|
||||||
<main className={styles.main}>
|
if (typeof window === "undefined") return ""
|
||||||
<section className={styles.section}>
|
|
||||||
<IntroSection email={email} />
|
const storedConfirmationNumber = sessionStorage.getItem(
|
||||||
<StaySection hotel={hotel} stay={stay} />
|
BOOKING_CONFIRMATION_NUMBER
|
||||||
<SummarySection summary={summary} />
|
)
|
||||||
</section>
|
// TODO: cleanup stored values
|
||||||
</main>
|
// sessionStorage.removeItem(BOOKING_CONFIRMATION_NUMBER)
|
||||||
|
return storedConfirmationNumber
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const bookingStatus = useHandleBookingStatus(
|
||||||
|
confirmationNumber,
|
||||||
|
BookingStatusEnum.BookingCompleted,
|
||||||
|
maxRetries,
|
||||||
|
retryInterval
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
confirmationNumber === null ||
|
||||||
|
bookingStatus.isError ||
|
||||||
|
(bookingStatus.isFetched && !bookingStatus.data)
|
||||||
|
) {
|
||||||
|
// TODO: handle error
|
||||||
|
throw new Error("Error fetching booking status")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
bookingStatus.data?.reservationStatus === BookingStatusEnum.BookingCompleted
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
<main className={styles.main}>
|
||||||
|
<section className={styles.section}>
|
||||||
|
<IntroSection email={email} />
|
||||||
|
<StaySection hotel={hotel} stay={stay} />
|
||||||
|
<SummarySection summary={summary} />
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <LoadingSpinner />
|
||||||
}
|
}
|
||||||
|
|||||||
37
app/api/web/payment-callback/[lang]/[status]/route.ts
Normal file
37
app/api/web/payment-callback/[lang]/[status]/route.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { NextRequest, NextResponse } from "next/server"
|
||||||
|
import { env } from "process"
|
||||||
|
|
||||||
|
import { Lang } from "@/constants/languages"
|
||||||
|
import {
|
||||||
|
bookingConfirmation,
|
||||||
|
payment,
|
||||||
|
} from "@/constants/routes/hotelReservation"
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: NextRequest,
|
||||||
|
{ params }: { params: { lang: string; status: string } }
|
||||||
|
): Promise<NextResponse> {
|
||||||
|
console.log(`[payment-callback] callback started`)
|
||||||
|
const lang = params.lang as Lang
|
||||||
|
const status = params.status
|
||||||
|
const returnUrl = new URL(`${env.PUBLIC_URL}/${payment[lang]}`)
|
||||||
|
|
||||||
|
if (status === "success") {
|
||||||
|
const confirmationUrl = new URL(
|
||||||
|
`${env.PUBLIC_URL}/${bookingConfirmation[lang]}`
|
||||||
|
)
|
||||||
|
console.log(`[payment-callback] redirecting to: ${confirmationUrl}`)
|
||||||
|
return NextResponse.redirect(confirmationUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === "cancel") {
|
||||||
|
returnUrl.searchParams.set("cancel", "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status === "error") {
|
||||||
|
returnUrl.searchParams.set("error", "true")
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[payment-callback] redirecting to: ${returnUrl}`)
|
||||||
|
return NextResponse.redirect(returnUrl)
|
||||||
|
}
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import Button from "@/components/TempDesignSystem/Button"
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
import Link from "@/components/TempDesignSystem/Link"
|
import Link from "@/components/TempDesignSystem/Link"
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
import Subtitle from "@/components/TempDesignSystem/Text/Subtitle"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
import { getIntl } from "@/i18n"
|
|
||||||
|
|
||||||
import styles from "./introSection.module.css"
|
import styles from "./introSection.module.css"
|
||||||
|
|
||||||
import { IntroSectionProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
|
import { IntroSectionProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
|
||||||
|
|
||||||
export default async function IntroSection({ email }: IntroSectionProps) {
|
export default function IntroSection({ email }: IntroSectionProps) {
|
||||||
const intl = await getIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={styles.section}>
|
<section className={styles.section}>
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import { ArrowRightIcon, ScandicLogoIcon } from "@/components/Icons"
|
import { ArrowRightIcon, ScandicLogoIcon } from "@/components/Icons"
|
||||||
import Image from "@/components/Image"
|
import Image from "@/components/Image"
|
||||||
import Body from "@/components/TempDesignSystem/Text/Body"
|
import Body from "@/components/TempDesignSystem/Text/Body"
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
import { getIntl } from "@/i18n"
|
|
||||||
|
|
||||||
import styles from "./staySection.module.css"
|
import styles from "./staySection.module.css"
|
||||||
|
|
||||||
import { StaySectionProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
|
import { StaySectionProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
|
||||||
|
|
||||||
export default async function StaySection({ hotel, stay }: StaySectionProps) {
|
export default function StaySection({ hotel, stay }: StaySectionProps) {
|
||||||
const intl = await getIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
const nightsText =
|
const nightsText =
|
||||||
stay.nights > 1
|
stay.nights > 1
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
import Caption from "@/components/TempDesignSystem/Text/Caption"
|
||||||
import Title from "@/components/TempDesignSystem/Text/Title"
|
import Title from "@/components/TempDesignSystem/Text/Title"
|
||||||
import { getIntl } from "@/i18n"
|
|
||||||
|
|
||||||
import styles from "./summarySection.module.css"
|
import styles from "./summarySection.module.css"
|
||||||
|
|
||||||
import { SummarySectionProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
|
import { SummarySectionProps } from "@/types/components/hotelReservation/bookingConfirmation/bookingConfirmation"
|
||||||
|
|
||||||
export default async function SummarySection({ summary }: SummarySectionProps) {
|
export default function SummarySection({ summary }: SummarySectionProps) {
|
||||||
const intl = await getIntl()
|
const intl = useIntl()
|
||||||
const roomType = `${intl.formatMessage({ id: "Type of room" })}: ${summary.roomType}`
|
const roomType = `${intl.formatMessage({ id: "Type of room" })}: ${summary.roomType}`
|
||||||
const bedType = `${intl.formatMessage({ id: "Type of bed" })}: ${summary.bedType}`
|
const bedType = `${intl.formatMessage({ id: "Type of bed" })}: ${summary.bedType}`
|
||||||
const breakfast = `${intl.formatMessage({ id: "Breakfast" })}: ${summary.breakfast}`
|
const breakfast = `${intl.formatMessage({ id: "Breakfast" })}: ${summary.breakfast}`
|
||||||
|
|||||||
@@ -1,62 +1,161 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import { useRouter } from "next/navigation"
|
||||||
|
import { useEffect, useState } from "react"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import {
|
||||||
|
BOOKING_CONFIRMATION_NUMBER,
|
||||||
|
BookingStatusEnum,
|
||||||
|
} from "@/constants/booking"
|
||||||
import { trpc } from "@/lib/trpc/client"
|
import { trpc } from "@/lib/trpc/client"
|
||||||
|
|
||||||
|
import LoadingSpinner from "@/components/LoadingSpinner"
|
||||||
import Button from "@/components/TempDesignSystem/Button"
|
import Button from "@/components/TempDesignSystem/Button"
|
||||||
|
import { toast } from "@/components/TempDesignSystem/Toasts"
|
||||||
|
import { useHandleBookingStatus } from "@/hooks/booking/useHandleBookingStatus"
|
||||||
|
import useLang from "@/hooks/useLang"
|
||||||
|
|
||||||
|
import styles from "./payment.module.css"
|
||||||
|
|
||||||
|
import { PaymentProps } from "@/types/components/hotelReservation/selectRate/section"
|
||||||
|
|
||||||
|
const maxRetries = 40
|
||||||
|
const retryInterval = 2000
|
||||||
|
|
||||||
|
export default function Payment({ hotel }: PaymentProps) {
|
||||||
|
const router = useRouter()
|
||||||
|
const lang = useLang()
|
||||||
|
const intl = useIntl()
|
||||||
|
const [confirmationNumber, setConfirmationNumber] = useState<string>("")
|
||||||
|
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState<string>("")
|
||||||
|
|
||||||
export default function Payment() {
|
|
||||||
const initiateBooking = trpc.booking.booking.create.useMutation({
|
const initiateBooking = trpc.booking.booking.create.useMutation({
|
||||||
onSuccess: (result) => {
|
onSuccess: (result) => {
|
||||||
// TODO: Handle success, poll for payment link and redirect the user to the payment
|
if (result?.confirmationNumber) {
|
||||||
console.log("Res", result)
|
// Planet doesn't support query params so we have to store values in session storage
|
||||||
|
sessionStorage.setItem(
|
||||||
|
BOOKING_CONFIRMATION_NUMBER,
|
||||||
|
result.confirmationNumber
|
||||||
|
)
|
||||||
|
|
||||||
|
setConfirmationNumber(result.confirmationNumber)
|
||||||
|
} else {
|
||||||
|
// TODO: add proper error message
|
||||||
|
toast.error("Failed to create booking")
|
||||||
|
}
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: (error) => {
|
||||||
// TODO: Handle error
|
console.error("Error", error)
|
||||||
console.log("Error")
|
// TODO: add proper error message
|
||||||
|
toast.error("Failed to create booking")
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
const bookingStatus = useHandleBookingStatus(
|
||||||
<Button
|
confirmationNumber,
|
||||||
onClick={() =>
|
BookingStatusEnum.PaymentRegistered,
|
||||||
// TODO: Use real values
|
maxRetries,
|
||||||
initiateBooking.mutate({
|
retryInterval
|
||||||
hotelId: "811",
|
)
|
||||||
checkInDate: "2024-12-10",
|
|
||||||
checkOutDate: "2024-12-11",
|
useEffect(() => {
|
||||||
rooms: [
|
if (bookingStatus?.data?.paymentUrl) {
|
||||||
{
|
router.push(bookingStatus.data.paymentUrl)
|
||||||
adults: 1,
|
}
|
||||||
children: 0,
|
}, [bookingStatus, router])
|
||||||
rateCode: "SAVEEU",
|
|
||||||
roomTypeCode: "QC",
|
function handleSubmit() {
|
||||||
guest: {
|
initiateBooking.mutate({
|
||||||
title: "Mr",
|
hotelId: hotel.operaId,
|
||||||
firstName: "Test",
|
checkInDate: "2024-12-10",
|
||||||
lastName: "User",
|
checkOutDate: "2024-12-11",
|
||||||
email: "test.user@scandichotels.com",
|
rooms: [
|
||||||
phoneCountryCodePrefix: "string",
|
{
|
||||||
phoneNumber: "string",
|
adults: 1,
|
||||||
countryCode: "string",
|
childrenAges: [],
|
||||||
},
|
rateCode: "SAVEEU",
|
||||||
smsConfirmationRequested: true,
|
roomTypeCode: "QC",
|
||||||
},
|
guest: {
|
||||||
],
|
title: "Mr",
|
||||||
payment: {
|
firstName: "Test",
|
||||||
cardHolder: {
|
lastName: "User",
|
||||||
Email: "test.user@scandichotels.com",
|
email: "test.user@scandichotels.com",
|
||||||
Name: "Test User",
|
phoneCountryCodePrefix: "string",
|
||||||
PhoneCountryCode: "",
|
phoneNumber: "string",
|
||||||
PhoneSubscriber: "",
|
countryCode: "string",
|
||||||
},
|
|
||||||
success: "success/handle",
|
|
||||||
error: "error/handle",
|
|
||||||
cancel: "cancel/handle",
|
|
||||||
},
|
},
|
||||||
})
|
packages: {
|
||||||
}
|
breakfast: true,
|
||||||
>
|
allergyFriendly: true,
|
||||||
Create booking
|
petFriendly: true,
|
||||||
</Button>
|
accessibility: true,
|
||||||
|
},
|
||||||
|
smsConfirmationRequested: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
payment: {
|
||||||
|
paymentMethod: selectedPaymentMethod,
|
||||||
|
cardHolder: {
|
||||||
|
email: "test.user@scandichotels.com",
|
||||||
|
name: "Test User",
|
||||||
|
phoneCountryCode: "",
|
||||||
|
phoneSubscriber: "",
|
||||||
|
},
|
||||||
|
success: `api/web/payment-callback/${lang}/success`,
|
||||||
|
error: `api/web/payment-callback/${lang}/error`,
|
||||||
|
cancel: `api/web/payment-callback/${lang}/cancel`,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
initiateBooking.isPending ||
|
||||||
|
(confirmationNumber && !bookingStatus.data?.paymentUrl)
|
||||||
|
) {
|
||||||
|
return <LoadingSpinner />
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<div className={styles.paymentItemContainer}>
|
||||||
|
<button
|
||||||
|
className={styles.paymentItem}
|
||||||
|
onClick={() => setSelectedPaymentMethod("card")}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="payment-method"
|
||||||
|
id="card"
|
||||||
|
value="card"
|
||||||
|
checked={selectedPaymentMethod === "card"}
|
||||||
|
/>
|
||||||
|
<label htmlFor="card">card</label>
|
||||||
|
</button>
|
||||||
|
{hotel.merchantInformationData.alternatePaymentOptions.map(
|
||||||
|
(paymentOption) => (
|
||||||
|
<button
|
||||||
|
key={paymentOption}
|
||||||
|
className={styles.paymentItem}
|
||||||
|
onClick={() => setSelectedPaymentMethod(paymentOption)}
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="radio"
|
||||||
|
name="payment-method"
|
||||||
|
id={paymentOption}
|
||||||
|
value={paymentOption}
|
||||||
|
checked={selectedPaymentMethod === paymentOption}
|
||||||
|
/>
|
||||||
|
<label htmlFor={paymentOption}>{paymentOption}</label>
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Button disabled={!selectedPaymentMethod} onClick={handleSubmit}>
|
||||||
|
{intl.formatMessage({ id: "Complete booking & go to payment" })}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
.paymentItemContainer {
|
||||||
|
max-width: 480px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--Spacing-x1);
|
||||||
|
padding-bottom: var(--Spacing-x4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.paymentItem {
|
||||||
|
background-color: var(--Base-Background-Normal);
|
||||||
|
padding: var(--Spacing-x3);
|
||||||
|
border: 1px solid var(--Base-Border-Normal);
|
||||||
|
border-radius: var(--Corner-radius-Medium);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--Spacing-x2);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
7
constants/booking.ts
Normal file
7
constants/booking.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export enum BookingStatusEnum {
|
||||||
|
CreatedInOhip = "CreatedInOhip",
|
||||||
|
PaymentRegistered = "PaymentRegistered",
|
||||||
|
BookingCompleted = "BookingCompleted",
|
||||||
|
}
|
||||||
|
|
||||||
|
export const BOOKING_CONFIRMATION_NUMBER = "bookingConfirmationNumber"
|
||||||
@@ -28,4 +28,24 @@ export const selectHotelMap = {
|
|||||||
de: `${selectHotel.de}/map`,
|
de: `${selectHotel.de}/map`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @type {import('@/types/routes').LangRoute} */
|
||||||
|
export const payment = {
|
||||||
|
en: `${hotelReservation.en}/payment`,
|
||||||
|
sv: `${hotelReservation.sv}/betalning`,
|
||||||
|
no: `${hotelReservation.no}/betaling`,
|
||||||
|
fi: `${hotelReservation.fi}/maksu`,
|
||||||
|
da: `${hotelReservation.da}/payment`,
|
||||||
|
de: `${hotelReservation.de}/bezahlung`,
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {import('@/types/routes').LangRoute} */
|
||||||
|
export const bookingConfirmation = {
|
||||||
|
en: `${hotelReservation.en}/booking-confirmation`,
|
||||||
|
sv: `${hotelReservation.sv}/bokningsbekraftelse`,
|
||||||
|
no: `${hotelReservation.no}/booking-confirmation`,
|
||||||
|
fi: `${hotelReservation.fi}/varausvahvistus`,
|
||||||
|
da: `${hotelReservation.da}/booking-confirmation`,
|
||||||
|
de: `${hotelReservation.de}/buchungsbesttigung`,
|
||||||
|
}
|
||||||
|
|
||||||
export const bookingFlow = [...Object.values(hotelReservation)]
|
export const bookingFlow = [...Object.values(hotelReservation)]
|
||||||
|
|||||||
35
hooks/booking/useHandleBookingStatus.ts
Normal file
35
hooks/booking/useHandleBookingStatus.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { BookingStatusEnum } from "@/constants/booking"
|
||||||
|
import { trpc } from "@/lib/trpc/client"
|
||||||
|
|
||||||
|
export function useHandleBookingStatus(
|
||||||
|
confirmationNumber: string | null,
|
||||||
|
expectedStatus: BookingStatusEnum,
|
||||||
|
maxRetries: number,
|
||||||
|
retryInterval: number
|
||||||
|
) {
|
||||||
|
const query = trpc.booking.status.useQuery(
|
||||||
|
{ confirmationNumber: confirmationNumber ?? "" },
|
||||||
|
{
|
||||||
|
enabled: !!confirmationNumber,
|
||||||
|
refetchInterval: (query) => {
|
||||||
|
if (query.state.error || query.state.dataUpdateCount >= maxRetries) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.state.data?.reservationStatus === expectedStatus) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return retryInterval
|
||||||
|
},
|
||||||
|
refetchIntervalInBackground: true,
|
||||||
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
retry: false,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return query
|
||||||
|
}
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
"Any changes you've made will be lost.": "Alle ændringer, du har foretaget, går tabt.",
|
"Any changes you've made will be lost.": "Alle ændringer, du har foretaget, går tabt.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Er du sikker på, at du vil fjerne kortet, der slutter me {lastFourDigits} fra din medlemsprofil?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Er du sikker på, at du vil fjerne kortet, der slutter me {lastFourDigits} fra din medlemsprofil?",
|
||||||
"Arrival date": "Ankomstdato",
|
"Arrival date": "Ankomstdato",
|
||||||
|
"as of today": "fra idag",
|
||||||
"As our": "Som vores {level}",
|
"As our": "Som vores {level}",
|
||||||
"As our Close Friend": "Som vores nære ven",
|
"As our Close Friend": "Som vores nære ven",
|
||||||
"At latest": "Senest",
|
"At latest": "Senest",
|
||||||
@@ -23,14 +24,16 @@
|
|||||||
"Bed type": "Seng type",
|
"Bed type": "Seng type",
|
||||||
"Book": "Book",
|
"Book": "Book",
|
||||||
"Book reward night": "Book bonusnat",
|
"Book reward night": "Book bonusnat",
|
||||||
"Code / Voucher": "Bookingkoder / voucher",
|
|
||||||
"Booking number": "Bookingnummer",
|
"Booking number": "Bookingnummer",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# nat} other {# nætter}}",
|
||||||
"Breakfast": "Morgenmad",
|
"Breakfast": "Morgenmad",
|
||||||
"Breakfast excluded": "Morgenmad ikke inkluderet",
|
"Breakfast excluded": "Morgenmad ikke inkluderet",
|
||||||
"Breakfast included": "Morgenmad inkluderet",
|
"Breakfast included": "Morgenmad inkluderet",
|
||||||
"Bus terminal": "Busstation",
|
"Bus terminal": "Busstation",
|
||||||
"Business": "Forretning",
|
"Business": "Forretning",
|
||||||
|
"by": "inden",
|
||||||
"Cancel": "Afbestille",
|
"Cancel": "Afbestille",
|
||||||
|
"characters": "tegn",
|
||||||
"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.",
|
||||||
@@ -45,8 +48,10 @@
|
|||||||
"Close menu": "Luk menu",
|
"Close menu": "Luk menu",
|
||||||
"Close my pages menu": "Luk mine sider menu",
|
"Close my pages menu": "Luk mine sider menu",
|
||||||
"Close the map": "Luk kortet",
|
"Close the map": "Luk kortet",
|
||||||
|
"Code / Voucher": "Bookingkoder / voucher",
|
||||||
"Coming up": "Er lige om hjørnet",
|
"Coming up": "Er lige om hjørnet",
|
||||||
"Compare all levels": "Sammenlign alle niveauer",
|
"Compare all levels": "Sammenlign alle niveauer",
|
||||||
|
"Complete booking & go to payment": "Udfyld booking & gå til betaling",
|
||||||
"Contact us": "Kontakt os",
|
"Contact us": "Kontakt os",
|
||||||
"Continue": "Blive ved",
|
"Continue": "Blive ved",
|
||||||
"Copyright all rights reserved": "Scandic AB Alle rettigheder forbeholdes",
|
"Copyright all rights reserved": "Scandic AB Alle rettigheder forbeholdes",
|
||||||
@@ -72,9 +77,9 @@
|
|||||||
"Explore all levels and benefits": "Udforsk alle niveauer og fordele",
|
"Explore all levels and benefits": "Udforsk alle niveauer og fordele",
|
||||||
"Explore nearby": "Udforsk i nærheden",
|
"Explore nearby": "Udforsk i nærheden",
|
||||||
"Extras to your booking": "Tillæg til din booking",
|
"Extras to your booking": "Tillæg til din booking",
|
||||||
"FAQ": "Ofte stillede spørgsmål",
|
|
||||||
"Failed to delete credit card, please try again later.": "Kunne ikke slette kreditkort. Prøv venligst igen senere.",
|
"Failed to delete credit card, please try again later.": "Kunne ikke slette kreditkort. Prøv venligst igen senere.",
|
||||||
"Fair": "Messe",
|
"Fair": "Messe",
|
||||||
|
"FAQ": "Ofte stillede spørgsmål",
|
||||||
"Find booking": "Find booking",
|
"Find booking": "Find booking",
|
||||||
"Find hotels": "Find hotel",
|
"Find hotels": "Find hotel",
|
||||||
"Flexibility": "Fleksibilitet",
|
"Flexibility": "Fleksibilitet",
|
||||||
@@ -85,17 +90,22 @@
|
|||||||
"Get inspired": "Bliv inspireret",
|
"Get inspired": "Bliv inspireret",
|
||||||
"Go back to edit": "Gå tilbage til redigering",
|
"Go back to edit": "Gå tilbage til redigering",
|
||||||
"Go back to overview": "Gå tilbage til oversigten",
|
"Go back to overview": "Gå tilbage til oversigten",
|
||||||
|
"Guests & Rooms": "Gæster & værelser",
|
||||||
"Hi": "Hei",
|
"Hi": "Hei",
|
||||||
"Highest level": "Højeste niveau",
|
"Highest level": "Højeste niveau",
|
||||||
"Hospital": "Hospital",
|
"Hospital": "Hospital",
|
||||||
"Hotel": "Hotel",
|
"Hotel": "Hotel",
|
||||||
"Hotel facilities": "Hotel faciliteter",
|
"Hotel facilities": "Hotel faciliteter",
|
||||||
"Hotel surroundings": "Hotel omgivelser",
|
"Hotel surroundings": "Hotel omgivelser",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "personer",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Se værelsesdetaljer",
|
||||||
"Hotels": "Hoteller",
|
"Hotels": "Hoteller",
|
||||||
"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 virker",
|
"How it works": "Hvordan det virker",
|
||||||
"Image gallery": "Billedgalleri",
|
"Image gallery": "Billedgalleri",
|
||||||
"Join Scandic Friends": "Tilmeld dig Scandic Friends",
|
"Join Scandic Friends": "Tilmeld dig Scandic Friends",
|
||||||
|
"km to city center": "km til byens centrum",
|
||||||
"Language": "Sprog",
|
"Language": "Sprog",
|
||||||
"Latest searches": "Seneste søgninger",
|
"Latest searches": "Seneste søgninger",
|
||||||
"Level": "Niveau",
|
"Level": "Niveau",
|
||||||
@@ -122,9 +132,9 @@
|
|||||||
"Member price": "Medlemspris",
|
"Member price": "Medlemspris",
|
||||||
"Member price from": "Medlemspris fra",
|
"Member price from": "Medlemspris fra",
|
||||||
"Members": "Medlemmer",
|
"Members": "Medlemmer",
|
||||||
|
"Membership cards": "Medlemskort",
|
||||||
"Membership ID": "Medlems-id",
|
"Membership ID": "Medlems-id",
|
||||||
"Membership ID copied to clipboard": "Medlems-ID kopieret til udklipsholder",
|
"Membership ID copied to clipboard": "Medlems-ID kopieret til udklipsholder",
|
||||||
"Membership cards": "Medlemskort",
|
|
||||||
"Menu": "Menu",
|
"Menu": "Menu",
|
||||||
"Modify": "Ændre",
|
"Modify": "Ændre",
|
||||||
"Month": "Måned",
|
"Month": "Måned",
|
||||||
@@ -139,6 +149,9 @@
|
|||||||
"Nearby companies": "Nærliggende virksomheder",
|
"Nearby companies": "Nærliggende virksomheder",
|
||||||
"New password": "Nyt kodeord",
|
"New password": "Nyt kodeord",
|
||||||
"Next": "Næste",
|
"Next": "Næste",
|
||||||
|
"next level:": "Næste niveau:",
|
||||||
|
"night": "nat",
|
||||||
|
"nights": "nætter",
|
||||||
"Nights needed to level up": "Nætter nødvendige for at komme i niveau",
|
"Nights needed to level up": "Nætter nødvendige for at komme i niveau",
|
||||||
"No content published": "Intet indhold offentliggjort",
|
"No content published": "Intet indhold offentliggjort",
|
||||||
"No matching location found": "Der blev ikke fundet nogen matchende placering",
|
"No matching location found": "Der blev ikke fundet nogen matchende placering",
|
||||||
@@ -149,11 +162,13 @@
|
|||||||
"Non-refundable": "Ikke-refunderbart",
|
"Non-refundable": "Ikke-refunderbart",
|
||||||
"Not found": "Ikke fundet",
|
"Not found": "Ikke fundet",
|
||||||
"Nr night, nr adult": "{nights, number} nat, {adults, number} voksen",
|
"Nr night, nr adult": "{nights, number} nat, {adults, number} voksen",
|
||||||
|
"number": "nummer",
|
||||||
"On your journey": "På din rejse",
|
"On your journey": "På din rejse",
|
||||||
"Open": "Åben",
|
"Open": "Åben",
|
||||||
"Open language menu": "Åbn sprogmenuen",
|
"Open language menu": "Åbn sprogmenuen",
|
||||||
"Open menu": "Åbn menuen",
|
"Open menu": "Åbn menuen",
|
||||||
"Open my pages menu": "Åbn mine sider menuen",
|
"Open my pages menu": "Åbn mine sider menuen",
|
||||||
|
"or": "eller",
|
||||||
"Overview": "Oversigt",
|
"Overview": "Oversigt",
|
||||||
"Parking": "Parkering",
|
"Parking": "Parkering",
|
||||||
"Parking / Garage": "Parkering / Garage",
|
"Parking / Garage": "Parkering / Garage",
|
||||||
@@ -165,6 +180,7 @@
|
|||||||
"Phone is required": "Telefonnummer er påkrævet",
|
"Phone is required": "Telefonnummer er påkrævet",
|
||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Indtast venligst et gyldigt telefonnummer",
|
"Please enter a valid phone number": "Indtast venligst et gyldigt telefonnummer",
|
||||||
|
"points": "Point",
|
||||||
"Points": "Point",
|
"Points": "Point",
|
||||||
"Points being calculated": "Point udregnes",
|
"Points being calculated": "Point udregnes",
|
||||||
"Points earned prior to May 1, 2021": "Point optjent inden 1. maj 2021",
|
"Points earned prior to May 1, 2021": "Point optjent inden 1. maj 2021",
|
||||||
@@ -183,7 +199,6 @@
|
|||||||
"Room & Terms": "Værelse & Vilkår",
|
"Room & Terms": "Værelse & Vilkår",
|
||||||
"Room facilities": "Værelsesfaciliteter",
|
"Room facilities": "Værelsesfaciliteter",
|
||||||
"Rooms": "Værelser",
|
"Rooms": "Værelser",
|
||||||
"Guests & Rooms": "Gæster & værelser",
|
|
||||||
"Save": "Gemme",
|
"Save": "Gemme",
|
||||||
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
||||||
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
||||||
@@ -208,25 +223,29 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Noget gik galt, og vi kunne ikke tilføje dit kort. Prøv venligst igen senere.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Noget gik galt, og vi kunne ikke tilføje dit kort. Prøv venligst igen senere.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Noget gik galt, og vi kunne ikke fjerne dit kort. Prøv venligst igen senere.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Noget gik galt, og vi kunne ikke fjerne dit kort. Prøv venligst igen senere.",
|
||||||
"Something went wrong!": "Noget gik galt!",
|
"Something went wrong!": "Noget gik galt!",
|
||||||
|
"special character": "speciel karakter",
|
||||||
|
"spendable points expiring by": "{points} Brugbare point udløber den {date}",
|
||||||
"Sports": "Sport",
|
"Sports": "Sport",
|
||||||
"Standard price": "Standardpris",
|
"Standard price": "Standardpris",
|
||||||
"Street": "Gade",
|
"Street": "Gade",
|
||||||
"Successfully updated profile!": "Profilen er opdateret med succes!",
|
"Successfully updated profile!": "Profilen er opdateret med succes!",
|
||||||
"Summary": "Opsummering",
|
"Summary": "Opsummering",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Fortæl os, hvilke oplysninger og opdateringer du gerne vil modtage, og hvordan, ved at klikke på linket nedenfor.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Fortæl os, hvilke oplysninger og opdateringer du gerne vil modtage, og hvordan, ved at klikke på linket nedenfor.",
|
||||||
"Thank you": "Tak",
|
"Thank you": "Tak",
|
||||||
"Theatre": "Teater",
|
"Theatre": "Teater",
|
||||||
"There are no transactions to display": "Der er ingen transaktioner at vise",
|
"There are no transactions to display": "Der er ingen transaktioner at vise",
|
||||||
"Things nearby HOTEL_NAME": "Ting i nærheden af {hotelName}",
|
"Things nearby HOTEL_NAME": "Ting i nærheden af {hotelName}",
|
||||||
|
"to": "til",
|
||||||
"Total Points": "Samlet antal point",
|
"Total Points": "Samlet antal point",
|
||||||
"Tourist": "Turist",
|
"Tourist": "Turist",
|
||||||
"Transaction date": "Overførselsdato",
|
"Transaction date": "Overførselsdato",
|
||||||
"Transactions": "Transaktioner",
|
"Transactions": "Transaktioner",
|
||||||
"Transportations": "Transport",
|
"Transportations": "Transport",
|
||||||
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Sengtype",
|
"Type of bed": "Sengtype",
|
||||||
"Type of room": "Værelsestype",
|
"Type of room": "Værelsestype",
|
||||||
|
"uppercase letter": "stort bogstav",
|
||||||
"Use bonus cheque": "Brug Bonus Cheque",
|
"Use bonus cheque": "Brug Bonus Cheque",
|
||||||
"User information": "Brugeroplysninger",
|
"User information": "Brugeroplysninger",
|
||||||
"View as list": "Vis som liste",
|
"View as list": "Vis som liste",
|
||||||
@@ -252,9 +271,9 @@
|
|||||||
"You canceled adding a new credit card.": "Du har annulleret tilføjelsen af et nyt kreditkort.",
|
"You canceled adding a new credit card.": "Du har annulleret tilføjelsen af et nyt kreditkort.",
|
||||||
"You have no previous stays.": "Du har ingen tidligere ophold.",
|
"You have no previous stays.": "Du har ingen tidligere ophold.",
|
||||||
"You have no upcoming stays.": "Du har ingen kommende ophold.",
|
"You have no upcoming stays.": "Du har ingen kommende ophold.",
|
||||||
"Your Challenges Conquer & Earn!": "Dine udfordringer Overvind og tjen!",
|
|
||||||
"Your card was successfully removed!": "Dit kort blev fjernet!",
|
"Your card was successfully removed!": "Dit kort blev fjernet!",
|
||||||
"Your card was successfully saved!": "Dit kort blev gemt!",
|
"Your card was successfully saved!": "Dit kort blev gemt!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Dine udfordringer Overvind og tjen!",
|
||||||
"Your current level": "Dit nuværende niveau",
|
"Your current level": "Dit nuværende niveau",
|
||||||
"Your details": "Dine oplysninger",
|
"Your details": "Dine oplysninger",
|
||||||
"Your level": "Dit niveau",
|
"Your level": "Dit niveau",
|
||||||
@@ -262,23 +281,5 @@
|
|||||||
"Zip code": "Postnummer",
|
"Zip code": "Postnummer",
|
||||||
"Zoo": "Zoo",
|
"Zoo": "Zoo",
|
||||||
"Zoom in": "Zoom ind",
|
"Zoom in": "Zoom ind",
|
||||||
"Zoom out": "Zoom ud",
|
"Zoom out": "Zoom ud"
|
||||||
"as of today": "pr. dags dato",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# nat} other {# nætter}}",
|
|
||||||
"by": "inden",
|
|
||||||
"characters": "tegn",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "personer",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Se værelsesdetaljer",
|
|
||||||
"km to city center": "km til byens centrum",
|
|
||||||
"next level:": "Næste niveau:",
|
|
||||||
"night": "nat",
|
|
||||||
"nights": "nætter",
|
|
||||||
"number": "nummer",
|
|
||||||
"or": "eller",
|
|
||||||
"points": "Point",
|
|
||||||
"special character": "speciel karakter",
|
|
||||||
"spendable points expiring by": "{points} Brugbare point udløber den {date}",
|
|
||||||
"to": "til",
|
|
||||||
"uppercase letter": "stort bogstav"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"Any changes you've made will be lost.": "Alle Änderungen, die Sie vorgenommen haben, gehen verloren.",
|
"Any changes you've made will be lost.": "Alle Änderungen, die Sie vorgenommen haben, gehen verloren.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Möchten Sie die Karte mit der Endung {lastFourDigits} wirklich aus Ihrem Mitgliedsprofil entfernen?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Möchten Sie die Karte mit der Endung {lastFourDigits} wirklich aus Ihrem Mitgliedsprofil entfernen?",
|
||||||
"Arrival date": "Ankunftsdatum",
|
"Arrival date": "Ankunftsdatum",
|
||||||
|
"as of today": "Stand heute",
|
||||||
"As our": "Als unser {level}",
|
"As our": "Als unser {level}",
|
||||||
"As our Close Friend": "Als unser enger Freund",
|
"As our Close Friend": "Als unser enger Freund",
|
||||||
"At latest": "Spätestens",
|
"At latest": "Spätestens",
|
||||||
@@ -23,14 +24,16 @@
|
|||||||
"Bed type": "Bettentyp",
|
"Bed type": "Bettentyp",
|
||||||
"Book": "Buchen",
|
"Book": "Buchen",
|
||||||
"Book reward night": "Bonusnacht buchen",
|
"Book reward night": "Bonusnacht buchen",
|
||||||
"Code / Voucher": "Buchungscodes / Gutscheine",
|
|
||||||
"Booking number": "Buchungsnummer",
|
"Booking number": "Buchungsnummer",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# nacht} other {# Nächte}}",
|
||||||
"Breakfast": "Frühstück",
|
"Breakfast": "Frühstück",
|
||||||
"Breakfast excluded": "Frühstück nicht inbegriffen",
|
"Breakfast excluded": "Frühstück nicht inbegriffen",
|
||||||
"Breakfast included": "Frühstück inbegriffen",
|
"Breakfast included": "Frühstück inbegriffen",
|
||||||
"Bus terminal": "Busbahnhof",
|
"Bus terminal": "Busbahnhof",
|
||||||
"Business": "Geschäft",
|
"Business": "Geschäft",
|
||||||
|
"by": "bis",
|
||||||
"Cancel": "Stornieren",
|
"Cancel": "Stornieren",
|
||||||
|
"characters": "figuren",
|
||||||
"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.",
|
||||||
@@ -45,8 +48,10 @@
|
|||||||
"Close menu": "Menü schließen",
|
"Close menu": "Menü schließen",
|
||||||
"Close my pages menu": "Meine Seiten Menü schließen",
|
"Close my pages menu": "Meine Seiten Menü schließen",
|
||||||
"Close the map": "Karte schließen",
|
"Close the map": "Karte schließen",
|
||||||
|
"Code / Voucher": "Buchungscodes / Gutscheine",
|
||||||
"Coming up": "Demnächst",
|
"Coming up": "Demnächst",
|
||||||
"Compare all levels": "Vergleichen Sie alle Levels",
|
"Compare all levels": "Vergleichen Sie alle Levels",
|
||||||
|
"Complete booking & go to payment": "Buchung abschließen & zur Bezahlung gehen",
|
||||||
"Contact us": "Kontaktieren Sie uns",
|
"Contact us": "Kontaktieren Sie uns",
|
||||||
"Continue": "Weitermachen",
|
"Continue": "Weitermachen",
|
||||||
"Copyright all rights reserved": "Scandic AB Alle Rechte vorbehalten",
|
"Copyright all rights reserved": "Scandic AB Alle Rechte vorbehalten",
|
||||||
@@ -72,9 +77,9 @@
|
|||||||
"Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile",
|
"Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile",
|
||||||
"Explore nearby": "Erkunden Sie die Umgebung",
|
"Explore nearby": "Erkunden Sie die Umgebung",
|
||||||
"Extras to your booking": "Extras zu Ihrer Buchung",
|
"Extras to your booking": "Extras zu Ihrer Buchung",
|
||||||
"FAQ": "Häufig gestellte Fragen",
|
|
||||||
"Failed to delete credit card, please try again later.": "Kreditkarte konnte nicht gelöscht werden. Bitte versuchen Sie es später noch einmal.",
|
"Failed to delete credit card, please try again later.": "Kreditkarte konnte nicht gelöscht werden. Bitte versuchen Sie es später noch einmal.",
|
||||||
"Fair": "Messe",
|
"Fair": "Messe",
|
||||||
|
"FAQ": "Häufig gestellte Fragen",
|
||||||
"Find booking": "Buchung finden",
|
"Find booking": "Buchung finden",
|
||||||
"Find hotels": "Hotels finden",
|
"Find hotels": "Hotels finden",
|
||||||
"Flexibility": "Flexibilität",
|
"Flexibility": "Flexibilität",
|
||||||
@@ -85,17 +90,22 @@
|
|||||||
"Get inspired": "Lassen Sie sich inspieren",
|
"Get inspired": "Lassen Sie sich inspieren",
|
||||||
"Go back to edit": "Zurück zum Bearbeiten",
|
"Go back to edit": "Zurück zum Bearbeiten",
|
||||||
"Go back to overview": "Zurück zur Übersicht",
|
"Go back to overview": "Zurück zur Übersicht",
|
||||||
|
"Guests & Rooms": "Gäste & Zimmer",
|
||||||
"Hi": "Hallo",
|
"Hi": "Hallo",
|
||||||
"Highest level": "Höchstes Level",
|
"Highest level": "Höchstes Level",
|
||||||
"Hospital": "Krankenhaus",
|
"Hospital": "Krankenhaus",
|
||||||
"Hotel": "Hotel",
|
"Hotel": "Hotel",
|
||||||
"Hotel facilities": "Hotel-Infos",
|
"Hotel facilities": "Hotel-Infos",
|
||||||
"Hotel surroundings": "Umgebung des Hotels",
|
"Hotel surroundings": "Umgebung des Hotels",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "personen",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Zimmerdetails ansehen",
|
||||||
"Hotels": "Hotels",
|
"Hotels": "Hotels",
|
||||||
"How do you want to sleep?": "Wie möchtest du schlafen?",
|
"How do you want to sleep?": "Wie möchtest du schlafen?",
|
||||||
"How it works": "Wie es funktioniert",
|
"How it works": "Wie es funktioniert",
|
||||||
"Image gallery": "Bildergalerie",
|
"Image gallery": "Bildergalerie",
|
||||||
"Join Scandic Friends": "Treten Sie Scandic Friends bei",
|
"Join Scandic Friends": "Treten Sie Scandic Friends bei",
|
||||||
|
"km to city center": "km bis zum Stadtzentrum",
|
||||||
"Language": "Sprache",
|
"Language": "Sprache",
|
||||||
"Latest searches": "Letzte Suchanfragen",
|
"Latest searches": "Letzte Suchanfragen",
|
||||||
"Level": "Level",
|
"Level": "Level",
|
||||||
@@ -122,9 +132,9 @@
|
|||||||
"Member price": "Mitgliederpreis",
|
"Member price": "Mitgliederpreis",
|
||||||
"Member price from": "Mitgliederpreis ab",
|
"Member price from": "Mitgliederpreis ab",
|
||||||
"Members": "Mitglieder",
|
"Members": "Mitglieder",
|
||||||
|
"Membership cards": "Mitgliedskarten",
|
||||||
"Membership ID": "Mitglieds-ID",
|
"Membership ID": "Mitglieds-ID",
|
||||||
"Membership ID copied to clipboard": "Mitglieds-ID in die Zwischenablage kopiert",
|
"Membership ID copied to clipboard": "Mitglieds-ID in die Zwischenablage kopiert",
|
||||||
"Membership cards": "Mitgliedskarten",
|
|
||||||
"Menu": "Menu",
|
"Menu": "Menu",
|
||||||
"Modify": "Ändern",
|
"Modify": "Ändern",
|
||||||
"Month": "Monat",
|
"Month": "Monat",
|
||||||
@@ -139,6 +149,9 @@
|
|||||||
"Nearby companies": "Nahe gelegene Unternehmen",
|
"Nearby companies": "Nahe gelegene Unternehmen",
|
||||||
"New password": "Neues Kennwort",
|
"New password": "Neues Kennwort",
|
||||||
"Next": "Nächste",
|
"Next": "Nächste",
|
||||||
|
"next level:": "Nächstes Level:",
|
||||||
|
"night": "nacht",
|
||||||
|
"nights": "Nächte",
|
||||||
"Nights needed to level up": "Nächte, die zum Levelaufstieg benötigt werden",
|
"Nights needed to level up": "Nächte, die zum Levelaufstieg benötigt werden",
|
||||||
"No content published": "Kein Inhalt veröffentlicht",
|
"No content published": "Kein Inhalt veröffentlicht",
|
||||||
"No matching location found": "Kein passender Standort gefunden",
|
"No matching location found": "Kein passender Standort gefunden",
|
||||||
@@ -149,11 +162,13 @@
|
|||||||
"Non-refundable": "Nicht erstattungsfähig",
|
"Non-refundable": "Nicht erstattungsfähig",
|
||||||
"Not found": "Nicht gefunden",
|
"Not found": "Nicht gefunden",
|
||||||
"Nr night, nr adult": "{nights, number} Nacht, {adults, number} Erwachsener",
|
"Nr night, nr adult": "{nights, number} Nacht, {adults, number} Erwachsener",
|
||||||
|
"number": "nummer",
|
||||||
"On your journey": "Auf deiner Reise",
|
"On your journey": "Auf deiner Reise",
|
||||||
"Open": "Offen",
|
"Open": "Offen",
|
||||||
"Open language menu": "Sprachmenü öffnen",
|
"Open language menu": "Sprachmenü öffnen",
|
||||||
"Open menu": "Menü öffnen",
|
"Open menu": "Menü öffnen",
|
||||||
"Open my pages menu": "Meine Seiten Menü öffnen",
|
"Open my pages menu": "Meine Seiten Menü öffnen",
|
||||||
|
"or": "oder",
|
||||||
"Overview": "Übersicht",
|
"Overview": "Übersicht",
|
||||||
"Parking": "Parken",
|
"Parking": "Parken",
|
||||||
"Parking / Garage": "Parken / Garage",
|
"Parking / Garage": "Parken / Garage",
|
||||||
@@ -164,6 +179,7 @@
|
|||||||
"Phone is required": "Telefon ist erforderlich",
|
"Phone is required": "Telefon ist erforderlich",
|
||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Bitte geben Sie eine gültige Telefonnummer ein",
|
"Please enter a valid phone number": "Bitte geben Sie eine gültige Telefonnummer ein",
|
||||||
|
"points": "Punkte",
|
||||||
"Points": "Punkte",
|
"Points": "Punkte",
|
||||||
"Points being calculated": "Punkte werden berechnet",
|
"Points being calculated": "Punkte werden berechnet",
|
||||||
"Points earned prior to May 1, 2021": "Zusammengeführte Punkte vor dem 1. Mai 2021",
|
"Points earned prior to May 1, 2021": "Zusammengeführte Punkte vor dem 1. Mai 2021",
|
||||||
@@ -182,7 +198,6 @@
|
|||||||
"Room & Terms": "Zimmer & Bedingungen",
|
"Room & Terms": "Zimmer & Bedingungen",
|
||||||
"Room facilities": "Zimmerausstattung",
|
"Room facilities": "Zimmerausstattung",
|
||||||
"Rooms": "Räume",
|
"Rooms": "Räume",
|
||||||
"Guests & Rooms": "Gäste & Zimmer",
|
|
||||||
"Save": "Speichern",
|
"Save": "Speichern",
|
||||||
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
||||||
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
||||||
@@ -207,25 +222,29 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Ein Fehler ist aufgetreten und wir konnten Ihre Karte nicht hinzufügen. Bitte versuchen Sie es später erneut.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Ein Fehler ist aufgetreten und wir konnten Ihre Karte nicht hinzufügen. Bitte versuchen Sie es später erneut.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Ein Fehler ist aufgetreten und wir konnten Ihre Karte nicht entfernen. Bitte versuchen Sie es später noch einmal.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Ein Fehler ist aufgetreten und wir konnten Ihre Karte nicht entfernen. Bitte versuchen Sie es später noch einmal.",
|
||||||
"Something went wrong!": "Etwas ist schief gelaufen!",
|
"Something went wrong!": "Etwas ist schief gelaufen!",
|
||||||
|
"special character": "sonderzeichen",
|
||||||
|
"spendable points expiring by": "{points} Einlösbare punkte verfallen bis zum {date}",
|
||||||
"Sports": "Sport",
|
"Sports": "Sport",
|
||||||
"Standard price": "Standardpreis",
|
"Standard price": "Standardpreis",
|
||||||
"Street": "Straße",
|
"Street": "Straße",
|
||||||
"Successfully updated profile!": "Profil erfolgreich aktualisiert!",
|
"Successfully updated profile!": "Profil erfolgreich aktualisiert!",
|
||||||
"Summary": "Zusammenfassung",
|
"Summary": "Zusammenfassung",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Teilen Sie uns mit, welche Informationen und Updates Sie wie erhalten möchten, indem Sie auf den unten stehenden Link klicken.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Teilen Sie uns mit, welche Informationen und Updates Sie wie erhalten möchten, indem Sie auf den unten stehenden Link klicken.",
|
||||||
"Thank you": "Danke",
|
"Thank you": "Danke",
|
||||||
"Theatre": "Theater",
|
"Theatre": "Theater",
|
||||||
"There are no transactions to display": "Es sind keine Transaktionen zum Anzeigen vorhanden",
|
"There are no transactions to display": "Es sind keine Transaktionen zum Anzeigen vorhanden",
|
||||||
"Things nearby HOTEL_NAME": "Dinge in der Nähe von {hotelName}",
|
"Things nearby HOTEL_NAME": "Dinge in der Nähe von {hotelName}",
|
||||||
|
"to": "zu",
|
||||||
"Total Points": "Gesamtpunktzahl",
|
"Total Points": "Gesamtpunktzahl",
|
||||||
"Tourist": "Tourist",
|
"Tourist": "Tourist",
|
||||||
"Transaction date": "Transaktionsdatum",
|
"Transaction date": "Transaktionsdatum",
|
||||||
"Transactions": "Transaktionen",
|
"Transactions": "Transaktionen",
|
||||||
"Transportations": "Transportmittel",
|
"Transportations": "Transportmittel",
|
||||||
"Tripadvisor reviews": "{rating} ({count} Bewertungen auf Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} Bewertungen auf Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Bettentyp",
|
"Type of bed": "Bettentyp",
|
||||||
"Type of room": "Zimmerart",
|
"Type of room": "Zimmerart",
|
||||||
|
"uppercase letter": "großbuchstabe",
|
||||||
"Use bonus cheque": "Bonusscheck nutzen",
|
"Use bonus cheque": "Bonusscheck nutzen",
|
||||||
"User information": "Nutzerinformation",
|
"User information": "Nutzerinformation",
|
||||||
"View as list": "Als Liste anzeigen",
|
"View as list": "Als Liste anzeigen",
|
||||||
@@ -251,9 +270,9 @@
|
|||||||
"You canceled adding a new credit card.": "Sie haben das Hinzufügen einer neuen Kreditkarte abgebrochen.",
|
"You canceled adding a new credit card.": "Sie haben das Hinzufügen einer neuen Kreditkarte abgebrochen.",
|
||||||
"You have no previous stays.": "Sie haben keine vorherigen Aufenthalte.",
|
"You have no previous stays.": "Sie haben keine vorherigen Aufenthalte.",
|
||||||
"You have no upcoming stays.": "Sie haben keine bevorstehenden Aufenthalte.",
|
"You have no upcoming stays.": "Sie haben keine bevorstehenden Aufenthalte.",
|
||||||
"Your Challenges Conquer & Earn!": "Meistern Sie Ihre Herausforderungen und verdienen Sie Geld!",
|
|
||||||
"Your card was successfully removed!": "Ihre Karte wurde erfolgreich entfernt!",
|
"Your card was successfully removed!": "Ihre Karte wurde erfolgreich entfernt!",
|
||||||
"Your card was successfully saved!": "Ihre Karte wurde erfolgreich gespeichert!",
|
"Your card was successfully saved!": "Ihre Karte wurde erfolgreich gespeichert!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Meistern Sie Ihre Herausforderungen und verdienen Sie Geld!",
|
||||||
"Your current level": "Ihr aktuelles Level",
|
"Your current level": "Ihr aktuelles Level",
|
||||||
"Your details": "Ihre Angaben",
|
"Your details": "Ihre Angaben",
|
||||||
"Your level": "Dein level",
|
"Your level": "Dein level",
|
||||||
@@ -261,23 +280,5 @@
|
|||||||
"Zip code": "PLZ",
|
"Zip code": "PLZ",
|
||||||
"Zoo": "Zoo",
|
"Zoo": "Zoo",
|
||||||
"Zoom in": "Vergrößern",
|
"Zoom in": "Vergrößern",
|
||||||
"Zoom out": "Verkleinern",
|
"Zoom out": "Verkleinern"
|
||||||
"as of today": "Stand heute",
|
}
|
||||||
"booking.nights": "{totalNights, plural, one {# nacht} other {# Nächte}}",
|
|
||||||
"by": "bis",
|
|
||||||
"characters": "figuren",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "personen",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Zimmerdetails ansehen",
|
|
||||||
"km to city center": "km bis zum Stadtzentrum",
|
|
||||||
"next level:": "Nächstes Level:",
|
|
||||||
"night": "nacht",
|
|
||||||
"nights": "Nächte",
|
|
||||||
"number": "nummer",
|
|
||||||
"or": "oder",
|
|
||||||
"points": "Punkte",
|
|
||||||
"special character": "sonderzeichen",
|
|
||||||
"spendable points expiring by": "{points} Einlösbare punkte verfallen bis zum {date}",
|
|
||||||
"to": "zu",
|
|
||||||
"uppercase letter": "großbuchstabe"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"Any changes you've made will be lost.": "Any changes you've made will be lost.",
|
"Any changes you've made will be lost.": "Any changes you've made will be lost.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?",
|
||||||
"Arrival date": "Arrival date",
|
"Arrival date": "Arrival date",
|
||||||
|
"as of today": "as of today",
|
||||||
"As our": "As our {level}",
|
"As our": "As our {level}",
|
||||||
"As our Close Friend": "As our Close Friend",
|
"As our Close Friend": "As our Close Friend",
|
||||||
"At latest": "At latest",
|
"At latest": "At latest",
|
||||||
@@ -23,14 +24,18 @@
|
|||||||
"Bed type": "Bed type",
|
"Bed type": "Bed type",
|
||||||
"Book": "Book",
|
"Book": "Book",
|
||||||
"Book reward night": "Book reward night",
|
"Book reward night": "Book reward night",
|
||||||
"Code / Voucher": "Code / Voucher",
|
|
||||||
"Booking number": "Booking number",
|
"Booking number": "Booking number",
|
||||||
|
"booking.adults": "{totalAdults, plural, one {# adult} other {# adults}}",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# night} other {# nights}}",
|
||||||
|
"booking.rooms": "{totalRooms, plural, one {# room} other {# rooms}}",
|
||||||
"Breakfast": "Breakfast",
|
"Breakfast": "Breakfast",
|
||||||
"Breakfast excluded": "Breakfast excluded",
|
"Breakfast excluded": "Breakfast excluded",
|
||||||
"Breakfast included": "Breakfast included",
|
"Breakfast included": "Breakfast included",
|
||||||
"Bus terminal": "Bus terminal",
|
"Bus terminal": "Bus terminal",
|
||||||
"Business": "Business",
|
"Business": "Business",
|
||||||
|
"by": "by",
|
||||||
"Cancel": "Cancel",
|
"Cancel": "Cancel",
|
||||||
|
"characters": "characters",
|
||||||
"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.",
|
||||||
@@ -45,8 +50,10 @@
|
|||||||
"Close menu": "Close menu",
|
"Close menu": "Close menu",
|
||||||
"Close my pages menu": "Close my pages menu",
|
"Close my pages menu": "Close my pages menu",
|
||||||
"Close the map": "Close the map",
|
"Close the map": "Close the map",
|
||||||
|
"Code / Voucher": "Code / Voucher",
|
||||||
"Coming up": "Coming up",
|
"Coming up": "Coming up",
|
||||||
"Compare all levels": "Compare all levels",
|
"Compare all levels": "Compare all levels",
|
||||||
|
"Complete booking & go to payment": "Complete booking & go to payment",
|
||||||
"Contact us": "Contact us",
|
"Contact us": "Contact us",
|
||||||
"Continue": "Continue",
|
"Continue": "Continue",
|
||||||
"Copyright all rights reserved": "Scandic AB All rights reserved",
|
"Copyright all rights reserved": "Scandic AB All rights reserved",
|
||||||
@@ -59,8 +66,8 @@
|
|||||||
"Date of Birth": "Date of Birth",
|
"Date of Birth": "Date of Birth",
|
||||||
"Day": "Day",
|
"Day": "Day",
|
||||||
"Description": "Description",
|
"Description": "Description",
|
||||||
"Destinations & hotels": "Destinations & hotels",
|
|
||||||
"Destination": "Destination",
|
"Destination": "Destination",
|
||||||
|
"Destinations & hotels": "Destinations & hotels",
|
||||||
"Discard changes": "Discard changes",
|
"Discard changes": "Discard changes",
|
||||||
"Discard unsaved changes?": "Discard unsaved changes?",
|
"Discard unsaved changes?": "Discard unsaved changes?",
|
||||||
"Distance to city centre": "{number}km to city centre",
|
"Distance to city centre": "{number}km to city centre",
|
||||||
@@ -73,9 +80,9 @@
|
|||||||
"Explore all levels and benefits": "Explore all levels and benefits",
|
"Explore all levels and benefits": "Explore all levels and benefits",
|
||||||
"Explore nearby": "Explore nearby",
|
"Explore nearby": "Explore nearby",
|
||||||
"Extras to your booking": "Extras to your booking",
|
"Extras to your booking": "Extras to your booking",
|
||||||
"FAQ": "FAQ",
|
|
||||||
"Failed to delete credit card, please try again later.": "Failed to delete credit card, please try again later.",
|
"Failed to delete credit card, please try again later.": "Failed to delete credit card, please try again later.",
|
||||||
"Fair": "Fair",
|
"Fair": "Fair",
|
||||||
|
"FAQ": "FAQ",
|
||||||
"Find booking": "Find booking",
|
"Find booking": "Find booking",
|
||||||
"Find hotels": "Find hotels",
|
"Find hotels": "Find hotels",
|
||||||
"Flexibility": "Flexibility",
|
"Flexibility": "Flexibility",
|
||||||
@@ -86,17 +93,22 @@
|
|||||||
"Get inspired": "Get inspired",
|
"Get inspired": "Get inspired",
|
||||||
"Go back to edit": "Go back to edit",
|
"Go back to edit": "Go back to edit",
|
||||||
"Go back to overview": "Go back to overview",
|
"Go back to overview": "Go back to overview",
|
||||||
|
"Guests & Rooms": "Guests & Rooms",
|
||||||
"Hi": "Hi",
|
"Hi": "Hi",
|
||||||
"Highest level": "Highest level",
|
"Highest level": "Highest level",
|
||||||
"Hospital": "Hospital",
|
"Hospital": "Hospital",
|
||||||
"Hotel": "Hotel",
|
"Hotel": "Hotel",
|
||||||
"Hotel facilities": "Hotel facilities",
|
"Hotel facilities": "Hotel facilities",
|
||||||
"Hotel surroundings": "Hotel surroundings",
|
"Hotel surroundings": "Hotel surroundings",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "persons",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "See room details",
|
||||||
"Hotels": "Hotels",
|
"Hotels": "Hotels",
|
||||||
"How do you want to sleep?": "How do you want to sleep?",
|
"How do you want to sleep?": "How do you want to sleep?",
|
||||||
"How it works": "How it works",
|
"How it works": "How it works",
|
||||||
"Image gallery": "Image gallery",
|
"Image gallery": "Image gallery",
|
||||||
"Join Scandic Friends": "Join Scandic Friends",
|
"Join Scandic Friends": "Join Scandic Friends",
|
||||||
|
"km to city center": "km to city center",
|
||||||
"Language": "Language",
|
"Language": "Language",
|
||||||
"Latest searches": "Latest searches",
|
"Latest searches": "Latest searches",
|
||||||
"Level": "Level",
|
"Level": "Level",
|
||||||
@@ -123,9 +135,9 @@
|
|||||||
"Member price": "Member price",
|
"Member price": "Member price",
|
||||||
"Member price from": "Member price from",
|
"Member price from": "Member price from",
|
||||||
"Members": "Members",
|
"Members": "Members",
|
||||||
|
"Membership cards": "Membership cards",
|
||||||
"Membership ID": "Membership ID",
|
"Membership ID": "Membership ID",
|
||||||
"Membership ID copied to clipboard": "Membership ID copied to clipboard",
|
"Membership ID copied to clipboard": "Membership ID copied to clipboard",
|
||||||
"Membership cards": "Membership cards",
|
|
||||||
"Menu": "Menu",
|
"Menu": "Menu",
|
||||||
"Modify": "Modify",
|
"Modify": "Modify",
|
||||||
"Month": "Month",
|
"Month": "Month",
|
||||||
@@ -140,6 +152,9 @@
|
|||||||
"Nearby companies": "Nearby companies",
|
"Nearby companies": "Nearby companies",
|
||||||
"New password": "New password",
|
"New password": "New password",
|
||||||
"Next": "Next",
|
"Next": "Next",
|
||||||
|
"next level:": "next level:",
|
||||||
|
"night": "night",
|
||||||
|
"nights": "nights",
|
||||||
"Nights needed to level up": "Nights needed to level up",
|
"Nights needed to level up": "Nights needed to level up",
|
||||||
"No content published": "No content published",
|
"No content published": "No content published",
|
||||||
"No matching location found": "No matching location found",
|
"No matching location found": "No matching location found",
|
||||||
@@ -150,11 +165,13 @@
|
|||||||
"Non-refundable": "Non-refundable",
|
"Non-refundable": "Non-refundable",
|
||||||
"Not found": "Not found",
|
"Not found": "Not found",
|
||||||
"Nr night, nr adult": "{nights, number} night, {adults, number} adult",
|
"Nr night, nr adult": "{nights, number} night, {adults, number} adult",
|
||||||
|
"number": "number",
|
||||||
"On your journey": "On your journey",
|
"On your journey": "On your journey",
|
||||||
"Open": "Open",
|
"Open": "Open",
|
||||||
"Open language menu": "Open language menu",
|
"Open language menu": "Open language menu",
|
||||||
"Open menu": "Open menu",
|
"Open menu": "Open menu",
|
||||||
"Open my pages menu": "Open my pages menu",
|
"Open my pages menu": "Open my pages menu",
|
||||||
|
"or": "or",
|
||||||
"Overview": "Overview",
|
"Overview": "Overview",
|
||||||
"Parking": "Parking",
|
"Parking": "Parking",
|
||||||
"Parking / Garage": "Parking / Garage",
|
"Parking / Garage": "Parking / Garage",
|
||||||
@@ -166,6 +183,7 @@
|
|||||||
"Phone is required": "Phone is required",
|
"Phone is required": "Phone is required",
|
||||||
"Phone number": "Phone number",
|
"Phone number": "Phone number",
|
||||||
"Please enter a valid phone number": "Please enter a valid phone number",
|
"Please enter a valid phone number": "Please enter a valid phone number",
|
||||||
|
"points": "Points",
|
||||||
"Points": "Points",
|
"Points": "Points",
|
||||||
"Points being calculated": "Points being calculated",
|
"Points being calculated": "Points being calculated",
|
||||||
"Points earned prior to May 1, 2021": "Points earned prior to May 1, 2021",
|
"Points earned prior to May 1, 2021": "Points earned prior to May 1, 2021",
|
||||||
@@ -184,12 +202,11 @@
|
|||||||
"Room & Terms": "Room & Terms",
|
"Room & Terms": "Room & Terms",
|
||||||
"Room facilities": "Room facilities",
|
"Room facilities": "Room facilities",
|
||||||
"Rooms": "Rooms",
|
"Rooms": "Rooms",
|
||||||
"Guests & Rooms": "Guests & Rooms",
|
|
||||||
"Save": "Save",
|
"Save": "Save",
|
||||||
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
||||||
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
||||||
"See all photos": "See all photos",
|
|
||||||
"Search": "Search",
|
"Search": "Search",
|
||||||
|
"See all photos": "See all photos",
|
||||||
"See hotel details": "See hotel details",
|
"See hotel details": "See hotel details",
|
||||||
"See room details": "See room details",
|
"See room details": "See room details",
|
||||||
"See rooms": "See rooms",
|
"See rooms": "See rooms",
|
||||||
@@ -210,25 +227,29 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Something went wrong and we couldn't add your card. Please try again later.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Something went wrong and we couldn't add your card. Please try again later.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Something went wrong and we couldn't remove your card. Please try again later.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Something went wrong and we couldn't remove your card. Please try again later.",
|
||||||
"Something went wrong!": "Something went wrong!",
|
"Something went wrong!": "Something went wrong!",
|
||||||
|
"special character": "special character",
|
||||||
|
"spendable points expiring by": "{points} spendable points expiring by {date}",
|
||||||
"Sports": "Sports",
|
"Sports": "Sports",
|
||||||
"Standard price": "Standard price",
|
"Standard price": "Standard price",
|
||||||
"Street": "Street",
|
"Street": "Street",
|
||||||
"Successfully updated profile!": "Successfully updated profile!",
|
"Successfully updated profile!": "Successfully updated profile!",
|
||||||
"Summary": "Summary",
|
"Summary": "Summary",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Tell us what information and updates you'd like to receive, and how, by clicking the link below.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Tell us what information and updates you'd like to receive, and how, by clicking the link below.",
|
||||||
"Thank you": "Thank you",
|
"Thank you": "Thank you",
|
||||||
"Theatre": "Theatre",
|
"Theatre": "Theatre",
|
||||||
"There are no transactions to display": "There are no transactions to display",
|
"There are no transactions to display": "There are no transactions to display",
|
||||||
"Things nearby HOTEL_NAME": "Things nearby {hotelName}",
|
"Things nearby HOTEL_NAME": "Things nearby {hotelName}",
|
||||||
|
"to": "to",
|
||||||
"Total Points": "Total Points",
|
"Total Points": "Total Points",
|
||||||
"Tourist": "Tourist",
|
"Tourist": "Tourist",
|
||||||
"Transaction date": "Transaction date",
|
"Transaction date": "Transaction date",
|
||||||
"Transactions": "Transactions",
|
"Transactions": "Transactions",
|
||||||
"Transportations": "Transportations",
|
"Transportations": "Transportations",
|
||||||
"Tripadvisor reviews": "{rating} ({count} reviews on Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} reviews on Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Type of bed",
|
"Type of bed": "Type of bed",
|
||||||
"Type of room": "Type of room",
|
"Type of room": "Type of room",
|
||||||
|
"uppercase letter": "uppercase letter",
|
||||||
"Use bonus cheque": "Use bonus cheque",
|
"Use bonus cheque": "Use bonus cheque",
|
||||||
"User information": "User information",
|
"User information": "User information",
|
||||||
"View as list": "View as list",
|
"View as list": "View as list",
|
||||||
@@ -254,9 +275,9 @@
|
|||||||
"You canceled adding a new credit card.": "You canceled adding a new credit card.",
|
"You canceled adding a new credit card.": "You canceled adding a new credit card.",
|
||||||
"You have no previous stays.": "You have no previous stays.",
|
"You have no previous stays.": "You have no previous stays.",
|
||||||
"You have no upcoming stays.": "You have no upcoming stays.",
|
"You have no upcoming stays.": "You have no upcoming stays.",
|
||||||
"Your Challenges Conquer & Earn!": "Your Challenges Conquer & Earn!",
|
|
||||||
"Your card was successfully removed!": "Your card was successfully removed!",
|
"Your card was successfully removed!": "Your card was successfully removed!",
|
||||||
"Your card was successfully saved!": "Your card was successfully saved!",
|
"Your card was successfully saved!": "Your card was successfully saved!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Your Challenges Conquer & Earn!",
|
||||||
"Your current level": "Your current level",
|
"Your current level": "Your current level",
|
||||||
"Your details": "Your details",
|
"Your details": "Your details",
|
||||||
"Your level": "Your level",
|
"Your level": "Your level",
|
||||||
@@ -264,25 +285,5 @@
|
|||||||
"Zip code": "Zip code",
|
"Zip code": "Zip code",
|
||||||
"Zoo": "Zoo",
|
"Zoo": "Zoo",
|
||||||
"Zoom in": "Zoom in",
|
"Zoom in": "Zoom in",
|
||||||
"Zoom out": "Zoom out",
|
"Zoom out": "Zoom out"
|
||||||
"as of today": "as of today",
|
}
|
||||||
"booking.adults": "{totalAdults, plural, one {# adult} other {# adults}}",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# night} other {# nights}}",
|
|
||||||
"booking.rooms": "{totalRooms, plural, one {# room} other {# rooms}}",
|
|
||||||
"by": "by",
|
|
||||||
"characters": "characters",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "persons",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "See room details",
|
|
||||||
"km to city center": "km to city center",
|
|
||||||
"next level:": "next level:",
|
|
||||||
"night": "night",
|
|
||||||
"nights": "nights",
|
|
||||||
"number": "number",
|
|
||||||
"or": "or",
|
|
||||||
"points": "Points",
|
|
||||||
"special character": "special character",
|
|
||||||
"spendable points expiring by": "{points} spendable points expiring by {date}",
|
|
||||||
"to": "to",
|
|
||||||
"uppercase letter": "uppercase letter"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"Any changes you've made will be lost.": "Kaikki tekemäsi muutokset menetetään.",
|
"Any changes you've made will be lost.": "Kaikki tekemäsi muutokset menetetään.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Haluatko varmasti poistaa kortin, joka päättyy numeroon {lastFourDigits} jäsenprofiilistasi?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Haluatko varmasti poistaa kortin, joka päättyy numeroon {lastFourDigits} jäsenprofiilistasi?",
|
||||||
"Arrival date": "Saapumispäivä",
|
"Arrival date": "Saapumispäivä",
|
||||||
|
"as of today": "tänään",
|
||||||
"As our": "{level}-etu",
|
"As our": "{level}-etu",
|
||||||
"As our Close Friend": "Läheisenä ystävänämme",
|
"As our Close Friend": "Läheisenä ystävänämme",
|
||||||
"At latest": "Viimeistään",
|
"At latest": "Viimeistään",
|
||||||
@@ -24,12 +25,15 @@
|
|||||||
"Book": "Varaa",
|
"Book": "Varaa",
|
||||||
"Book reward night": "Kirjapalkinto-ilta",
|
"Book reward night": "Kirjapalkinto-ilta",
|
||||||
"Booking number": "Varausnumero",
|
"Booking number": "Varausnumero",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# yö} other {# yötä}}",
|
||||||
"Breakfast": "Aamiainen",
|
"Breakfast": "Aamiainen",
|
||||||
"Breakfast excluded": "Aamiainen ei sisälly",
|
"Breakfast excluded": "Aamiainen ei sisälly",
|
||||||
"Breakfast included": "Aamiainen sisältyy",
|
"Breakfast included": "Aamiainen sisältyy",
|
||||||
"Bus terminal": "Bussiasema",
|
"Bus terminal": "Bussiasema",
|
||||||
"Business": "Business",
|
"Business": "Business",
|
||||||
|
"by": "mennessä",
|
||||||
"Cancel": "Peruuttaa",
|
"Cancel": "Peruuttaa",
|
||||||
|
"characters": "hahmoja",
|
||||||
"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.",
|
||||||
@@ -47,6 +51,7 @@
|
|||||||
"Code / Voucher": "Varauskoodit / kupongit",
|
"Code / Voucher": "Varauskoodit / kupongit",
|
||||||
"Coming up": "Tulossa",
|
"Coming up": "Tulossa",
|
||||||
"Compare all levels": "Vertaa kaikkia tasoja",
|
"Compare all levels": "Vertaa kaikkia tasoja",
|
||||||
|
"Complete booking & go to payment": "Täydennä varaus & siirry maksamaan",
|
||||||
"Contact us": "Ota meihin yhteyttä",
|
"Contact us": "Ota meihin yhteyttä",
|
||||||
"Continue": "Jatkaa",
|
"Continue": "Jatkaa",
|
||||||
"Copyright all rights reserved": "Scandic AB Kaikki oikeudet pidätetään",
|
"Copyright all rights reserved": "Scandic AB Kaikki oikeudet pidätetään",
|
||||||
@@ -72,9 +77,9 @@
|
|||||||
"Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin",
|
"Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin",
|
||||||
"Explore nearby": "Tutustu lähialueeseen",
|
"Explore nearby": "Tutustu lähialueeseen",
|
||||||
"Extras to your booking": "Varauksessa lisäpalveluita",
|
"Extras to your booking": "Varauksessa lisäpalveluita",
|
||||||
"FAQ": "UKK",
|
|
||||||
"Failed to delete credit card, please try again later.": "Luottokortin poistaminen epäonnistui, yritä myöhemmin uudelleen.",
|
"Failed to delete credit card, please try again later.": "Luottokortin poistaminen epäonnistui, yritä myöhemmin uudelleen.",
|
||||||
"Fair": "Messukeskus",
|
"Fair": "Messukeskus",
|
||||||
|
"FAQ": "UKK",
|
||||||
"Find booking": "Etsi varaus",
|
"Find booking": "Etsi varaus",
|
||||||
"Find hotels": "Etsi hotelleja",
|
"Find hotels": "Etsi hotelleja",
|
||||||
"Flexibility": "Joustavuus",
|
"Flexibility": "Joustavuus",
|
||||||
@@ -92,11 +97,15 @@
|
|||||||
"Hotel": "Hotelli",
|
"Hotel": "Hotelli",
|
||||||
"Hotel facilities": "Hotellin palvelut",
|
"Hotel facilities": "Hotellin palvelut",
|
||||||
"Hotel surroundings": "Hotellin ympäristö",
|
"Hotel surroundings": "Hotellin ympäristö",
|
||||||
|
"hotelPages.rooms.roomCard.person": "henkilö",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "Henkilöä",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Katso huoneen tiedot",
|
||||||
"Hotels": "Hotellit",
|
"Hotels": "Hotellit",
|
||||||
"How do you want to sleep?": "Kuinka haluat nukkua?",
|
"How do you want to sleep?": "Kuinka haluat nukkua?",
|
||||||
"How it works": "Kuinka se toimii",
|
"How it works": "Kuinka se toimii",
|
||||||
"Image gallery": "Kuvagalleria",
|
"Image gallery": "Kuvagalleria",
|
||||||
"Join Scandic Friends": "Liity jäseneksi",
|
"Join Scandic Friends": "Liity jäseneksi",
|
||||||
|
"km to city center": "km keskustaan",
|
||||||
"Language": "Kieli",
|
"Language": "Kieli",
|
||||||
"Latest searches": "Viimeisimmät haut",
|
"Latest searches": "Viimeisimmät haut",
|
||||||
"Level": "Level",
|
"Level": "Level",
|
||||||
@@ -123,9 +132,9 @@
|
|||||||
"Member price": "Jäsenhinta",
|
"Member price": "Jäsenhinta",
|
||||||
"Member price from": "Jäsenhinta alkaen",
|
"Member price from": "Jäsenhinta alkaen",
|
||||||
"Members": "Jäsenet",
|
"Members": "Jäsenet",
|
||||||
|
"Membership cards": "Jäsenkortit",
|
||||||
"Membership ID": "Jäsentunnus",
|
"Membership ID": "Jäsentunnus",
|
||||||
"Membership ID copied to clipboard": "Jäsenyystunnus kopioitu leikepöydälle",
|
"Membership ID copied to clipboard": "Jäsenyystunnus kopioitu leikepöydälle",
|
||||||
"Membership cards": "Jäsenkortit",
|
|
||||||
"Menu": "Valikko",
|
"Menu": "Valikko",
|
||||||
"Modify": "Muokkaa",
|
"Modify": "Muokkaa",
|
||||||
"Month": "Kuukausi",
|
"Month": "Kuukausi",
|
||||||
@@ -140,6 +149,9 @@
|
|||||||
"Nearby companies": "Läheiset yritykset",
|
"Nearby companies": "Läheiset yritykset",
|
||||||
"New password": "Uusi salasana",
|
"New password": "Uusi salasana",
|
||||||
"Next": "Seuraava",
|
"Next": "Seuraava",
|
||||||
|
"next level:": "pistettä tasolle:",
|
||||||
|
"night": "yö",
|
||||||
|
"nights": "yötä",
|
||||||
"Nights needed to level up": "Yöt, joita tarvitaan tasolle",
|
"Nights needed to level up": "Yöt, joita tarvitaan tasolle",
|
||||||
"No content published": "Ei julkaistua sisältöä",
|
"No content published": "Ei julkaistua sisältöä",
|
||||||
"No matching location found": "Vastaavaa sijaintia ei löytynyt",
|
"No matching location found": "Vastaavaa sijaintia ei löytynyt",
|
||||||
@@ -150,11 +162,13 @@
|
|||||||
"Non-refundable": "Ei palautettavissa",
|
"Non-refundable": "Ei palautettavissa",
|
||||||
"Not found": "Ei löydetty",
|
"Not found": "Ei löydetty",
|
||||||
"Nr night, nr adult": "{nights, number} yö, {adults, number} aikuinen",
|
"Nr night, nr adult": "{nights, number} yö, {adults, number} aikuinen",
|
||||||
|
"number": "määrä",
|
||||||
"On your journey": "Matkallasi",
|
"On your journey": "Matkallasi",
|
||||||
"Open": "Avata",
|
"Open": "Avata",
|
||||||
"Open language menu": "Avaa kielivalikko",
|
"Open language menu": "Avaa kielivalikko",
|
||||||
"Open menu": "Avaa valikko",
|
"Open menu": "Avaa valikko",
|
||||||
"Open my pages menu": "Avaa omat sivut -valikko",
|
"Open my pages menu": "Avaa omat sivut -valikko",
|
||||||
|
"or": "tai",
|
||||||
"Overview": "Yleiskatsaus",
|
"Overview": "Yleiskatsaus",
|
||||||
"Parking": "Pysäköinti",
|
"Parking": "Pysäköinti",
|
||||||
"Parking / Garage": "Pysäköinti / Autotalli",
|
"Parking / Garage": "Pysäköinti / Autotalli",
|
||||||
@@ -166,6 +180,7 @@
|
|||||||
"Phone is required": "Puhelin vaaditaan",
|
"Phone is required": "Puhelin vaaditaan",
|
||||||
"Phone number": "Puhelinnumero",
|
"Phone number": "Puhelinnumero",
|
||||||
"Please enter a valid phone number": "Ole hyvä ja näppäile voimassaoleva puhelinnumero",
|
"Please enter a valid phone number": "Ole hyvä ja näppäile voimassaoleva puhelinnumero",
|
||||||
|
"points": "pistettä",
|
||||||
"Points": "Pisteet",
|
"Points": "Pisteet",
|
||||||
"Points being calculated": "Pisteitä lasketaan",
|
"Points being calculated": "Pisteitä lasketaan",
|
||||||
"Points earned prior to May 1, 2021": "Pisteet, jotka ansaittu ennen 1.5.2021",
|
"Points earned prior to May 1, 2021": "Pisteet, jotka ansaittu ennen 1.5.2021",
|
||||||
@@ -208,25 +223,29 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Jotain meni pieleen, emmekä voineet lisätä korttiasi. Yritä myöhemmin uudelleen.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Jotain meni pieleen, emmekä voineet lisätä korttiasi. Yritä myöhemmin uudelleen.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Jotain meni pieleen, emmekä voineet poistaa korttiasi. Yritä myöhemmin uudelleen.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Jotain meni pieleen, emmekä voineet poistaa korttiasi. Yritä myöhemmin uudelleen.",
|
||||||
"Something went wrong!": "Jotain meni pieleen!",
|
"Something went wrong!": "Jotain meni pieleen!",
|
||||||
|
"special character": "erikoishahmo",
|
||||||
|
"spendable points expiring by": "{points} pistettä vanhenee {date} mennessä",
|
||||||
"Sports": "Urheilu",
|
"Sports": "Urheilu",
|
||||||
"Standard price": "Normaali hinta",
|
"Standard price": "Normaali hinta",
|
||||||
"Street": "Katu",
|
"Street": "Katu",
|
||||||
"Successfully updated profile!": "Profiilin päivitys onnistui!",
|
"Successfully updated profile!": "Profiilin päivitys onnistui!",
|
||||||
"Summary": "Yhteenveto",
|
"Summary": "Yhteenveto",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Kerro meille, mitä tietoja ja päivityksiä haluat saada ja miten, napsauttamalla alla olevaa linkkiä.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Kerro meille, mitä tietoja ja päivityksiä haluat saada ja miten, napsauttamalla alla olevaa linkkiä.",
|
||||||
"Thank you": "Kiitos",
|
"Thank you": "Kiitos",
|
||||||
"Theatre": "Teatteri",
|
"Theatre": "Teatteri",
|
||||||
"There are no transactions to display": "Näytettäviä tapahtumia ei ole",
|
"There are no transactions to display": "Näytettäviä tapahtumia ei ole",
|
||||||
"Things nearby HOTEL_NAME": "Lähellä olevia asioita {hotelName}",
|
"Things nearby HOTEL_NAME": "Lähellä olevia asioita {hotelName}",
|
||||||
|
"to": "to",
|
||||||
"Total Points": "Kokonaispisteet",
|
"Total Points": "Kokonaispisteet",
|
||||||
"Tourist": "Turisti",
|
"Tourist": "Turisti",
|
||||||
"Transaction date": "Tapahtuman päivämäärä",
|
"Transaction date": "Tapahtuman päivämäärä",
|
||||||
"Transactions": "Tapahtumat",
|
"Transactions": "Tapahtumat",
|
||||||
"Transportations": "Kuljetukset",
|
"Transportations": "Kuljetukset",
|
||||||
"Tripadvisor reviews": "{rating} ({count} arvostelua TripAdvisorissa)",
|
"Tripadvisor reviews": "{rating} ({count} arvostelua TripAdvisorissa)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Vuodetyyppi",
|
"Type of bed": "Vuodetyyppi",
|
||||||
"Type of room": "Huonetyyppi",
|
"Type of room": "Huonetyyppi",
|
||||||
|
"uppercase letter": "iso kirjain",
|
||||||
"Use bonus cheque": "Käytä bonussekkiä",
|
"Use bonus cheque": "Käytä bonussekkiä",
|
||||||
"User information": "Käyttäjän tiedot",
|
"User information": "Käyttäjän tiedot",
|
||||||
"View as list": "Näytä listana",
|
"View as list": "Näytä listana",
|
||||||
@@ -252,9 +271,9 @@
|
|||||||
"You canceled adding a new credit card.": "Peruutit uuden luottokortin lisäämisen.",
|
"You canceled adding a new credit card.": "Peruutit uuden luottokortin lisäämisen.",
|
||||||
"You have no previous stays.": "Sinulla ei ole aiempia majoituksia.",
|
"You have no previous stays.": "Sinulla ei ole aiempia majoituksia.",
|
||||||
"You have no upcoming stays.": "Sinulla ei ole tulevia majoituksia.",
|
"You have no upcoming stays.": "Sinulla ei ole tulevia majoituksia.",
|
||||||
"Your Challenges Conquer & Earn!": "Voita ja ansaitse haasteesi!",
|
|
||||||
"Your card was successfully removed!": "Korttisi poistettiin onnistuneesti!",
|
"Your card was successfully removed!": "Korttisi poistettiin onnistuneesti!",
|
||||||
"Your card was successfully saved!": "Korttisi tallennettu onnistuneesti!",
|
"Your card was successfully saved!": "Korttisi tallennettu onnistuneesti!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Voita ja ansaitse haasteesi!",
|
||||||
"Your current level": "Nykyinen tasosi",
|
"Your current level": "Nykyinen tasosi",
|
||||||
"Your details": "Tietosi",
|
"Your details": "Tietosi",
|
||||||
"Your level": "Tasosi",
|
"Your level": "Tasosi",
|
||||||
@@ -262,23 +281,5 @@
|
|||||||
"Zip code": "Postinumero",
|
"Zip code": "Postinumero",
|
||||||
"Zoo": "Eläintarha",
|
"Zoo": "Eläintarha",
|
||||||
"Zoom in": "Lähennä",
|
"Zoom in": "Lähennä",
|
||||||
"Zoom out": "Loitonna",
|
"Zoom out": "Loitonna"
|
||||||
"as of today": "tänään",
|
}
|
||||||
"booking.nights": "{totalNights, plural, one {# yö} other {# yötä}}",
|
|
||||||
"by": "mennessä",
|
|
||||||
"characters": "hahmoja",
|
|
||||||
"hotelPages.rooms.roomCard.person": "henkilö",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "Henkilöä",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Katso huoneen tiedot",
|
|
||||||
"km to city center": "km keskustaan",
|
|
||||||
"next level:": "pistettä tasolle:",
|
|
||||||
"night": "yö",
|
|
||||||
"nights": "yötä",
|
|
||||||
"number": "määrä",
|
|
||||||
"or": "tai",
|
|
||||||
"points": "pistettä",
|
|
||||||
"special character": "erikoishahmo",
|
|
||||||
"spendable points expiring by": "{points} pistettä vanhenee {date} mennessä",
|
|
||||||
"to": "to",
|
|
||||||
"uppercase letter": "iso kirjain"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"Any changes you've made will be lost.": "Eventuelle endringer du har gjort, går tapt.",
|
"Any changes you've made will be lost.": "Eventuelle endringer du har gjort, går tapt.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Er du sikker på at du vil fjerne kortet som slutter på {lastFourDigits} fra medlemsprofilen din?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Er du sikker på at du vil fjerne kortet som slutter på {lastFourDigits} fra medlemsprofilen din?",
|
||||||
"Arrival date": "Ankomstdato",
|
"Arrival date": "Ankomstdato",
|
||||||
|
"as of today": "per idag",
|
||||||
"As our": "Som vår {level}",
|
"As our": "Som vår {level}",
|
||||||
"As our Close Friend": "Som vår nære venn",
|
"As our Close Friend": "Som vår nære venn",
|
||||||
"At latest": "Senest",
|
"At latest": "Senest",
|
||||||
@@ -23,14 +24,16 @@
|
|||||||
"Bed type": "Seng type",
|
"Bed type": "Seng type",
|
||||||
"Book": "Bestill",
|
"Book": "Bestill",
|
||||||
"Book reward night": "Bestill belønningskveld",
|
"Book reward night": "Bestill belønningskveld",
|
||||||
"Code / Voucher": "Bestillingskoder / kuponger",
|
|
||||||
"Booking number": "Bestillingsnummer",
|
"Booking number": "Bestillingsnummer",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# natt} other {# netter}}",
|
||||||
"Breakfast": "Frokost",
|
"Breakfast": "Frokost",
|
||||||
"Breakfast excluded": "Frokost ekskludert",
|
"Breakfast excluded": "Frokost ekskludert",
|
||||||
"Breakfast included": "Frokost inkludert",
|
"Breakfast included": "Frokost inkludert",
|
||||||
"Bus terminal": "Bussterminal",
|
"Bus terminal": "Bussterminal",
|
||||||
"Business": "Forretnings",
|
"Business": "Forretnings",
|
||||||
|
"by": "innen",
|
||||||
"Cancel": "Avbryt",
|
"Cancel": "Avbryt",
|
||||||
|
"characters": "tegn",
|
||||||
"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.",
|
||||||
@@ -45,8 +48,10 @@
|
|||||||
"Close menu": "Lukk meny",
|
"Close menu": "Lukk meny",
|
||||||
"Close my pages menu": "Lukk mine sidermenyn",
|
"Close my pages menu": "Lukk mine sidermenyn",
|
||||||
"Close the map": "Lukk kartet",
|
"Close the map": "Lukk kartet",
|
||||||
|
"Code / Voucher": "Bestillingskoder / kuponger",
|
||||||
"Coming up": "Kommer opp",
|
"Coming up": "Kommer opp",
|
||||||
"Compare all levels": "Sammenlign alle nivåer",
|
"Compare all levels": "Sammenlign alle nivåer",
|
||||||
|
"Complete booking & go to payment": "Fullfør bestilling & gå til betaling",
|
||||||
"Contact us": "Kontakt oss",
|
"Contact us": "Kontakt oss",
|
||||||
"Continue": "Fortsette",
|
"Continue": "Fortsette",
|
||||||
"Copyright all rights reserved": "Scandic AB Alle rettigheter forbeholdt",
|
"Copyright all rights reserved": "Scandic AB Alle rettigheter forbeholdt",
|
||||||
@@ -72,9 +77,9 @@
|
|||||||
"Explore all levels and benefits": "Utforsk alle nivåer og fordeler",
|
"Explore all levels and benefits": "Utforsk alle nivåer og fordeler",
|
||||||
"Explore nearby": "Utforsk i nærheten",
|
"Explore nearby": "Utforsk i nærheten",
|
||||||
"Extras to your booking": "Tilvalg til bestillingen din",
|
"Extras to your booking": "Tilvalg til bestillingen din",
|
||||||
"FAQ": "FAQ",
|
|
||||||
"Failed to delete credit card, please try again later.": "Kunne ikke slette kredittkortet, prøv igjen senere.",
|
"Failed to delete credit card, please try again later.": "Kunne ikke slette kredittkortet, prøv igjen senere.",
|
||||||
"Fair": "Messe",
|
"Fair": "Messe",
|
||||||
|
"FAQ": "FAQ",
|
||||||
"Find booking": "Finn booking",
|
"Find booking": "Finn booking",
|
||||||
"Find hotels": "Finn hotell",
|
"Find hotels": "Finn hotell",
|
||||||
"Flexibility": "Fleksibilitet",
|
"Flexibility": "Fleksibilitet",
|
||||||
@@ -85,17 +90,22 @@
|
|||||||
"Get inspired": "Bli inspirert",
|
"Get inspired": "Bli inspirert",
|
||||||
"Go back to edit": "Gå tilbake til redigering",
|
"Go back to edit": "Gå tilbake til redigering",
|
||||||
"Go back to overview": "Gå tilbake til oversikten",
|
"Go back to overview": "Gå tilbake til oversikten",
|
||||||
|
"Guests & Rooms": "Gjester & rom",
|
||||||
"Hi": "Hei",
|
"Hi": "Hei",
|
||||||
"Highest level": "Høyeste nivå",
|
"Highest level": "Høyeste nivå",
|
||||||
"Hospital": "Sykehus",
|
"Hospital": "Sykehus",
|
||||||
"Hotel": "Hotel",
|
"Hotel": "Hotel",
|
||||||
"Hotel facilities": "Hotelfaciliteter",
|
"Hotel facilities": "Hotelfaciliteter",
|
||||||
"Hotel surroundings": "Hotellomgivelser",
|
"Hotel surroundings": "Hotellomgivelser",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "personer",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Se detaljer om rommet",
|
||||||
"Hotels": "Hoteller",
|
"Hotels": "Hoteller",
|
||||||
"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",
|
||||||
"Join Scandic Friends": "Bli med i Scandic Friends",
|
"Join Scandic Friends": "Bli med i Scandic Friends",
|
||||||
|
"km to city center": "km til sentrum",
|
||||||
"Language": "Språk",
|
"Language": "Språk",
|
||||||
"Latest searches": "Siste søk",
|
"Latest searches": "Siste søk",
|
||||||
"Level": "Nivå",
|
"Level": "Nivå",
|
||||||
@@ -122,9 +132,9 @@
|
|||||||
"Member price": "Medlemspris",
|
"Member price": "Medlemspris",
|
||||||
"Member price from": "Medlemspris fra",
|
"Member price from": "Medlemspris fra",
|
||||||
"Members": "Medlemmer",
|
"Members": "Medlemmer",
|
||||||
|
"Membership cards": "Medlemskort",
|
||||||
"Membership ID": "Medlems-ID",
|
"Membership ID": "Medlems-ID",
|
||||||
"Membership ID copied to clipboard": "Medlems-ID kopiert til utklippstavlen",
|
"Membership ID copied to clipboard": "Medlems-ID kopiert til utklippstavlen",
|
||||||
"Membership cards": "Medlemskort",
|
|
||||||
"Menu": "Menu",
|
"Menu": "Menu",
|
||||||
"Modify": "Endre",
|
"Modify": "Endre",
|
||||||
"Month": "Måned",
|
"Month": "Måned",
|
||||||
@@ -139,6 +149,9 @@
|
|||||||
"Nearby companies": "Nærliggende selskaper",
|
"Nearby companies": "Nærliggende selskaper",
|
||||||
"New password": "Nytt passord",
|
"New password": "Nytt passord",
|
||||||
"Next": "Neste",
|
"Next": "Neste",
|
||||||
|
"next level:": "Neste nivå:",
|
||||||
|
"night": "natt",
|
||||||
|
"nights": "netter",
|
||||||
"Nights needed to level up": "Netter som trengs for å komme opp i nivå",
|
"Nights needed to level up": "Netter som trengs for å komme opp i nivå",
|
||||||
"No content published": "Ingen innhold publisert",
|
"No content published": "Ingen innhold publisert",
|
||||||
"No matching location found": "Fant ingen samsvarende plassering",
|
"No matching location found": "Fant ingen samsvarende plassering",
|
||||||
@@ -149,11 +162,13 @@
|
|||||||
"Non-refundable": "Ikke-refunderbart",
|
"Non-refundable": "Ikke-refunderbart",
|
||||||
"Not found": "Ikke funnet",
|
"Not found": "Ikke funnet",
|
||||||
"Nr night, nr adult": "{nights, number} natt, {adults, number} voksen",
|
"Nr night, nr adult": "{nights, number} natt, {adults, number} voksen",
|
||||||
|
"number": "antall",
|
||||||
"On your journey": "På reisen din",
|
"On your journey": "På reisen din",
|
||||||
"Open": "Åpen",
|
"Open": "Åpen",
|
||||||
"Open language menu": "Åpne språkmenyen",
|
"Open language menu": "Åpne språkmenyen",
|
||||||
"Open menu": "Åpne menyen",
|
"Open menu": "Åpne menyen",
|
||||||
"Open my pages menu": "Åpne mine sider menyen",
|
"Open my pages menu": "Åpne mine sider menyen",
|
||||||
|
"or": "eller",
|
||||||
"Overview": "Oversikt",
|
"Overview": "Oversikt",
|
||||||
"Parking": "Parkering",
|
"Parking": "Parkering",
|
||||||
"Parking / Garage": "Parkering / Garasje",
|
"Parking / Garage": "Parkering / Garasje",
|
||||||
@@ -165,6 +180,7 @@
|
|||||||
"Phone is required": "Telefon kreves",
|
"Phone is required": "Telefon kreves",
|
||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Vennligst oppgi et gyldig telefonnummer",
|
"Please enter a valid phone number": "Vennligst oppgi et gyldig telefonnummer",
|
||||||
|
"points": "poeng",
|
||||||
"Points": "Poeng",
|
"Points": "Poeng",
|
||||||
"Points being calculated": "Poeng beregnes",
|
"Points being calculated": "Poeng beregnes",
|
||||||
"Points earned prior to May 1, 2021": "Opptjente poeng før 1. mai 2021",
|
"Points earned prior to May 1, 2021": "Opptjente poeng før 1. mai 2021",
|
||||||
@@ -183,7 +199,6 @@
|
|||||||
"Room & Terms": "Rom & Vilkår",
|
"Room & Terms": "Rom & Vilkår",
|
||||||
"Room facilities": "Romfasiliteter",
|
"Room facilities": "Romfasiliteter",
|
||||||
"Rooms": "Rom",
|
"Rooms": "Rom",
|
||||||
"Guests & Rooms": "Gjester & rom",
|
|
||||||
"Save": "Lagre",
|
"Save": "Lagre",
|
||||||
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
||||||
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
||||||
@@ -208,25 +223,29 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Noe gikk galt, og vi kunne ikke legge til kortet ditt. Prøv igjen senere.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Noe gikk galt, og vi kunne ikke legge til kortet ditt. Prøv igjen senere.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Noe gikk galt, og vi kunne ikke fjerne kortet ditt. Vennligst prøv igjen senere.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Noe gikk galt, og vi kunne ikke fjerne kortet ditt. Vennligst prøv igjen senere.",
|
||||||
"Something went wrong!": "Noe gikk galt!",
|
"Something went wrong!": "Noe gikk galt!",
|
||||||
|
"special character": "spesiell karakter",
|
||||||
|
"spendable points expiring by": "{points} Brukbare poeng utløper innen {date}",
|
||||||
"Sports": "Sport",
|
"Sports": "Sport",
|
||||||
"Standard price": "Standardpris",
|
"Standard price": "Standardpris",
|
||||||
"Street": "Gate",
|
"Street": "Gate",
|
||||||
"Successfully updated profile!": "Vellykket oppdatert profil!",
|
"Successfully updated profile!": "Vellykket oppdatert profil!",
|
||||||
"Summary": "Sammendrag",
|
"Summary": "Sammendrag",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Fortell oss hvilken informasjon og hvilke oppdateringer du ønsker å motta, og hvordan, ved å klikke på lenken nedenfor.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Fortell oss hvilken informasjon og hvilke oppdateringer du ønsker å motta, og hvordan, ved å klikke på lenken nedenfor.",
|
||||||
"Thank you": "Takk",
|
"Thank you": "Takk",
|
||||||
"Theatre": "Teater",
|
"Theatre": "Teater",
|
||||||
"There are no transactions to display": "Det er ingen transaksjoner å vise",
|
"There are no transactions to display": "Det er ingen transaksjoner å vise",
|
||||||
"Things nearby HOTEL_NAME": "Ting i nærheten av {hotelName}",
|
"Things nearby HOTEL_NAME": "Ting i nærheten av {hotelName}",
|
||||||
|
"to": "til",
|
||||||
"Total Points": "Totale poeng",
|
"Total Points": "Totale poeng",
|
||||||
"Tourist": "Turist",
|
"Tourist": "Turist",
|
||||||
"Transaction date": "Transaksjonsdato",
|
"Transaction date": "Transaksjonsdato",
|
||||||
"Transactions": "Transaksjoner",
|
"Transactions": "Transaksjoner",
|
||||||
"Transportations": "Transport",
|
"Transportations": "Transport",
|
||||||
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} anmeldelser på Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Sengtype",
|
"Type of bed": "Sengtype",
|
||||||
"Type of room": "Romtype",
|
"Type of room": "Romtype",
|
||||||
|
"uppercase letter": "stor bokstav",
|
||||||
"Use bonus cheque": "Bruk bonussjekk",
|
"Use bonus cheque": "Bruk bonussjekk",
|
||||||
"User information": "Brukerinformasjon",
|
"User information": "Brukerinformasjon",
|
||||||
"View as list": "Vis som liste",
|
"View as list": "Vis som liste",
|
||||||
@@ -252,9 +271,9 @@
|
|||||||
"You canceled adding a new credit card.": "Du kansellerte å legge til et nytt kredittkort.",
|
"You canceled adding a new credit card.": "Du kansellerte å legge til et nytt kredittkort.",
|
||||||
"You have no previous stays.": "Du har ingen tidligere opphold.",
|
"You have no previous stays.": "Du har ingen tidligere opphold.",
|
||||||
"You have no upcoming stays.": "Du har ingen kommende opphold.",
|
"You have no upcoming stays.": "Du har ingen kommende opphold.",
|
||||||
"Your Challenges Conquer & Earn!": "Dine utfordringer Erobre og tjen!",
|
|
||||||
"Your card was successfully removed!": "Kortet ditt ble fjernet!",
|
"Your card was successfully removed!": "Kortet ditt ble fjernet!",
|
||||||
"Your card was successfully saved!": "Kortet ditt ble lagret!",
|
"Your card was successfully saved!": "Kortet ditt ble lagret!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Dine utfordringer Erobre og tjen!",
|
||||||
"Your current level": "Ditt nåværende nivå",
|
"Your current level": "Ditt nåværende nivå",
|
||||||
"Your details": "Dine detaljer",
|
"Your details": "Dine detaljer",
|
||||||
"Your level": "Ditt nivå",
|
"Your level": "Ditt nivå",
|
||||||
@@ -262,23 +281,5 @@
|
|||||||
"Zip code": "Post kode",
|
"Zip code": "Post kode",
|
||||||
"Zoo": "Dyrehage",
|
"Zoo": "Dyrehage",
|
||||||
"Zoom in": "Zoom inn",
|
"Zoom in": "Zoom inn",
|
||||||
"Zoom out": "Zoom ut",
|
"Zoom out": "Zoom ut"
|
||||||
"as of today": "per i dag",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# natt} other {# netter}}",
|
|
||||||
"by": "innen",
|
|
||||||
"characters": "tegn",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "personer",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Se detaljer om rommet",
|
|
||||||
"km to city center": "km til sentrum",
|
|
||||||
"next level:": "Neste nivå:",
|
|
||||||
"night": "natt",
|
|
||||||
"nights": "netter",
|
|
||||||
"number": "antall",
|
|
||||||
"or": "eller",
|
|
||||||
"points": "poeng",
|
|
||||||
"special character": "spesiell karakter",
|
|
||||||
"spendable points expiring by": "{points} Brukbare poeng utløper innen {date}",
|
|
||||||
"to": "til",
|
|
||||||
"uppercase letter": "stor bokstav"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"Any changes you've made will be lost.": "Alla ändringar du har gjort kommer att gå förlorade.",
|
"Any changes you've made will be lost.": "Alla ändringar du har gjort kommer att gå förlorade.",
|
||||||
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Är du säker på att du vill ta bort kortet som slutar med {lastFourDigits} från din medlemsprofil?",
|
"Are you sure you want to remove the card ending with {lastFourDigits} from your member profile?": "Är du säker på att du vill ta bort kortet som slutar med {lastFourDigits} från din medlemsprofil?",
|
||||||
"Arrival date": "Ankomstdatum",
|
"Arrival date": "Ankomstdatum",
|
||||||
|
"as of today": "från och med idag",
|
||||||
"As our": "Som vår {level}",
|
"As our": "Som vår {level}",
|
||||||
"As our Close Friend": "Som vår nära vän",
|
"As our Close Friend": "Som vår nära vän",
|
||||||
"At latest": "Senast",
|
"At latest": "Senast",
|
||||||
@@ -23,14 +24,16 @@
|
|||||||
"Bed type": "Sängtyp",
|
"Bed type": "Sängtyp",
|
||||||
"Book": "Boka",
|
"Book": "Boka",
|
||||||
"Book reward night": "Boka frinatt",
|
"Book reward night": "Boka frinatt",
|
||||||
"Code / Voucher": "Bokningskoder / kuponger",
|
|
||||||
"Booking number": "Bokningsnummer",
|
"Booking number": "Bokningsnummer",
|
||||||
|
"booking.nights": "{totalNights, plural, one {# natt} other {# nätter}}",
|
||||||
"Breakfast": "Frukost",
|
"Breakfast": "Frukost",
|
||||||
"Breakfast excluded": "Frukost ingår ej",
|
"Breakfast excluded": "Frukost ingår ej",
|
||||||
"Breakfast included": "Frukost ingår",
|
"Breakfast included": "Frukost ingår",
|
||||||
"Bus terminal": "Bussterminal",
|
"Bus terminal": "Bussterminal",
|
||||||
"Business": "Business",
|
"Business": "Business",
|
||||||
|
"by": "innan",
|
||||||
"Cancel": "Avbryt",
|
"Cancel": "Avbryt",
|
||||||
|
"characters": "tecken",
|
||||||
"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.",
|
||||||
@@ -45,8 +48,10 @@
|
|||||||
"Close menu": "Stäng menyn",
|
"Close menu": "Stäng menyn",
|
||||||
"Close my pages menu": "Stäng mina sidor menyn",
|
"Close my pages menu": "Stäng mina sidor menyn",
|
||||||
"Close the map": "Stäng kartan",
|
"Close the map": "Stäng kartan",
|
||||||
|
"Code / Voucher": "Bokningskoder / kuponger",
|
||||||
"Coming up": "Kommer härnäst",
|
"Coming up": "Kommer härnäst",
|
||||||
"Compare all levels": "Jämför alla nivåer",
|
"Compare all levels": "Jämför alla nivåer",
|
||||||
|
"Complete booking & go to payment": "Fullför bokning & gå till betalning",
|
||||||
"Contact us": "Kontakta oss",
|
"Contact us": "Kontakta oss",
|
||||||
"Continue": "Fortsätt",
|
"Continue": "Fortsätt",
|
||||||
"Copyright all rights reserved": "Scandic AB Alla rättigheter förbehålls",
|
"Copyright all rights reserved": "Scandic AB Alla rättigheter förbehålls",
|
||||||
@@ -72,9 +77,9 @@
|
|||||||
"Explore all levels and benefits": "Utforska alla nivåer och fördelar",
|
"Explore all levels and benefits": "Utforska alla nivåer och fördelar",
|
||||||
"Explore nearby": "Utforska i närheten",
|
"Explore nearby": "Utforska i närheten",
|
||||||
"Extras to your booking": "Extra tillval till din bokning",
|
"Extras to your booking": "Extra tillval till din bokning",
|
||||||
"FAQ": "FAQ",
|
|
||||||
"Failed to delete credit card, please try again later.": "Det gick inte att ta bort kreditkortet, försök igen senare.",
|
"Failed to delete credit card, please try again later.": "Det gick inte att ta bort kreditkortet, försök igen senare.",
|
||||||
"Fair": "Mässa",
|
"Fair": "Mässa",
|
||||||
|
"FAQ": "FAQ",
|
||||||
"Find booking": "Hitta bokning",
|
"Find booking": "Hitta bokning",
|
||||||
"Find hotels": "Hitta hotell",
|
"Find hotels": "Hitta hotell",
|
||||||
"Flexibility": "Flexibilitet",
|
"Flexibility": "Flexibilitet",
|
||||||
@@ -85,17 +90,22 @@
|
|||||||
"Get inspired": "Bli inspirerad",
|
"Get inspired": "Bli inspirerad",
|
||||||
"Go back to edit": "Gå tillbaka till redigeringen",
|
"Go back to edit": "Gå tillbaka till redigeringen",
|
||||||
"Go back to overview": "Gå tillbaka till översikten",
|
"Go back to overview": "Gå tillbaka till översikten",
|
||||||
|
"Guests & Rooms": "Gäster & rum",
|
||||||
"Hi": "Hej",
|
"Hi": "Hej",
|
||||||
"Highest level": "Högsta nivå",
|
"Highest level": "Högsta nivå",
|
||||||
"Hospital": "Sjukhus",
|
"Hospital": "Sjukhus",
|
||||||
"Hotel": "Hotell",
|
"Hotel": "Hotell",
|
||||||
"Hotel facilities": "Hotellfaciliteter",
|
"Hotel facilities": "Hotellfaciliteter",
|
||||||
"Hotel surroundings": "Hotellomgivning",
|
"Hotel surroundings": "Hotellomgivning",
|
||||||
|
"hotelPages.rooms.roomCard.person": "person",
|
||||||
|
"hotelPages.rooms.roomCard.persons": "personer",
|
||||||
|
"hotelPages.rooms.roomCard.seeRoomDetails": "Se information om rummet",
|
||||||
"Hotels": "Hotell",
|
"Hotels": "Hotell",
|
||||||
"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",
|
||||||
"Join Scandic Friends": "Gå med i Scandic Friends",
|
"Join Scandic Friends": "Gå med i Scandic Friends",
|
||||||
|
"km to city center": "km till stadens centrum",
|
||||||
"Language": "Språk",
|
"Language": "Språk",
|
||||||
"Latest searches": "Senaste sökningarna",
|
"Latest searches": "Senaste sökningarna",
|
||||||
"Level": "Nivå",
|
"Level": "Nivå",
|
||||||
@@ -122,9 +132,9 @@
|
|||||||
"Member price": "Medlemspris",
|
"Member price": "Medlemspris",
|
||||||
"Member price from": "Medlemspris från",
|
"Member price from": "Medlemspris från",
|
||||||
"Members": "Medlemmar",
|
"Members": "Medlemmar",
|
||||||
|
"Membership cards": "Medlemskort",
|
||||||
"Membership ID": "Medlems-ID",
|
"Membership ID": "Medlems-ID",
|
||||||
"Membership ID copied to clipboard": "Medlems-ID kopierat till urklipp",
|
"Membership ID copied to clipboard": "Medlems-ID kopierat till urklipp",
|
||||||
"Membership cards": "Medlemskort",
|
|
||||||
"Menu": "Meny",
|
"Menu": "Meny",
|
||||||
"Modify": "Ändra",
|
"Modify": "Ändra",
|
||||||
"Month": "Månad",
|
"Month": "Månad",
|
||||||
@@ -139,6 +149,9 @@
|
|||||||
"Nearby companies": "Närliggande företag",
|
"Nearby companies": "Närliggande företag",
|
||||||
"New password": "Nytt lösenord",
|
"New password": "Nytt lösenord",
|
||||||
"Next": "Nästa",
|
"Next": "Nästa",
|
||||||
|
"next level:": "Nästa nivå:",
|
||||||
|
"night": "natt",
|
||||||
|
"nights": "nätter",
|
||||||
"Nights needed to level up": "Nätter som behövs för att gå upp i nivå",
|
"Nights needed to level up": "Nätter som behövs för att gå upp i nivå",
|
||||||
"No content published": "Inget innehåll publicerat",
|
"No content published": "Inget innehåll publicerat",
|
||||||
"No matching location found": "Ingen matchande plats hittades",
|
"No matching location found": "Ingen matchande plats hittades",
|
||||||
@@ -149,11 +162,13 @@
|
|||||||
"Non-refundable": "Ej återbetalningsbar",
|
"Non-refundable": "Ej återbetalningsbar",
|
||||||
"Not found": "Hittades inte",
|
"Not found": "Hittades inte",
|
||||||
"Nr night, nr adult": "{nights, number} natt, {adults, number} vuxen",
|
"Nr night, nr adult": "{nights, number} natt, {adults, number} vuxen",
|
||||||
|
"number": "nummer",
|
||||||
"On your journey": "På din resa",
|
"On your journey": "På din resa",
|
||||||
"Open": "Öppna",
|
"Open": "Öppna",
|
||||||
"Open language menu": "Öppna språkmenyn",
|
"Open language menu": "Öppna språkmenyn",
|
||||||
"Open menu": "Öppna menyn",
|
"Open menu": "Öppna menyn",
|
||||||
"Open my pages menu": "Öppna mina sidor menyn",
|
"Open my pages menu": "Öppna mina sidor menyn",
|
||||||
|
"or": "eller",
|
||||||
"Overview": "Översikt",
|
"Overview": "Översikt",
|
||||||
"Parking": "Parkering",
|
"Parking": "Parkering",
|
||||||
"Parking / Garage": "Parkering / Garage",
|
"Parking / Garage": "Parkering / Garage",
|
||||||
@@ -165,6 +180,7 @@
|
|||||||
"Phone is required": "Telefonnummer är obligatorisk",
|
"Phone is required": "Telefonnummer är obligatorisk",
|
||||||
"Phone number": "Telefonnummer",
|
"Phone number": "Telefonnummer",
|
||||||
"Please enter a valid phone number": "Var vänlig och ange ett giltigt telefonnummer",
|
"Please enter a valid phone number": "Var vänlig och ange ett giltigt telefonnummer",
|
||||||
|
"points": "poäng",
|
||||||
"Points": "Poäng",
|
"Points": "Poäng",
|
||||||
"Points being calculated": "Poäng beräknas",
|
"Points being calculated": "Poäng beräknas",
|
||||||
"Points earned prior to May 1, 2021": "Intjänade poäng före den 1 maj 2021",
|
"Points earned prior to May 1, 2021": "Intjänade poäng före den 1 maj 2021",
|
||||||
@@ -183,7 +199,6 @@
|
|||||||
"Room & Terms": "Rum & Villkor",
|
"Room & Terms": "Rum & Villkor",
|
||||||
"Room facilities": "Rumfaciliteter",
|
"Room facilities": "Rumfaciliteter",
|
||||||
"Rooms": "Rum",
|
"Rooms": "Rum",
|
||||||
"Guests & Rooms": "Gäster & rum",
|
|
||||||
"Save": "Spara",
|
"Save": "Spara",
|
||||||
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
"Scandic Friends Mastercard": "Scandic Friends Mastercard",
|
||||||
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
"Scandic Friends Point Shop": "Scandic Friends Point Shop",
|
||||||
@@ -208,25 +223,29 @@
|
|||||||
"Something went wrong and we couldn't add your card. Please try again later.": "Något gick fel och vi kunde inte lägga till ditt kort. Försök igen senare.",
|
"Something went wrong and we couldn't add your card. Please try again later.": "Något gick fel och vi kunde inte lägga till ditt kort. Försök igen senare.",
|
||||||
"Something went wrong and we couldn't remove your card. Please try again later.": "Något gick fel och vi kunde inte ta bort ditt kort. Försök igen senare.",
|
"Something went wrong and we couldn't remove your card. Please try again later.": "Något gick fel och vi kunde inte ta bort ditt kort. Försök igen senare.",
|
||||||
"Something went wrong!": "Något gick fel!",
|
"Something went wrong!": "Något gick fel!",
|
||||||
|
"special character": "speciell karaktär",
|
||||||
|
"spendable points expiring by": "{points} poäng förfaller {date}",
|
||||||
"Sports": "Sport",
|
"Sports": "Sport",
|
||||||
"Standard price": "Standardpris",
|
"Standard price": "Standardpris",
|
||||||
"Street": "Gata",
|
"Street": "Gata",
|
||||||
"Successfully updated profile!": "Profilen har uppdaterats framgångsrikt!",
|
"Successfully updated profile!": "Profilen har uppdaterats framgångsrikt!",
|
||||||
"Summary": "Sammanfattning",
|
"Summary": "Sammanfattning",
|
||||||
"TUI Points": "TUI Points",
|
|
||||||
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Berätta för oss vilken information och vilka uppdateringar du vill få och hur genom att klicka på länken nedan.",
|
"Tell us what information and updates you'd like to receive, and how, by clicking the link below.": "Berätta för oss vilken information och vilka uppdateringar du vill få och hur genom att klicka på länken nedan.",
|
||||||
"Thank you": "Tack",
|
"Thank you": "Tack",
|
||||||
"Theatre": "Teater",
|
"Theatre": "Teater",
|
||||||
"There are no transactions to display": "Det finns inga transaktioner att visa",
|
"There are no transactions to display": "Det finns inga transaktioner att visa",
|
||||||
"Things nearby HOTEL_NAME": "Saker i närheten av {hotelName}",
|
"Things nearby HOTEL_NAME": "Saker i närheten av {hotelName}",
|
||||||
|
"to": "till",
|
||||||
"Total Points": "Poäng totalt",
|
"Total Points": "Poäng totalt",
|
||||||
"Tourist": "Turist",
|
"Tourist": "Turist",
|
||||||
"Transaction date": "Transaktionsdatum",
|
"Transaction date": "Transaktionsdatum",
|
||||||
"Transactions": "Transaktioner",
|
"Transactions": "Transaktioner",
|
||||||
"Transportations": "Transport",
|
"Transportations": "Transport",
|
||||||
"Tripadvisor reviews": "{rating} ({count} recensioner på Tripadvisor)",
|
"Tripadvisor reviews": "{rating} ({count} recensioner på Tripadvisor)",
|
||||||
|
"TUI Points": "TUI Points",
|
||||||
"Type of bed": "Sängtyp",
|
"Type of bed": "Sängtyp",
|
||||||
"Type of room": "Rumstyp",
|
"Type of room": "Rumstyp",
|
||||||
|
"uppercase letter": "stor bokstav",
|
||||||
"Use bonus cheque": "Use bonus cheque",
|
"Use bonus cheque": "Use bonus cheque",
|
||||||
"User information": "Användarinformation",
|
"User information": "Användarinformation",
|
||||||
"View as list": "Visa som lista",
|
"View as list": "Visa som lista",
|
||||||
@@ -252,9 +271,9 @@
|
|||||||
"You canceled adding a new credit card.": "Du avbröt att lägga till ett nytt kreditkort.",
|
"You canceled adding a new credit card.": "Du avbröt att lägga till ett nytt kreditkort.",
|
||||||
"You have no previous stays.": "Du har inga tidigare vistelser.",
|
"You have no previous stays.": "Du har inga tidigare vistelser.",
|
||||||
"You have no upcoming stays.": "Du har inga planerade resor.",
|
"You have no upcoming stays.": "Du har inga planerade resor.",
|
||||||
"Your Challenges Conquer & Earn!": "Dina utmaningar Erövra och tjäna!",
|
|
||||||
"Your card was successfully removed!": "Ditt kort har tagits bort!",
|
"Your card was successfully removed!": "Ditt kort har tagits bort!",
|
||||||
"Your card was successfully saved!": "Ditt kort har sparats!",
|
"Your card was successfully saved!": "Ditt kort har sparats!",
|
||||||
|
"Your Challenges Conquer & Earn!": "Dina utmaningar Erövra och tjäna!",
|
||||||
"Your current level": "Din nuvarande nivå",
|
"Your current level": "Din nuvarande nivå",
|
||||||
"Your details": "Dina uppgifter",
|
"Your details": "Dina uppgifter",
|
||||||
"Your level": "Din nivå",
|
"Your level": "Din nivå",
|
||||||
@@ -262,23 +281,5 @@
|
|||||||
"Zip code": "Postnummer",
|
"Zip code": "Postnummer",
|
||||||
"Zoo": "Djurpark",
|
"Zoo": "Djurpark",
|
||||||
"Zoom in": "Zooma in",
|
"Zoom in": "Zooma in",
|
||||||
"Zoom out": "Zooma ut",
|
"Zoom out": "Zooma ut"
|
||||||
"as of today": "per idag",
|
|
||||||
"booking.nights": "{totalNights, plural, one {# natt} other {# nätter}}",
|
|
||||||
"by": "innan",
|
|
||||||
"characters": "tecken",
|
|
||||||
"hotelPages.rooms.roomCard.person": "person",
|
|
||||||
"hotelPages.rooms.roomCard.persons": "personer",
|
|
||||||
"hotelPages.rooms.roomCard.seeRoomDetails": "Se information om rummet",
|
|
||||||
"km to city center": "km till stadens centrum",
|
|
||||||
"next level:": "Nästa nivå:",
|
|
||||||
"night": "natt",
|
|
||||||
"nights": "nätter",
|
|
||||||
"number": "nummer",
|
|
||||||
"or": "eller",
|
|
||||||
"points": "poäng",
|
|
||||||
"special character": "speciell karaktär",
|
|
||||||
"spendable points expiring by": "{points} poäng förfaller {date}",
|
|
||||||
"to": "till",
|
|
||||||
"uppercase letter": "stor bokstav"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { mergeRouters } from "@/server/trpc"
|
import { mergeRouters } from "@/server/trpc"
|
||||||
|
|
||||||
import { bookingMutationRouter } from "./mutation"
|
import { bookingMutationRouter } from "./mutation"
|
||||||
|
import { bookingQueryRouter } from "./query"
|
||||||
|
|
||||||
export const bookingRouter = mergeRouters(bookingMutationRouter)
|
export const bookingRouter = mergeRouters(
|
||||||
|
bookingMutationRouter,
|
||||||
|
bookingQueryRouter
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,38 +1,68 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
// Query
|
const roomsSchema = z.array(
|
||||||
|
z.object({
|
||||||
|
adults: z.number().int().nonnegative(),
|
||||||
|
childrenAges: z
|
||||||
|
.array(
|
||||||
|
z.object({
|
||||||
|
age: z.number().int().nonnegative(),
|
||||||
|
bedType: z.string(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.default([]),
|
||||||
|
rateCode: z.string(),
|
||||||
|
roomTypeCode: z.string(),
|
||||||
|
guest: z.object({
|
||||||
|
title: z.string(),
|
||||||
|
firstName: z.string(),
|
||||||
|
lastName: z.string(),
|
||||||
|
email: z.string().email(),
|
||||||
|
phoneCountryCodePrefix: z.string(),
|
||||||
|
phoneNumber: z.string(),
|
||||||
|
countryCode: z.string(),
|
||||||
|
membershipNumber: z.string().optional(),
|
||||||
|
}),
|
||||||
|
smsConfirmationRequested: z.boolean(),
|
||||||
|
packages: z.object({
|
||||||
|
breakfast: z.boolean(),
|
||||||
|
allergyFriendly: z.boolean(),
|
||||||
|
petFriendly: z.boolean(),
|
||||||
|
accessibility: z.boolean(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const paymentSchema = z.object({
|
||||||
|
paymentMethod: z.string(),
|
||||||
|
card: z
|
||||||
|
.object({
|
||||||
|
alias: z.string(),
|
||||||
|
expiryDate: z.string(),
|
||||||
|
cardType: z.string(),
|
||||||
|
})
|
||||||
|
.optional(),
|
||||||
|
cardHolder: z.object({
|
||||||
|
email: z.string().email(),
|
||||||
|
name: z.string(),
|
||||||
|
phoneCountryCode: z.string(),
|
||||||
|
phoneSubscriber: z.string(),
|
||||||
|
}),
|
||||||
|
success: z.string(),
|
||||||
|
error: z.string(),
|
||||||
|
cancel: z.string(),
|
||||||
|
})
|
||||||
|
|
||||||
// Mutation
|
// Mutation
|
||||||
export const createBookingInput = z.object({
|
export const createBookingInput = z.object({
|
||||||
hotelId: z.string(),
|
hotelId: z.string(),
|
||||||
checkInDate: z.string(),
|
checkInDate: z.string(),
|
||||||
checkOutDate: z.string(),
|
checkOutDate: z.string(),
|
||||||
rooms: z.array(
|
rooms: roomsSchema,
|
||||||
z.object({
|
payment: paymentSchema,
|
||||||
adults: z.number().int().nonnegative(),
|
})
|
||||||
children: z.number().int().nonnegative(),
|
|
||||||
rateCode: z.string(),
|
// Query
|
||||||
roomTypeCode: z.string(),
|
export const getBookingStatusInput = z.object({
|
||||||
guest: z.object({
|
confirmationNumber: z.string(),
|
||||||
title: z.string(),
|
|
||||||
firstName: z.string(),
|
|
||||||
lastName: z.string(),
|
|
||||||
email: z.string().email(),
|
|
||||||
phoneCountryCodePrefix: z.string(),
|
|
||||||
phoneNumber: z.string(),
|
|
||||||
countryCode: z.string(),
|
|
||||||
}),
|
|
||||||
smsConfirmationRequested: z.boolean(),
|
|
||||||
})
|
|
||||||
),
|
|
||||||
payment: z.object({
|
|
||||||
cardHolder: z.object({
|
|
||||||
Email: z.string().email(),
|
|
||||||
Name: z.string(),
|
|
||||||
PhoneCountryCode: z.string(),
|
|
||||||
PhoneSubscriber: z.string(),
|
|
||||||
}),
|
|
||||||
success: z.string(),
|
|
||||||
error: z.string(),
|
|
||||||
cancel: z.string(),
|
|
||||||
}),
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { metrics } from "@opentelemetry/api"
|
|||||||
|
|
||||||
import * as api from "@/lib/api"
|
import * as api from "@/lib/api"
|
||||||
import { getVerifiedUser } from "@/server/routers/user/query"
|
import { getVerifiedUser } from "@/server/routers/user/query"
|
||||||
import { router, safeProtectedProcedure } from "@/server/trpc"
|
import { bookingServiceProcedure, router } from "@/server/trpc"
|
||||||
|
|
||||||
import { getMembership } from "@/utils/user"
|
import { getMembership } from "@/utils/user"
|
||||||
|
|
||||||
@@ -36,13 +36,15 @@ async function getMembershipNumber(
|
|||||||
|
|
||||||
export const bookingMutationRouter = router({
|
export const bookingMutationRouter = router({
|
||||||
booking: router({
|
booking: router({
|
||||||
create: safeProtectedProcedure
|
create: bookingServiceProcedure
|
||||||
.input(createBookingInput)
|
.input(createBookingInput)
|
||||||
.mutation(async function ({ ctx, input }) {
|
.mutation(async function ({ ctx, input }) {
|
||||||
const { checkInDate, checkOutDate, hotelId } = input
|
const { checkInDate, checkOutDate, hotelId } = input
|
||||||
|
|
||||||
|
// TODO: add support for user token OR service token in procedure
|
||||||
|
// then we can fetch membership number if user token exists
|
||||||
const loggingAttributes = {
|
const loggingAttributes = {
|
||||||
membershipNumber: await getMembershipNumber(ctx.session),
|
// membershipNumber: await getMembershipNumber(ctx.session),
|
||||||
checkInDate,
|
checkInDate,
|
||||||
checkOutDate,
|
checkOutDate,
|
||||||
hotelId,
|
hotelId,
|
||||||
@@ -56,11 +58,10 @@ export const bookingMutationRouter = router({
|
|||||||
query: loggingAttributes,
|
query: loggingAttributes,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
const headers = ctx.session
|
const headers = {
|
||||||
? {
|
Authorization: `Bearer ${ctx.serviceToken}`,
|
||||||
Authorization: `Bearer ${ctx.session?.token.access_token}`,
|
}
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
const apiResponse = await api.post(api.endpoints.v1.booking, {
|
const apiResponse = await api.post(api.endpoints.v1.booking, {
|
||||||
headers,
|
headers,
|
||||||
body: input,
|
body: input,
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ export const createBookingSchema = z
|
|||||||
data: z.object({
|
data: z.object({
|
||||||
attributes: z.object({
|
attributes: z.object({
|
||||||
confirmationNumber: z.string(),
|
confirmationNumber: z.string(),
|
||||||
cancellationNumber: z.string().nullable(),
|
cancellationNumber: z.string().optional(),
|
||||||
reservationStatus: z.string(),
|
reservationStatus: z.string(),
|
||||||
paymentUrl: z.string().nullable(),
|
paymentUrl: z.string().optional(),
|
||||||
}),
|
}),
|
||||||
type: z.string(),
|
type: z.string(),
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
|
|||||||
85
server/routers/booking/query.ts
Normal file
85
server/routers/booking/query.ts
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import { metrics } from "@opentelemetry/api"
|
||||||
|
|
||||||
|
import * as api from "@/lib/api"
|
||||||
|
import { badRequestError, serverErrorByStatus } from "@/server/errors/trpc"
|
||||||
|
import { bookingServiceProcedure, router } from "@/server/trpc"
|
||||||
|
|
||||||
|
import { getBookingStatusInput } from "./input"
|
||||||
|
import { createBookingSchema } from "./output"
|
||||||
|
|
||||||
|
const meter = metrics.getMeter("trpc.booking")
|
||||||
|
const getBookingStatusCounter = meter.createCounter("trpc.booking.status")
|
||||||
|
const getBookingStatusSuccessCounter = meter.createCounter(
|
||||||
|
"trpc.booking.status-success"
|
||||||
|
)
|
||||||
|
const getBookingStatusFailCounter = meter.createCounter(
|
||||||
|
"trpc.booking.status-fail"
|
||||||
|
)
|
||||||
|
|
||||||
|
export const bookingQueryRouter = router({
|
||||||
|
status: bookingServiceProcedure
|
||||||
|
.input(getBookingStatusInput)
|
||||||
|
.query(async function ({ ctx, input }) {
|
||||||
|
const { confirmationNumber } = input
|
||||||
|
getBookingStatusCounter.add(1, { confirmationNumber })
|
||||||
|
|
||||||
|
const apiResponse = await api.get(
|
||||||
|
`${api.endpoints.v1.booking}/${confirmationNumber}/status`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${ctx.serviceToken}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!apiResponse.ok) {
|
||||||
|
const responseMessage = await apiResponse.text()
|
||||||
|
getBookingStatusFailCounter.add(1, {
|
||||||
|
confirmationNumber,
|
||||||
|
error_type: "http_error",
|
||||||
|
error: responseMessage,
|
||||||
|
})
|
||||||
|
console.error(
|
||||||
|
"api.booking.status error",
|
||||||
|
JSON.stringify({
|
||||||
|
query: { confirmationNumber },
|
||||||
|
error: {
|
||||||
|
status: apiResponse.status,
|
||||||
|
statusText: apiResponse.statusText,
|
||||||
|
text: responseMessage,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
throw serverErrorByStatus(apiResponse.status, apiResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
const apiJson = await apiResponse.json()
|
||||||
|
const verifiedData = createBookingSchema.safeParse(apiJson)
|
||||||
|
if (!verifiedData.success) {
|
||||||
|
getBookingStatusFailCounter.add(1, {
|
||||||
|
confirmationNumber,
|
||||||
|
error_type: "validation_error",
|
||||||
|
error: JSON.stringify(verifiedData.error),
|
||||||
|
})
|
||||||
|
console.error(
|
||||||
|
"api.booking.status validation error",
|
||||||
|
JSON.stringify({
|
||||||
|
query: { confirmationNumber },
|
||||||
|
error: verifiedData.error,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
throw badRequestError()
|
||||||
|
}
|
||||||
|
|
||||||
|
getBookingStatusSuccessCounter.add(1, { confirmationNumber })
|
||||||
|
console.info(
|
||||||
|
"api.booking.status success",
|
||||||
|
JSON.stringify({
|
||||||
|
query: { confirmationNumber },
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
return verifiedData.data
|
||||||
|
}),
|
||||||
|
})
|
||||||
@@ -436,6 +436,22 @@ export const roomSchema = z.object({
|
|||||||
type: z.enum(["roomcategories"]),
|
type: z.enum(["roomcategories"]),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const merchantInformationSchema = z.object({
|
||||||
|
webMerchantId: z.string(),
|
||||||
|
cards: z.record(z.string(), z.boolean()).transform((val) => {
|
||||||
|
return Object.entries(val)
|
||||||
|
.filter(([_, enabled]) => enabled)
|
||||||
|
.map(([key]) => key)
|
||||||
|
}),
|
||||||
|
alternatePaymentOptions: z
|
||||||
|
.record(z.string(), z.boolean())
|
||||||
|
.transform((val) => {
|
||||||
|
return Object.entries(val)
|
||||||
|
.filter(([_, enabled]) => enabled)
|
||||||
|
.map(([key]) => key)
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
// NOTE: Find schema at: https://aks-test.scandichotels.com/hotel/swagger/v1/index.html
|
// NOTE: Find schema at: https://aks-test.scandichotels.com/hotel/swagger/v1/index.html
|
||||||
export const getHotelDataSchema = z.object({
|
export const getHotelDataSchema = z.object({
|
||||||
data: z.object({
|
data: z.object({
|
||||||
@@ -471,6 +487,7 @@ export const getHotelDataSchema = z.object({
|
|||||||
hotelContent: hotelContentSchema,
|
hotelContent: hotelContentSchema,
|
||||||
detailedFacilities: z.array(detailedFacilitySchema),
|
detailedFacilities: z.array(detailedFacilitySchema),
|
||||||
healthFacilities: z.array(healthFacilitySchema),
|
healthFacilities: z.array(healthFacilitySchema),
|
||||||
|
merchantInformationData: merchantInformationSchema,
|
||||||
rewardNight: rewardNightSchema,
|
rewardNight: rewardNightSchema,
|
||||||
pointsOfInterest: z
|
pointsOfInterest: z
|
||||||
.array(pointOfInterestSchema)
|
.array(pointOfInterestSchema)
|
||||||
|
|||||||
@@ -121,29 +121,24 @@ export const safeProtectedProcedure = t.procedure.use(async function (opts) {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
export const profileServiceProcedure = t.procedure.use(async (opts) => {
|
function createServiceProcedure(serviceName: string) {
|
||||||
const { access_token } = await fetchServiceToken(["profile"])
|
return t.procedure.use(async (opts) => {
|
||||||
if (!access_token) {
|
const { access_token } = await fetchServiceToken([serviceName])
|
||||||
throw internalServerError("Failed to obtain profile service token")
|
if (!access_token) {
|
||||||
}
|
throw internalServerError(`Failed to obtain ${serviceName} service token`)
|
||||||
return opts.next({
|
}
|
||||||
ctx: {
|
return opts.next({
|
||||||
serviceToken: access_token,
|
ctx: {
|
||||||
},
|
serviceToken: access_token,
|
||||||
|
},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
export const bookingServiceProcedure = createServiceProcedure("booking")
|
||||||
|
export const hotelServiceProcedure = createServiceProcedure("hotel")
|
||||||
|
export const profileServiceProcedure = createServiceProcedure("profile")
|
||||||
|
|
||||||
export const hotelServiceProcedure = t.procedure.use(async (opts) => {
|
|
||||||
const { access_token } = await fetchServiceToken(["hotel"])
|
|
||||||
if (!access_token) {
|
|
||||||
throw internalServerError("Failed to obtain hotel service token")
|
|
||||||
}
|
|
||||||
return opts.next({
|
|
||||||
ctx: {
|
|
||||||
serviceToken: access_token,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
})
|
|
||||||
export const serverActionProcedure = t.procedure.experimental_caller(
|
export const serverActionProcedure = t.procedure.experimental_caller(
|
||||||
experimental_nextAppDirCaller({
|
experimental_nextAppDirCaller({
|
||||||
createContext,
|
createContext,
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { Rate } from "@/server/routers/hotels/output"
|
import { Rate } from "@/server/routers/hotels/output"
|
||||||
|
|
||||||
|
import { Hotel } from "@/types/hotel"
|
||||||
|
|
||||||
export interface SectionProps {
|
export interface SectionProps {
|
||||||
nextPath: string
|
nextPath: string
|
||||||
}
|
}
|
||||||
@@ -33,6 +35,10 @@ export interface RoomSelectionProps extends SectionProps {
|
|||||||
|
|
||||||
export interface DetailsProps extends SectionProps {}
|
export interface DetailsProps extends SectionProps {}
|
||||||
|
|
||||||
|
export interface PaymentProps {
|
||||||
|
hotel: Hotel
|
||||||
|
}
|
||||||
|
|
||||||
export interface SectionPageProps {
|
export interface SectionPageProps {
|
||||||
breakfast?: string
|
breakfast?: string
|
||||||
bed?: string
|
bed?: string
|
||||||
|
|||||||
Reference in New Issue
Block a user