import { Dialog, DialogContent } from "@components/Dialog"; import Loader from "@components/Loader"; import { Tooltip } from "@components/Tooltip"; import { Button } from "@components/ui/Button"; import { Menu, Transition } from "@headlessui/react"; import { ClockIcon, DotsHorizontalIcon, ExternalLinkIcon, InformationCircleIcon, LinkIcon, PlusIcon, UserIcon, } from "@heroicons/react/solid"; import classNames from "@lib/classNames"; import showToast from "@lib/notification"; import dayjs from "dayjs"; import { useSession } from "next-auth/client"; import Link from "next/link"; import { useRouter } from "next/router"; import React, { Fragment, useRef } from "react"; import Shell from "@components/Shell"; import prisma from "@lib/prisma"; import { GetServerSidePropsContext } from "next"; import { useMutation } from "react-query"; import createEventType from "@lib/mutations/event-types/create-event-type"; import { getSession } from "@lib/auth"; import { ONBOARDING_INTRODUCED_AT } from "@lib/getting-started"; import { useToggleQuery } from "@lib/hooks/useToggleQuery"; import { inferSSRProps } from "@lib/types/inferSSRProps"; import { Alert } from "@components/ui/Alert"; import { HttpError } from "@lib/core/http/error"; const EventTypesPage = (props: inferSSRProps) => { const { user, types } = props; const [session, loading] = useSession(); const router = useRouter(); const createMutation = useMutation(createEventType, { onSuccess: async ({ eventType }) => { await router.push("/event-types/" + eventType.slug); showToast(`${eventType.title} event type created successfully`, "success"); }, onError: (err: HttpError) => { const message = `${err.statusCode}: ${err.message}`; showToast(message, "error"); }, }); const modalOpen = useToggleQuery("new"); const slugRef = useRef(null); if (loading) { return ; } const renderEventDialog = () => ( { router.push(isOpen ? modalOpen.hrefOn : modalOpen.hrefOff); }}>

Create a new event type for people to book times with.

{ e.preventDefault(); const target = e.target as unknown as Record< "title" | "slug" | "description" | "length", { value: string } >; const body = { title: target.title.value, slug: target.slug.value, description: target.description.value, length: parseInt(target.length.value), }; createMutation.mutate(body); }}>
{ if (!slugRef.current) { return; } const slug = e.target.value.replace(/\s+/g, "-").toLowerCase(); slugRef.current.value = slug; }} type="text" name="title" id="title" required className="block w-full border-gray-300 rounded-sm shadow-sm focus:border-neutral-900 focus:ring-neutral-900 sm:text-sm" placeholder="Quick Chat" />
{location.hostname}/{user.username}/
minutes
); return (
{props.user.plan === "FREE" && ( You need to upgrade your plan to have more than one active event type.} message={ <> To upgrade go to{" "} calendso.com/upgrade } className="my-4" /> )}
    {types.map((item) => (
  • {item.title}

    {item.hidden && ( Hidden )}
    {item.description && (
    )}
    {({ open }) => ( <>
    Open options
    {({ active }) => ( )} {({ active }) => ( )} {/**/} {/* {({ active }) => (*/} {/* */} {/* */}
    {/*
    */} {/* */} {/* {({ active }) => (*/} {/* */} {/* */} {/*
    */}
    )}
  • ))}
{types.length === 0 && (

Create your first event type

Event types enable you to share links that show available times on your calendar and allow people to make bookings with you.

{renderEventDialog()}
)}
); }; export const getServerSideProps = async (context: GetServerSidePropsContext) => { const { req } = context; const session = await getSession({ req }); if (!session?.user?.id) { return { redirect: { permanent: false, destination: "/auth/login", }, } as const; } const user = await prisma.user.findUnique({ where: { id: session.user.id, }, select: { id: true, username: true, startTime: true, endTime: true, bufferTime: true, completedOnboarding: true, createdDate: true, plan: true, }, }); if (!user) { // this shouldn't happen return { redirect: { permanent: false, destination: "/auth/login", }, } as const; } if (!user.completedOnboarding && dayjs(user.createdDate).isAfter(ONBOARDING_INTRODUCED_AT)) { return { redirect: { permanent: false, destination: "/getting-started", }, } as const; } const typesRaw = await prisma.eventType.findMany({ where: { userId: user.id, }, select: { id: true, title: true, slug: true, description: true, length: true, hidden: true, }, }); const types = typesRaw.map((type, index) => user.plan === "FREE" && index > 0 ? { ...type, $disabled: true, } : { ...type, $disabled: false, } ); const userObj = Object.assign({}, user, { createdDate: user.createdDate.toString(), }); const canAddEvents = user.plan !== "FREE" || types.length < 1; return { props: { user: userObj, types, canAddEvents, }, }; }; export default EventTypesPage;