split dialog, dropdown and tooltip into separate components

event-type-list
Ryukemeister 2023-11-01 00:21:05 +05:30
parent c517d4dacd
commit 1bdb75a363
6 changed files with 255 additions and 0 deletions

View File

@ -0,0 +1,30 @@
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog";
import type { ReactNode } from "react";
export function EventTypeDialog({
open,
onOpenChange,
title,
description,
content,
}: {
open: boolean;
onOpenChange: () => void;
title: string;
description: string;
content?: ReactNode;
}) {
return (
<>
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent>
<DialogHeader>
<DialogTitle>{title}</DialogTitle>
<DialogDescription>{description}</DialogDescription>
</DialogHeader>
{!!content && content}
</DialogContent>
</Dialog>
</>
);
}

View File

@ -0,0 +1,100 @@
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu";
import { MoreHorizontal, Copy, Code, Trash } from "lucide-react";
import { EventTypeEmbedButton } from "@calcom/features/embed/EventTypeEmbed";
export function EventTypeDropdown({
group,
isReadOnly,
id,
isManagedEventType,
isChildrenManagedEventType,
embedLink,
onEdit,
onDuplicate,
}: {
group: any;
isReadOnly: boolean;
isManagedEventType: boolean;
isChildrenManagedEventType: boolean;
id: any;
embedLink: string;
onEdit: (id: string) => void;
onDuplicate: (id: string) => void;
}) {
return (
<>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
type="button"
className="bg-secondary text-secondary ltr:radix-state-open:rounded-r-md rtl:radix-state-open:rounded-l-md">
<MoreHorizontal />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
{!isReadOnly && (
<DropdownMenuItem>
<Button
type="button"
data-testid={`event-type-edit-${id}`}
onClick={() => {
onEdit(id);
}}>
Edit
</Button>
</DropdownMenuItem>
)}
{!isManagedEventType && !isChildrenManagedEventType && (
<DropdownMenuItem className="outline-none">
<Button
type="button"
data-testid={`event-type-duplicate-${id}`}
onClick={() => {
onDuplicate(id);
}}>
<Copy />
Duplicate
</Button>
</DropdownMenuItem>
)}
{!isManagedEventType && (
<DropdownMenuItem>
<EventTypeEmbedButton
className="w-full rounded-none"
eventId={id}
type="button"
StartIcon={Code}
embedUrl={encodeURIComponent(embedLink)}>
Embed
</EventTypeEmbedButton>
</DropdownMenuItem>
)}
{(group.metadata?.readOnly === false || group.metadata.readOnly === null) &&
!isChildrenManagedEventType && (
<>
<DropdownMenuSeparator />
<DropdownMenuItem>
<Button
variant="destructive"
onClick={() => {
// Add appropriate handler for destruction
}}
className="w-full rounded-none">
<Trash /> Delete
</Button>
</DropdownMenuItem>
</>
)}
</DropdownMenuContent>
</DropdownMenu>
</>
);
}

View File

@ -0,0 +1,21 @@
import { TooltipProvider, Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
import type { ReactNode } from "react";
export function EventTypeTooltip({
trigger,
content,
}: {
trigger: ReactNode | string;
content: ReactNode | string;
}) {
return (
<>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>{trigger}</TooltipTrigger>
<TooltipContent>{content}</TooltipContent>
</Tooltip>
</TooltipProvider>
</>
);
}

View File

@ -0,0 +1,21 @@
import { Button } from "@/components/ui/button";
import { EmptyScreen } from "EventTypeList/components/empty-screen";
import { LinkIcon } from "lucide-react";
export function CreateFirstEventTypeView({ slug }: { slug: string }) {
return (
<>
<EmptyScreen
Icon={LinkIcon}
className="mb-16"
headline="Create your first event type"
description="Event types enable you to share links that show available times on your calendar and allow people to make bookings with you."
buttonRaw={
<Button>
<a href={`?dialog=new&eventPage=${slug}`}>Create</a>
</Button>
}
/>
</>
);
}

View File

@ -0,0 +1,17 @@
import { Button } from "@/components/ui/button";
import { EmptyScreen } from "EventTypeList/components/empty-screen";
export function EmptyEventTypeList({ group }: { group: any }) {
return (
<>
<EmptyScreen
headline="This team has no event types"
buttonRaw={
<Button type="button" className="mt-5">
<a href={`?dialog=new&eventPage=${group.profile.slug}&teamId=${group.teamId}`}>Create</a>
</Button>
}
/>
</>
);
}

View File

@ -0,0 +1,66 @@
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import type { LucideIcon as IconType } from "lucide-react";
import type { ReactNode } from "react";
import React from "react";
import type { SVGComponent } from "@calcom/types/SVGComponent";
type EmptyScreenProps = {
Icon?: SVGComponent | IconType;
avatar?: React.ReactElement;
headline: string | React.ReactElement;
description?: string | React.ReactElement;
buttonText?: string;
buttonOnClick?: (event: React.MouseEvent<HTMLElement, MouseEvent>) => void;
buttonRaw?: ReactNode; // Used incase you want to provide your own button.
border?: boolean;
dashedBorder?: boolean;
};
export function EmptyScreen({
Icon,
avatar,
headline,
description,
buttonText,
buttonOnClick,
buttonRaw,
border = true,
dashedBorder = true,
className,
}: EmptyScreenProps & React.HTMLAttributes<HTMLDivElement>) {
return (
<>
<div
data-testid="empty-screen"
className={cn(
"flex w-full select-none flex-col items-center justify-center rounded-lg p-7 lg:p-20",
border && "border-subtle border",
dashedBorder && "border-dashed",
className
)}>
{!avatar ? null : (
<div className="flex h-[72px] w-[72px] items-center justify-center rounded-full">{avatar}</div>
)}
{!Icon ? null : (
<div className="bg-emphasis flex h-[72px] w-[72px] items-center justify-center rounded-full ">
<Icon className="text-default inline-block h-10 w-10 stroke-[1.3px]" />
</div>
)}
<div className="flex max-w-[420px] flex-col items-center">
<h2 className={cn("text-semibold font-cal text-emphasis text-center text-xl", !!Icon && "mt-6")}>
{headline}
</h2>
{!!description && (
<div className="text-default mb-8 mt-3 text-center text-sm font-normal leading-6">
{description}
</div>
)}
{!!buttonOnClick && !!buttonText && <Button onClick={(e) => buttonOnClick(e)}>{buttonText}</Button>}
{buttonRaw}
</div>
</div>
</>
);
}