This commit is contained in:
zomars 2022-03-01 09:58:02 -07:00
parent f0438ed35d
commit 5519cf36e3
8 changed files with 1324 additions and 88 deletions

View File

@ -191,6 +191,7 @@ function CalendarList(props: Props) {
/>
);
}
export function CalendarListContainer(props: { heading?: false }) {
const { t } = useLocale();
const { heading = true } = props;

View File

@ -13,7 +13,7 @@ const ALL_APPS_MAP = {
...CalendarApps,
...ConferencingApps,
...PaymentApps,
};
} as App[];
const credentialData = Prisma.validator<Prisma.CredentialArgs>()({
select: { id: true, type: true },
@ -54,6 +54,7 @@ export function hasIntegration(apps: AppMeta, type: string): boolean {
(type === "jitsi_video" || type === "huddle01_video" || app.credentials.length > 0)
);
}
export function hasIntegrationInstalled(type: App["type"]): boolean {
return ALL_APPS.some((app) => app.type === type && !!app.installed);
}

View File

@ -2,7 +2,7 @@ import { ChevronRightIcon, PencilAltIcon, SwitchHorizontalIcon, TrashIcon } from
import { ClipboardIcon } from "@heroicons/react/solid";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@radix-ui/react-collapsible";
import Image from "next/image";
import React, { useEffect, useState } from "react";
import { useEffect, useState } from "react";
import { Controller, useForm, useWatch } from "react-hook-form";
import { JSONObject } from "superjson/dist/types";
@ -21,7 +21,7 @@ import Loader from "@components/Loader";
import Shell, { ShellSubHeading } from "@components/Shell";
import { Tooltip } from "@components/Tooltip";
import ConfirmationDialogContent from "@components/dialog/ConfirmationDialogContent";
import { FieldsetLegend, Form, InputGroupBox, TextField, TextArea } from "@components/form/fields";
import { FieldsetLegend, Form, InputGroupBox, TextArea, TextField } from "@components/form/fields";
import ConnectIntegration from "@components/integrations/ConnectIntegrations";
import DisconnectIntegration from "@components/integrations/DisconnectIntegration";
import IntegrationListItem from "@components/integrations/IntegrationListItem";
@ -122,7 +122,7 @@ function WebhookTestDisclosure() {
return (
<Collapsible open={open} onOpenChange={() => setOpen(!open)}>
<CollapsibleTrigger type="button" className={"flex w-full cursor-pointer"}>
<ChevronRightIcon className={`${open ? "rotate-90 transform" : ""} h-5 w-5 text-neutral-500`} />
<ChevronRightIcon className={`${open ? "rotate-90 transform" : ""} text-neutral-500 h-5 w-5`} />
<span className="text-sm font-medium text-gray-700">{t("webhook_test")}</span>
</CollapsibleTrigger>
<CollapsibleContent>

View File

@ -404,7 +404,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
{formMethods.getValues("locations").map((location) => (
<li
key={location.type}
className="mb-2 rounded-sm border border-neutral-300 py-1.5 px-2 shadow-sm">
className="border-neutral-300 mb-2 rounded-sm border py-1.5 px-2 shadow-sm">
<div className="flex justify-between">
{location.type === LocationType.InPerson && (
<div className="flex flex-grow items-center">
@ -625,8 +625,8 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
type="button"
className="flex rounded-sm px-3 py-2 hover:bg-gray-100"
onClick={() => setShowLocationModal(true)}>
<PlusIcon className="mt-0.5 h-4 w-4 text-neutral-900" />
<span className="ml-1 text-sm font-medium text-neutral-700">{t("add_location")}</span>
<PlusIcon className="text-neutral-900 mt-0.5 h-4 w-4" />
<span className="text-neutral-700 ml-1 text-sm font-medium">{t("add_location")}</span>
</button>
</li>
)}
@ -659,7 +659,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
autoFocus
style={{ top: -6, fontSize: 22 }}
required
className="relative h-10 w-full cursor-pointer border-none bg-transparent pl-0 text-gray-900 hover:text-gray-700 focus:text-black focus:outline-none focus:ring-0"
className="focus:outline-none relative h-10 w-full cursor-pointer border-none bg-transparent pl-0 text-gray-900 hover:text-gray-700 focus:text-black focus:ring-0"
placeholder={t("quick_chat")}
{...formMethods.register("title")}
defaultValue={eventType.title}
@ -671,7 +671,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
subtitle={eventType.description || ""}>
<div className="mx-auto block sm:flex md:max-w-5xl">
<div className="w-full ltr:mr-2 rtl:ml-2 sm:w-9/12">
<div className="-mx-4 rounded-sm border border-neutral-200 bg-white p-4 py-6 sm:mx-0 sm:px-8">
<div className="border-neutral-200 -mx-4 rounded-sm border bg-white p-4 py-6 sm:mx-0 sm:px-8">
<Form
form={formMethods}
handleSubmit={async (values) => {
@ -695,8 +695,8 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="space-y-3">
<div className="block items-center sm:flex">
<div className="min-w-48 mb-4 sm:mb-0">
<label htmlFor="slug" className="flex text-sm font-medium text-neutral-700">
<LinkIcon className="mt-0.5 h-4 w-4 text-neutral-500 ltr:mr-2 rtl:ml-2" />
<label htmlFor="slug" className="text-neutral-700 flex text-sm font-medium">
<LinkIcon className="text-neutral-500 mt-0.5 h-4 w-4 ltr:mr-2 rtl:ml-2" />
{t("url")}
</label>
</div>
@ -726,7 +726,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<MinutesField
label={
<>
<ClockIcon className="mt-0.5 h-4 w-4 text-neutral-500 ltr:mr-2 rtl:ml-2" />{" "}
<ClockIcon className="text-neutral-500 mt-0.5 h-4 w-4 ltr:mr-2 rtl:ml-2" />{" "}
{t("duration")}
</>
}
@ -746,8 +746,8 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="space-y-3">
<div className="block sm:flex">
<div className="min-w-48 sm:mb-0">
<label htmlFor="location" className="mt-2.5 flex text-sm font-medium text-neutral-700">
<LocationMarkerIcon className="mt-0.5 h-4 w-4 text-neutral-500 ltr:mr-2 rtl:ml-2" />
<label htmlFor="location" className="text-neutral-700 mt-2.5 flex text-sm font-medium">
<LocationMarkerIcon className="text-neutral-500 mt-0.5 h-4 w-4 ltr:mr-2 rtl:ml-2" />
{t("location")}
</label>
</div>
@ -763,8 +763,8 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="space-y-3">
<div className="block sm:flex">
<div className="min-w-48 mb-4 mt-2.5 sm:mb-0">
<label htmlFor="description" className="mt-0 flex text-sm font-medium text-neutral-700">
<DocumentIcon className="mt-0.5 h-4 w-4 text-neutral-500 ltr:mr-2 rtl:ml-2" />
<label htmlFor="description" className="text-neutral-700 mt-0 flex text-sm font-medium">
<DocumentIcon className="text-neutral-500 mt-0.5 h-4 w-4 ltr:mr-2 rtl:ml-2" />
{t("description")}
</label>
</div>
@ -785,8 +785,8 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="min-w-48 mb-4 sm:mb-0">
<label
htmlFor="schedulingType"
className="mt-2 flex text-sm font-medium text-neutral-700">
<UsersIcon className="h-5 w-5 text-neutral-500 ltr:mr-2 rtl:ml-2" />{" "}
className="text-neutral-700 mt-2 flex text-sm font-medium">
<UsersIcon className="text-neutral-500 h-5 w-5 ltr:mr-2 rtl:ml-2" />{" "}
{t("scheduling_type")}
</label>
</div>
@ -809,8 +809,8 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="block sm:flex">
<div className="min-w-48 mb-4 sm:mb-0">
<label htmlFor="users" className="flex text-sm font-medium text-neutral-700">
<UserAddIcon className="h-5 w-5 text-neutral-500 ltr:mr-2 rtl:ml-2" />{" "}
<label htmlFor="users" className="text-neutral-700 flex text-sm font-medium">
<UserAddIcon className="text-neutral-500 h-5 w-5 ltr:mr-2 rtl:ml-2" />{" "}
{t("attendees")}
</label>
</div>
@ -846,9 +846,9 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<ChevronRightIcon
className={`${
advancedSettingsVisible ? "rotate-90 transform" : ""
} ml-auto h-5 w-5 text-neutral-500`}
} text-neutral-500 ml-auto h-5 w-5`}
/>
<span className="text-sm font-medium text-neutral-700">
<span className="text-neutral-700 text-sm font-medium">
{t("show_advanced_settings")}
</span>
</CollapsibleTrigger>
@ -863,7 +863,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="min-w-48 mb-4 sm:mb-0">
<label
htmlFor="createEventsOn"
className="flex text-sm font-medium text-neutral-700">
className="text-neutral-700 flex text-sm font-medium">
{t("create_events_on")}
</label>
</div>
@ -887,7 +887,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
)}
<div className="block items-center sm:flex">
<div className="min-w-48 mb-4 sm:mb-0">
<label htmlFor="eventName" className="flex text-sm font-medium text-neutral-700">
<label htmlFor="eventName" className="text-neutral-700 flex text-sm font-medium">
{t("event_name")} <InfoBadge content={t("event_name_tooltip")} />
</label>
</div>
@ -908,7 +908,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="min-w-48 mb-4 sm:mb-0">
<label
htmlFor="smartContractAddress"
className="flex text-sm font-medium text-neutral-700">
className="text-neutral-700 flex text-sm font-medium">
{t("Smart Contract Address")}
</label>
</div>
@ -931,7 +931,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="min-w-48 mb-4 sm:mb-0">
<label
htmlFor="additionalFields"
className="flexflex mt-2 text-sm font-medium text-neutral-700">
className="flexflex text-neutral-700 mt-2 text-sm font-medium">
{t("additional_inputs")}
</label>
</div>
@ -1037,7 +1037,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
)}
/>
<hr className="my-2 border-neutral-200" />
<hr className="border-neutral-200 my-2" />
<Controller
name="minimumBookingNotice"
control={formMethods.control}
@ -1058,7 +1058,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="block items-center sm:flex">
<div className="min-w-48 mb-4 sm:mb-0">
<label htmlFor="eventName" className="flex text-sm font-medium text-neutral-700">
<label htmlFor="eventName" className="text-neutral-700 flex text-sm font-medium">
{t("slot_interval")}
</label>
</div>
@ -1107,7 +1107,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="min-w-48 mb-4 sm:mb-0">
<label
htmlFor="inviteesCanSchedule"
className="mt-2.5 flex text-sm font-medium text-neutral-700">
className="text-neutral-700 mt-2.5 flex text-sm font-medium">
{t("invitees_can_schedule")}
</label>
</div>
@ -1127,7 +1127,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<RadioGroup.Item
id={period.type}
value={period.type}
className="flex h-4 w-4 cursor-pointer items-center rounded-full border border-black bg-white focus:border-2 focus:outline-none ltr:mr-2 rtl:ml-2">
className="focus:outline-none flex h-4 w-4 cursor-pointer items-center rounded-full border border-black bg-white focus:border-2 ltr:mr-2 rtl:ml-2">
<RadioGroup.Indicator className="relative flex h-4 w-4 items-center justify-center after:block after:h-2 after:w-2 after:rounded-full after:bg-black" />
</RadioGroup.Item>
{period.prefix ? <span>{period.prefix}&nbsp;</span> : null}
@ -1142,7 +1142,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
/>
<select
id=""
className="focus:border-primary-500 focus:ring-primary-500 block w-full rounded-sm border-gray-300 py-2 pl-3 pr-10 text-base focus:outline-none sm:text-sm"
className="focus:border-primary-500 focus:ring-primary-500 focus:outline-none block w-full rounded-sm border-gray-300 py-2 pl-3 pr-10 text-base sm:text-sm"
{...formMethods.register("periodCountCalendarDays")}
defaultValue={eventType.periodCountCalendarDays ? "1" : "0"}>
<option value="1">{t("calendar_days")}</option>
@ -1183,7 +1183,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="block sm:flex">
<div className="min-w-48 mb-4 sm:mb-0">
<label htmlFor="availability" className="flex text-sm font-medium text-neutral-700">
<label htmlFor="availability" className="text-neutral-700 flex text-sm font-medium">
{t("availability")}
</label>
</div>
@ -1226,7 +1226,7 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
<div className="min-w-48 mb-4 sm:mb-0">
<label
htmlFor="payment"
className="mt-2 flex text-sm font-medium text-neutral-700">
className="text-neutral-700 mt-2 flex text-sm font-medium">
{t("payment")}
</label>
</div>
@ -1351,8 +1351,8 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
href={permalink}
target="_blank"
rel="noreferrer"
className="text-md inline-flex items-center rounded-sm px-2 py-1 text-sm font-medium text-neutral-700 hover:bg-gray-200 hover:text-gray-900">
<ExternalLinkIcon className="h-4 w-4 text-neutral-500 ltr:mr-2 rtl:ml-2" aria-hidden="true" />
className="text-md text-neutral-700 inline-flex items-center rounded-sm px-2 py-1 text-sm font-medium hover:bg-gray-200 hover:text-gray-900">
<ExternalLinkIcon className="text-neutral-500 h-4 w-4 ltr:mr-2 rtl:ml-2" aria-hidden="true" />
{t("preview")}
</a>
<button
@ -1362,12 +1362,12 @@ const EventTypePage = (props: inferSSRProps<typeof getServerSideProps>) => {
}}
type="button"
className="text-md flex items-center rounded-sm px-2 py-1 text-sm font-medium text-gray-700 hover:bg-gray-200 hover:text-gray-900">
<LinkIcon className="h-4 w-4 text-neutral-500 ltr:mr-2 rtl:ml-2" />
<LinkIcon className="text-neutral-500 h-4 w-4 ltr:mr-2 rtl:ml-2" />
{t("copy_link")}
</button>
<Dialog>
<DialogTrigger className="text-md flex items-center rounded-sm px-2 py-1 text-sm font-medium text-neutral-700 hover:bg-gray-200 hover:text-gray-900">
<TrashIcon className="h-4 w-4 text-neutral-500 ltr:mr-2 rtl:ml-2" />
<DialogTrigger className="text-md text-neutral-700 flex items-center rounded-sm px-2 py-1 text-sm font-medium hover:bg-gray-200 hover:text-gray-900">
<TrashIcon className="text-neutral-500 h-4 w-4 ltr:mr-2 rtl:ml-2" />
{t("delete")}
</DialogTrigger>
<ConfirmationDialogContent

View File

@ -0,0 +1,4 @@
# Place these on `apps/web/.env`
# @see https://github.com/calcom/cal.com/#obtaining-zoom-client-id-and-secret
ZOOM_CLIENT_ID=
ZOOM_CLIENT_SECRET=

View File

@ -1,9 +1,10 @@
import type { App } from "@calcom/types/App";
import _metadata from "./package.json";
import _package from "./package.json";
export const metadata = {
..._metadata,
name: "Zoom Video",
description: _package.description,
installed: !!(process.env.ZOOM_CLIENT_ID && process.env.ZOOM_CLIENT_SECRET),
type: "zoom_video",
imageSrc: "apps/zoom.svg",
@ -14,7 +15,12 @@ export const metadata = {
verified: true,
rating: 4.3, // TODO: placeholder for now, pull this from TrustPilot or G2
reviews: 69, // TODO: placeholder for now, pull this from TrustPilot or G2
} as Partial<App>;
category: "video",
label: "Zoom Video",
slug: "zoom_video",
title: "Zoom Video",
trending: true,
} as App;
export * as api from "./api";
export * as lib from "./lib";

1318
yarn.lock

File diff suppressed because it is too large Load Diff