This commit is contained in:
Joakim Jäderberg
2024-11-21 12:43:25 +01:00
50 changed files with 590 additions and 316 deletions

View File

@@ -1,60 +1,13 @@
import { serverClient } from "@/lib/trpc/server"
import { ChevronRightSmallIcon,HouseIcon } from "@/components/Icons"
import Link from "@/components/TempDesignSystem/Link"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import styles from "./breadcrumbs.module.css"
import BreadcrumbsComp from "@/components/TempDesignSystem/Breadcrumbs"
export default async function Breadcrumbs() {
const breadcrumbs = await serverClient().contentstack.breadcrumbs.get()
if (!breadcrumbs?.length) {
return null
}
const homeBreadcrumb = breadcrumbs.shift()
return (
<nav className={styles.breadcrumbs}>
<ul className={styles.list}>
{homeBreadcrumb ? (
<li className={styles.listItem}>
<Link
className={styles.homeLink}
color="peach80"
href={homeBreadcrumb.href!}
variant="breadcrumb"
>
<HouseIcon width={16} height={16} color="peach80" />
</Link>
<ChevronRightSmallIcon aria-hidden="true" color="peach80" />
</li>
) : null}
{breadcrumbs.map((breadcrumb) => {
if (breadcrumb.href) {
return (
<li key={breadcrumb.uid} className={styles.listItem}>
<Link
color="peach80"
href={breadcrumb.href}
variant="breadcrumb"
>
{breadcrumb.title}
</Link>
<ChevronRightSmallIcon aria-hidden="true" color="peach80" />
</li>
)
}
return (
<li key={breadcrumb.uid} className={styles.listItem}>
<Footnote color="burgundy" type="bold">
{breadcrumb.title}
</Footnote>
</li>
)
})}
</ul>
</nav>
)
return <BreadcrumbsComp breadcrumbs={breadcrumbs} />
}

View File

@@ -55,4 +55,8 @@ export const signedInDetailsSchema = z.object({
firstName: z.string().optional(),
lastName: z.string().optional(),
phoneNumber: z.string().optional(),
join: z
.boolean()
.optional()
.transform((_) => false),
})

View File

@@ -0,0 +1,42 @@
"use client"
import { useRouter } from "next/navigation"
import { useEffect } from "react"
import { detailsStorageName } from "@/stores/details"
import { createQueryParamsForEnterDetails } from "@/components/HotelReservation/SelectRate/RoomSelection/utils"
import LoadingSpinner from "@/components/LoadingSpinner"
import { DetailsState } from "@/types/stores/details"
export default function PaymentCallback({
returnUrl,
searchObject,
}: {
returnUrl: string
searchObject: URLSearchParams
}) {
const router = useRouter()
useEffect(() => {
const bookingData = window.sessionStorage.getItem(detailsStorageName)
if (bookingData) {
const detailsStorage: Record<
"state",
Pick<DetailsState, "data">
> = JSON.parse(bookingData)
const searchParams = createQueryParamsForEnterDetails(
detailsStorage.state.data.booking,
searchObject
)
if (searchParams.size > 0) {
router.replace(`${returnUrl}?${searchParams.toString()}`)
}
}
}, [returnUrl, router, searchObject])
return <LoadingSpinner />
}

View File

