feat: add new design for join scandic friends checkbox

This commit is contained in:
Christel Westerberg
2024-11-15 16:31:11 +01:00
parent b91085d2e7
commit 117cbcd20d
16 changed files with 189 additions and 65 deletions

View File

@@ -33,11 +33,10 @@ export default function ChildInfoSelector({
const ageLabel = intl.formatMessage({ id: "Age" })
const bedLabel = intl.formatMessage({ id: "Bed" })
const errorMessage = intl.formatMessage({ id: "Child age is required" })
const { setValue, formState, register, trigger } = useFormContext()
const { setValue, formState, register } = useFormContext()
function updateSelectedBed(bed: number) {
setValue(`rooms.${roomIndex}.child.${index}.bed`, bed)
trigger()
}
function updateSelectedAge(age: number) {

View File

@@ -7,9 +7,9 @@ import { useIntl } from "react-intl"
import { privacyPolicy } from "@/constants/currentWebHrefs"
import Checkbox from "@/components/TempDesignSystem/Form/Checkbox"
import CheckboxCard from "@/components/TempDesignSystem/Form/ChoiceCard/Checkbox"
import DateSelect from "@/components/TempDesignSystem/Form/Date"
import Input from "@/components/TempDesignSystem/Form/Input"
import JoinScandicFriendsCard from "@/components/TempDesignSystem/Form/JoinScandicFriendsCard"
import Link from "@/components/TempDesignSystem/Link"
import Body from "@/components/TempDesignSystem/Text/Body"
import Caption from "@/components/TempDesignSystem/Text/Caption"
@@ -31,29 +31,11 @@ export default function Signup({ name }: { name: string }) {
setIsJoinChecked(joinValue)
}, [joinValue])
const list = [
{ title: intl.formatMessage({ id: "Earn bonus nights & points" }) },
{ title: intl.formatMessage({ id: "Get member benefits & offers" }) },
{ title: intl.formatMessage({ id: "Join at no cost" }) },
]
return (
<div className={styles.container}>
<CheckboxCard
highlightSubtitle
list={list}
<JoinScandicFriendsCard
name={name}
subtitle={intl.formatMessage(
{
id: "{difference}{amount} {currency}",
},
{
amount: "491",
currency: "SEK",
difference: "-",
}
)}
title={intl.formatMessage({ id: "Join Scandic Friends" })}
difference={{ price: 1000, currency: "SEK" }}
/>
{isJoinChecked ? (
<div className={styles.additionalFormData}>

View File

@@ -13,19 +13,16 @@ import { trackLoginClick } from "@/utils/tracking"
import { TrackingPosition } from "@/types/components/tracking"
export default function LoginButton({
className,
position,
trackingId,
children,
color = "black",
variant = "navigation",
}: PropsWithChildren<{
className: string
trackingId: string
position: TrackingPosition
color?: LinkProps["color"]
variant?: "navigation" | "signupVerification"
}>) {
...props
}: PropsWithChildren<
{
trackingId: string
position: TrackingPosition
} & Omit<LinkProps, "href">
>) {
const lang = useLang()
const pathName = useLazyPathname({ includeSearchParams: true })
@@ -45,14 +42,7 @@ export default function LoginButton({
}, [position, trackingId])
return (
<Link
className={className}
id={trackingId}
color={color}
href={href}
prefetch={false}
variant={variant}
>
<Link id={trackingId} prefetch={false} {...props} href={href}>
{children}
</Link>
)

View File

@@ -12,6 +12,7 @@ import styles from "./checkbox.module.css"
import { CheckboxProps } from "@/types/components/checkbox"
export default function Checkbox({
className,
name,
children,
registerOptions,
@@ -25,16 +26,17 @@ export default function Checkbox({
return (
<AriaCheckbox
className={styles.container}
className={`${styles.container} ${className}`}
isSelected={field.value}
onChange={field.onChange}
data-testid={name}
isDisabled={registerOptions?.disabled}
excludeFromTabOrder
>
{({ isSelected }) => (
<>
<span className={styles.checkboxContainer}>
<span className={styles.checkbox}>
<span className={styles.checkbox} tabIndex={0}>
{isSelected && <CheckIcon color="white" />}
</span>
{children}

View File

@@ -1,7 +0,0 @@
import Card from "./_Card"
import type { CheckboxProps } from "./_Card/card"
export default function CheckboxCard(props: CheckboxProps) {
return <Card {...props} type="checkbox" />
}

View File

@@ -0,0 +1,108 @@
"use client"
import { useIntl } from "react-intl"
import { privacyPolicy } from "@/constants/currentWebHrefs"
import { CheckIcon } from "@/components/Icons"
import LoginButton from "@/components/LoginButton"
import useLang from "@/hooks/useLang"
import Link from "../../Link"
import Caption from "../../Text/Caption"
import Footnote from "../../Text/Footnote"
import Checkbox from "../Checkbox"
import styles from "./joinScandicFriendsCard.module.css"
type JoinScandicFriendsCardProps = {
name: string
difference: { price: number; currency: string }
}
export default function JoinScandicFriendsCard({
name,
difference,
}: JoinScandicFriendsCardProps) {
const lang = useLang()
const intl = useIntl()
const list = [
{ title: intl.formatMessage({ id: "Earn bonus nights & points" }) },
{ title: intl.formatMessage({ id: "Get member benefits & offers" }) },
{ title: intl.formatMessage({ id: "Join at no cost" }) },
]
return (
<label className={styles.cardContainer}>
<header className={styles.header}>
<Checkbox name={name} className={styles.checkBox} />
<div>
<Caption type="label" textTransform="uppercase" color="red">
{intl.formatMessage(
{
id: "Only pay {amount} {currency}",
},
{
amount: intl.formatNumber(difference.price),
currency: difference.currency,
}
)}
</Caption>
<Caption
type="label"
textTransform="uppercase"
color="uiTextHighContrast"
>
{intl.formatMessage({ id: "Join Scandic Friends" })}
</Caption>
</div>
<Footnote color="uiTextHighContrast">
{intl.formatMessage({ id: "Already a friend?" })}{" "}
<LoginButton
color="burgundy"
position="enter details"
trackingId="join-scandic-friends-enter-details"
variant="breadcrumb"
target="_blank"
>
{intl.formatMessage({ id: "Log in" })}
</LoginButton>
</Footnote>
</header>
<div className={styles.list}>
{list.map((item) => (
<Caption
key={item.title}
color="uiTextPlaceholder"
className={styles.listItem}
>
<CheckIcon color="uiTextPlaceholder" height="20" /> {item.title}
</Caption>
))}
</div>
<Footnote color="uiTextPlaceholder">
{intl.formatMessage<React.ReactNode>(
{
id: "signup.terms",
},
{
termsLink: (str) => (
<Link
variant="default"
textDecoration="underline"
size="tiny"
target="_blank"
color="uiTextPlaceholder"
href={privacyPolicy[lang]}
>
{str}
</Link>
),
}
)}
</Footnote>
</label>
)
}

View File

@@ -0,0 +1,30 @@
.cardContainer {
align-self: flex-start;
background-color: var(--Base-Surface-Primary-light-Normal);
border: 1px solid var(--Base-Border-Subtle);
border-radius: var(--Corner-radius-Large);
display: grid;
cursor: pointer;
gap: var(--Spacing-x2);
padding: var(--Spacing-x-one-and-half) var(--Spacing-x2);
width: min(100%, 600px);
}
.header {
display: grid;
gap: var(--Spacing-x-one-and-half);
grid-template-columns: auto 1fr auto;
}
.checkBox {
align-self: center;
}
.list {
display: flex;
gap: var(--Spacing-x1);
}
.listItem {
display: flex;
}

View File

@@ -16,7 +16,7 @@
.breadcrumb {
font-family: var(--typography-Footnote-Bold-fontFamily);
font-size: var(--typography-Footnote-Bold-fontSize);
font-weight: var(--typography-Footnote-Bold-fontWeight);
font-weight: 450; /* var(--typography-Footnote-Bold-fontWeight); */
letter-spacing: var(--typography-Footnote-Bold-letterSpacing);
line-height: var(--typography-Footnote-Bold-lineHeight);
}
@@ -24,7 +24,7 @@
.link.breadcrumb {
font-family: var(--typography-Footnote-Bold-fontFamily);
font-size: var(--typography-Footnote-Bold-fontSize);
font-weight: var(--typography-Footnote-Bold-fontWeight);
font-weight: 450; /* var(--typography-Footnote-Bold-fontWeight); */
letter-spacing: var(--typography-Footnote-Bold-letterSpacing);
line-height: var(--typography-Footnote-Bold-lineHeight);
}
@@ -128,6 +128,15 @@
color: #000;
}
.uiTextPlaceholder {
color: var(--Base-Text-Placeholder);
}
.uiTextPlaceholder:hover,
.uiTextPlaceholder:active {
color: var(--Base-Text-Medium-contrast);
}
.burgundy {
color: var(--Base-Text-High-contrast);
}
@@ -211,6 +220,14 @@
line-height: var(--typography-Caption-Regular-lineHeight);
}
.tiny {
font-family: var(--typography-Footnote-Regular-fontFamily);
font-size: var(--typography-Footnote-Regular-fontSize);
font-weight: var(--typography-Footnote-Regular-fontWeight);
letter-spacing: var(--typography-Footnote-Regular-letterSpacing);
line-height: var(--typography-Footnote-Regular-lineHeight);
}
.activeSmall {
font-family: var(--typography-Caption-Bold-fontFamily);
font-size: var(--typography-Caption-Bold-fontSize);

View File

@@ -17,10 +17,12 @@ export const linkVariants = cva(styles.link, {
peach80: styles.peach80,
white: styles.white,
red: styles.red,
uiTextPlaceholder: styles.uiTextPlaceholder,
},
size: {
small: styles.small,
regular: styles.regular,
tiny: styles.tiny,
},
textDecoration: {
none: styles.noDecoration,

View File

@@ -238,6 +238,7 @@
"Number of parking spots": "Antal parkeringspladser",
"OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER",
"On your journey": "På din rejse",
"Only pay {amount} {currency}": "Betal kun {amount} {currency}",
"Open": "Åben",
"Open gift(s)": "Åbne {amount, plural, one {gave} other {gaver}}",
"Open image gallery": "Åbn billedgalleri",
@@ -458,6 +459,5 @@
"to": "til",
"uppercase letter": "stort bogstav",
"{amount} out of {total}": "{amount} ud af {total}",
"{amount} {currency}": "{amount} {currency}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}"
"{amount} {currency}": "{amount} {currency}"
}

View File

@@ -236,6 +236,7 @@
"Number of parking spots": "Anzahl der Parkplätze",
"OTHER PAYMENT METHODS": "ANDERE BEZAHLMETHODE",
"On your journey": "Auf deiner Reise",
"Only pay {amount} {currency}": "Nur bezahlen {amount} {currency}",
"Open": "Offen",
"Open gift(s)": "{amount, plural, one {Geschenk} other {Geschenke}} öffnen",
"Open image gallery": "Bildergalerie öffnen",
@@ -456,6 +457,5 @@
"to": "zu",
"uppercase letter": "großbuchstabe",
"{amount} out of {total}": "{amount} von {total}",
"{amount} {currency}": "{amount} {currency}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}"
"{amount} {currency}": "{amount} {currency}"
}

View File

@@ -255,6 +255,7 @@
"Number of parking spots": "Number of parking spots",
"OTHER PAYMENT METHODS": "OTHER PAYMENT METHODS",
"On your journey": "On your journey",
"Only pay {amount} {currency}": "Only pay {amount} {currency}",
"Open": "Open",
"Open gift(s)": "Open {amount, plural, one {gift} other {gifts}}",
"Open image gallery": "Open image gallery",
@@ -427,7 +428,6 @@
"Which room class suits you the best?": "Which room class suits you the best?",
"Year": "Year",
"Yes": "Yes",
"Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with": "Yes, I accept the Terms and conditions for Scandic Friends and understand that Scandic will process my personal data in accordance with",
"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.",
@@ -490,12 +490,12 @@
"points": "Points",
"room type": "room type",
"room types": "room types",
"signup.terms": "By signing up you accept the Scandic Friends <termsLink>Terms and Conditions</termsLink>. Your membership is valid until further notice, and you can terminate your membership at any time by sending an email to Scandics customer service",
"special character": "special character",
"spendable points expiring by": "{points} spendable points expiring by {date}",
"to": "to",
"uppercase letter": "uppercase letter",
"{amount} out of {total}": "{amount} out of {total}",
"{amount} {currency}": "{amount} {currency}",
"{card} ending with {cardno}": "{card} ending with {cardno}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}"
"{card} ending with {cardno}": "{card} ending with {cardno}"
}

View File

@@ -238,6 +238,7 @@
"Number of parking spots": "Pysäköintipaikkojen määrä",
"OTHER PAYMENT METHODS": "MUISE KORT",
"On your journey": "Matkallasi",
"Only pay {amount} {currency}": "Vain maksaa {amount} {currency}",
"Open": "Avata",
"Open gift(s)": "{amount, plural, one {Avoin lahja} other {Avoimet lahjat}}",
"Open image gallery": "Avaa kuvagalleria",
@@ -456,6 +457,5 @@
"to": "to",
"uppercase letter": "iso kirjain",
"{amount} out of {total}": "{amount}/{total}",
"{amount} {currency}": "{amount} {currency}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}"
"{amount} {currency}": "{amount} {currency}"
}

View File

@@ -236,6 +236,7 @@
"Number of parking spots": "Antall parkeringsplasser",
"OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER",
"On your journey": "På reisen din",
"Only pay {amount} {currency}": "Bare betal {amount} {currency}",
"Open": "Åpen",
"Open gift(s)": "{amount, plural, one {Åpen gave} other {Åpnen gaver}}",
"Open image gallery": "Åpne bildegalleri",
@@ -454,6 +455,5 @@
"to": "til",
"uppercase letter": "stor bokstav",
"{amount} out of {total}": "{amount} av {total}",
"{amount} {currency}": "{amount} {currency}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}"
"{amount} {currency}": "{amount} {currency}"
}

View File

@@ -236,6 +236,7 @@
"Number of parking spots": "Antal parkeringsplatser",
"OTHER PAYMENT METHODS": "ANDRE BETALINGSMETODER",
"On your journey": "På din resa",
"Only pay {amount} {currency}": "Betala endast {amount} {currency}",
"Open": "Öppna",
"Open gift(s)": "Öppna {amount, plural, one {gåva} other {gåvor}}",
"Open image gallery": "Öppna bildgalleri",
@@ -457,6 +458,5 @@
"types": "typer",
"uppercase letter": "stor bokstav",
"{amount} out of {total}": "{amount} av {total}",
"{amount} {currency}": "{amount} {currency}",
"{difference}{amount} {currency}": "{difference}{amount} {currency}"
"{amount} {currency}": "{amount} {currency}"
}

View File

@@ -80,3 +80,4 @@ export type TrackingPosition =
| "hamburger menu"
| "join scandic friends sidebar"
| "sign up verification"
| "enter details"