From 5f3e4175936a2ad90fbba4ae6ecab06050f6f010 Mon Sep 17 00:00:00 2001 From: Simon Emanuelsson Date: Fri, 7 Jun 2024 10:36:23 +0200 Subject: [PATCH] feat(WEB-162): final design for my profile page --- .../(protected)/my-pages/layout.module.css | 2 +- .../@communication/[...catchAll]/page.tsx | 6 +- .../profile/@communication/page.module.css | 10 ++ .../my-pages/profile/@communication/page.tsx | 32 +++- .../@creditCards/[...catchAll]/page.tsx | 6 +- .../profile/@creditCards/page.module.css | 10 ++ .../my-pages/profile/@creditCards/page.tsx | 30 +++- .../my-pages/profile/@edit/edit/page.tsx | 41 ------ .../my-pages/profile/@edit/page.tsx | 3 - .../@membershipCard/[...catchAll]/page.tsx | 5 - .../my-pages/profile/@membershipCard/page.tsx | 5 - .../profile/@password/[...catchAll]/page.tsx | 5 - .../my-pages/profile/@password/page.tsx | 5 - .../my-pages/profile/@profile/page.module.css | 36 +++++ .../my-pages/profile/@profile/page.tsx | 97 ++++++++++++- .../my-pages/profile/@view/default.tsx | 3 - .../my-pages/profile/@view/edit/default.tsx | 3 - .../my-pages/profile/@view/edit/page.tsx | 3 - .../my-pages/profile/@view/page.tsx | 18 --- .../profile/@wishes/[...catchAll]/page.tsx | 5 - .../my-pages/profile/@wishes/page.tsx | 5 - .../my-pages/profile/edit/page.tsx | 5 - .../(protected)/my-pages/profile/layout.tsx | 25 +--- .../my-pages/profile/profileLayout.css | 26 +--- .../@languageSwitcher/[...paths]/page.tsx | 17 +++ .../(live)/@languageSwitcher/default.tsx | 3 + app/globals.css | 8 + components/Icons/ArrowRight.tsx | 6 +- components/Icons/Cellphone.tsx | 40 +++++ components/Icons/Globe.tsx | 36 +++++ components/Icons/Location.tsx | 40 +++++ components/Icons/Lock.tsx | 36 +++++ components/Icons/Phone.tsx | 20 +-- components/Icons/PlusCircle.tsx | 40 +++++ components/Icons/icon.module.css | 5 + components/Icons/index.tsx | 5 + .../JoinLoyalty/joinLoyalty.module.css | 2 +- .../MyPages/Blocks/Stays/Previous/Client.tsx | 12 +- .../Blocks/Stays/StayCard/stay.module.css | 2 +- components/MyProfile/Card/card.module.css | 6 - components/MyProfile/Card/index.tsx | 16 -- .../CommunicationPreferences/com.module.css | 5 - .../CommunicationPreferences/index.tsx | 16 -- components/MyProfile/MembershipCard/index.tsx | 14 -- .../MembershipCard/membershipCard.module.css | 5 - components/MyProfile/Password/index.tsx | 14 -- .../MyProfile/Password/password.module.css | 5 - components/MyProfile/Profile/Container.tsx | 30 ---- components/MyProfile/Profile/Edit/index.tsx | 7 +- components/MyProfile/Profile/index.tsx | 37 ----- .../MyProfile/Profile/profile.module.css | 19 --- components/MyProfile/Wishes/index.tsx | 14 -- components/MyProfile/Wishes/wishes.module.css | 5 - .../TempDesignSystem/Button/button.module.css | 14 +- .../TempDesignSystem/Button/variants.ts | 3 +- .../TempDesignSystem/Card/card.module.css | 2 +- .../CardGrid/cardGrid.module.css | 55 +++++++ .../Divider/divider.module.css | 8 + components/TempDesignSystem/Divider/index.tsx | 9 +- .../TempDesignSystem/Divider/variants.ts | 5 + .../Form/Country/country.module.css | 5 +- .../Form/ErrorMessage/error.module.css | 2 +- .../Form/Input/input.module.css | 2 +- .../TempDesignSystem/Form/Phone/index.tsx | 8 +- .../TempDesignSystem/Link/link.module.css | 6 + components/TempDesignSystem/Link/variants.ts | 1 + .../Text/BiroScript/biroScript.module.css | 18 +-- .../Text/Body/body.module.css | 4 + components/TempDesignSystem/Text/Body/body.ts | 2 +- .../TempDesignSystem/Text/Body/index.tsx | 18 +-- .../TempDesignSystem/Text/Body/variants.ts | 1 + .../TempDesignSystem/Text/Caption/caption.ts | 2 +- .../TempDesignSystem/Text/Caption/index.tsx | 14 +- .../Text/Footnote/footnote.module.css | 2 +- .../Text/Footnote/footnote.ts | 2 +- .../TempDesignSystem/Text/Footnote/index.tsx | 18 +-- .../Text/Title/title.module.css | 8 + .../TempDesignSystem/Text/Title/variants.ts | 2 + i18n/dictionaries/da.json | 4 + i18n/dictionaries/de.json | 4 + i18n/dictionaries/en.json | 3 + i18n/dictionaries/fi.json | 4 + i18n/dictionaries/no.json | 4 + i18n/dictionaries/sv.json | 4 + public/_static/icons/globe.svg | 8 + public/_static/icons/location.svg | 8 + public/_static/icons/phone.svg | 10 +- server/routers/user/input.ts | 6 + server/routers/user/query.ts | 137 ++++++++++++------ .../components/myPages/myPage/earnAndBurn.ts | 8 +- .../myPages/myProfile/{card => }/card.ts | 0 .../components/myPages/myProfile/container.ts | 6 - types/components/myPages/myProfile/layout.ts | 5 - types/components/myPages/stays/previous.ts | 4 +- types/components/myPages/stays/upcoming.ts | 4 +- utils/maskValue.ts | 15 ++ 96 files changed, 802 insertions(+), 494 deletions(-) create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@communication/page.module.css create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/page.module.css delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@edit/edit/page.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@edit/page.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@membershipCard/[...catchAll]/page.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@membershipCard/page.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@password/[...catchAll]/page.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@password/page.tsx create mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.module.css delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@view/default.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@view/edit/default.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@view/edit/page.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@view/page.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@wishes/[...catchAll]/page.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/@wishes/page.tsx delete mode 100644 app/[lang]/(live)/(protected)/my-pages/profile/edit/page.tsx create mode 100644 app/[lang]/(live)/@languageSwitcher/[...paths]/page.tsx create mode 100644 app/[lang]/(live)/@languageSwitcher/default.tsx create mode 100644 components/Icons/Cellphone.tsx create mode 100644 components/Icons/Globe.tsx create mode 100644 components/Icons/Location.tsx create mode 100644 components/Icons/Lock.tsx create mode 100644 components/Icons/PlusCircle.tsx delete mode 100644 components/MyProfile/Card/card.module.css delete mode 100644 components/MyProfile/Card/index.tsx delete mode 100644 components/MyProfile/CommunicationPreferences/com.module.css delete mode 100644 components/MyProfile/CommunicationPreferences/index.tsx delete mode 100644 components/MyProfile/MembershipCard/index.tsx delete mode 100644 components/MyProfile/MembershipCard/membershipCard.module.css delete mode 100644 components/MyProfile/Password/index.tsx delete mode 100644 components/MyProfile/Password/password.module.css delete mode 100644 components/MyProfile/Profile/Container.tsx delete mode 100644 components/MyProfile/Profile/index.tsx delete mode 100644 components/MyProfile/Profile/profile.module.css delete mode 100644 components/MyProfile/Wishes/index.tsx delete mode 100644 components/MyProfile/Wishes/wishes.module.css create mode 100644 components/TempDesignSystem/CardGrid/cardGrid.module.css create mode 100644 public/_static/icons/globe.svg create mode 100644 public/_static/icons/location.svg rename types/components/myPages/myProfile/{card => }/card.ts (100%) delete mode 100644 types/components/myPages/myProfile/container.ts create mode 100644 utils/maskValue.ts diff --git a/app/[lang]/(live)/(protected)/my-pages/layout.module.css b/app/[lang]/(live)/(protected)/my-pages/layout.module.css index 7c1ee448d..6b967122c 100644 --- a/app/[lang]/(live)/(protected)/my-pages/layout.module.css +++ b/app/[lang]/(live)/(protected)/my-pages/layout.module.css @@ -1,5 +1,5 @@ .layout { - background-color: var(--Scandic-Brand-Pale-Peach); + background-color: var(--Scandic-Brand-Warm-White); display: grid; font-family: var(--typography-Body-Regular-fontFamily); gap: var(--Spacing-x3); diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@communication/[...catchAll]/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@communication/[...catchAll]/page.tsx index cd138565d..03a82e5f5 100644 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@communication/[...catchAll]/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@communication/[...catchAll]/page.tsx @@ -1,5 +1 @@ -import CommunicationPreferences from "@/components/MyProfile/CommunicationPreferences" - -export default function Communication() { - return -} +export { default } from "../page" diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@communication/page.module.css b/app/[lang]/(live)/(protected)/my-pages/profile/@communication/page.module.css new file mode 100644 index 000000000..76b9b1c13 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@communication/page.module.css @@ -0,0 +1,10 @@ +.container { + display: grid; + gap: var(--Spacing-x3); + max-width: 510px; +} + +.content { + display: grid; + gap: var(--Spacing-x1); +} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@communication/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@communication/page.tsx index cd138565d..6798f65ed 100644 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@communication/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@communication/page.tsx @@ -1,5 +1,31 @@ -import CommunicationPreferences from "@/components/MyProfile/CommunicationPreferences" +import { ArrowRightIcon } from "@/components/Icons" +import Link from "@/components/TempDesignSystem/Link" +import Body from "@/components/TempDesignSystem/Text/Body" +import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" +import { getIntl } from "@/i18n" -export default function Communication() { - return +import styles from "./page.module.css" + +export default async function CommunicationSlot() { + const { formatMessage } = await getIntl() + return ( +
+
+ + {formatMessage({ id: "My communication preferences" })} + + + {formatMessage({ + id: "Tell us what information and updates you'd like to receive, and how, by clicking the link below.", + })} + +
+ + + + {formatMessage({ id: "Add new card" })} + + +
+ ) } diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/[...catchAll]/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/[...catchAll]/page.tsx index fc36f789e..03a82e5f5 100644 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/[...catchAll]/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/[...catchAll]/page.tsx @@ -1,5 +1 @@ -import CreditCards from "@/components/MyProfile/CreditCards" - -export default function CreditCardSlot() { - return -} +export { default } from "../page" diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/page.module.css b/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/page.module.css new file mode 100644 index 000000000..76b9b1c13 --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/page.module.css @@ -0,0 +1,10 @@ +.container { + display: grid; + gap: var(--Spacing-x3); + max-width: 510px; +} + +.content { + display: grid; + gap: var(--Spacing-x1); +} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/page.tsx index fc36f789e..c3d256388 100644 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@creditCards/page.tsx @@ -1,5 +1,29 @@ -import CreditCards from "@/components/MyProfile/CreditCards" +import { PlusCircleIcon } from "@/components/Icons" +import Link from "@/components/TempDesignSystem/Link" +import Body from "@/components/TempDesignSystem/Text/Body" +import Subtitle from "@/components/TempDesignSystem/Text/Subtitle" +import { getIntl } from "@/i18n" -export default function CreditCardSlot() { - return +import styles from "./page.module.css" + +export default async function CreditCardSlot() { + const { formatMessage } = await getIntl() + return ( +
+
+ {formatMessage({ id: "My credit cards" })} + + {formatMessage({ + id: "Check out the credit cards saved to your profile. Pay with a saved card when signed in for a smoother web experience.", + })} + +
+ + + + {formatMessage({ id: "Add new card" })} + + +
+ ) } diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@edit/edit/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@edit/edit/page.tsx deleted file mode 100644 index 9eada21c6..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@edit/edit/page.tsx +++ /dev/null @@ -1,41 +0,0 @@ -"use client" -import { useIntl } from "react-intl" - -import { profile } from "@/constants/routes/myPages" -import { useProfileStore } from "@/stores/edit-profile" - -import Button from "@/components/TempDesignSystem/Button" -import Link from "@/components/TempDesignSystem/Link" - -import type { LangParams, PageArgs } from "@/types/params" - -export default function EditProfile({ params }: PageArgs) { - const { formatMessage } = useIntl() - const isPending = useProfileStore((store) => store.pending) - const isValid = useProfileStore((store) => store.valid) - - const cancel = formatMessage({ id: "Cancel" }) - const save = formatMessage({ id: "Save" }) - return ( - <> - - - - ) -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@edit/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@edit/page.tsx deleted file mode 100644 index c17431379..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@edit/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Page() { - return null -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@membershipCard/[...catchAll]/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@membershipCard/[...catchAll]/page.tsx deleted file mode 100644 index 924d5c4cb..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@membershipCard/[...catchAll]/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import MembershipCard from "@/components/MyProfile/MembershipCard" - -export default function MembershipCardSlot() { - return -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@membershipCard/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@membershipCard/page.tsx deleted file mode 100644 index 924d5c4cb..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@membershipCard/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import MembershipCard from "@/components/MyProfile/MembershipCard" - -export default function MembershipCardSlot() { - return -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@password/[...catchAll]/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@password/[...catchAll]/page.tsx deleted file mode 100644 index 51895bc82..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@password/[...catchAll]/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import Password from "@/components/MyProfile/Password" - -export default function PasswordSlot() { - return -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@password/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@password/page.tsx deleted file mode 100644 index 51895bc82..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@password/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import Password from "@/components/MyProfile/Password" - -export default function PasswordSlot() { - return -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.module.css b/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.module.css new file mode 100644 index 000000000..9f0ac135e --- /dev/null +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.module.css @@ -0,0 +1,36 @@ +.container { + background-color: var(--Scandic-Brand-Warm-White); + border-radius: var(--Corner-radius-Large); + display: grid; + gap: var(--Spacing-x3); + padding: var(--Spacing-x3); +} + +.header { + align-items: center; + display: flex; + gap: var(--Spacing-x2); + justify-content: space-between; +} + +button.btn { + border: 1px solid var(--Base-Border-Subtle); +} + +.profile { + display: flex; + gap: var(--Spacing-x2); + justify-content: space-between; +} + +.info { + display: grid; + gap: var(--Spacing-x-one-and-half) var(--Spacing-x7); + grid-template-columns: auto auto; +} + +.item { + display: grid; + gap: var(--Spacing-x1); + grid-template-columns: auto auto 1fr; +} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.tsx index fd7a32b77..620da9bc8 100644 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/profile/@profile/page.tsx @@ -1,5 +1,96 @@ -import Profile from "@/components/MyProfile/Profile" +// import { dt } from "@/lib/dt" +import { serverClient } from "@/lib/trpc/server" -export default function ProfileInfo() { - return +import { + EmailIcon, + GlobeIcon, + LocationIcon, + LockIcon, + PhoneIcon, +} from "@/components/Icons" +import Button from "@/components/TempDesignSystem/Button" +import Divider from "@/components/TempDesignSystem/Divider" +import Body from "@/components/TempDesignSystem/Text/Body" +import Title from "@/components/TempDesignSystem/Text/Title" +import { getIntl } from "@/i18n" + +import styles from "./page.module.css" + +export default async function Profile() { + const { formatMessage } = await getIntl() + const user = await serverClient().user.get() + if (!user) { + return null + } + // const dob = dt(user.dateOfBirth).format("DD/MM/YYYY") + return ( +
+
+
+ + {user.name} + + + {user.dateOfBirth} + +
+ +
+ +
+
+
+ + + {formatMessage({ id: "Address" })} + + + {user.address.streetAddress + ? `${user.address.streetAddress}, ` + : ""} + {user.address.city ? `${user.address.city}, ` : ""} + {user.address.country ? `${user.address.country}` : ""} + {!user.address.streetAddress && + !user.address.city && + !user.address.country + ? "N/A" + : null} + +
+
+ + + {formatMessage({ id: "Email" })} + + {user.email} +
+
+ + + {formatMessage({ id: "Phone number" })} + + {user.phoneNumber} +
+
+ + + {formatMessage({ id: "Language" })} + + {user.language} +
+
+ +
+
+ ) } diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@view/default.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@view/default.tsx deleted file mode 100644 index 86b9e9a38..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@view/default.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Default() { - return null -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@view/edit/default.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@view/edit/default.tsx deleted file mode 100644 index 86b9e9a38..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@view/edit/default.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Default() { - return null -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@view/edit/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@view/edit/page.tsx deleted file mode 100644 index fe4978be0..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@view/edit/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function EditPage() { - return null -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@view/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@view/page.tsx deleted file mode 100644 index 9f95596dd..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@view/page.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { profileEdit } from "@/constants/routes/myPages" - -import Button from "@/components/TempDesignSystem/Button" -import Link from "@/components/TempDesignSystem/Link" -import { getIntl } from "@/i18n" - -import type { LangParams, PageArgs } from "@/types/params" - -export default async function ProfileView({ params }: PageArgs) { - const { formatMessage } = await getIntl() - return ( - - ) -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@wishes/[...catchAll]/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@wishes/[...catchAll]/page.tsx deleted file mode 100644 index d22592741..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@wishes/[...catchAll]/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import Wishes from "@/components/MyProfile/Wishes" - -export default function WishesSlot() { - return -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/@wishes/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/@wishes/page.tsx deleted file mode 100644 index d22592741..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/@wishes/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import Wishes from "@/components/MyProfile/Wishes" - -export default function WishesSlot() { - return -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/edit/page.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/edit/page.tsx deleted file mode 100644 index 496477ced..000000000 --- a/app/[lang]/(live)/(protected)/my-pages/profile/edit/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import "../profileLayout.css" - -export default function EditProfilePage() { - return null -} diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/layout.tsx b/app/[lang]/(live)/(protected)/my-pages/profile/layout.tsx index 26c1df4d6..a5983461d 100644 --- a/app/[lang]/(live)/(protected)/my-pages/profile/layout.tsx +++ b/app/[lang]/(live)/(protected)/my-pages/profile/layout.tsx @@ -1,4 +1,4 @@ -import MaxWidth from "@/components/MaxWidth" +import Divider from "@/components/TempDesignSystem/Divider" import type { ProfileLayoutProps } from "@/types/components/myPages/myProfile/layout" @@ -6,28 +6,17 @@ export default function ProfileLayout({ children, communication, creditCards, - edit, - membershipCard, - password, profile, - view, - wishes, }: React.PropsWithChildren) { return ( - -
- {edit} - {view} -
- {profile} +
{children} -
- {communication} - {wishes} - {membershipCard} +
+ {profile} {creditCards} - {password} + + {communication}
- +
) } diff --git a/app/[lang]/(live)/(protected)/my-pages/profile/profileLayout.css b/app/[lang]/(live)/(protected)/my-pages/profile/profileLayout.css index 6246001ca..a8c0e99b1 100644 --- a/app/[lang]/(live)/(protected)/my-pages/profile/profileLayout.css +++ b/app/[lang]/(live)/(protected)/my-pages/profile/profileLayout.css @@ -2,26 +2,10 @@ * Due to css import issues with parallell routes we are forced to * use a regular css file and import it in the page.tsx */ -.profile-page { +.profile-layout { + background-color: var(--Main-Grey-White); + border-radius: var(--Corner-radius-xLarge); display: grid; - gap: 3rem; -} - -.profile-btns { - align-items: center; - display: flex; - gap: 1rem; - justify-content: flex-end; - position: absolute; - right: 0; - /* Creates the 16px gap from design */ - top: -1.6rem; - /* Moves itself to top of container to avoid calc */ - transform: translateY(-100%); -} - -.profile-cards { - display: grid; - gap: 0.4rem; - grid-template-columns: 1fr 1fr; + gap: var(--Spacing-x4); + padding: var(--Spacing-x3); } diff --git a/app/[lang]/(live)/@languageSwitcher/[...paths]/page.tsx b/app/[lang]/(live)/@languageSwitcher/[...paths]/page.tsx new file mode 100644 index 000000000..e68f13082 --- /dev/null +++ b/app/[lang]/(live)/@languageSwitcher/[...paths]/page.tsx @@ -0,0 +1,17 @@ +import { serverClient } from "@/lib/trpc/server" + +import Desktop from "@/components/Current/Header/LanguageSwitcher/Desktop" +import Mobile from "@/components/Current/Header/LanguageSwitcher/Mobile" + +export default async function LanguageSwitcher() { + const data = await serverClient().contentstack.languageSwitcher.get() + if (!data) { + return null + } + return ( + <> + + + + ) +} diff --git a/app/[lang]/(live)/@languageSwitcher/default.tsx b/app/[lang]/(live)/@languageSwitcher/default.tsx new file mode 100644 index 000000000..f41067bc5 --- /dev/null +++ b/app/[lang]/(live)/@languageSwitcher/default.tsx @@ -0,0 +1,3 @@ +export default function DefaultLanguageSwitcher() { + return null +} diff --git a/app/globals.css b/app/globals.css index 99216e464..b234c821d 100644 --- a/app/globals.css +++ b/app/globals.css @@ -72,6 +72,14 @@ src: url(/_static/fonts/fira-sans/medium.woff2) format("woff2"); } +@font-face { + font-display: swap; + font-family: "fira sans"; + font-style: normal; + font-weight: 500; + src: url(/_static/fonts/fira-sans/Medium.woff2) format("woff2"); +} + @font-face { font-display: swap; font-family: "fira sans"; diff --git a/components/Icons/ArrowRight.tsx b/components/Icons/ArrowRight.tsx index 907a87d7a..a4d4f955d 100644 --- a/components/Icons/ArrowRight.tsx +++ b/components/Icons/ArrowRight.tsx @@ -2,7 +2,11 @@ import { iconVariants } from "./variants" import type { IconProps } from "@/types/components/icon" -export default function ArrowRight({ className, color, ...props }: IconProps) { +export default function ArrowRightIcon({ + className, + color, + ...props +}: IconProps) { const classNames = iconVariants({ className, color }) return ( + + + + + + + + ) +} diff --git a/components/Icons/Globe.tsx b/components/Icons/Globe.tsx new file mode 100644 index 000000000..7ea19bf87 --- /dev/null +++ b/components/Icons/Globe.tsx @@ -0,0 +1,36 @@ +import { iconVariants } from "./variants" + +import type { IconProps } from "@/types/components/icon" + +export default function GlobeIcon({ className, color, ...props }: IconProps) { + const classNames = iconVariants({ className, color }) + return ( + + + + + + + + + ) +} diff --git a/components/Icons/Location.tsx b/components/Icons/Location.tsx new file mode 100644 index 000000000..b5d1d0e64 --- /dev/null +++ b/components/Icons/Location.tsx @@ -0,0 +1,40 @@ +import { iconVariants } from "./variants" + +import type { IconProps } from "@/types/components/icon" + +export default function LocationIcon({ + className, + color, + ...props +}: IconProps) { + const classNames = iconVariants({ className, color }) + return ( + + + + + + + + + ) +} diff --git a/components/Icons/Lock.tsx b/components/Icons/Lock.tsx new file mode 100644 index 000000000..ce38caa46 --- /dev/null +++ b/components/Icons/Lock.tsx @@ -0,0 +1,36 @@ +import { iconVariants } from "./variants" + +import type { IconProps } from "@/types/components/icon" + +export default function LockIcon({ className, color, ...props }: IconProps) { + const classNames = iconVariants({ className, color }) + return ( + + + + + + + + + ) +} diff --git a/components/Icons/Phone.tsx b/components/Icons/Phone.tsx index cb00f3d09..11dcf769e 100644 --- a/components/Icons/Phone.tsx +++ b/components/Icons/Phone.tsx @@ -8,27 +8,27 @@ export default function PhoneIcon({ className, color, ...props }: IconProps) { - + - + diff --git a/components/Icons/PlusCircle.tsx b/components/Icons/PlusCircle.tsx new file mode 100644 index 000000000..aa2c40afb --- /dev/null +++ b/components/Icons/PlusCircle.tsx @@ -0,0 +1,40 @@ +import { iconVariants } from "./variants" + +import type { IconProps } from "@/types/components/icon" + +export default function PlusCircleIcon({ + className, + color, + ...props +}: IconProps) { + const classNames = iconVariants({ className, color }) + return ( + + + + + + + + + ) +} diff --git a/components/Icons/icon.module.css b/components/Icons/icon.module.css index 2f76d1778..a13e28e21 100644 --- a/components/Icons/icon.module.css +++ b/components/Icons/icon.module.css @@ -27,3 +27,8 @@ .plosa * { fill: var(--Theme-Primary-Light-On-Surface-Accent); } + +.red, +.red * { + fill: var(--Scandic-Brand-Scandic-Red); +} diff --git a/components/Icons/index.tsx b/components/Icons/index.tsx index 780d23a5f..0448d8ffc 100644 --- a/components/Icons/index.tsx +++ b/components/Icons/index.tsx @@ -1,10 +1,15 @@ export { default as AccountCircleIcon } from "./AccountCircle" export { default as ArrowRightIcon } from "./ArrowRight" export { default as CalendarIcon } from "./Calendar" +export { default as CellphoneIcon } from "./Cellphone" export { default as CheckIcon } from "./Check" export { default as CheckCircleIcon } from "./CheckCircle" export { default as ChevronDownIcon } from "./ChevronDown" export { default as ChevronRightIcon } from "./ChevronRight" export { default as EmailIcon } from "./Email" +export { default as GlobeIcon } from "./Globe" export { default as HouseIcon } from "./House" +export { default as LocationIcon } from "./Location" +export { default as LockIcon } from "./Lock" export { default as PhoneIcon } from "./Phone" +export { default as PlusCircleIcon } from "./PlusCircle" diff --git a/components/Loyalty/Sidebar/JoinLoyalty/joinLoyalty.module.css b/components/Loyalty/Sidebar/JoinLoyalty/joinLoyalty.module.css index cc464abac..b183b40da 100644 --- a/components/Loyalty/Sidebar/JoinLoyalty/joinLoyalty.module.css +++ b/components/Loyalty/Sidebar/JoinLoyalty/joinLoyalty.module.css @@ -9,4 +9,4 @@ flex-direction: column; gap: var(--Spacing-x5); padding: var(--Spacing-x4) var(--Spacing-x2) var(--Spacing-x5); -} +} \ No newline at end of file diff --git a/components/MyPages/Blocks/Stays/Previous/Client.tsx b/components/MyPages/Blocks/Stays/Previous/Client.tsx index 11f919fcd..156bc2e35 100644 --- a/components/MyPages/Blocks/Stays/Previous/Client.tsx +++ b/components/MyPages/Blocks/Stays/Previous/Client.tsx @@ -56,11 +56,13 @@ export default function ClientPreviousStays({ stay={stay} /> ))} - - {hasNextPage ? ( - - ) : null} - + + { + hasNextPage ? ( + + ) : null + } + ) : ( ) diff --git a/components/MyPages/Blocks/Stays/StayCard/stay.module.css b/components/MyPages/Blocks/Stays/StayCard/stay.module.css index 1f2604f3a..124203040 100644 --- a/components/MyPages/Blocks/Stays/StayCard/stay.module.css +++ b/components/MyPages/Blocks/Stays/StayCard/stay.module.css @@ -36,4 +36,4 @@ align-items: center; display: flex; gap: var(--Spacing-x-half); -} +} \ No newline at end of file diff --git a/components/MyProfile/Card/card.module.css b/components/MyProfile/Card/card.module.css deleted file mode 100644 index 45f418611..000000000 --- a/components/MyProfile/Card/card.module.css +++ /dev/null @@ -1,6 +0,0 @@ -.card { - background-color: var(--Scandic-Brand-Warm-White); - border-radius: var(--Corner-radius-Small); - min-height: 156px; - padding: var(--Spacing-x5); -} diff --git a/components/MyProfile/Card/index.tsx b/components/MyProfile/Card/index.tsx deleted file mode 100644 index b361bb9ea..000000000 --- a/components/MyProfile/Card/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { cva } from "class-variance-authority" - -import styles from "./card.module.css" - -import type { CardProps } from "@/types/components/myPages/myProfile/card/card" - -const cardStyles = cva(styles.card) - -export default function Card({ - className, - tag = "section", - ...props -}: CardProps) { - const Cmp = tag - return -} diff --git a/components/MyProfile/CommunicationPreferences/com.module.css b/components/MyProfile/CommunicationPreferences/com.module.css deleted file mode 100644 index fd51a93d0..000000000 --- a/components/MyProfile/CommunicationPreferences/com.module.css +++ /dev/null @@ -1,5 +0,0 @@ -.container { - align-items: center; - display: flex; - justify-content: center; -} \ No newline at end of file diff --git a/components/MyProfile/CommunicationPreferences/index.tsx b/components/MyProfile/CommunicationPreferences/index.tsx deleted file mode 100644 index 9da6e415d..000000000 --- a/components/MyProfile/CommunicationPreferences/index.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import Card from "@/components/MyProfile/Card" -import Title from "@/components/TempDesignSystem/Text/Title" -import { getIntl } from "@/i18n" - -import styles from "./com.module.css" - -export default async function CommunicationPreferences() { - const { formatMessage } = await getIntl() - return ( - - - {formatMessage({ id: "My communication preferences" })} - - - ) -} diff --git a/components/MyProfile/MembershipCard/index.tsx b/components/MyProfile/MembershipCard/index.tsx deleted file mode 100644 index bf9d06a1b..000000000 --- a/components/MyProfile/MembershipCard/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import Card from "@/components/MyProfile/Card" -import Title from "@/components/TempDesignSystem/Text/Title" -import { getIntl } from "@/i18n" - -import styles from "./membershipCard.module.css" - -export default async function MembershipCard() { - const { formatMessage } = await getIntl() - return ( - - {formatMessage({ id: "Membership cards" })} - - ) -} diff --git a/components/MyProfile/MembershipCard/membershipCard.module.css b/components/MyProfile/MembershipCard/membershipCard.module.css deleted file mode 100644 index fd51a93d0..000000000 --- a/components/MyProfile/MembershipCard/membershipCard.module.css +++ /dev/null @@ -1,5 +0,0 @@ -.container { - align-items: center; - display: flex; - justify-content: center; -} \ No newline at end of file diff --git a/components/MyProfile/Password/index.tsx b/components/MyProfile/Password/index.tsx deleted file mode 100644 index e665aaa2e..000000000 --- a/components/MyProfile/Password/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import Card from "@/components/MyProfile/Card" -import Title from "@/components/TempDesignSystem/Text/Title" -import { getIntl } from "@/i18n" - -import styles from "./password.module.css" - -export default async function Password() { - const { formatMessage } = await getIntl() - return ( - - {formatMessage({ id: "Password" })} - - ) -} diff --git a/components/MyProfile/Password/password.module.css b/components/MyProfile/Password/password.module.css deleted file mode 100644 index fd51a93d0..000000000 --- a/components/MyProfile/Password/password.module.css +++ /dev/null @@ -1,5 +0,0 @@ -.container { - align-items: center; - display: flex; - justify-content: center; -} \ No newline at end of file diff --git a/components/MyProfile/Profile/Container.tsx b/components/MyProfile/Profile/Container.tsx deleted file mode 100644 index 50d2546ca..000000000 --- a/components/MyProfile/Profile/Container.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { cva } from "class-variance-authority" - -import { AccountCircleIcon } from "@/components/Icons" -import Card from "@/components/MyProfile/Card" -import Title from "@/components/TempDesignSystem/Text/Title" - -import styles from "./profile.module.css" - -import type { ContainerProps } from "@/types/components/myPages/myProfile/container" - -const profileStyles = cva(styles.profile) - -export default function Container({ - children, - className, - user, - ...props -}: ContainerProps) { - return ( - -
- - - {user.name} - -
- {children} -
- ) -} diff --git a/components/MyProfile/Profile/Edit/index.tsx b/components/MyProfile/Profile/Edit/index.tsx index 30c461223..4d8a3cf07 100644 --- a/components/MyProfile/Profile/Edit/index.tsx +++ b/components/MyProfile/Profile/Edit/index.tsx @@ -1,6 +1,5 @@ import { serverClient } from "@/lib/trpc/server" -import Container from "../Container" import Form from "./Form" export default async function EditProfile() { @@ -8,9 +7,5 @@ export default async function EditProfile() { if (!user) { return null } - return ( - -
- - ) + return } diff --git a/components/MyProfile/Profile/index.tsx b/components/MyProfile/Profile/index.tsx deleted file mode 100644 index c80b52858..000000000 --- a/components/MyProfile/Profile/index.tsx +++ /dev/null @@ -1,37 +0,0 @@ -// import { dt } from "@/lib/dt" -import { serverClient } from "@/lib/trpc/server" - -import { - CalendarIcon, - EmailIcon, - HouseIcon, - PhoneIcon, -} from "@/components/Icons" - -// import { countries } from "@/components/TempDesignSystem/Form/Country/countries" -// import { getIntl } from "@/i18n" -import Container from "./Container" - -import styles from "./profile.module.css" - -export default async function Profile() { - // const { formatMessage } = await getIntl() - const user = await serverClient().user.get() - if (!user) { - return null - } - // const countryName = countries.find( - // (country) => country.code === user.address.country - // ) - // const dob = dt(user.dateOfBirth).format("DD/MM/YYYY") - return ( - -
- - - - -
-
- ) -} diff --git a/components/MyProfile/Profile/profile.module.css b/components/MyProfile/Profile/profile.module.css deleted file mode 100644 index f02433839..000000000 --- a/components/MyProfile/Profile/profile.module.css +++ /dev/null @@ -1,19 +0,0 @@ -.profile { - display: grid; - gap: var(--Spacing-x4); - grid-template-rows: auto 1fr; - min-height: 460px; -} - -.header { - align-items: center; - display: grid; - gap: var(--Spacing-x2); - grid-template-columns: auto 1fr; -} - -.info { - display: grid; - gap: var(--Spacing-x2); - grid-template-columns: 1fr 1fr; -} diff --git a/components/MyProfile/Wishes/index.tsx b/components/MyProfile/Wishes/index.tsx deleted file mode 100644 index c635b8390..000000000 --- a/components/MyProfile/Wishes/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import Card from "@/components/MyProfile/Card" -import Title from "@/components/TempDesignSystem/Text/Title" -import { getIntl } from "@/i18n" - -import styles from "./wishes.module.css" - -export default async function Wishes() { - const { formatMessage } = await getIntl() - return ( - - {formatMessage({ id: "My wishes" })} - - ) -} diff --git a/components/MyProfile/Wishes/wishes.module.css b/components/MyProfile/Wishes/wishes.module.css deleted file mode 100644 index fd51a93d0..000000000 --- a/components/MyProfile/Wishes/wishes.module.css +++ /dev/null @@ -1,5 +0,0 @@ -.container { - align-items: center; - display: flex; - justify-content: center; -} \ No newline at end of file diff --git a/components/TempDesignSystem/Button/button.module.css b/components/TempDesignSystem/Button/button.module.css index 0162cc2ee..0cc4fb920 100644 --- a/components/TempDesignSystem/Button/button.module.css +++ b/components/TempDesignSystem/Button/button.module.css @@ -14,8 +14,8 @@ .primary, a.primary { - color: var(--font-color); background-color: var(--background-color); + color: var(--font-color); } .primary:hover, @@ -82,6 +82,7 @@ a.default { .large { font-size: 16px; + height: 50px; gap: var(--Spacing-x-half); padding: var(--Spacing-x2) var(--Spacing-x3); } @@ -108,6 +109,17 @@ a.default { --disabled-color: var(--Theme-Primary-Dark-Button-Primary-On-Fill-Disabled); } +.primaryStrong { + --background-color: var(--Theme-Primary-Strong-Button-Primary-Fill-Normal); + --disabled-background-color: var( + --Theme-Primary-Strong-Button-Primary-Fill-Disabled + ); + --disabled-color: var(--Theme-Primary-Strong-Button-Primary-On-Fill-Disabled); + --font-color: var(--Theme-Primary-Strong-Button-Primary-On-Fill-Normal); + --hover-background: var(--Theme-Primary-Strong-Button-Primary-Fill-Hover); + --hover-color: var(--Theme-Primary-Strong-Button-Primary-On-Fill-Hover); +} + .secondaryLight { --font-color: var(--Theme-Secondary-Light-Button-Primary-On-Fill-Normal); --background-color: var(--Theme-Secondary-Light-Button-Primary-Fill-Normal); diff --git a/components/TempDesignSystem/Button/variants.ts b/components/TempDesignSystem/Button/variants.ts index 32de5ba3e..f6f6e4d8a 100644 --- a/components/TempDesignSystem/Button/variants.ts +++ b/components/TempDesignSystem/Button/variants.ts @@ -14,8 +14,9 @@ export const buttonVariants = cva(styles.btn, { large: styles.large, }, theme: { - primaryLight: styles.primaryLight, primaryDark: styles.primaryDark, + primaryLight: styles.primaryLight, + primaryStrong: styles.primaryStrong, secondaryLight: styles.secondaryLight, secondaryDark: styles.secondaryDark, tertiaryLight: styles.tertiaryLight, diff --git a/components/TempDesignSystem/Card/card.module.css b/components/TempDesignSystem/Card/card.module.css index 1455059ea..bf2605a63 100644 --- a/components/TempDesignSystem/Card/card.module.css +++ b/components/TempDesignSystem/Card/card.module.css @@ -60,4 +60,4 @@ p.bodyText { display: flex; gap: var(--Spacing-x1); justify-content: center; -} +} \ No newline at end of file diff --git a/components/TempDesignSystem/CardGrid/cardGrid.module.css b/components/TempDesignSystem/CardGrid/cardGrid.module.css new file mode 100644 index 000000000..b457bff79 --- /dev/null +++ b/components/TempDesignSystem/CardGrid/cardGrid.module.css @@ -0,0 +1,55 @@ +.gridContainer { + display: grid; + gap: var(--Spacing-x2); +} + +.carousel { + display: grid; + grid-auto-columns: 80dvw; + grid-auto-flow: column; + gap: var(--Spacing-x2); + margin-left: calc(0 - var(--Spacing-x2)); + margin-right: calc(0 - var(--Spacing-x2)); + padding-left: var(--Spacing-x2); + overflow-x: scroll; + scroll-padding-left: var(--Spacing-x2); + scroll-snap-type: x mandatory; + scrollbar-width: none; + /* Hide scrollbar IE and Edge */ + -ms-overflow-style: none; + /* Hide Scrollbar Firefox */ +} + +.carousel:last-child { + margin-right: var(--Spacing-x2); +} + +.carousel > * { + scroll-snap-align: start; +} + +/* Hide Scrollbar Chrome, Safari and Opera */ +.gridContainer::-webkit-scrollbar { + display: none; +} + +@media screen and (min-width: 1367px) { + .twoColumnGrid, + .twoPlusOne { + grid-template-columns: repeat(2, 1fr); + } + + .threeColumnGrid { + grid-template-columns: repeat(3, 1fr); + } + + .twoPlusOne > *:last-child { + grid-column: span 2; + } + + .carousel { + grid-auto-flow: unset; + margin: 0; + padding: 0; + } +} diff --git a/components/TempDesignSystem/Divider/divider.module.css b/components/TempDesignSystem/Divider/divider.module.css index 842ba9948..29cd94f74 100644 --- a/components/TempDesignSystem/Divider/divider.module.css +++ b/components/TempDesignSystem/Divider/divider.module.css @@ -16,3 +16,11 @@ .peach { border-bottom-color: var(--Theme-Primary-Light-On-Surface-Divider); } + +.opacity100 { + opacity: 1; +} + +.opacity8 { + opacity: 0.08; +} diff --git a/components/TempDesignSystem/Divider/index.tsx b/components/TempDesignSystem/Divider/index.tsx index f154e37a4..5dcb8d3a7 100644 --- a/components/TempDesignSystem/Divider/index.tsx +++ b/components/TempDesignSystem/Divider/index.tsx @@ -2,7 +2,12 @@ import { dividerVariants } from "./variants" import type { DividerProps } from "./divider" -export default function Divider({ className, color, variant }: DividerProps) { - const classNames = dividerVariants({ className, color, variant }) +export default function Divider({ + className, + color, + opacity, + variant, +}: DividerProps) { + const classNames = dividerVariants({ className, color, opacity, variant }) return
} diff --git a/components/TempDesignSystem/Divider/variants.ts b/components/TempDesignSystem/Divider/variants.ts index c14b7fb33..42ef16c49 100644 --- a/components/TempDesignSystem/Divider/variants.ts +++ b/components/TempDesignSystem/Divider/variants.ts @@ -8,6 +8,10 @@ export const dividerVariants = cva(styles.divider, { burgundy: styles.burgundy, peach: styles.peach, }, + opacity: { + 100: styles.opacity100, + 8: styles.opacity8, + }, variant: { default: styles.default, dotted: styles.dotted, @@ -15,6 +19,7 @@ export const dividerVariants = cva(styles.divider, { }, defaultVariants: { color: "burgundy", + opacity: 100, variant: "default", }, }) diff --git a/components/TempDesignSystem/Form/Country/country.module.css b/components/TempDesignSystem/Form/Country/country.module.css index fa2fcd88b..d5f645878 100644 --- a/components/TempDesignSystem/Form/Country/country.module.css +++ b/components/TempDesignSystem/Form/Country/country.module.css @@ -41,11 +41,10 @@ border: var(--select-border); border-radius: var(--Corner-radius-Small); overflow: auto; - padding: var(--Spacing-x2) var(--Spacing-x2) var(--Spacing-x2) - var(--Spacing-x1); + padding: var(--Spacing-x2) var(--Spacing-x2) var(--Spacing-x2) var(--Spacing-x1); width: var(--select-width); } .listBoxItem { padding: 0 var(--Spacing-x1); -} +} \ No newline at end of file diff --git a/components/TempDesignSystem/Form/ErrorMessage/error.module.css b/components/TempDesignSystem/Form/ErrorMessage/error.module.css index bf4cbb05d..77cdfc9f1 100644 --- a/components/TempDesignSystem/Form/ErrorMessage/error.module.css +++ b/components/TempDesignSystem/Form/ErrorMessage/error.module.css @@ -1,4 +1,4 @@ .message { color: var(--Scandic-Red-60); margin: var(--Spacing-x-half) 0 0; -} +} \ No newline at end of file diff --git a/components/TempDesignSystem/Form/Input/input.module.css b/components/TempDesignSystem/Form/Input/input.module.css index e1a43510c..eee9098d5 100644 --- a/components/TempDesignSystem/Form/Input/input.module.css +++ b/components/TempDesignSystem/Form/Input/input.module.css @@ -5,4 +5,4 @@ height: 40px; padding: var(--Spacing-x1) var(--Spacing-x2); width: min(280px, 100%); -} +} \ No newline at end of file diff --git a/components/TempDesignSystem/Form/Phone/index.tsx b/components/TempDesignSystem/Form/Phone/index.tsx index 368573354..a7d5e8975 100644 --- a/components/TempDesignSystem/Form/Phone/index.tsx +++ b/components/TempDesignSystem/Form/Phone/index.tsx @@ -3,8 +3,12 @@ import "react-international-phone/style.css" import { useCallback, useEffect, useRef } from "react" import { useController, useFormContext, useWatch } from "react-hook-form" -import { defaultCountries, getCountry } from "react-international-phone" -import { PhoneInput, type PhoneInputRefType } from "react-international-phone" +import { + defaultCountries, + getCountry, + PhoneInput, + type PhoneInputRefType, +} from "react-international-phone" import ErrorMessage from "@/components/TempDesignSystem/Form/ErrorMessage" diff --git a/components/TempDesignSystem/Link/link.module.css b/components/TempDesignSystem/Link/link.module.css index 95e8d1770..6f04eb0cb 100644 --- a/components/TempDesignSystem/Link/link.module.css +++ b/components/TempDesignSystem/Link/link.module.css @@ -14,6 +14,12 @@ line-height: var(--typography-Footnote-Bold-lineHeight); } +.icon { + align-items: center; + display: flex; + gap: var(--Spacing-x1); +} + .myPage { font-family: var(--typography-Body-Underlined-fontFamily); font-size: var(--typography-Body-Underlined-fontSize); diff --git a/components/TempDesignSystem/Link/variants.ts b/components/TempDesignSystem/Link/variants.ts index 265304b59..faef05d1d 100644 --- a/components/TempDesignSystem/Link/variants.ts +++ b/components/TempDesignSystem/Link/variants.ts @@ -20,6 +20,7 @@ export const linkVariants = cva(styles.link, { variant: { breadcrumb: styles.breadcrumb, default: styles.default, + icon: styles.icon, myPage: styles.myPage, shortcut: styles.shortcut, sidebar: styles.sidebar, diff --git a/components/TempDesignSystem/Text/BiroScript/biroScript.module.css b/components/TempDesignSystem/Text/BiroScript/biroScript.module.css index 553cbb4df..d907c7240 100644 --- a/components/TempDesignSystem/Text/BiroScript/biroScript.module.css +++ b/components/TempDesignSystem/Text/BiroScript/biroScript.module.css @@ -5,22 +5,18 @@ } .one { - font-size: clamp( - var(--typography-Script-1-Mobile-fontSize), - 1.3vw + 14px, - var(--typography-Script-1-Desktop-fontSize) - ); + font-size: clamp(var(--typography-Script-1-Mobile-fontSize), + 1.3vw + 14px, + var(--typography-Script-1-Desktop-fontSize)); font-weight: var(--typography-Script-1-fontWeight); letter-spacing: var(--typography-Script-1-letterSpacing); line-height: var(--typography-Script-1-lineHeight); } .two { - font-size: clamp( - var(--typography-Script-2-Mobile-fontSize), - 0.6vw + 15px, - var(--typography-Script-2-Desktop-fontSize) - ); + font-size: clamp(var(--typography-Script-2-Mobile-fontSize), + 0.6vw + 15px, + var(--typography-Script-2-Desktop-fontSize)); font-weight: var(--typography-Script-2-fontWeight); letter-spacing: var(--typography-Script-2-letterSpacing); line-height: var(--typography-Script-2-lineHeight); @@ -48,4 +44,4 @@ .plosa { color: var(--Theme-Primary-Light-On-Surface-Accent); -} +} \ No newline at end of file diff --git a/components/TempDesignSystem/Text/Body/body.module.css b/components/TempDesignSystem/Text/Body/body.module.css index eb04f1889..aba1c9f95 100644 --- a/components/TempDesignSystem/Text/Body/body.module.css +++ b/components/TempDesignSystem/Text/Body/body.module.css @@ -54,3 +54,7 @@ .pale { color: var(--Scandic-Brand-Pale-Peach); } + +.red { + color: var(--Scandic-Brand-Scandic-Red); +} \ No newline at end of file diff --git a/components/TempDesignSystem/Text/Body/body.ts b/components/TempDesignSystem/Text/Body/body.ts index 5b942bfd4..a0261fa05 100644 --- a/components/TempDesignSystem/Text/Body/body.ts +++ b/components/TempDesignSystem/Text/Body/body.ts @@ -4,7 +4,7 @@ import type { VariantProps } from "class-variance-authority" export interface BodyProps extends Omit, "color">, - VariantProps { + VariantProps { asChild?: boolean fontOnly?: boolean } diff --git a/components/TempDesignSystem/Text/Body/index.tsx b/components/TempDesignSystem/Text/Body/index.tsx index 61f71d19f..0553375a5 100644 --- a/components/TempDesignSystem/Text/Body/index.tsx +++ b/components/TempDesignSystem/Text/Body/index.tsx @@ -16,15 +16,15 @@ export default function Body({ const Comp = asChild ? Slot : "p" const classNames = fontOnly ? bodyFontOnlyVariants({ - className, - textAlign, - textTransform, - }) + className, + textAlign, + textTransform, + }) : bodyVariants({ - className, - color, - textAlign, - textTransform, - }) + className, + color, + textAlign, + textTransform, + }) return } diff --git a/components/TempDesignSystem/Text/Body/variants.ts b/components/TempDesignSystem/Text/Body/variants.ts index c7737950b..5b4bb2ff4 100644 --- a/components/TempDesignSystem/Text/Body/variants.ts +++ b/components/TempDesignSystem/Text/Body/variants.ts @@ -8,6 +8,7 @@ const config = { black: styles.black, burgundy: styles.burgundy, pale: styles.pale, + red: styles.red, }, textAlign: { center: styles.textAlignCenter, diff --git a/components/TempDesignSystem/Text/Caption/caption.ts b/components/TempDesignSystem/Text/Caption/caption.ts index a57c8f4f6..b74c05d5a 100644 --- a/components/TempDesignSystem/Text/Caption/caption.ts +++ b/components/TempDesignSystem/Text/Caption/caption.ts @@ -4,7 +4,7 @@ import type { VariantProps } from "class-variance-authority" export interface CaptionProps extends Omit, "color">, - VariantProps { + VariantProps { asChild?: boolean fontOnly?: boolean } diff --git a/components/TempDesignSystem/Text/Caption/index.tsx b/components/TempDesignSystem/Text/Caption/index.tsx index 449e89a23..a63680d98 100644 --- a/components/TempDesignSystem/Text/Caption/index.tsx +++ b/components/TempDesignSystem/Text/Caption/index.tsx @@ -15,13 +15,13 @@ export default function Caption({ const Comp = asChild ? Slot : "p" const classNames = fontOnly ? fontOnlycaptionVariants({ - className, - textTransform, - }) + className, + textTransform, + }) : captionVariants({ - className, - color, - textTransform, - }) + className, + color, + textTransform, + }) return } diff --git a/components/TempDesignSystem/Text/Footnote/footnote.module.css b/components/TempDesignSystem/Text/Footnote/footnote.module.css index e8e60bb79..f7cc5520a 100644 --- a/components/TempDesignSystem/Text/Footnote/footnote.module.css +++ b/components/TempDesignSystem/Text/Footnote/footnote.module.css @@ -44,4 +44,4 @@ .pale { color: var(--Scandic-Brand-Pale-Peach); -} +} \ No newline at end of file diff --git a/components/TempDesignSystem/Text/Footnote/footnote.ts b/components/TempDesignSystem/Text/Footnote/footnote.ts index 792a098cf..bf59ff1ef 100644 --- a/components/TempDesignSystem/Text/Footnote/footnote.ts +++ b/components/TempDesignSystem/Text/Footnote/footnote.ts @@ -4,7 +4,7 @@ import type { VariantProps } from "class-variance-authority" export interface FootnoteProps extends Omit, "color">, - VariantProps { + VariantProps { asChild?: boolean fontOnly?: boolean } diff --git a/components/TempDesignSystem/Text/Footnote/index.tsx b/components/TempDesignSystem/Text/Footnote/index.tsx index 091f087fc..b8c834672 100644 --- a/components/TempDesignSystem/Text/Footnote/index.tsx +++ b/components/TempDesignSystem/Text/Footnote/index.tsx @@ -16,15 +16,15 @@ export default function Footnote({ const Comp = asChild ? Slot : "p" const classNames = fontOnly ? footnoteFontOnlyVariants({ - className, - textAlign, - textTransform, - }) + className, + textAlign, + textTransform, + }) : footnoteVariants({ - className, - color, - textAlign, - textTransform, - }) + className, + color, + textAlign, + textTransform, + }) return } diff --git a/components/TempDesignSystem/Text/Title/title.module.css b/components/TempDesignSystem/Text/Title/title.module.css index 7a7490f15..91b823f57 100644 --- a/components/TempDesignSystem/Text/Title/title.module.css +++ b/components/TempDesignSystem/Text/Title/title.module.css @@ -84,6 +84,10 @@ text-align: left; } +.black { + color: #000; +} + .burgundy { color: var(--Scandic-Brand-Burgundy); } @@ -91,3 +95,7 @@ .pale { color: var(--Scandic-Brand-Pale-Peach); } + +.red { + color: var(--Scandic-Brand-Scandic-Red); +} diff --git a/components/TempDesignSystem/Text/Title/variants.ts b/components/TempDesignSystem/Text/Title/variants.ts index 93fb40595..45bcd3d5f 100644 --- a/components/TempDesignSystem/Text/Title/variants.ts +++ b/components/TempDesignSystem/Text/Title/variants.ts @@ -5,8 +5,10 @@ import styles from "./title.module.css" const config = { variants: { color: { + black: styles.black, burgundy: styles.burgundy, pale: styles.pale, + red: styles.red, }, textAlign: { center: styles.center, diff --git a/i18n/dictionaries/da.json b/i18n/dictionaries/da.json index d36b9679a..cf9cdb965 100644 --- a/i18n/dictionaries/da.json +++ b/i18n/dictionaries/da.json @@ -1,4 +1,5 @@ { + "Add new card": "Tilføj nyt kort", "Address": "Adresse", "Already a friend?": "Allerede en ven?", "Arrival date": "Ankomstdato", @@ -22,14 +23,17 @@ "Day": "Dag", "Description": "Beskrivelse", "Edit": "Redigere", + "Edit profile": "Rediger profil", "Email": "E-mail", "Empty": "Empty", "Explore all levels and benefits": "Udforsk alle niveauer og fordele", "Find booking": "Find booking", + "Free soft drink voucher for the kids when staying": "Gratis sodavandskupon til børnene, når de bor", "Get inspired": "Blive inspireret", "Go back to overview": "Gå tilbage til oversigten", "How it works": "Hvordan det virker", "Join Scandic Friends": "Tilmeld dig Scandic Friends", + "Language": "Sprog", "Level": "Niveau", "Level up to unlock": "Niveau op for at låse op", "Log in": "Log på", diff --git a/i18n/dictionaries/de.json b/i18n/dictionaries/de.json index 582928fdf..11d3128df 100644 --- a/i18n/dictionaries/de.json +++ b/i18n/dictionaries/de.json @@ -1,4 +1,5 @@ { + "Add new card": "Neue Karte hinzufügen", "Address": "Adresse", "Already a friend?": "Schon ein Freund?", "Arrival date": "Ankunftsdatum", @@ -22,14 +23,17 @@ "Day": "Tag", "Description": "Beschreibung", "Edit": "Bearbeiten", + "Edit profile": "Profil bearbeiten", "Email": "Email", "Empty": "Empty", "Explore all levels and benefits": "Entdecken Sie alle Levels und Vorteile", "Find booking": "Buchung finden", + "Free soft drink voucher for the kids when staying": "Gutschein für einen kostenlosen Softdrink für die Kinder bei Aufenthalt", "Get inspired": "Lass dich inspirieren", "Go back to overview": "Zurück zur Übersicht", "How it works": "Wie es funktioniert", "Join Scandic Friends": "Treten Sie Scandic Friends bei", + "Language": "Sprache", "Level": "Ebene", "Level up to unlock": "Zum Freischalten aufsteigen", "Log in": "Anmeldung", diff --git a/i18n/dictionaries/en.json b/i18n/dictionaries/en.json index 8b6584d56..7a9b1b383 100644 --- a/i18n/dictionaries/en.json +++ b/i18n/dictionaries/en.json @@ -1,4 +1,5 @@ { + "Add new card": "Add new card", "Address": "Address", "Already a friend?": "Already a friend?", "Arrival date": "Arrival date", @@ -22,6 +23,7 @@ "Day": "Day", "Description": "Description", "Edit": "Edit", + "Edit profile": "Edit profile", "Email": "Email", "Empty": "Empty", "Explore all levels and benefits": "Explore all levels and benefits", @@ -31,6 +33,7 @@ "Go back to overview": "Go back to overview", "How it works": "How it works", "Join Scandic Friends": "Join Scandic Friends", + "Language": "Language", "Level": "Level", "Level up to unlock": "Level up to unlock", "Log in": "Log in", diff --git a/i18n/dictionaries/fi.json b/i18n/dictionaries/fi.json index 1de0db32c..33fbead47 100644 --- a/i18n/dictionaries/fi.json +++ b/i18n/dictionaries/fi.json @@ -1,4 +1,5 @@ { + "Add new card": "Lisää uusi kortti", "Address": "Osoite", "Already a friend?": "Oletko jo ystävä?", "Arrival date": "Saapumispäivä", @@ -22,14 +23,17 @@ "Day": "Päivä", "Description": "Kuvaus", "Edit": "Muokata", + "Edit profile": "Muokkaa profiilia", "Email": "Sähköposti", "Empty": "Empty", "Explore all levels and benefits": "Tutustu kaikkiin tasoihin ja etuihin", "Find booking": "Etsi varaus", + "Free soft drink voucher for the kids when staying": "Ilmainen virvoitusjuomakuponki lapsille majoittuessaan", "Get inspired": "Inspiroidu", "Go back to overview": "Palaa yleiskatsaukseen", "How it works": "Kuinka se toimii", "Join Scandic Friends": "Liity Scandic Friends", + "Language": "Kieli", "Level": "Taso", "Level up to unlock": "Nosta taso avataksesi lukituksen", "Log in": "Kirjaudu sisään", diff --git a/i18n/dictionaries/no.json b/i18n/dictionaries/no.json index a6697321b..d5a6bee8a 100644 --- a/i18n/dictionaries/no.json +++ b/i18n/dictionaries/no.json @@ -1,4 +1,5 @@ { + "Add new card": "Legg til nytt kort", "Address": "Adresse", "Already a friend?": "Allerede en venn?", "Arrival date": "Ankomstdato", @@ -22,14 +23,17 @@ "Day": "Dag", "Description": "Beskrivelse", "Edit": "Redigere", + "Edit profile": "Rediger profil", "Email": "E-post", "Empty": "Empty", "Explore all levels and benefits": "Utforsk alle nivåer og fordeler", "Find booking": "Finn booking", + "Free soft drink voucher for the kids when staying": "Gratis bruskupong for barna når de bor", "Get inspired": "Bli inspirert", "Go back to overview": "Gå tilbake til oversikten", "How it works": "Hvordan det fungerer", "Join Scandic Friends": "Bli med i Scandic Friends", + "Language": "Språk", "Level": "Nivå", "Level up to unlock": "Nivå opp for å låse opp", "Log in": "Logg Inn", diff --git a/i18n/dictionaries/sv.json b/i18n/dictionaries/sv.json index b877fe118..5b61f6f45 100644 --- a/i18n/dictionaries/sv.json +++ b/i18n/dictionaries/sv.json @@ -1,4 +1,5 @@ { + "Add new card": "Lägg till nytt kort", "Address": "Adress", "Already a friend?": "Redan en vän?", "Arrival date": "Ankomstdatum", @@ -22,14 +23,17 @@ "Day": "Dag", "Description": "Beskrivning", "Edit": "Redigera", + "Edit profile": "Redigera profil", "Email": "E-post", "Empty": "Tom", "Explore all levels and benefits": "Utforska alla nivåer och fördelar", "Find booking": "Hitta bokning", + "Free soft drink voucher for the kids when staying": "Gratis läskkupong för barnen när de bor", "Get inspired": "Bli inspirerad", "Go back to overview": "Gå tillbaka till översikten", "How it works": "Hur det fungerar", "Join Scandic Friends": "Gå med i Scandic Friends", + "Language": "Språk", "Level": "Nivå", "Level up to unlock": "Nivå upp för att låsa upp", "Log in": "Logga in", diff --git a/public/_static/icons/globe.svg b/public/_static/icons/globe.svg new file mode 100644 index 000000000..11fd8f406 --- /dev/null +++ b/public/_static/icons/globe.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/_static/icons/location.svg b/public/_static/icons/location.svg new file mode 100644 index 000000000..f9bbc667c --- /dev/null +++ b/public/_static/icons/location.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/public/_static/icons/phone.svg b/public/_static/icons/phone.svg index 91a4801ff..d5915fe88 100644 --- a/public/_static/icons/phone.svg +++ b/public/_static/icons/phone.svg @@ -1,8 +1,8 @@ - - - + + + - - + + diff --git a/server/routers/user/input.ts b/server/routers/user/input.ts index 3572b6a63..d3a54e353 100644 --- a/server/routers/user/input.ts +++ b/server/routers/user/input.ts @@ -1,5 +1,11 @@ import { z } from "zod" +export const getUserInputSchema = z + .object({ + mask: z.boolean().default(true), + }) + .default({}) + export const staysInput = z .object({ cursor: z.number().optional(), diff --git a/server/routers/user/query.ts b/server/routers/user/query.ts index 08a04db48..38105a6e5 100644 --- a/server/routers/user/query.ts +++ b/server/routers/user/query.ts @@ -1,7 +1,16 @@ +import { parsePhoneNumber } from "libphonenumber-js" + import * as api from "@/lib/api" import { protectedProcedure, router } from "@/server/trpc" -import { friendTransactionsInput, staysInput } from "./input" +import { countries } from "@/components/TempDesignSystem/Form/Country/countries" +import * as maskValue from "@/utils/maskValue" + +import { + friendTransactionsInput, + getUserInputSchema, + staysInput, +} from "./input" import { getCreditCardsSchema, getFriendTransactionsSchema, @@ -19,53 +28,95 @@ function fakingRequest(payload: T): Promise { } export const userQueryRouter = router({ - get: protectedProcedure.query(async function ({ ctx }) { - const apiResponse = await api.get(api.endpoints.v1.profile, { - cache: "no-store", - headers: { - Authorization: `Bearer ${ctx.session.token.access_token}`, - }, - }) + get: protectedProcedure + .input(getUserInputSchema) + .query(async function getUser({ ctx, input }) { + const apiResponse = await api.get(api.endpoints.v1.profile, { + cache: "no-store", + headers: { + Authorization: `Bearer ${ctx.session.token.access_token}`, + }, + }) - if (!apiResponse.ok) { - // switch (apiResponse.status) { - // case 400: - // throw badRequestError(apiResponse) - // case 401: - // throw unauthorizedError(apiResponse) - // case 403: - // throw forbiddenError(apiResponse) - // default: - // throw internalServerError(apiResponse) - // } - console.info(`API Response Failed - Getting User`) - console.info(`User: (${JSON.stringify(ctx.session.user)})`) - console.error(apiResponse) - return null - } + if (!apiResponse.ok) { + // switch (apiResponse.status) { + // case 400: + // throw badRequestError() + // case 401: + // throw unauthorizedError() + // case 403: + // throw forbiddenError() + // default: + // throw internalServerError() + // } + console.info(`API Response Failed - Getting User`) + console.info(`User: (${JSON.stringify(ctx.session.user)})`) + console.error(apiResponse) + return null + } - const apiJson = await apiResponse.json() - if (!apiJson.data?.attributes) { - // throw notFound(apiJson) - console.error( - `User has no data - (user: ${JSON.stringify(ctx.session.user)})` + const apiJson = await apiResponse.json() + console.log({ apiJson }) + console.log({ attr: apiJson.data.attributes }) + if (!apiJson.data?.attributes) { + // throw notFound(apiJson) + console.error( + `User has no data - (user: ${JSON.stringify(ctx.session.user)})` + ) + return null + } + + const verifiedData = getUserSchema.safeParse(apiJson.data.attributes) + if (!verifiedData.success) { + console.info( + `Failed to validate User - (User: ${JSON.stringify(ctx.session.user)})` + ) + console.error(verifiedData.error) + return null + } + + const country = countries.find( + (c) => c.code === verifiedData.data.address.countryCode ) - return null - } - const verifiedData = getUserSchema.safeParse(apiJson.data.attributes) - if (!verifiedData.success) { - console.info(`Failed to validate User - (name: ${ctx.session.user?.name}`) - console.error(verifiedData.error) - return null - } + const user = { + ...extendedUser, + address: { + city: verifiedData.data.address.city, + country: country?.name ?? verifiedData.data.address.countryCode, + streetAddress: verifiedData.data.address.streetAddress, + zipCode: verifiedData.data.address.zipCode, + }, + dateOfBirth: verifiedData.data.dateOfBirth, + email: verifiedData.data.email, + firstName: verifiedData.data.firstName, + language: verifiedData.data.language, + lastName: verifiedData.data.lastName, + memberships: verifiedData.data.memberships, + name: `${verifiedData.data.firstName} ${verifiedData.data.lastName}`, + phoneNumber: verifiedData.data.phoneNumber, + profileId: verifiedData.data.profileId, + } - return { - ...extendedUser, - ...verifiedData.data, - name: `${verifiedData.data.firstName} ${verifiedData.data.lastName}`, - } - }), + if (input.mask) { + if (user.address.city) { + user.address.city = maskValue.text(user.address.city) + } + if (user.address.streetAddress) { + user.address.streetAddress = maskValue.text( + user.address.streetAddress + ) + } + + user.address.zipCode = maskValue.text(verifiedData.data.address.zipCode) + user.email = maskValue.email(user.email) + + const phonenumber = parsePhoneNumber(user.phoneNumber) + user.phoneNumber = `+${phonenumber.countryCallingCode} ${maskValue.phone(user.phoneNumber)}` + } + + return user + }), benefits: router({ current: protectedProcedure.query(async function (opts) { diff --git a/types/components/myPages/myPage/earnAndBurn.ts b/types/components/myPages/myPage/earnAndBurn.ts index 5d079c33b..1d4a6bcbc 100644 --- a/types/components/myPages/myPage/earnAndBurn.ts +++ b/types/components/myPages/myPage/earnAndBurn.ts @@ -4,12 +4,12 @@ import type { UserQueryRouter } from "../user" export type TransactionResponse = Awaited< ReturnType > -export type TransactionsObject = NonNullable -export type Transactions = NonNullable["data"] -export type Transaction = NonNullable["data"][number] +export type TransactionsNonNullResponseObject = NonNullable +export type Transactions = NonNullable["data"] +export type Transaction = NonNullable["data"][number] export type ClientEarnAndBurnProps = { - initialData: TransactionsObject + initialData: TransactionsNonNullResponseObject lang: Lang } diff --git a/types/components/myPages/myProfile/card/card.ts b/types/components/myPages/myProfile/card.ts similarity index 100% rename from types/components/myPages/myProfile/card/card.ts rename to types/components/myPages/myProfile/card.ts diff --git a/types/components/myPages/myProfile/container.ts b/types/components/myPages/myProfile/container.ts deleted file mode 100644 index 8569083aa..000000000 --- a/types/components/myPages/myProfile/container.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { CardProps } from "./card/card" -import type { User } from "@/types/user" - -export interface ContainerProps extends CardProps { - user: User -} diff --git a/types/components/myPages/myProfile/layout.ts b/types/components/myPages/myProfile/layout.ts index 380d42c68..be50c920a 100644 --- a/types/components/myPages/myProfile/layout.ts +++ b/types/components/myPages/myProfile/layout.ts @@ -1,10 +1,5 @@ export type ProfileLayoutProps = { communication: React.ReactNode creditCards: React.ReactNode - edit: React.ReactNode - membershipCard: React.ReactNode - password: React.ReactNode profile: React.ReactNode - view: React.ReactNode - wishes: React.ReactNode } diff --git a/types/components/myPages/stays/previous.ts b/types/components/myPages/stays/previous.ts index 5a146a11d..844581123 100644 --- a/types/components/myPages/stays/previous.ts +++ b/types/components/myPages/stays/previous.ts @@ -6,8 +6,8 @@ export type PreviousStaysResponse = Awaited< > export type PreviousStaysNonNullResponseObject = NonNullable -export type PreviousStays = NonNullable["data"] -export type PreviousStay = NonNullable["data"][number] +export type PreviousStays = NonNullable["data"] +export type PreviousStay = NonNullable["data"][number] export interface PreviousStaysClientProps { lang: Lang diff --git a/types/components/myPages/stays/upcoming.ts b/types/components/myPages/stays/upcoming.ts index c8c46d943..d87d33b7b 100644 --- a/types/components/myPages/stays/upcoming.ts +++ b/types/components/myPages/stays/upcoming.ts @@ -6,8 +6,8 @@ export type UpcomingStaysResponse = Awaited< > export type UpcomingStaysNonNullResponseObject = NonNullable -export type UpcomingStays = NonNullable["data"] -export type UpcomingStay = NonNullable["data"][number] +export type UpcomingStays = NonNullable["data"] +export type UpcomingStay = NonNullable["data"][number] export interface UpcomingStaysClientProps { lang: Lang diff --git a/utils/maskValue.ts b/utils/maskValue.ts new file mode 100644 index 000000000..741b3fc31 --- /dev/null +++ b/utils/maskValue.ts @@ -0,0 +1,15 @@ +const emailRegex = + /(?<=.)[^@\n](?=[^@\n]*?@)|(?:(?<=@.+)|(?!^)\G(?=[^@\n]*$)).(?=.*\.)/gm +export function email(str: string) { + return str.replace(emailRegex, "*") +} + +const phoneRegex = /.(?!.{0,1}$)/gm +export function phone(str: string) { + return str.replace(phoneRegex, "*") +} + +const textRegex = /(?!^)./gm +export function text(str: string) { + return str.replace(textRegex, "*") +}