@@ -51,6 +51,7 @@ function isPaymentMethodEnum(value: string): value is PaymentMethodEnum {
}
export default function Payment({
user,
roomPrice,
otherPaymentOptions,
savedCreditCards,
@@ -59,7 +60,6 @@ export default function Payment({
const router = useRouter()
const lang = useLang()
const intl = useIntl()
const queryParams = useSearchParams()
const { booking, ...userData } = useDetailsStore((state) => state.data)
const setIsSubmittingDisabled = useDetailsStore(
(state) => state.actions.setIsSubmittingDisabled
@@ -163,9 +163,6 @@ export default function Payment({
])
function handleSubmit(data: PaymentFormData) {
const allQueryParams =
queryParams.size > 0 ? `?${queryParams.toString()}` : ""
// set payment method to card if saved card is submitted
const paymentMethod = isPaymentMethodEnum(data.paymentMethod)
? data.paymentMethod
@@ -175,6 +172,8 @@ export default function Payment({
(card) => card.id === data.paymentMethod
)
const paymentRedirectUrl = `${env.NEXT_PUBLIC_NODE_ENV === "development" ? `http://localhost:${env.NEXT_PUBLIC_PORT}` : ""}/${lang}/hotelreservation/payment-callback`
initiateBooking.mutate({
hotelId: hotel,
checkInDate: fromDate,
@@ -185,7 +184,8 @@ export default function Payment({
age: child.age,
bedType: bedTypeMap[parseInt(child.bed.toString())],
})),
rateCode: room.rateCode,
rateCode:
user || join || membershipNo ? room.counterRateCode : room.rateCode,
roomTypeCode: bedType!.roomTypeCode, // A selection has been made in order to get to this step.
guest: {
title: "",
@@ -222,9 +222,9 @@ export default function Payment({
}
: undefined,
success: `${env.NEXT_PUBLIC_PAYMENT_CALLBACK_URL}/${lang}/success`,
error: `${env.NEXT_PUBLIC_PAYMENT_CALLBACK_URL}/${lang}/error${allQueryParams}`,
cancel: `${env.NEXT_PUBLIC_PAYMENT_CALLBACK_URL}/${lang}/cancel${allQueryParams}`,
success: `${paymentRedirectUrl}/success`,
error: `${paymentRedirectUrl}/error`,
cancel: `${paymentRedirectUrl}/cancel`,
},
})
}

View File

@@ -38,7 +38,7 @@ export function SummaryBottomSheet({ children }: PropsWithChildren) {
{intl.formatMessage(
{ id: "{amount} {currency}" },
{
amount: intl.formatNumber(totalPrice.local.price),
amount: intl.formatNumber(totalPrice.local.amount),
currency: totalPrice.local.currency,
}
)}

View File

@@ -1,6 +1,6 @@
"use client"
import { useEffect, useState } from "react"
import { useEffect, useRef, useState } from "react"
import { ChevronDown } from "react-feather"
import { useIntl } from "react-intl"
@@ -33,6 +33,8 @@ function storeSelector(state: DetailsState) {
toggleSummaryOpen: state.actions.toggleSummaryOpen,
setTotalPrice: state.actions.setTotalPrice,
totalPrice: state.totalPrice,
join: state.data.join,
membershipNo: state.data.membershipNo,
}
}
@@ -51,6 +53,8 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
toDate,
toggleSummaryOpen,
totalPrice,
join,
membershipNo,
} = useDetailsStore(storeSelector)
const diff = dt(toDate).diff(fromDate, "days")
@@ -60,10 +64,8 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
{ totalNights: diff }
)
let color: "uiTextHighContrast" | "red" = "uiTextHighContrast"
if (showMemberPrice) {
color = "red"
}
const color = useRef<"uiTextHighContrast" | "red">("uiTextHighContrast")
const [price, setPrice] = useState(room.prices.public)
const additionalPackageCost = room.packages?.reduce(
(acc, curr) => {
@@ -74,11 +76,23 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
{ local: 0, euro: 0 }
) || { local: 0, euro: 0 }
const roomsPriceLocal = room.localPrice.price + additionalPackageCost.local
const roomsPriceEuro = room.euroPrice
? room.euroPrice.price + additionalPackageCost.euro
const roomsPriceLocal = price.local.amount + additionalPackageCost.local
const roomsPriceEuro = price.euro
? price.euro.amount + additionalPackageCost.euro
: undefined
useEffect(() => {
if (showMemberPrice || join || membershipNo) {
color.current = "red"
if (room.prices.member) {
setPrice(room.prices.member)
}
} else {
color.current = "uiTextHighContrast"
setPrice(room.prices.public)
}
}, [showMemberPrice, join, membershipNo, room.prices])
useEffect(() => {
setChosenBed(bedType)
@@ -87,30 +101,30 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
if (breakfast === false) {
setTotalPrice({
local: {
price: roomsPriceLocal,
currency: room.localPrice.currency,
amount: roomsPriceLocal,
currency: price.local.currency,
},
euro:
room.euroPrice && roomsPriceEuro
price.euro && roomsPriceEuro
? {
price: roomsPriceEuro,
currency: room.euroPrice.currency,
amount: roomsPriceEuro,
currency: price.euro.currency,
}
: undefined,
})
} else {
setTotalPrice({
local: {
price: roomsPriceLocal + parseInt(breakfast.localPrice.totalPrice),
currency: room.localPrice.currency,
amount: roomsPriceLocal + parseInt(breakfast.localPrice.totalPrice),
currency: price.local.currency,
},
euro:
room.euroPrice && roomsPriceEuro
price.euro && roomsPriceEuro
? {
price:
amount:
roomsPriceEuro +
parseInt(breakfast.requestedPrice.totalPrice),
currency: room.euroPrice.currency,
currency: price.euro.currency,
}
: undefined,
})
@@ -120,8 +134,8 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
bedType,
breakfast,
roomsPriceLocal,
room.localPrice.currency,
room.euroPrice,
price.local.currency,
price.euro,
roomsPriceEuro,
setTotalPrice,
])
@@ -151,12 +165,12 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
<div>
<div className={styles.entry}>
<Body color="uiTextHighContrast">{room.roomType}</Body>
<Caption color={color}>
<Caption color={color.current}>
{intl.formatMessage(
{ id: "{amount} {currency}" },
{
amount: intl.formatNumber(room.localPrice.price),
currency: room.localPrice.currency,
amount: intl.formatNumber(price.local.amount),
currency: price.local.currency,
}
)}
</Caption>
@@ -229,7 +243,7 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
<Caption color="uiTextHighContrast">
{intl.formatMessage(
{ id: "{amount} {currency}" },
{ amount: "0", currency: room.localPrice.currency }
{ amount: "0", currency: price.local.currency }
)}
</Caption>
</div>
@@ -243,7 +257,7 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
<Caption color="uiTextMediumContrast">
{intl.formatMessage(
{ id: "{amount} {currency}" },
{ amount: "0", currency: room.localPrice.currency }
{ amount: "0", currency: price.local.currency }
)}
</Caption>
</div>
@@ -279,22 +293,24 @@ export default function Summary({ showMemberPrice, room }: SummaryProps) {
</Link>
</div>
<div>
<Body textTransform="bold">
{intl.formatMessage(
{ id: "{amount} {currency}" },
{
amount: intl.formatNumber(totalPrice.local.price),
currency: totalPrice.local.currency,
}
)}
</Body>
{totalPrice.euro && (
{totalPrice.local.amount > 0 && (
<Body textTransform="bold">
{intl.formatMessage(
{ id: "{amount} {currency}" },
{
amount: intl.formatNumber(totalPrice.local.amount),
currency: totalPrice.local.currency,
}
)}
</Body>
)}
{totalPrice.euro && totalPrice.euro.amount > 0 && (
<Caption color="uiTextMediumContrast">
{intl.formatMessage({ id: "Approx." })}{" "}
{intl.formatMessage(
{ id: "{amount} {currency}" },
{
amount: intl.formatNumber(totalPrice.euro.price),
amount: intl.formatNumber(totalPrice.euro.amount),
currency: totalPrice.euro.currency,
}
)}

View File

@@ -1,9 +1,11 @@
"use client"
import { useSearchParams } from "next/navigation"
import { useEffect, useMemo, useState } from "react"
import { useIntl } from "react-intl"
import { useHotelFilterStore } from "@/stores/hotel-filters"
import Alert from "@/components/TempDesignSystem/Alert"
import { BackToTopButton } from "@/components/TempDesignSystem/BackToTopButton"
import HotelCard from "../HotelCard"
@@ -17,6 +19,7 @@ import {
type HotelData,
} from "@/types/components/hotelReservation/selectHotel/hotelCardListingProps"
import { SortOrder } from "@/types/components/hotelReservation/selectHotel/hotelSorter"
import { AlertTypeEnum } from "@/types/enums/alert"
export default function HotelCardListing({
hotelData,
@@ -28,6 +31,7 @@ export default function HotelCardListing({
const activeFilters = useHotelFilterStore((state) => state.activeFilters)
const setResultCount = useHotelFilterStore((state) => state.setResultCount)
const [showBackToTop, setShowBackToTop] = useState<boolean>(false)
const intl = useIntl()
const sortBy = useMemo(
() => searchParams.get("sort") ?? DEFAULT_SORT,
@@ -69,7 +73,6 @@ export default function HotelCardListing({
const hotels = useMemo(() => {
if (activeFilters.length === 0) {
setResultCount(sortedHotels.length)
return sortedHotels
}
@@ -81,9 +84,8 @@ export default function HotelCardListing({
)
)
setResultCount(filteredHotels.length)
return filteredHotels
}, [activeFilters, sortedHotels, setResultCount])
}, [activeFilters, sortedHotels])
useEffect(() => {
const handleScroll = () => {
@@ -95,23 +97,33 @@ export default function HotelCardListing({
return () => window.removeEventListener("scroll", handleScroll)
}, [])
useEffect(() => {
setResultCount(hotels ? hotels.length : 0)
}, [hotels, setResultCount])
function scrollToTop() {
window.scrollTo({ top: 0, behavior: "smooth" })
}
return (
<section className={styles.hotelCards}>
{hotels?.length
? hotels.map((hotel) => (
<HotelCard
key={hotel.hotelData.operaId}
hotel={hotel}
type={type}
state={hotel.hotelData.name === activeCard ? "active" : "default"}
onHotelCardHover={onHotelCardHover}
/>
))
: null}
{hotels?.length ? (
hotels.map((hotel) => (
<HotelCard
key={hotel.hotelData.operaId}
hotel={hotel}
type={type}
state={hotel.hotelData.name === activeCard ? "active" : "default"}
onHotelCardHover={onHotelCardHover}
/>
))
) : activeFilters ? (
<Alert
type={AlertTypeEnum.Info}
heading={intl.formatMessage({ id: "filters.nohotel.heading" })}
text={intl.formatMessage({ id: "filters.nohotel.text" })}
/>
) : null}
{showBackToTop && <BackToTopButton onClick={scrollToTop} />}
</section>
)

View File

@@ -99,11 +99,13 @@ export default function RoomFilter({
<form onSubmit={handleSubmit(submitFilter)}>
<div className={styles.roomsFilter}>
{filterOptions.map((option) => {
const { code, description } = option
const { code, description, itemCode } = option
const isPetRoom = code === RoomPackageCodeEnum.PET_ROOM
const isAllergyRoom = code === RoomPackageCodeEnum.ALLERGY_ROOM
const isDisabled =
(isAllergyRoom && petFriendly) || (isPetRoom && allergyFriendly)
(isAllergyRoom && petFriendly) ||
(isPetRoom && allergyFriendly) ||
!itemCode
const checkboxChip = (
<CheckboxChip

View File

@@ -36,7 +36,7 @@ export default function FlexibilityOption({
</div>
<Label size="regular" className={styles.noPricesLabel}>
<Caption color="uiTextHighContrast" type="bold">
{intl.formatMessage({ id: "No Prices available" })}
{intl.formatMessage({ id: "No prices available" })}
</Caption>
</Label>
</div>

View File

@@ -14,7 +14,7 @@ export default function RoomSelection({
roomsAvailability,
roomCategories,
user,
packages,
availablePackages,
selectedPackages,
setRateCode,
rateSummary,
@@ -72,7 +72,7 @@ export default function RoomSelection({
roomCategories={roomCategories}
handleSelectRate={setRateCode}
selectedPackages={selectedPackages}
packages={packages}
packages={availablePackages}
/>
</li>
))}
@@ -81,7 +81,7 @@ export default function RoomSelection({
<RateSummary
rateSummary={rateSummary}
isUserLoggedIn={isUserLoggedIn}
packages={packages}
packages={availablePackages}
roomsAvailability={roomsAvailability}
/>
)}

View File

@@ -50,6 +50,54 @@ export function getQueryParamsForEnterDetails(
roomTypeCode: room.roomtype,
rateCode: room.ratecode,
packages: room.packages?.split(",") as RoomPackageCodeEnum[],
counterRateCode: room.counterratecode,
})),
}
}
export function createQueryParamsForEnterDetails(
bookingData: BookingData,
intitalSearchParams: URLSearchParams
) {
const { hotel, fromDate, toDate, rooms } = bookingData
const bookingSearchParams = new URLSearchParams({ hotel, fromDate, toDate })
const searchParams = new URLSearchParams([
...intitalSearchParams,
...bookingSearchParams,
])
rooms.forEach((item, index) => {
if (item?.adults) {
searchParams.set(`room[${index}].adults`, item.adults.toString())
}
if (item?.children) {
item.children.forEach((child, childIndex) => {
searchParams.set(
`room[${index}].child[${childIndex}].age`,
child.age.toString()
)
searchParams.set(
`room[${index}].child[${childIndex}].bed`,
child.bed.toString()
)
})
}
if (item?.roomTypeCode) {
searchParams.set(`room[${index}].roomtype`, item.roomTypeCode)
}
if (item?.rateCode) {
searchParams.set(`room[${index}].ratecode`, item.rateCode)
}
if (item?.counterRateCode) {
searchParams.set(`room[${index}].counterratecode`, item.counterRateCode)
}
if (item.packages && item.packages.length > 0) {
searchParams.set(`room[${index}].packages`, item.packages.join(","))
}
})
return searchParams
}

View File

@@ -88,7 +88,7 @@ export async function RoomsContainer({
return (
<Rooms
user={user}
packages={packages ?? []}
availablePackages={packages ?? []}
roomsAvailability={roomsAvailability}
roomCategories={hotelData?.included ?? []}
/>

View File

@@ -9,6 +9,7 @@ import { filterDuplicateRoomTypesByLowestPrice } from "./utils"
import styles from "./rooms.module.css"
import {
DefaultFilterOptions,
RoomPackageCodeEnum,
type RoomPackageCodes,
} from "@/types/components/hotelReservation/selectRate/roomFilter"
@@ -20,17 +21,39 @@ export default function Rooms({
roomsAvailability,
roomCategories = [],
user,
packages,
availablePackages,
}: SelectRateProps) {
const visibleRooms: RoomConfiguration[] =
filterDuplicateRoomTypesByLowestPrice(roomsAvailability.roomConfigurations)
// const [internalRateSummary, setRateSummary] = useState<Rate | null>(null)
const [selectedRate, setSelectedRate] = useState<
{ publicRateCode: string; roomTypeCode: string } | undefined
>(undefined)
const [selectedPackages, setSelectedPackages] = useState<RoomPackageCodes[]>(
[]
)
const defaultPackages: DefaultFilterOptions[] = [
{
code: RoomPackageCodeEnum.ACCESSIBILITY_ROOM,
description: "Accessible Room",
itemCode: availablePackages.find(
(pkg) => pkg.code === RoomPackageCodeEnum.ACCESSIBILITY_ROOM
)?.itemCode,
},
{
code: RoomPackageCodeEnum.ALLERGY_ROOM,
description: "Allergy Room",
itemCode: availablePackages.find(
(pkg) => pkg.code === RoomPackageCodeEnum.ALLERGY_ROOM
)?.itemCode,
},
{
code: RoomPackageCodeEnum.PET_ROOM,
description: "Pet Room",
itemCode: availablePackages.find(
(pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
)?.itemCode,
},
]
const handleFilter = useCallback(
(filter: Record<RoomPackageCodeEnum, boolean | undefined>) => {
@@ -39,7 +62,6 @@ export default function Rooms({
) as RoomPackageCodeEnum[]
setSelectedPackages(filteredPackages)
// setRateSummary(null)
},
[]
)
@@ -94,7 +116,9 @@ export default function Rooms({
const petRoomPackage =
(selectedPackages.includes(RoomPackageCodeEnum.PET_ROOM) &&
packages.find((pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM)) ||
availablePackages.find(
(pkg) => pkg.code === RoomPackageCodeEnum.PET_ROOM
)) ||
undefined
const features = filteredRooms.find((room) =>
@@ -113,7 +137,7 @@ export default function Rooms({
}
return rateSummary
}, [filteredRooms, packages, selectedPackages, selectedRate])
}, [filteredRooms, availablePackages, selectedPackages, selectedRate])
useEffect(() => {
if (rateSummary) return
@@ -127,13 +151,13 @@ export default function Rooms({
<RoomFilter
numberOfRooms={rooms.roomConfigurations.length}
onFilter={handleFilter}
filterOptions={packages}
filterOptions={defaultPackages}
/>
<RoomSelection
roomsAvailability={rooms}
roomCategories={roomCategories}
user={user}
packages={packages}
availablePackages={availablePackages}
selectedPackages={selectedPackages}
setRateCode={setSelectedRate}
rateSummary={rateSummary}

View File

@@ -227,7 +227,7 @@
.galleryContent {
width: 1090px;
height: 725px;
height: min(725px, 85dvh);
}
.fullViewContent {

View File

@@ -1,8 +1,7 @@
import { ChevronRightIcon, HouseIcon } from "@/components/Icons"
import styles from "@/components/TempDesignSystem/Breadcrumbs/breadcrumbs.module.css"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import styles from "./breadcrumbs.module.css"
export default function BreadcrumbsSkeleton() {
return (
<nav className={styles.breadcrumbs}>

View File

@@ -1,8 +1,6 @@
.breadcrumbs {
display: block;
padding-left: var(--Spacing-x2);
padding-right: var(--Spacing-x2);
padding-top: var(--Spacing-x2);
padding: var(--Spacing-x2) var(--Spacing-x2) 0;
max-width: var(--max-width);
margin: 0 auto;
width: 100%;

View File

@@ -0,0 +1,9 @@
type Breadcrumb = {
title: string
uid: string
href?: string
}
export interface BreadcrumbsProps {
breadcrumbs: Breadcrumb[]
}

View File

@@ -0,0 +1,61 @@
import { HouseIcon } from "@/components/Icons"
import ChevronRightSmallIcon from "@/components/Icons/ChevronRightSmall"
import Link from "@/components/TempDesignSystem/Link"
import Footnote from "@/components/TempDesignSystem/Text/Footnote"
import styles from "./breadcrumbs.module.css"
import type { BreadcrumbsProps } from "@/components/TempDesignSystem/Breadcrumbs/breadcrumbs"
export default function Breadcrumbs({ breadcrumbs }: BreadcrumbsProps) {
if (!breadcrumbs?.length) {
return null
}
const homeBreadcrumb = breadcrumbs.shift()
return (
<nav className={styles.breadcrumbs}>
<ul className={styles.list}>
{homeBreadcrumb ? (
<li className={styles.listItem}>
<Link
className={styles.homeLink}
color="peach80"
href={homeBreadcrumb.href!}
variant="breadcrumb"
aria-label={homeBreadcrumb.title}
>
<HouseIcon width={16} height={16} color="peach80" />
</Link>
<ChevronRightSmallIcon aria-hidden="true" color="peach80" />
</li>
) : null}
{breadcrumbs.map((breadcrumb) => {
if (breadcrumb.href) {
return (
<li key={breadcrumb.uid} className={styles.listItem}>
<Link
color="peach80"
href={breadcrumb.href}
variant="breadcrumb"
>
{breadcrumb.title}
</Link>
<ChevronRightSmallIcon aria-hidden="true" color="peach80" />
</li>
)
}
return (
<li key={breadcrumb.uid} className={styles.listItem}>
<Footnote color="burgundy" type="bold">
{breadcrumb.title}
</Footnote>
</li>
)
})}
</ul>
</nav>
)
}

View File

@@ -2,11 +2,13 @@
display: flex;
align-items: center;
gap: var(--Spacing-x-half);
padding: var(--Spacing-x1) var(--Spacing-x-one-and-half);
padding: calc(var(--Spacing-x1) - 2px) var(--Spacing-x-one-and-half);
border: 1px solid var(--Base-Border-Subtle);
border-radius: var(--Corner-radius-Small);
background-color: var(--Base-Surface-Secondary-light-Normal);
cursor: pointer;
height: 32px;
background-color: var(--Base-Surface-Secondary-light-Normal);
}
.label[data-selected="true"],
@@ -21,8 +23,9 @@
}
.label[data-disabled="true"] {
background-color: var(--Base-Button-Primary-Fill-Disabled);
border-color: var(--Base-Button-Primary-Fill-Disabled);
background-color: var(--UI-Input-Controls-Surface-Disabled);
border-color: var(--UI-Input-Controls-Border-Disabled);
color: var(--Base-Text-Disabled);
cursor: not-allowed;
}