// TODO: replace headlessui with radix-ui import { Menu, Transition } from "@headlessui/react"; import { ArrowDownIcon, ArrowUpIcon, DotsHorizontalIcon, ExternalLinkIcon, LinkIcon, UsersIcon, } from "@heroicons/react/solid"; import { Trans } from "next-i18next"; import Head from "next/head"; import Link from "next/link"; import React, { Fragment, useEffect, useState } from "react"; import { QueryCell } from "@lib/QueryCell"; import classNames from "@lib/classNames"; import { useLocale } from "@lib/hooks/useLocale"; import showToast from "@lib/notification"; import { inferQueryOutput, trpc } from "@lib/trpc"; import Shell from "@components/Shell"; import { Tooltip } from "@components/Tooltip"; import CreateEventTypeButton from "@components/eventtype/CreateEventType"; import EventTypeDescription from "@components/eventtype/EventTypeDescription"; import { Alert } from "@components/ui/Alert"; import Avatar from "@components/ui/Avatar"; import AvatarGroup from "@components/ui/AvatarGroup"; import Badge from "@components/ui/Badge"; import UserCalendarIllustration from "@components/ui/svg/UserCalendarIllustration"; type Profiles = inferQueryOutput<"viewer.eventTypes">["profiles"]; type EventTypeGroups = inferQueryOutput<"viewer.eventTypes">["eventTypeGroups"]; type EventTypeGroupProfile = EventTypeGroups[number]["profile"]; interface CreateEventTypeProps { canAddEvents: boolean; profiles: Profiles; } const CreateFirstEventTypeView = ({ canAddEvents, profiles }: CreateEventTypeProps) => { const { t } = useLocale(); return (

{t("new_event_type_heading")}

{t("new_event_type_description")}

); }; type EventTypeGroup = inferQueryOutput<"viewer.eventTypes">["eventTypeGroups"][number]; type EventType = EventTypeGroup["eventTypes"][number]; interface EventTypeListProps { profile: { slug: string | null }; readOnly: boolean; types: EventType[]; } const EventTypeList = ({ readOnly, types, profile }: EventTypeListProps): JSX.Element => { const { t } = useLocale(); const utils = trpc.useContext(); const mutation = trpc.useMutation("viewer.eventTypeOrder", { onError: (err) => { console.error(err.message); }, async onSettled() { await utils.cancelQuery(["viewer.eventTypes"]); await utils.invalidateQueries(["viewer.eventTypes"]); }, }); const [sortableTypes, setSortableTypes] = useState(types); useEffect(() => { setSortableTypes(types); }, [types]); function moveEventType(index: number, increment: 1 | -1) { const newList = [...sortableTypes]; const type = sortableTypes[index]; const tmp = sortableTypes[index + increment]; if (tmp) { newList[index] = tmp; newList[index + increment] = type; } setSortableTypes(newList); mutation.mutate({ ids: newList.map((type) => type.id), }); } return (
); }; interface EventTypeListHeadingProps { profile: EventTypeGroupProfile; membershipCount: number; } const EventTypeListHeading = ({ profile, membershipCount }: EventTypeListHeadingProps): JSX.Element => (
{profile?.name || ""} {membershipCount && ( {membershipCount} )} {profile?.slug && ( {`${process.env.NEXT_PUBLIC_APP_URL?.replace( "https://", "" )}/${profile.slug}`} )}
); const EventTypesPage = () => { const { t } = useLocale(); const query = trpc.useQuery(["viewer.eventTypes"]); return (
Home | Cal.com ) }> ( <> {data.viewer.plan === "FREE" && !data.viewer.canAddEvents && ( {t("plan_upgrade")}} message={ You can upgrade here . } className="mb-4" /> )} {data.eventTypeGroups.map((group) => ( {/* hide list heading when there is only one (current user) */} {(data.eventTypeGroups.length !== 1 || group.teamId) && ( )} ))} {data.eventTypeGroups.length === 0 && ( )} )} />
); }; export default EventTypesPage;