feat: frontend to handle multiple calendars for connect atoms (#16527)

* handle multiple calendars in connect atoms

* resolve merge conflicts

* fixup

* frontend for multiple calendars

* fixup

* remove comment

* add missing props

* add prop for multi calendar view

* add multi calendar support

* fixup
This commit is contained in:
Rajiv Sahal authored and GitHub committed 2024-09-30 11:33:18 +00:00
1 parent 26a1c749f7
commit 1d203dc566
6 files changed
+113 -14

No files matched your search

@@ -1,5 +1,6 @@
"use client";
import type { ReactNode } from "react";
import type { FC } from "react";
import type { CALENDARS } from "@calcom/platform-constants";
@@ -8,6 +9,7 @@ import { Button } from "@calcom/ui";
import type { OnCheckErrorType, UseCheckProps } from "../hooks/connect/useCheck";
import { useCheck } from "../hooks/connect/useCheck";
import { useConnect } from "../hooks/connect/useConnect";
import { useConnectedCalendars } from "../hooks/useConnectedCalendars";
import { AtomsWrapper } from "../src/components/atoms-wrapper";
import { cn } from "../src/lib/utils";
@@ -19,6 +21,10 @@ export type OAuthConnectProps = {
onCheckError?: OnCheckErrorType;
redir?: string;
initialData: UseCheckProps["initialData"];
isMultiCalendar?: boolean;
tooltip?: ReactNode;
tooltipSide?: "top" | "bottom" | "left" | "right";
isClickable?: boolean;
};
export const OAuthConnect: FC<
@@ -34,9 +40,12 @@ export const OAuthConnect: FC<
calendar,
redir,
initialData,
isMultiCalendar = false,
tooltip,
tooltipSide = "bottom",
isClickable,
}) => {
const { connect } = useConnect(calendar, redir);
const { allowConnect, checked } = useCheck({
onCheckError,
calendar: calendar,
@@ -54,6 +63,24 @@ export const OAuthConnect: FC<
displayedLabel = alreadyConnectedLabel;
}
if (isMultiCalendar) {
return (
<AtomsWrapper>
<Button
StartIcon="calendar-days"
color="primary"
disabled={isClickable ? false : isChecking}
tooltip={tooltip ? tooltip : <ConnectedCalendarsTooltip />}
tooltipSide={tooltipSide}
tooltipOffset={10}
className={cn("", !isDisabled && "cursor-pointer", className)}
onClick={() => connect()}>
{displayedLabel}
</Button>
</AtomsWrapper>
);
}
return (
<AtomsWrapper>
<Button
@@ -62,10 +89,10 @@ export const OAuthConnect: FC<
disabled={isDisabled}
className={cn(
"",
className,
isChecking && "animate-pulse",
isDisabled && "cursor-not-allowed",
!isDisabled && "cursor-pointer"
!isDisabled && "cursor-pointer",
className
)}
onClick={() => connect()}>
{displayedLabel}
@@ -73,3 +100,27 @@ export const OAuthConnect: FC<
</AtomsWrapper>
);
};
export const ConnectedCalendarsTooltip = () => {
const { data: connectedCalendars, isLoading: isConnectedCalendarsLoading } = useConnectedCalendars({});
if (isConnectedCalendarsLoading)
return (
<div className="bg-subtle flex flex-col rounded-md border border-gray-300 px-4 py-2">Loading...</div>
);
return (
<div className="bg-subtle flex flex-col rounded-md border border-gray-300">
{connectedCalendars?.connectedCalendars.map((calendar, index, arr) => {
return (
<>
<div key={calendar.primary?.externalId} className="bg-transparent px-4 py-2 text-black">
{calendar.primary?.name} - {calendar.primary?.email}
</div>
{arr.length - 1 !== index && <hr className="w-[90%] self-center" />}
</>
);
})}
</div>
);
};
@@ -21,6 +21,7 @@ import { useSaveCalendarCredentials } from "../../hooks/connect/useConnect";
import { AtomsWrapper } from "../../src/components/atoms-wrapper";
import { useToast } from "../../src/components/ui/use-toast";
import { cn } from "../../src/lib/utils";
import { ConnectedCalendarsTooltip } from "../OAuthConnect";
import type { OAuthConnectProps } from "../OAuthConnect";
export const AppleConnect: FC<Partial<Omit<OAuthConnectProps, "redir">>> = ({
@@ -29,6 +30,10 @@ export const AppleConnect: FC<Partial<Omit<OAuthConnectProps, "redir">>> = ({
loadingLabel,
className,
initialData,
isMultiCalendar = false,
tooltip,
tooltipSide = "bottom",
isClickable,
}) => {
const { t } = useLocale();
const form = useForm({
@@ -77,14 +82,36 @@ export const AppleConnect: FC<Partial<Omit<OAuthConnectProps, "redir">>> = ({
<AtomsWrapper>
<Dialog open={isDialogOpen}>
<DialogTrigger asChild>
<Button
StartIcon="calendar-days"
color="primary"
disabled={isDisabled}
className={cn("", className, isDisabled && "cursor-not-allowed", !isDisabled && "cursor-pointer")}
onClick={() => setIsDialogOpen(true)}>
{displayedLabel}
</Button>
<>
{isMultiCalendar && (
<Button
StartIcon="calendar-days"
color="primary"
disabled={isClickable ? false : isChecking}
tooltip={tooltip ? tooltip : <ConnectedCalendarsTooltip />}
tooltipSide={tooltipSide}
tooltipOffset={10}
className={cn("", !isDisabled && "cursor-pointer", className)}
onClick={() => setIsDialogOpen(true)}>
{displayedLabel}
</Button>
)}
{!isMultiCalendar && (
<Button
StartIcon="calendar-days"
color="primary"
disabled={isDisabled}
className={cn(
"",
isDisabled && "cursor-not-allowed",
!isDisabled && "cursor-pointer",
className
)}
onClick={() => setIsDialogOpen(true)}>
{displayedLabel}
</Button>
)}
</>
</DialogTrigger>
<DialogContent>
<DialogHeader>
@@ -16,6 +16,10 @@ export const GcalConnect: FC<Partial<OAuthConnectProps>> = ({
onCheckError,
redir,
initialData,
isMultiCalendar = false,
tooltipSide,
tooltip,
isClickable,
}) => {
const { t } = useLocale();
return (
@@ -28,6 +32,10 @@ export const GcalConnect: FC<Partial<OAuthConnectProps>> = ({
onCheckError={onCheckError}
redir={redir}
initialData={initialData}
isMultiCalendar={isMultiCalendar}
tooltipSide={tooltipSide}
tooltip={tooltip}
isClickable={isClickable}
/>
);
};
@@ -16,6 +16,10 @@ export const OutlookConnect: FC<Partial<OAuthConnectProps>> = ({
onCheckError,
redir,
initialData,
isMultiCalendar = false,
tooltipSide,
tooltip,
isClickable,
}) => {
const { t } = useLocale();
return (
@@ -28,6 +32,10 @@ export const OutlookConnect: FC<Partial<OAuthConnectProps>> = ({
onCheckError={onCheckError}
redir={redir}
initialData={initialData}
isMultiCalendar={isMultiCalendar}
tooltipSide={tooltipSide}
tooltip={tooltip}
isClickable={isClickable}
/>
);
};
@@ -25,17 +25,21 @@ export default function Home(props: { calUsername: string; calEmail: string }) {
className="h-[40px] bg-gradient-to-r from-[#8A2387] via-[#E94057] to-[#F27121] text-center text-base font-semibold text-transparent text-white hover:bg-orange-700"
/>
<Connect.OutlookCalendar
isMultiCalendar={true}
redir="http://localhost:4321/calendars"
className="h-[40px] bg-gradient-to-r from-[#8A2387] via-[#E94057] to-[#F27121] text-center text-base font-semibold text-transparent text-white hover:bg-orange-700"
/>
<Connect.AppleCalendar className="h-[40px] bg-gradient-to-r from-[#8A2387] via-[#E94057] to-[#F27121] text-center text-base font-semibold text-transparent text-white hover:bg-orange-700" />
<Connect.AppleCalendar
isMultiCalendar={true}
className="h-[40px] bg-gradient-to-r from-[#8A2387] via-[#E94057] to-[#F27121] text-center text-base font-semibold text-transparent text-white hover:bg-orange-700"
/>
</div>
</div>
<div className="hidden lg:block">
<img
width="76%"
height="76%"
className=" rounded-lg shadow-2xl"
className="rounded-lg shadow-2xl"
alt="cover image"
src="https://images.unsplash.com/photo-1506784365847-bbad939e9335?q=80&w=2668&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
/>
+2 -1
View File
@@ -32,7 +32,8 @@ export function Tooltip({
"calcom-tooltip",
side === "top" && "-mt-7",
side === "right" && "ml-2",
"bg-inverted text-inverted relative z-50 rounded-md px-2 py-1 text-xs font-semibold shadow-lg",
"relative z-50 rounded-md text-xs font-semibold shadow-lg",
!isPlatform && "bg-inverted text-inverted px-2 py-1",
props.className && `${props.className}`
)}
side={side}