refactor: left booking information box component (#4251)
Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: Jeroen Reumkens <hello@jeroenreumkens.nl>
This commit is contained in:
4 files changed
+157
-71
No files matched your search
@@ -0,0 +1,106 @@
|
||||
import { SchedulingType } from "@prisma/client";
|
||||
import { FC, ReactNode } from "react";
|
||||
|
||||
import { classNames } from "@calcom/lib";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { Icon } from "@calcom/ui/Icon";
|
||||
|
||||
import { UserAvatars } from "@components/booking/UserAvatars";
|
||||
import EventTypeDescriptionSafeHTML from "@components/eventtype/EventTypeDescriptionSafeHTML";
|
||||
|
||||
import type { AvailabilityPageProps } from "../../pages/[user]/[type]";
|
||||
import type { BookPageProps } from "../../pages/[user]/book";
|
||||
import type { DynamicAvailabilityPageProps } from "../../pages/d/[link]/[slug]";
|
||||
import type { HashLinkPageProps } from "../../pages/d/[link]/book";
|
||||
import type { AvailabilityTeamPageProps } from "../../pages/team/[slug]/[type]";
|
||||
import type { TeamBookingPageProps } from "../../pages/team/[slug]/book";
|
||||
import { AvailableEventLocations } from "./AvailableEventLocations";
|
||||
|
||||
interface Props {
|
||||
profile:
|
||||
| AvailabilityPageProps["profile"]
|
||||
| HashLinkPageProps["profile"]
|
||||
| TeamBookingPageProps["profile"]
|
||||
| BookPageProps["profile"]
|
||||
| AvailabilityTeamPageProps["profile"]
|
||||
| DynamicAvailabilityPageProps["profile"];
|
||||
eventType:
|
||||
| AvailabilityPageProps["eventType"]
|
||||
| HashLinkPageProps["eventType"]
|
||||
| TeamBookingPageProps["eventType"]
|
||||
| BookPageProps["eventType"]
|
||||
| AvailabilityTeamPageProps["eventType"]
|
||||
| DynamicAvailabilityPageProps["eventType"];
|
||||
isBookingPage?: boolean;
|
||||
children: ReactNode;
|
||||
isMobile?: boolean;
|
||||
}
|
||||
|
||||
const BookingDescription: FC<Props> = (props) => {
|
||||
const { profile, eventType, isBookingPage = false, children } = props;
|
||||
const { t } = useLocale();
|
||||
return (
|
||||
<>
|
||||
<UserAvatars
|
||||
profile={profile}
|
||||
users={eventType.users}
|
||||
showMembers={eventType.schedulingType !== SchedulingType.ROUND_ROBIN}
|
||||
size={10}
|
||||
truncateAfter={3}
|
||||
/>
|
||||
<h2 className="mt-2 break-words text-sm font-medium text-gray-600 dark:text-gray-300">
|
||||
{profile.name}
|
||||
</h2>
|
||||
<h1 className="font-cal dark:text-darkgray-900 mb-6 break-words text-2xl font-semibold text-gray-900">
|
||||
{eventType.title}
|
||||
</h1>
|
||||
<div className="dark:text-darkgray-600 flex flex-col space-y-3 text-sm font-medium text-gray-600">
|
||||
{eventType?.description && (
|
||||
<div
|
||||
className={classNames(
|
||||
"flex",
|
||||
isBookingPage && "dark:text-darkgray-600 text-sm font-medium text-gray-600"
|
||||
)}>
|
||||
<div>
|
||||
<Icon.FiInfo
|
||||
className={classNames(
|
||||
"mr-[10px] ml-[2px] inline-block h-4 w-4",
|
||||
isBookingPage && "dark:text-darkgray-600 -mt-1 text-gray-500"
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
<EventTypeDescriptionSafeHTML eventType={eventType} />
|
||||
</div>
|
||||
)}
|
||||
{eventType?.requiresConfirmation && (
|
||||
<div
|
||||
className={classNames(
|
||||
"flex items-center",
|
||||
isBookingPage && "dark:text-darkgray-600 text-sm font-medium text-gray-600"
|
||||
)}>
|
||||
<div>
|
||||
<Icon.FiCheckSquare className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4 " />
|
||||
</div>
|
||||
{t("requires_confirmation")}
|
||||
</div>
|
||||
)}
|
||||
{!isBookingPage ? (
|
||||
<AvailableEventLocations
|
||||
locations={eventType.locations as AvailabilityPageProps["eventType"]["locations"]}
|
||||
/>
|
||||
) : null}
|
||||
<p
|
||||
className={classNames(
|
||||
"text-sm font-medium",
|
||||
isBookingPage && "dark:text-darkgray-600 text-gray-600"
|
||||
)}>
|
||||
<Icon.FiClock className="mr-[10px] -mt-1 ml-[2px] inline-block h-4 w-4" />
|
||||
{eventType.length} {t("minutes")}
|
||||
</p>
|
||||
{children}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default BookingDescription;
|
||||
@@ -37,6 +37,7 @@ import { isBrandingHidden } from "@lib/isBrandingHidden";
|
||||
|
||||
import Gates, { Gate, GateState } from "@components/Gates";
|
||||
import AvailableTimes from "@components/booking/AvailableTimes";
|
||||
import BookingDescription from "@components/booking/BookingDescription";
|
||||
import TimeOptions from "@components/booking/TimeOptions";
|
||||
import { UserAvatars } from "@components/booking/UserAvatars";
|
||||
import EventTypeDescriptionSafeHTML from "@components/eventtype/EventTypeDescriptionSafeHTML";
|
||||
@@ -415,41 +416,7 @@ const AvailabilityPage = ({ profile, eventType }: Props) => {
|
||||
"min-w-full md:w-[280px] md:min-w-[280px]",
|
||||
recurringEventCount && "xl:w-[380px] xl:min-w-[380px]"
|
||||
)}>
|
||||
<UserAvatars
|
||||
profile={profile}
|
||||
users={eventType.users}
|
||||
showMembers={eventType.schedulingType !== SchedulingType.ROUND_ROBIN}
|
||||
size={10}
|
||||
truncateAfter={3}
|
||||
/>
|
||||
<h2 className="mt-2 break-words text-sm font-medium text-gray-600 dark:text-gray-300">
|
||||
{profile.name}
|
||||
</h2>
|
||||
<h1 className="font-cal dark:text-darkgray-900 mb-6 break-words text-2xl font-semibold text-gray-900">
|
||||
{eventType.title}
|
||||
</h1>
|
||||
<div className="dark:text-darkgray-600 flex flex-col space-y-3 text-sm font-medium text-gray-600">
|
||||
{eventType?.description && (
|
||||
<div className="flex">
|
||||
<div>
|
||||
<Icon.FiInfo className="mr-[10px] ml-[2px] inline-block h-4 w-4" />
|
||||
</div>
|
||||
<EventTypeDescriptionSafeHTML eventType={eventType} />
|
||||
</div>
|
||||
)}
|
||||
{eventType?.requiresConfirmation && (
|
||||
<div className="flex items-center">
|
||||
<div>
|
||||
<Icon.FiCheckSquare className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4 " />
|
||||
</div>
|
||||
{t("requires_confirmation")}
|
||||
</div>
|
||||
)}
|
||||
<AvailableEventLocations locations={eventType.locations} />
|
||||
<p className="text-sm font-medium">
|
||||
<Icon.FiClock className="mr-[10px] -mt-1 ml-[2px] inline-block h-4 w-4" />
|
||||
{eventType.length} {t("minutes")}
|
||||
</p>
|
||||
<BookingDescription profile={profile} eventType={eventType}>
|
||||
{!rescheduleUid && eventType.recurringEvent && (
|
||||
<div className="flex items-start text-sm font-medium">
|
||||
<Icon.FiRefreshCcw className="float-left mr-[10px] mt-[7px] ml-[2px] inline-block h-4 w-4 " />
|
||||
@@ -488,7 +455,7 @@ const AvailabilityPage = ({ profile, eventType }: Props) => {
|
||||
</p>
|
||||
)}
|
||||
{timezoneDropdown}
|
||||
</div>
|
||||
</BookingDescription>
|
||||
|
||||
{!isEmbed && (
|
||||
<div className="mt-auto hidden md:block">
|
||||
|
||||
@@ -49,6 +49,7 @@ import { parseDate, parseRecurringDates } from "@lib/parseDate";
|
||||
import slugify from "@lib/slugify";
|
||||
|
||||
import Gates, { Gate, GateState } from "@components/Gates";
|
||||
import BookingDescription from "@components/booking/BookingDescription";
|
||||
import { UserAvatars } from "@components/booking/UserAvatars";
|
||||
import EventTypeDescriptionSafeHTML from "@components/eventtype/EventTypeDescriptionSafeHTML";
|
||||
|
||||
@@ -450,40 +451,7 @@ const BookingPage = ({
|
||||
)}>
|
||||
<div className="sm:flex">
|
||||
<div className="sm:dark:border-darkgray-300 dark:text-darkgray-600 flex flex-col px-6 pt-6 pb-0 text-gray-600 sm:w-1/2 sm:border-r sm:pb-6">
|
||||
<UserAvatars
|
||||
profile={profile}
|
||||
users={eventType.users}
|
||||
showMembers={eventType.schedulingType !== SchedulingType.ROUND_ROBIN}
|
||||
size={10}
|
||||
truncateAfter={3}
|
||||
/>
|
||||
<h2 className="mt-2 break-words text-sm font-medium text-gray-500 dark:text-gray-300">
|
||||
{profile.name}
|
||||
</h2>
|
||||
<h1 className="font-cal dark:text-darkgray-900 break-words text-2xl text-gray-900 ">
|
||||
{eventType.title}
|
||||
</h1>
|
||||
<div className="mt-4 flex flex-col space-y-3 lg:mt-9">
|
||||
{eventType?.description && (
|
||||
<div className="dark:text-darkgray-600 flex text-sm font-medium text-gray-600">
|
||||
<div>
|
||||
<Icon.FiInfo className="dark:text-darkgray-600 mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4 text-gray-500" />
|
||||
</div>
|
||||
<EventTypeDescriptionSafeHTML eventType={eventType} />
|
||||
</div>
|
||||
)}
|
||||
{eventType?.requiresConfirmation && (
|
||||
<div className="dark:text-darkgray-600 flex items-center text-sm font-medium text-gray-600">
|
||||
<div>
|
||||
<Icon.FiCheckSquare className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4 " />
|
||||
</div>
|
||||
{t("requires_confirmation")}
|
||||
</div>
|
||||
)}
|
||||
<p className="dark:text-darkgray-600 text-sm font-medium text-gray-600">
|
||||
<Icon.FiClock className="mr-[10px] -mt-1 ml-[2px] inline-block h-4 w-4" />
|
||||
{eventType.length} {t("minutes")}
|
||||
</p>
|
||||
<BookingDescription isBookingPage profile={profile} eventType={eventType}>
|
||||
{eventType.price > 0 && (
|
||||
<p className="text-bookinglight -ml-2 px-2 text-sm ">
|
||||
<Icon.FiCreditCard className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
|
||||
@@ -559,7 +527,7 @@ const BookingPage = ({
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</BookingDescription>
|
||||
</div>
|
||||
<div className="p-6 sm:w-1/2">
|
||||
<Form form={bookingForm} handleSubmit={bookEvent}>
|
||||
|
||||
@@ -4549,6 +4549,24 @@
|
||||
aria-hidden "^1.1.1"
|
||||
react-remove-scroll "^2.4.0"
|
||||
|
||||
"@radix-ui/react-slider@^0.1.1":
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-slider/-/react-slider-0.1.4.tgz#a7b7a480ee00158195794b08cd3f1583cf102518"
|
||||
integrity sha512-0z3bCcdrAi+FIcoLXS6r0ESVWuuyMnUJoCsFm7tC7Rtv95x34YtaI8YfSyQmzuMVS4rTsNtCCTZ/s727uRaVkQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/number" "0.1.0"
|
||||
"@radix-ui/primitive" "0.1.0"
|
||||
"@radix-ui/react-collection" "0.1.4"
|
||||
"@radix-ui/react-compose-refs" "0.1.0"
|
||||
"@radix-ui/react-context" "0.1.1"
|
||||
"@radix-ui/react-primitive" "0.1.4"
|
||||
"@radix-ui/react-use-controllable-state" "0.1.0"
|
||||
"@radix-ui/react-use-direction" "0.1.0"
|
||||
"@radix-ui/react-use-layout-effect" "0.1.0"
|
||||
"@radix-ui/react-use-previous" "0.1.1"
|
||||
"@radix-ui/react-use-size" "0.1.1"
|
||||
|
||||
"@radix-ui/react-slider@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-slider/-/react-slider-1.0.0.tgz#4cabadd243aa088eb45ac710cd7cdc518fafb07e"
|
||||
@@ -4694,6 +4712,13 @@
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/react-use-callback-ref" "1.0.0"
|
||||
|
||||
"@radix-ui/react-use-direction@0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-direction/-/react-use-direction-0.1.0.tgz#97ac1d52e497c974389e7988f809238ed72e7df7"
|
||||
integrity sha512-NajpY/An9TCPSfOVkgWIdXJV+VuWl67PxB6kOKYmtNAFHvObzIoh8o0n9sAuwSAyFCZVq211FEf9gvVDRhOyiA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
|
||||
"@radix-ui/react-use-escape-keydown@0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-0.1.0.tgz#dc80cb3753e9d1bd992adbad9a149fb6ea941874"
|
||||
@@ -4746,6 +4771,13 @@
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@radix-ui/rect" "1.0.0"
|
||||
|
||||
"@radix-ui/react-use-size@0.1.1":
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-0.1.1.tgz#f6b75272a5d41c3089ca78c8a2e48e5f204ef90f"
|
||||
integrity sha512-pTgWM5qKBu6C7kfKxrKPoBI2zZYZmp2cSXzpUiGM3qEBQlMLtYhaY2JXdXUCxz+XmD1YEjc8oRwvyfsD4AG4WA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
|
||||
"@radix-ui/react-use-size@1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.0.0.tgz#a0b455ac826749419f6354dc733e2ca465054771"
|
||||
@@ -6257,6 +6289,11 @@
|
||||
lodash.isplainobject "^4.0.6"
|
||||
lodash.merge "^4.6.2"
|
||||
|
||||
"@tanstack/query-core@4.10.3":
|
||||
version "4.10.3"
|
||||
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.10.3.tgz#a6477bab9ed1ae4561ca0a59ae06f8c615c692b7"
|
||||
integrity sha512-+ME02sUmBfx3Pjd+0XtEthK8/4rVMD2jcxvnW9DSgFONpKtpjzfRzjY4ykzpDw1QEo2eoPvl7NS8J5mNI199aA==
|
||||
|
||||
"@tanstack/query-core@4.2.3":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.2.3.tgz#52d75430c9662cc85c160761c1421de483c7791f"
|
||||
@@ -6286,6 +6323,14 @@
|
||||
"@types/use-sync-external-store" "^0.0.3"
|
||||
use-sync-external-store "^1.2.0"
|
||||
|
||||
"@tanstack/react-query@^4.2.3":
|
||||
version "4.10.3"
|
||||
resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.10.3.tgz#294deefa0fb6ada88bc4631d346ef5d5551c5443"
|
||||
integrity sha512-4OEJjkcsCTmG3ui7RjsVzsXerWQvInTe95CBKFyOV/GchMUlNztoFnnYmlMhX7hLUqJMhbG9l7M507V7+xU8Hw==
|
||||
dependencies:
|
||||
"@tanstack/query-core" "4.10.3"
|
||||
use-sync-external-store "^1.2.0"
|
||||
|
||||
"@tanstack/react-query@^4.3.9":
|
||||
version "4.3.9"
|
||||
resolved "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.3.9.tgz#13332a1d4dd404baec24c2853883bcb3cc61ea92"
|
||||
|
||||
Reference in new issue
Block a user