Calendar toggle

feat/troubleshooter-v2
Sean Brydon 2023-10-25 14:18:29 +01:00
parent daab6a17d0
commit 6b6e9dba2b
1 changed files with 86 additions and 12 deletions

View File

@ -1,13 +1,60 @@
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Badge, Button, Switch } from "@calcom/ui"; import { Badge, Button, Switch } from "@calcom/ui";
import { TroubleshooterListItemContainer } from "./TroubleshooterListItemContainer"; import { TroubleshooterListItemContainer } from "./TroubleshooterListItemContainer";
function CalendarToggleItem() { const SELECTION_COLORS = ["#f97316", "#84cc16", "#06b6d4", "#8b5cf6", "#ec4899", "#f43f5e"];
interface CalendarToggleItemProps {
title: string;
subtitle: string;
colorDot?: string;
status: "connected" | "not_found";
calendars?: {
active?: boolean;
name?: string;
}[];
}
function CalendarToggleItem(props: CalendarToggleItemProps) {
const badgeStatus = props.status === "connected" ? "green" : "orange";
const badgeText = props.status === "connected" ? "Connected" : "Not found";
return ( return (
<TroubleshooterListItemContainer <TroubleshooterListItemContainer
title="Google Cal" title={props.title}
subtitle="google@calendar.com" subtitle={props.subtitle}
prefixSlot={
<>
<div
className="h-4 w-4 self-center rounded-[4px]"
style={{
backgroundColor: props.colorDot,
}}
/>
</>
}
suffixSlot={
<div>
<Badge variant={badgeStatus} withDot size="sm">
{badgeText}
</Badge>
</div>
}>
<div className="[&>*]:text-emphasis flex flex-col gap-3">
{props.calendars?.map((calendar) => {
return <Switch key={calendar.name} checked={calendar.active} label={calendar.name} disabled />;
})}
</div>
</TroubleshooterListItemContainer>
);
}
function EmptyCalendarToggleItem() {
const { t } = useLocale();
return (
<TroubleshooterListItemContainer
title="Please install a calendar"
prefixSlot={ prefixSlot={
<> <>
<div className="h-4 w-4 self-center rounded-[4px] bg-blue-500" /> <div className="h-4 w-4 self-center rounded-[4px] bg-blue-500" />
@ -15,14 +62,15 @@ function CalendarToggleItem() {
} }
suffixSlot={ suffixSlot={
<div> <div>
<Badge variant="green" withDot size="sm"> <Badge variant="orange" withDot size="sm">
Connected Not found
</Badge> </Badge>
</div> </div>
}> }>
<div className="flex flex-col gap-3"> <div className="flex flex-col gap-3">
<Switch label="google@calendar.com" /> <Button color="secondary" className="justify-center gap-2">
<Switch label="google@calendar.com" /> {t("install_calendar")}
</Button>
</div> </div>
</TroubleshooterListItemContainer> </TroubleshooterListItemContainer>
); );
@ -30,14 +78,40 @@ function CalendarToggleItem() {
export function CalendarToggleContainer() { export function CalendarToggleContainer() {
const { t } = useLocale(); const { t } = useLocale();
const { data, isLoading } = trpc.viewer.connectedCalendars.useQuery();
const hasConnectedCalendars = data && data?.connectedCalendars.length > 0;
return ( return (
<div className="flex flex-col space-y-3"> <div className="flex flex-col space-y-3">
<p className="text-sm font-medium leading-none">{t("calendars_were_checking_for_conflicts")}</p> <p className="text-sm font-medium leading-none">{t("calendars_were_checking_for_conflicts")}</p>
<CalendarToggleItem /> {hasConnectedCalendars && !isLoading ? (
<CalendarToggleItem /> <>
<Button color="secondary" className="justify-center gap-2"> {data.connectedCalendars.map((calendar, idx) => {
{t("manage_calendars")} const foundPrimary = calendar.calendars?.find((item) => item.primary);
</Button> return (
<CalendarToggleItem
key={calendar.credentialId}
title={calendar.integration.name}
colorDot={SELECTION_COLORS[idx] || "#000000"}
subtitle={foundPrimary?.name ?? "Nameless Calendar"}
status={calendar.error ? "not_found" : "connected"}
calendars={calendar.calendars?.map((item) => {
return {
active: item.isSelected,
name: item.name,
};
})}
/>
);
})}
<Button color="secondary" className="justify-center gap-2">
{t("manage_calendars")}
</Button>
</>
) : (
<EmptyCalendarToggleItem />
)}
</div> </div>
); );
} }