Merged in feat/LOY-196-dtmc-modal (pull request #1982)
feat(LOY-196): add modal to dtmc button containing card Approved-by: Chuma Mcphoy (We Ahead)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
|
import { cx } from "class-variance-authority"
|
||||||
import { motion } from "framer-motion"
|
import { motion } from "framer-motion"
|
||||||
import { type PropsWithChildren, useEffect, useState } from "react"
|
import { type PropsWithChildren, useEffect, useState } from "react"
|
||||||
import {
|
import {
|
||||||
@@ -40,6 +41,7 @@ function InnerModal({
|
|||||||
subtitle,
|
subtitle,
|
||||||
withActions,
|
withActions,
|
||||||
hideHeader,
|
hideHeader,
|
||||||
|
className,
|
||||||
}: PropsWithChildren<InnerModalProps>) {
|
}: PropsWithChildren<InnerModalProps>) {
|
||||||
const intl = useIntl()
|
const intl = useIntl()
|
||||||
|
|
||||||
@@ -67,7 +69,7 @@ function InnerModal({
|
|||||||
<MotionOverlay
|
<MotionOverlay
|
||||||
animate={animation}
|
animate={animation}
|
||||||
className={styles.overlay}
|
className={styles.overlay}
|
||||||
initial={"hidden"}
|
initial="hidden"
|
||||||
isDismissable
|
isDismissable
|
||||||
isExiting={animation === AnimationStateEnum.hidden}
|
isExiting={animation === AnimationStateEnum.hidden}
|
||||||
onAnimationComplete={modalStateHandler}
|
onAnimationComplete={modalStateHandler}
|
||||||
@@ -76,10 +78,10 @@ function InnerModal({
|
|||||||
onOpenChange={onOpenChange}
|
onOpenChange={onOpenChange}
|
||||||
>
|
>
|
||||||
<MotionModal
|
<MotionModal
|
||||||
className={styles.modal}
|
className={cx(styles.modal, className)}
|
||||||
variants={slideInOut}
|
variants={slideInOut}
|
||||||
animate={animation}
|
animate={animation}
|
||||||
initial={"hidden"}
|
initial="hidden"
|
||||||
>
|
>
|
||||||
<Dialog
|
<Dialog
|
||||||
className={styles.dialog}
|
className={styles.dialog}
|
||||||
@@ -135,6 +137,7 @@ export default function Modal({
|
|||||||
children,
|
children,
|
||||||
withActions = false,
|
withActions = false,
|
||||||
hideHeader = false,
|
hideHeader = false,
|
||||||
|
className = "",
|
||||||
}: PropsWithChildren<ModalProps>) {
|
}: PropsWithChildren<ModalProps>) {
|
||||||
const [animation, setAnimation] = useState<AnimationState>(
|
const [animation, setAnimation] = useState<AnimationState>(
|
||||||
AnimationStateEnum.visible
|
AnimationStateEnum.visible
|
||||||
@@ -163,6 +166,7 @@ export default function Modal({
|
|||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
withActions={withActions}
|
withActions={withActions}
|
||||||
hideHeader={hideHeader}
|
hideHeader={hideHeader}
|
||||||
|
className={className}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</InnerModal>
|
</InnerModal>
|
||||||
@@ -185,6 +189,7 @@ export default function Modal({
|
|||||||
title={title}
|
title={title}
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
withActions={withActions}
|
withActions={withActions}
|
||||||
|
className={className}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</InnerModal>
|
</InnerModal>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export type ModalProps = {
|
|||||||
subtitle?: string
|
subtitle?: string
|
||||||
withActions?: boolean
|
withActions?: boolean
|
||||||
hideHeader?: boolean
|
hideHeader?: boolean
|
||||||
|
className?: string
|
||||||
} & (
|
} & (
|
||||||
| { trigger: JSX.Element; isOpen?: never; onToggle?: never }
|
| { trigger: JSX.Element; isOpen?: never; onToggle?: never }
|
||||||
| {
|
| {
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
"use client"
|
||||||
|
|
||||||
|
import { Button } from "react-aria-components"
|
||||||
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
|
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
|
import Modal from "@/components/Modal"
|
||||||
|
|
||||||
|
import styles from "./digitalTeamMemberCard.module.css"
|
||||||
|
|
||||||
|
import type { User } from "@/types/user"
|
||||||
|
|
||||||
|
interface DigitalTeamMemberCardClientProps {
|
||||||
|
user: User
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DigitalTeamMemberCardClient({
|
||||||
|
user,
|
||||||
|
}: DigitalTeamMemberCardClientProps) {
|
||||||
|
const intl = useIntl()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
trigger={
|
||||||
|
<Button className={styles.button}>
|
||||||
|
<Typography variant="Body/Paragraph/mdBold">
|
||||||
|
<span className={styles.text}>
|
||||||
|
{/* @ts-expect-error Icon is supported in font, just not in React Material Symbols package */}
|
||||||
|
<MaterialIcon icon="id_card" size={24} color="CurrentColor" />
|
||||||
|
{intl.formatMessage({
|
||||||
|
defaultMessage: "Show Team Member Card",
|
||||||
|
})}
|
||||||
|
</span>
|
||||||
|
</Typography>
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
className={styles.modal}
|
||||||
|
>
|
||||||
|
<Typography variant="Title/xs">
|
||||||
|
<h2 className={styles.title}>
|
||||||
|
{intl.formatMessage({ defaultMessage: "Scandic Family" })}
|
||||||
|
</h2>
|
||||||
|
</Typography>
|
||||||
|
<div className={styles.card}>
|
||||||
|
<div className={styles.content}>
|
||||||
|
<div className={styles.top}>
|
||||||
|
<Typography variant="Tag/sm">
|
||||||
|
<span>
|
||||||
|
{intl.formatMessage({ defaultMessage: "Team Member" })}
|
||||||
|
</span>
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="Tag/sm">
|
||||||
|
{/* TODO: Should display country of employment */}
|
||||||
|
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
||||||
|
<span>SWE</span>
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<div className={styles.middle}>
|
||||||
|
<div className={styles.employeeNumber}>
|
||||||
|
<Typography variant="Title/sm">
|
||||||
|
{/* TODO: Should display employee number */}
|
||||||
|
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
||||||
|
<div>123 456</div>
|
||||||
|
</Typography>
|
||||||
|
<svg
|
||||||
|
width="42"
|
||||||
|
height="42"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className={styles.icon}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M3.5 35V12.288C3.5 8.933 3.5 7 4.268 7c.912 0 1.569 1.156 3.17 3.978l11.374 20.044C20.413 33.844 21.041 35 21.982 35c.768 0 .768-1.933.768-5.288V7M28 22.75h10.5M29.016 8.016c1.355-1.355 7.113-1.355 8.468 0 1.355 1.355 1.355 7.113 0 8.468-1.355 1.355-7.114 1.355-8.468 0-1.355-1.355-1.355-7.113 0-8.468Z"
|
||||||
|
strokeWidth="2.625"
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Typography variant="Title/md">
|
||||||
|
<div>
|
||||||
|
{user.firstName} {user.lastName}
|
||||||
|
</div>
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
<div className={styles.bottom}>
|
||||||
|
<Typography variant="Tag/sm">
|
||||||
|
<span>
|
||||||
|
{/* TODO: Should display department of employment */}
|
||||||
|
{/* eslint-disable formatjs/no-literal-string-in-jsx */}
|
||||||
|
Haymarket by Scandic
|
||||||
|
{/* eslint-enable */}
|
||||||
|
</span>
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="Tag/sm">
|
||||||
|
{/* TODO: Should display current state of employment */}
|
||||||
|
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
|
||||||
|
<span>Employee</span>
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Typography variant="Body/Paragraph/mdRegular">
|
||||||
|
<div className={styles.footer}>
|
||||||
|
{intl.formatMessage({
|
||||||
|
defaultMessage:
|
||||||
|
"Book discounted stays for yourself, family and friends!",
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</Typography>
|
||||||
|
</Modal>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
.card {
|
.button {
|
||||||
padding: var(--Space-x2) var(--Space-x15);
|
padding: var(--Space-x2) var(--Space-x15);
|
||||||
border-radius: var(--Corner-radius-md);
|
border-radius: var(--Corner-radius-md);
|
||||||
border: 0;
|
border: 0;
|
||||||
@@ -28,3 +28,90 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: var(--Space-x1);
|
gap: var(--Space-x1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
color: var(--Text-Accent-Primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: var(--Corner-radius-lg);
|
||||||
|
box-shadow: 0 2px 1px rgb(255 255 255 / 11%) inset;
|
||||||
|
padding: var(--Space-x2);
|
||||||
|
height: 400px;
|
||||||
|
width: 327px;
|
||||||
|
max-width: 100%;
|
||||||
|
color: var(--Text-Brand-OnPrimary-3-Accent);
|
||||||
|
background-color: var(--Surface-Brand-Primary-1-OnSurface-Default);
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
z-index: 2;
|
||||||
|
bottom: 158px;
|
||||||
|
left: 132px;
|
||||||
|
width: 360px;
|
||||||
|
height: 360px;
|
||||||
|
opacity: 0.3;
|
||||||
|
background: #e9aba3;
|
||||||
|
box-shadow: 192px 192px 192px;
|
||||||
|
border-radius: 9999px;
|
||||||
|
filter: blur(96px);
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
top: 60px;
|
||||||
|
left: -210px;
|
||||||
|
width: 2465px;
|
||||||
|
height: 459px;
|
||||||
|
background-image: url("/_static/img/scandic-logotype.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.employeeNumber {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--Base-Text-Inverted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
stroke: var(--Text-Brand-OnPrimary-3-Accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.top,
|
||||||
|
.bottom {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.middle {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
.modal {
|
||||||
|
max-width: 375px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
|
||||||
|
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
|
|
||||||
import { getIntl } from "@/i18n"
|
import DigitalTeamMemberCardClient from "./Client"
|
||||||
|
|
||||||
import styles from "./digitalTeamMemberCard.module.css"
|
|
||||||
|
|
||||||
import type { User } from "@/types/user"
|
import type { User } from "@/types/user"
|
||||||
|
|
||||||
@@ -13,25 +8,14 @@ interface DigitalTeamMemberCardProps {
|
|||||||
user: User
|
user: User
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function DigitalTeamMemberCard(
|
export default async function DigitalTeamMemberCard({
|
||||||
// TODO: Make a check whether user is eligible for benefits or not
|
user,
|
||||||
_props: DigitalTeamMemberCardProps
|
}: DigitalTeamMemberCardProps) {
|
||||||
) {
|
|
||||||
if (!env.ENABLE_DTMC) {
|
if (!env.ENABLE_DTMC) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const intl = await getIntl()
|
// TODO: Make a check whether user is eligible for benefits or not
|
||||||
|
|
||||||
return (
|
return <DigitalTeamMemberCardClient user={user} />
|
||||||
<button className={styles.card} type="button">
|
|
||||||
<Typography variant="Body/Paragraph/mdBold">
|
|
||||||
<span className={styles.text}>
|
|
||||||
{/* @ts-expect-error Icon is supported in font, just not in React Material Symbols package */}
|
|
||||||
<MaterialIcon icon="id_card" size={24} color="CurrentColor" />
|
|
||||||
{intl.formatMessage({ defaultMessage: "Show Team Member Card" })}
|
|
||||||
</span>
|
|
||||||
</Typography>
|
|
||||||
</button>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user