diff --git a/app/[lang]/(live)/(public)/hotelreservation/[section]/page.tsx b/app/[lang]/(live)/(public)/hotelreservation/[section]/page.tsx index 9f91bee96..d2f2a5450 100644 --- a/app/[lang]/(live)/(public)/hotelreservation/[section]/page.tsx +++ b/app/[lang]/(live)/(public)/hotelreservation/[section]/page.tsx @@ -4,9 +4,9 @@ import { getProfileSafely } from "@/lib/trpc/memoizedRequests" import { serverClient } from "@/lib/trpc/server" import BedType from "@/components/HotelReservation/EnterDetails/BedType" +import Breakfast from "@/components/HotelReservation/EnterDetails/Breakfast" import Details from "@/components/HotelReservation/EnterDetails/Details" import HotelSelectionHeader from "@/components/HotelReservation/HotelSelectionHeader" -import BreakfastSelection from "@/components/HotelReservation/SelectRate/BreakfastSelection" import Payment from "@/components/HotelReservation/SelectRate/Payment" import RoomSelection from "@/components/HotelReservation/SelectRate/RoomSelection" import SectionAccordion from "@/components/HotelReservation/SelectRate/SectionAccordion" @@ -104,7 +104,7 @@ export default async function SectionsPage({ const selectedBreakfast = searchParams.breakfast ? breakfastAlternatives.find((a) => a.value === searchParams.breakfast) - ?.name + ?.name : undefined const selectedRoom = searchParams.roomClass @@ -132,9 +132,9 @@ export default async function SectionsPage({ selection={ selectedRoom ? [ - selectedRoom, - intl.formatMessage({ id: selectedFlexibility }), - ] + selectedRoom, + intl.formatMessage({ id: selectedFlexibility }), + ] : undefined } path={`select-rate?${currentSearchParams}`} @@ -162,12 +162,7 @@ export default async function SectionsPage({ selection={selectedBreakfast} path={`breakfast?${currentSearchParams}`} > - {params.section === "breakfast" && ( - - )} + {params.section === "breakfast" ? : null} ({ - defaultValues: { - bed: bedTypeEnum.KING, - }, criteriaMode: "all", mode: "all", resolver: zodResolver(bedTypeSchema), diff --git a/components/HotelReservation/EnterDetails/Breakfast/breakfast.module.css b/components/HotelReservation/EnterDetails/Breakfast/breakfast.module.css new file mode 100644 index 000000000..81fd223b9 --- /dev/null +++ b/components/HotelReservation/EnterDetails/Breakfast/breakfast.module.css @@ -0,0 +1,7 @@ +.form { + display: grid; + gap: var(--Spacing-x2); + grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); + padding-bottom: var(--Spacing-x3); + width: min(600px, 100%); +} diff --git a/components/HotelReservation/EnterDetails/Breakfast/index.tsx b/components/HotelReservation/EnterDetails/Breakfast/index.tsx new file mode 100644 index 000000000..b8f00ec83 --- /dev/null +++ b/components/HotelReservation/EnterDetails/Breakfast/index.tsx @@ -0,0 +1,70 @@ +"use client" + +import { zodResolver } from "@hookform/resolvers/zod" +import { FormProvider, useForm } from "react-hook-form" +import { useIntl } from "react-intl" + +import { BreakfastIcon, NoBreakfastIcon } from "@/components/Icons" +import RadioCard from "@/components/TempDesignSystem/Form/Card/Radio" + +import { breakfastSchema } from "./schema" + +import styles from "./breakfast.module.css" + +import type { BreakfastSchema } from "@/types/components/enterDetails/breakfast" +import { breakfastEnum } from "@/types/enums/breakfast" + +export default function Breakfast() { + const intl = useIntl() + + const methods = useForm({ + criteriaMode: "all", + mode: "all", + resolver: zodResolver(breakfastSchema), + reValidateMode: "onChange", + }) + + return ( + +
+ {amount} {currency}/night per adult" }, + { + amount: "150", + b: (str) => {str}, + currency: "SEK", + } + )} + text={intl.formatMessage({ + id: "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.", + })} + title={intl.formatMessage({ id: "Breakfast buffet" })} + value={breakfastEnum.BREAKFAST} + /> + + +
+ ) +} diff --git a/components/HotelReservation/EnterDetails/Breakfast/schema.ts b/components/HotelReservation/EnterDetails/Breakfast/schema.ts new file mode 100644 index 000000000..34cc5efca --- /dev/null +++ b/components/HotelReservation/EnterDetails/Breakfast/schema.ts @@ -0,0 +1,7 @@ +import { z } from "zod" + +import { breakfastEnum } from "@/types/enums/breakfast" + +export const breakfastSchema = z.object({ + breakfast: z.nativeEnum(breakfastEnum), +}) diff --git a/components/Icons/Breakfast.tsx b/components/Icons/Breakfast.tsx new file mode 100644 index 000000000..dccfc0c39 --- /dev/null +++ b/components/Icons/Breakfast.tsx @@ -0,0 +1,40 @@ +import { iconVariants } from "./variants" + +import type { IconProps } from "@/types/components/icon" + +export default function BreakfastIcon({ + className, + color, + ...props +}: IconProps) { + const classNames = iconVariants({ className, color }) + return ( + + + + + + + + + ) +} diff --git a/components/Icons/NoBreakfast.tsx b/components/Icons/NoBreakfast.tsx new file mode 100644 index 000000000..c09af6616 --- /dev/null +++ b/components/Icons/NoBreakfast.tsx @@ -0,0 +1,40 @@ +import { iconVariants } from "./variants" + +import type { IconProps } from "@/types/components/icon" + +export default function NoBreakfastIcon({ + className, + color, + ...props +}: IconProps) { + const classNames = iconVariants({ className, color }) + return ( + + + + + + + + + ) +} diff --git a/components/Icons/index.tsx b/components/Icons/index.tsx index 73b554342..f26933255 100644 --- a/components/Icons/index.tsx +++ b/components/Icons/index.tsx @@ -4,6 +4,7 @@ export { default as AirplaneIcon } from "./Airplane" export { default as ArrowRightIcon } from "./ArrowRight" export { default as BarIcon } from "./Bar" export { default as BikingIcon } from "./Biking" +export { default as BreakfastIcon } from "./Breakfast" export { default as BusinessIcon } from "./Business" export { default as CalendarIcon } from "./Calendar" export { default as CameraIcon } from "./Camera" @@ -40,6 +41,7 @@ export { default as LockIcon } from "./Lock" export { default as MapIcon } from "./Map" export { default as MinusIcon } from "./Minus" export { default as MuseumIcon } from "./Museum" +export { default as NoBreakfastIcon } from "./NoBreakfast" export { default as ParkingIcon } from "./Parking" export { default as People2Icon } from "./People2" export { default as PersonIcon } from "./Person" diff --git a/i18n/dictionaries/da.json b/i18n/dictionaries/da.json index dd139b105..e29d7cf6d 100644 --- a/i18n/dictionaries/da.json +++ b/i18n/dictionaries/da.json @@ -1,5 +1,6 @@ { "Included (based on availability)": "Inkluderet (baseret på tilgængelighed)", + "{amount} {currency}/night per adult": "{amount} {currency}/nat pr. voksen", "A destination or hotel name is needed to be able to search for a hotel room.": "Et destinations- eller hotelnavn er nødvendigt for at kunne søge efter et hotelværelse.", "A photo of the room": "Et foto af værelset", "About meetings & conferences": "About meetings & conferences", @@ -8,6 +9,7 @@ "Add new card": "Tilføj nyt kort", "Address": "Adresse", "Airport": "Lufthavn", + "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle vores morgenmadsbuffeter tilbyder glutenfrie, veganske og allergivenlige muligheder.", "Already a friend?": "Allerede en ven?", "Amenities": "Faciliteter", "Amusement park": "Forlystelsespark", @@ -29,6 +31,7 @@ "Book reward night": "Book bonusnat", "Booking number": "Bookingnummer", "Breakfast": "Morgenmad", + "Breakfast buffet": "Morgenbuffet", "Breakfast excluded": "Morgenmad ikke inkluderet", "Breakfast included": "Morgenmad inkluderet", "Bus terminal": "Busstation", @@ -159,6 +162,7 @@ "New password": "Nyt kodeord", "Next": "Næste", "Nights needed to level up": "Nætter nødvendige for at komme i niveau", + "No breakfast": "Ingen morgenmad", "No content published": "Intet indhold offentliggjort", "No matching location found": "Der blev ikke fundet nogen matchende placering", "No results": "Ingen resultater", @@ -275,6 +279,7 @@ "Year": "År", "Yes, discard changes": "Ja, kasser ændringer", "Yes, remove my card": "Ja, fjern mit kort", + "You can always change your mind later and add breakfast at the hotel.": "Du kan altid ombestemme dig senere og tilføje morgenmad på hotellet.", "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 upcoming stays.": "Du har ingen kommende ophold.", @@ -309,6 +314,7 @@ "spendable points expiring by": "{points} Brugbare point udløber den {date}", "to": "til", "uppercase letter": "stort bogstav", + "{amount} {currency}": "{amount} {currency}", "{difference}{amount} {currency}": "{difference}{amount} {currency}", "{width} cm × {length} cm": "{width} cm × {length} cm" -} \ No newline at end of file +} diff --git a/i18n/dictionaries/de.json b/i18n/dictionaries/de.json index cca633251..ee4bccf96 100644 --- a/i18n/dictionaries/de.json +++ b/i18n/dictionaries/de.json @@ -1,5 +1,6 @@ { "Included (based on availability)": "Inbegriffen (je nach Verfügbarkeit)", + "{amount} {currency}/night per adult": "{amount} {currency}/Nacht pro Erwachsener", "A destination or hotel name is needed to be able to search for a hotel room.": "Ein Reiseziel oder Hotelname wird benötigt, um nach einem Hotelzimmer suchen zu können.", "A photo of the room": "Ein Foto des Zimmers", "About meetings & conferences": "About meetings & conferences", @@ -8,6 +9,7 @@ "Add new card": "Neue Karte hinzufügen", "Address": "Adresse", "Airport": "Flughafen", + "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle unsere Frühstücksbuffets bieten glutenfreie, vegane und allergikerfreundliche Speisen.", "Already a friend?": "Sind wir schon Freunde?", "Amenities": "Annehmlichkeiten", "Amusement park": "Vergnügungspark", @@ -29,6 +31,7 @@ "Book reward night": "Bonusnacht buchen", "Booking number": "Buchungsnummer", "Breakfast": "Frühstück", + "Breakfast buffet": "Frühstücksbuffet", "Breakfast excluded": "Frühstück nicht inbegriffen", "Breakfast included": "Frühstück inbegriffen", "Breakfast restaurant": "Breakfast restaurant", @@ -159,6 +162,7 @@ "New password": "Neues Kennwort", "Next": "Nächste", "Nights needed to level up": "Nächte, die zum Levelaufstieg benötigt werden", + "No breakfast": "Kein Frühstück", "No content published": "Kein Inhalt veröffentlicht", "No matching location found": "Kein passender Standort gefunden", "No results": "Keine Ergebnisse", @@ -275,6 +279,7 @@ "Year": "Jahr", "Yes, discard changes": "Ja, Änderungen verwerfen", "Yes, remove my card": "Ja, meine Karte entfernen", + "You can always change your mind later and add breakfast at the hotel.": "Sie können es sich später jederzeit anders überlegen und das Frühstück im Hotel hinzufügen.", "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 upcoming stays.": "Sie haben keine bevorstehenden Aufenthalte.", @@ -309,6 +314,7 @@ "spendable points expiring by": "{points} Einlösbare punkte verfallen bis zum {date}", "to": "zu", "uppercase letter": "großbuchstabe", + "{amount} {currency}": "{amount} {currency}", "{difference}{amount} {currency}": "{difference}{amount} {currency}", "{width} cm × {length} cm": "{width} cm × {length} cm" -} \ No newline at end of file +} diff --git a/i18n/dictionaries/en.json b/i18n/dictionaries/en.json index f13a60b2c..1e51379f2 100644 --- a/i18n/dictionaries/en.json +++ b/i18n/dictionaries/en.json @@ -1,5 +1,6 @@ { "Included (based on availability)": "Included (based on availability)", + "{amount} {currency}/night per adult": "{amount} {currency}/night per adult", "A destination or hotel name is needed to be able to search for a hotel room.": "A destination or hotel name is needed to be able to search for a hotel room.", "A photo of the room": "A photo of the room", "About meetings & conferences": "About meetings & conferences", @@ -8,6 +9,7 @@ "Add new card": "Add new card", "Address": "Address", "Airport": "Airport", + "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.", "Already a friend?": "Already a friend?", "Amenities": "Amenities", "Amusement park": "Amusement park", @@ -29,6 +31,7 @@ "Book reward night": "Book reward night", "Booking number": "Booking number", "Breakfast": "Breakfast", + "Breakfast buffet": "Breakfast buffet", "Breakfast excluded": "Breakfast excluded", "Breakfast included": "Breakfast included", "Breakfast restaurant": "Breakfast restaurant", @@ -159,6 +162,7 @@ "New password": "New password", "Next": "Next", "Nights needed to level up": "Nights needed to level up", + "No breakfast": "No breakfast", "No content published": "No content published", "No matching location found": "No matching location found", "No results": "No results", @@ -275,6 +279,7 @@ "Year": "Year", "Yes, discard changes": "Yes, discard changes", "Yes, remove my card": "Yes, remove my card", + "You can always change your mind later and add breakfast at the hotel.": "You can always change your mind later and add breakfast at the hotel.", "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 upcoming stays.": "You have no upcoming stays.", @@ -309,6 +314,7 @@ "spendable points expiring by": "{points} spendable points expiring by {date}", "to": "to", "uppercase letter": "uppercase letter", + "{amount} {currency}": "{amount} {currency}", "{difference}{amount} {currency}": "{difference}{amount} {currency}", "{width} cm × {length} cm": "{width} cm × {length} cm" -} \ No newline at end of file +} diff --git a/i18n/dictionaries/fi.json b/i18n/dictionaries/fi.json index 064cffe7c..5e3ab2fc4 100644 --- a/i18n/dictionaries/fi.json +++ b/i18n/dictionaries/fi.json @@ -1,5 +1,6 @@ { "Included (based on availability)": "Sisältyy (saatavuuden mukaan)", + "{amount} {currency}/night per adult": "{amount} {currency}/yö per aikuinen", "A destination or hotel name is needed to be able to search for a hotel room.": "Kohteen tai hotellin nimi tarvitaan, jotta hotellihuonetta voidaan hakea.", "A photo of the room": "Kuva huoneesta", "About meetings & conferences": "About meetings & conferences", @@ -8,6 +9,7 @@ "Add new card": "Lisää uusi kortti", "Address": "Osoite", "Airport": "Lentokenttä", + "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Kaikki aamiaisbuffettimme tarjoavat gluteenittomia, vegaanisia ja allergiaystävällisiä vaihtoehtoja.", "Already a friend?": "Oletko jo ystävä?", "Amenities": "Mukavuudet", "Amusement park": "Huvipuisto", @@ -29,6 +31,7 @@ "Book reward night": "Kirjapalkinto-ilta", "Booking number": "Varausnumero", "Breakfast": "Aamiainen", + "Breakfast buffet": "Aamiaisbuffet", "Breakfast excluded": "Aamiainen ei sisälly", "Breakfast included": "Aamiainen sisältyy", "Bus terminal": "Bussiasema", @@ -159,6 +162,7 @@ "New password": "Uusi salasana", "Next": "Seuraava", "Nights needed to level up": "Yöt, joita tarvitaan tasolle", + "No breakfast": "Ei aamiaista", "No content published": "Ei julkaistua sisältöä", "No matching location found": "Vastaavaa sijaintia ei löytynyt", "No results": "Ei tuloksia", @@ -276,6 +280,7 @@ "Year": "Vuosi", "Yes, discard changes": "Kyllä, hylkää muutokset", "Yes, remove my card": "Kyllä, poista korttini", + "You can always change your mind later and add breakfast at the hotel.": "Voit aina muuttaa mieltäsi myöhemmin ja lisätä aamiaisen hotelliin.", "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 upcoming stays.": "Sinulla ei ole tulevia majoituksia.", @@ -310,6 +315,7 @@ "spendable points expiring by": "{points} pistettä vanhenee {date} mennessä", "to": "to", "uppercase letter": "iso kirjain", + "{amount} {currency}": "{amount} {currency}", "{difference}{amount} {currency}": "{difference}{amount} {currency}", "{width} cm × {length} cm": "{width} cm × {length} cm" -} \ No newline at end of file +} diff --git a/i18n/dictionaries/no.json b/i18n/dictionaries/no.json index aea1e69a1..1dd97b8f2 100644 --- a/i18n/dictionaries/no.json +++ b/i18n/dictionaries/no.json @@ -1,5 +1,6 @@ { "Included (based on availability)": "Inkludert (basert på tilgjengelighet)", + "{amount} {currency}/night per adult": "{amount} {currency}/natt per voksen", "A destination or hotel name is needed to be able to search for a hotel room.": "Et reisemål eller hotellnavn er nødvendig for å kunne søke etter et hotellrom.", "A photo of the room": "Et bilde av rommet", "About meetings & conferences": "About meetings & conferences", @@ -8,6 +9,7 @@ "Add new card": "Legg til nytt kort", "Address": "Adresse", "Airport": "Flyplass", + "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alle våre frokostbufféer tilbyr glutenfrie, veganske og allergivennlige alternativer.", "Already a friend?": "Allerede Friend?", "Amenities": "Fasiliteter", "Amusement park": "Tivoli", @@ -29,6 +31,7 @@ "Book reward night": "Bestill belønningskveld", "Booking number": "Bestillingsnummer", "Breakfast": "Frokost", + "Breakfast buffet": "Breakfast buffet", "Breakfast excluded": "Frokost ekskludert", "Breakfast included": "Frokost inkludert", "Bus terminal": "Bussterminal", @@ -158,6 +161,7 @@ "New password": "Nytt passord", "Next": "Neste", "Nights needed to level up": "Netter som trengs for å komme opp i nivå", + "No breakfast": "Ingen frokost", "No content published": "Ingen innhold publisert", "No matching location found": "Fant ingen samsvarende plassering", "No results": "Ingen resultater", @@ -274,6 +278,7 @@ "Year": "År", "Yes, discard changes": "Ja, forkast endringer", "Yes, remove my card": "Ja, fjern kortet mitt", + "You can always change your mind later and add breakfast at the hotel.": "Du kan alltid ombestemme deg senere og legge til frokost på hotellet.", "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 upcoming stays.": "Du har ingen kommende opphold.", @@ -308,6 +313,7 @@ "spendable points expiring by": "{points} Brukbare poeng utløper innen {date}", "to": "til", "uppercase letter": "stor bokstav", + "{amount} {currency}": "{amount} {currency}", "{difference}{amount} {currency}": "{difference}{amount} {currency}", "{width} cm × {length} cm": "{width} cm × {length} cm" -} \ No newline at end of file +} diff --git a/i18n/dictionaries/sv.json b/i18n/dictionaries/sv.json index f70bb5cf3..6f5fcd37a 100644 --- a/i18n/dictionaries/sv.json +++ b/i18n/dictionaries/sv.json @@ -1,5 +1,6 @@ { "Included (based on availability)": "Ingår (baserat på tillgänglighet)", + "{amount} {currency}/night per adult": "{amount} {currency}/natt per vuxen", "A destination or hotel name is needed to be able to search for a hotel room.": "Ett destinations- eller hotellnamn behövs för att kunna söka efter ett hotellrum.", "A photo of the room": "Ett foto av rummet", "About meetings & conferences": "About meetings & conferences", @@ -8,6 +9,7 @@ "Add new card": "Lägg till nytt kort", "Address": "Adress", "Airport": "Flygplats", + "All our breakfast buffets offer gluten free, vegan, and allergy-friendly options.": "Alla våra frukostbufféer erbjuder glutenfria, veganska och allergivänliga alternativ.", "Already a friend?": "Är du redan en vän?", "Amenities": "Bekvämligheter", "Amusement park": "Nöjespark", @@ -29,6 +31,7 @@ "Book reward night": "Boka frinatt", "Booking number": "Bokningsnummer", "Breakfast": "Frukost", + "Breakfast buffet": "Frukostbuffé", "Breakfast excluded": "Frukost ingår ej", "Breakfast included": "Frukost ingår", "Bus terminal": "Bussterminal", @@ -160,6 +163,7 @@ "New password": "Nytt lösenord", "Next": "Nästa", "Nights needed to level up": "Nätter som behövs för att gå upp i nivå", + "No breakfast": "Ingen frukost", "No content published": "Inget innehåll publicerat", "No matching location found": "Ingen matchande plats hittades", "No results": "Inga resultat", @@ -276,6 +280,7 @@ "Year": "År", "Yes, discard changes": "Ja, ignorera ändringar", "Yes, remove my card": "Ja, ta bort mitt kort", + "You can always change your mind later and add breakfast at the hotel.": "Du kan alltid ändra dig senare och lägga till frukost på hotellet.", "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 upcoming stays.": "Du har inga planerade resor.", @@ -310,6 +315,7 @@ "spendable points expiring by": "{points} poäng förfaller {date}", "to": "till", "uppercase letter": "stor bokstav", + "{amount} {currency}": "{amount} {currency}", "{difference}{amount} {currency}": "{difference}{amount} {currency}", "{width} cm × {length} cm": "{width} cm × {length} cm" -} \ No newline at end of file +} diff --git a/types/components/enterDetails/breakfast.ts b/types/components/enterDetails/breakfast.ts new file mode 100644 index 000000000..868bc96a1 --- /dev/null +++ b/types/components/enterDetails/breakfast.ts @@ -0,0 +1,5 @@ +import { z } from "zod" + +import { breakfastSchema } from "@/components/HotelReservation/EnterDetails/Breakfast/schema" + +export interface BreakfastSchema extends z.output {} diff --git a/types/enums/breakfast.ts b/types/enums/breakfast.ts new file mode 100644 index 000000000..567db2860 --- /dev/null +++ b/types/enums/breakfast.ts @@ -0,0 +1,4 @@ +export enum breakfastEnum { + BREAKFAST = "BREAKFAST", + NO_BREAKFAST = "NO_BREAKFAST", +}