2
0
Files
2024-08-09 00:39:27 +02:00

84 lines
2.8 KiB
TypeScript

import type { TFunction } from "next-i18next";
import { useEffect } from "react";
import { useIsPlatform } from "@calcom/atoms/monorepo";
import { useBookerStore } from "@calcom/features/bookings/Booker/store";
import type { BookerEvent } from "@calcom/features/bookings/types";
import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Badge } from "@calcom/ui";
/** Render X mins as X hours or X hours Y mins instead of in minutes once >= 60 minutes */
export const getDurationFormatted = (mins: number | undefined, t: TFunction) => {
if (!mins) return null;
const hours = Math.floor(mins / 60);
mins %= 60;
// format minutes string
let minStr = "";
if (mins > 0) {
minStr =
mins === 1
? t("minute_one", { count: 1 })
: t("multiple_duration_timeUnit", { count: mins, unit: "minute" });
}
// format hours string
let hourStr = "";
if (hours > 0) {
hourStr =
hours === 1
? t("hour_one", { count: 1 })
: t("multiple_duration_timeUnit", { count: hours, unit: "hour" });
}
if (hourStr && minStr) return `${hourStr} ${minStr}`;
return hourStr || minStr;
};
export const EventDuration = ({
event,
}: {
event: Pick<BookerEvent, "length" | "metadata" | "isDynamic">;
}) => {
const { t } = useLocale();
const isPlatform = useIsPlatform();
const [selectedDuration, setSelectedDuration, state] = useBookerStore((state) => [
state.selectedDuration,
state.setSelectedDuration,
state.state,
]);
const isDynamicEvent = "isDynamic" in event && event.isDynamic;
// Sets initial value of selected duration to the default duration.
useEffect(() => {
// Only store event duration in url if event has multiple durations.
if (!selectedDuration && (event.metadata?.multipleDuration || isDynamicEvent))
setSelectedDuration(event.length);
}, [selectedDuration, setSelectedDuration, event.metadata?.multipleDuration, event.length, isDynamicEvent]);
if ((!event?.metadata?.multipleDuration && !isDynamicEvent) || isPlatform)
return <>{getDurationFormatted(event.length, t)}</>;
const durations = event?.metadata?.multipleDuration || [15, 30, 60, 90];
return (
<div className="flex flex-wrap gap-2">
{durations
.filter((dur) => state !== "booking" || dur === selectedDuration)
.map((duration) => (
<Badge
data-testId={`multiple-choice-${duration}mins`}
data-active={selectedDuration === duration ? "true" : "false"}
variant="gray"
className={classNames(selectedDuration === duration && "bg-brand-default text-brand")}
size="md"
key={duration}
onClick={() => setSelectedDuration(duration)}>
{getDurationFormatted(duration, t)}
</Badge>
))}
</div>
);
};