diff --git a/apps/web/components/Embed.tsx b/apps/web/components/Embed.tsx
index 1885747c..b48eea54 100644
--- a/apps/web/components/Embed.tsx
+++ b/apps/web/components/Embed.tsx
@@ -1,18 +1,18 @@
-import { CodeIcon, EyeIcon, SunIcon, ChevronRightIcon, ArrowLeftIcon } from "@heroicons/react/solid";
+import { ArrowLeftIcon, ChevronRightIcon, CodeIcon, EyeIcon, SunIcon } from "@heroicons/react/solid";
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@radix-ui/react-collapsible";
import classNames from "classnames";
import { useRouter } from "next/router";
import { useRef, useState } from "react";
-import { components, ControlProps, SingleValue } from "react-select";
+import { components, ControlProps } from "react-select";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import showToast from "@calcom/lib/notification";
import { EventType } from "@calcom/prisma/client";
import { Button, Switch } from "@calcom/ui";
-import { Dialog, DialogContent, DialogClose } from "@calcom/ui/Dialog";
+import { Dialog, DialogClose, DialogContent } from "@calcom/ui/Dialog";
import { InputLeading, Label, TextArea, TextField } from "@calcom/ui/form/fields";
-import { WEBAPP_URL, EMBED_LIB_URL } from "@lib/config/constants";
+import { EMBED_LIB_URL, WEBAPP_URL } from "@lib/config/constants";
import { trpc } from "@lib/trpc";
import NavTabs from "@components/NavTabs";
@@ -241,7 +241,10 @@ const EmbedNavBar = () => {
return ;
};
-const ThemeSelectControl = ({ children, ...props }: ControlProps) => {
+const ThemeSelectControl = ({
+ children,
+ ...props
+}: ControlProps<{ value: string; label: string }, false>) => {
return (
@@ -381,7 +384,7 @@ Cal("inline", {
});
${getEmbedUIInstructionString().trim()}`;
} else if (embedType === "floating-popup") {
- let floatingButtonArg = {
+ const floatingButtonArg = {
calLink,
...previewState.floatingPopup,
};
@@ -418,7 +421,7 @@ ${getEmbedUIInstructionString().trim()}`;
});
};
- const previewInstruction = (instruction: { name: string; arg: any }) => {
+ const previewInstruction = (instruction: { name: string; arg: unknown }) => {
iframeRef.current?.contentWindow?.postMessage(
{
mode: "cal:preview",
@@ -544,7 +547,7 @@ ${getEmbedUIInstructionString().trim()}`;
value={previewState.inline.width}
onChange={(e) => {
setPreviewState((previewState) => {
- let width = e.target.value || "100%";
+ const width = e.target.value || "100%";
return {
...previewState,
@@ -759,11 +762,11 @@ ${getEmbedUIInstructionString().trim()}`;
{
- //@ts-ignore - How to support dynamic palette names?
addToPalette({
- [palette.name]: color,
+ [palette.name as keyof typeof previewState["palette"]]: color,
});
- }}>
+ }}
+ />
))}
diff --git a/apps/web/components/NavTabs.tsx b/apps/web/components/NavTabs.tsx
index a08f79d4..4aefe925 100644
--- a/apps/web/components/NavTabs.tsx
+++ b/apps/web/components/NavTabs.tsx
@@ -1,4 +1,5 @@
import { AdminRequired } from "components/ui/AdminRequired";
+import noop from "lodash/noop";
import Link, { LinkProps } from "next/link";
import { useRouter } from "next/router";
import { FC, Fragment, MouseEventHandler } from "react";
@@ -28,11 +29,11 @@ const NavTabs: FC = ({ tabs, linkProps, ...props }) => {
aria-label="Tabs"
{...props}>
{tabs.map((tab) => {
- let href: string;
- let isCurrent;
if ((tab.tabName && tab.href) || (!tab.tabName && !tab.href)) {
throw new Error("Use either tabName or href");
}
+ let href = "";
+ let isCurrent;
if (tab.href) {
href = tab.href;
isCurrent = router.asPath === tab.href;
@@ -40,6 +41,7 @@ const NavTabs: FC = ({ tabs, linkProps, ...props }) => {
href = "";
isCurrent = router.query.tabName === tab.tabName;
}
+
const onClick: MouseEventHandler = tab.tabName
? (e) => {
e.preventDefault();
@@ -50,12 +52,14 @@ const NavTabs: FC = ({ tabs, linkProps, ...props }) => {
},
});
}
- : () => {};
+ : noop;
const Component = tab.adminRequired ? AdminRequired : Fragment;
+
+ if (!href) return null;
return (
-
+
({
+const Slider = ({
title = "",
className = "",
items,
diff --git a/apps/web/components/availability/NewScheduleButton.tsx b/apps/web/components/availability/NewScheduleButton.tsx
index 8dc84a9e..6960d2eb 100644
--- a/apps/web/components/availability/NewScheduleButton.tsx
+++ b/apps/web/components/availability/NewScheduleButton.tsx
@@ -6,7 +6,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import showToast from "@calcom/lib/notification";
import { Button } from "@calcom/ui";
import { Dialog, DialogClose, DialogContent, DialogTrigger } from "@calcom/ui/Dialog";
-import { Form, TextField } from "@calcom/ui/form/fields";
+import { Form } from "@calcom/ui/form/fields";
import { HttpError } from "@lib/core/http/error";
import { trpc } from "@lib/trpc";
diff --git a/apps/web/components/availability/Schedule.tsx b/apps/web/components/availability/Schedule.tsx
index 76bc4b1c..1369f480 100644
--- a/apps/web/components/availability/Schedule.tsx
+++ b/apps/web/components/availability/Schedule.tsx
@@ -6,7 +6,7 @@ import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { Controller, useFieldArray, useFormContext } from "react-hook-form";
-import { GroupBase, Props, SingleValue } from "react-select";
+import { GroupBase, Props } from "react-select";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import Button from "@calcom/ui/Button";
diff --git a/apps/web/components/availability/ScheduleListItem.tsx b/apps/web/components/availability/ScheduleListItem.tsx
index f085c0de..74f75956 100644
--- a/apps/web/components/availability/ScheduleListItem.tsx
+++ b/apps/web/components/availability/ScheduleListItem.tsx
@@ -16,7 +16,7 @@ export function ScheduleListItem({
isDeleting = false,
}: {
schedule: inferQueryOutput<"viewer.availability.list">["schedules"][number];
- deleteFunction: Function;
+ deleteFunction: ({ scheduleId }: { scheduleId: number }) => void;
isDeleting: boolean;
}) {
const { t, i18n } = useLocale();
diff --git a/apps/web/components/booking/DatePicker.tsx b/apps/web/components/booking/DatePicker.tsx
index 6ff2334a..ff4848ff 100644
--- a/apps/web/components/booking/DatePicker.tsx
+++ b/apps/web/components/booking/DatePicker.tsx
@@ -51,12 +51,13 @@ function isOutOfBounds(
>
) {
const date = dayjs(time);
+ if (!periodDays) throw Error("periodDays is undefined");
switch (periodType) {
case PeriodType.ROLLING: {
const periodRollingEndDay = periodCountCalendarDays
- ? dayjs().utcOffset(date.utcOffset()).add(periodDays!, "days").endOf("day")
- : dayjs().utcOffset(date.utcOffset()).businessDaysAdd(periodDays!).endOf("day");
+ ? dayjs().utcOffset(date.utcOffset()).add(periodDays, "days").endOf("day")
+ : dayjs().utcOffset(date.utcOffset()).businessDaysAdd(periodDays).endOf("day");
return date.endOf("day").isAfter(periodRollingEndDay);
}
@@ -94,7 +95,7 @@ function DatePicker({
const [isFirstMonth, setIsFirstMonth] = useState(false);
const [daysFromState, setDays] = useState<
| {
- disabled: Boolean;
+ disabled: boolean;
date: number;
}[]
| null
@@ -191,7 +192,7 @@ function DatePicker({
name: "DatePicker",
length: daysInMonth,
callback: (i: number) => {
- let day = i + 1;
+ const day = i + 1;
days[daysInitialOffset + i] = {
disabled: isDisabledMemoized(day, {
browsingDate,
diff --git a/apps/web/components/booking/pages/AvailabilityPage.tsx b/apps/web/components/booking/pages/AvailabilityPage.tsx
index 604a9ace..ab1ecbe8 100644
--- a/apps/web/components/booking/pages/AvailabilityPage.tsx
+++ b/apps/web/components/booking/pages/AvailabilityPage.tsx
@@ -25,7 +25,6 @@ import {
useIsEmbed,
useIsBackgroundTransparent,
sdkActionManager,
- useEmbedType,
useEmbedNonStylesConfig,
} from "@calcom/embed-core";
import classNames from "@calcom/lib/classNames";
@@ -68,7 +67,7 @@ const AvailabilityPage = ({ profile, plan, eventType, workingHours, previousPage
const availabilityDatePickerEmbedStyles = useEmbedStyles("availabilityDatePicker");
const shouldAlignCentrallyInEmbed = useEmbedNonStylesConfig("align") !== "left";
const shouldAlignCentrally = !isEmbed || shouldAlignCentrallyInEmbed;
- let isBackgroundTransparent = useIsBackgroundTransparent();
+ const isBackgroundTransparent = useIsBackgroundTransparent();
useExposePlanGlobally(plan);
useEffect(() => {
if (eventType.metadata.smartContractAddress) {
diff --git a/apps/web/components/booking/pages/BookingPage.tsx b/apps/web/components/booking/pages/BookingPage.tsx
index f479d00e..0bff2931 100644
--- a/apps/web/components/booking/pages/BookingPage.tsx
+++ b/apps/web/components/booking/pages/BookingPage.tsx
@@ -52,6 +52,15 @@ import { BookPageProps } from "../../../pages/[user]/book";
import { HashLinkPageProps } from "../../../pages/d/[link]/book";
import { TeamBookingPageProps } from "../../../pages/team/[slug]/book";
+declare global {
+ // eslint-disable-next-line no-var
+ var web3: {
+ currentProvider: {
+ selectedAddress: string;
+ };
+ };
+}
+
/** These are like 40kb that not every user needs */
const PhoneInput = dynamic(
() => import("@components/ui/form/PhoneInput")
@@ -107,7 +116,6 @@ const BookingPage = ({
const eventOwner = eventType.users[0];
if (!contracts[(eventType.metadata.smartContractAddress || null) as number])
- /* @ts-ignore */
router.replace(`/${eventOwner.username}`);
}
}, [contracts, eventType.metadata.smartContractAddress, eventType.users, router]);
@@ -331,7 +339,6 @@ const BookingPage = ({
let web3Details: Record<"userWallet" | "userSignature", string> | undefined;
if (eventTypeDetail.metadata.smartContractAddress) {
web3Details = {
- // @ts-ignore
userWallet: window.web3.currentProvider.selectedAddress,
userSignature: contracts[(eventTypeDetail.metadata.smartContractAddress || null) as number],
};
@@ -359,8 +366,8 @@ const BookingPage = ({
),
metadata,
customInputs: Object.keys(booking.customInputs || {}).map((inputId) => ({
- label: eventType.customInputs.find((input) => input.id === parseInt(inputId))!.label,
- value: booking.customInputs![inputId],
+ label: eventType.customInputs.find((input) => input.id === parseInt(inputId))?.label || "",
+ value: booking.customInputs && inputId in booking.customInputs ? booking.customInputs[inputId] : "",
})),
hasHashedBookingLink,
hashedLink,
@@ -383,8 +390,8 @@ const BookingPage = ({
),
metadata,
customInputs: Object.keys(booking.customInputs || {}).map((inputId) => ({
- label: eventType.customInputs.find((input) => input.id === parseInt(inputId))!.label,
- value: booking.customInputs![inputId],
+ label: eventType.customInputs.find((input) => input.id === parseInt(inputId))?.label || "",
+ value: booking.customInputs && inputId in booking.customInputs ? booking.customInputs[inputId] : "",
})),
hasHashedBookingLink,
hashedLink,
diff --git a/apps/web/components/dialog/DeleteStripeDialogContent.tsx b/apps/web/components/dialog/DeleteStripeDialogContent.tsx
index 18ab4e49..02409bda 100644
--- a/apps/web/components/dialog/DeleteStripeDialogContent.tsx
+++ b/apps/web/components/dialog/DeleteStripeDialogContent.tsx
@@ -1,15 +1,13 @@
import { ExclamationIcon } from "@heroicons/react/outline";
import { CheckIcon } from "@heroicons/react/solid";
import * as DialogPrimitive from "@radix-ui/react-dialog";
-import React, { PropsWithChildren, ReactNode } from "react";
+import React, { PropsWithChildren } from "react";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button } from "@calcom/ui/Button";
import { DialogClose, DialogContent } from "@calcom/ui/Dialog";
-import { useLocale } from "@lib/hooks/useLocale";
-
export type DeleteStripeDialogContentProps = {
- confirmBtn?: ReactNode;
cancelAllBookingsBtnText?: string;
removeBtnText?: string;
cancelBtnText?: string;
@@ -24,7 +22,6 @@ export default function DeleteStripeDialogContent(props: PropsWithChildren;
+ formMethods: UseFormReturn;
paymentEnabled: boolean;
- onRecurringEventDefined: Function;
+ onRecurringEventDefined: (value: boolean) => void;
};
export default function RecurringEventController({
diff --git a/apps/web/components/ui/ImpersonatingBanner.tsx b/apps/web/components/ui/ImpersonatingBanner.tsx
index 41238970..72403498 100644
--- a/apps/web/components/ui/ImpersonatingBanner.tsx
+++ b/apps/web/components/ui/ImpersonatingBanner.tsx
@@ -4,9 +4,7 @@ import { Trans } from "next-i18next";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Alert } from "@calcom/ui/Alert";
-type Props = {};
-
-function ImpersonatingBanner({}: Props) {
+function ImpersonatingBanner() {
const { t } = useLocale();
const { data } = useSession();
diff --git a/apps/web/components/ui/ModalContainer.tsx b/apps/web/components/ui/ModalContainer.tsx
index 94f79dd4..63964207 100644
--- a/apps/web/components/ui/ModalContainer.tsx
+++ b/apps/web/components/ui/ModalContainer.tsx
@@ -1,7 +1,7 @@
import classNames from "classnames";
import React from "react";
-import { Dialog, DialogContent, DialogFooter } from "@calcom/ui/Dialog";
+import { Dialog, DialogContent } from "@calcom/ui/Dialog";
interface Props extends React.PropsWithChildren {
wide?: boolean;
diff --git a/apps/web/lib/auth/next-auth-custom-adapter.ts b/apps/web/lib/auth/next-auth-custom-adapter.ts
index 1fda3b95..64aded03 100644
--- a/apps/web/lib/auth/next-auth-custom-adapter.ts
+++ b/apps/web/lib/auth/next-auth-custom-adapter.ts
@@ -1,4 +1,5 @@
import { Account, IdentityProvider, Prisma, PrismaClient, User, VerificationToken } from "@prisma/client";
+import { PrismaClientKnownRequestError } from "@prisma/client/runtime";
import { identityProviderNameMap } from "@lib/auth";
@@ -45,6 +46,7 @@ export default function CalComAdapter(prismaClient: PrismaClient) {
prismaClient.user.update({ where: { id }, data }),
deleteUser: (id: User["id"]) => prismaClient.user.delete({ where: { id } }),
async createVerificationToken(data: VerificationToken) {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { id: _, ...verificationToken } = await prismaClient.verificationToken.create({
data,
});
@@ -52,6 +54,7 @@ export default function CalComAdapter(prismaClient: PrismaClient) {
},
async useVerificationToken(identifier_token: Prisma.VerificationTokenIdentifierTokenCompoundUniqueInput) {
try {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { id: _, ...verificationToken } = await prismaClient.verificationToken.delete({
where: { identifier_token },
});
@@ -59,8 +62,9 @@ export default function CalComAdapter(prismaClient: PrismaClient) {
} catch (error) {
// If token already used/deleted, just return null
// https://www.prisma.io/docs/reference/api-reference/error-reference#p2025
- // @ts-ignore
- if (error.code === "P2025") return null;
+ if (error instanceof PrismaClientKnownRequestError) {
+ if (error.code === "P2025") return null;
+ }
throw error;
}
},
diff --git a/apps/web/lib/doWorkAsync.ts b/apps/web/lib/doWorkAsync.ts
index 9033db4c..dc9ee623 100644
--- a/apps/web/lib/doWorkAsync.ts
+++ b/apps/web/lib/doWorkAsync.ts
@@ -1,3 +1,5 @@
+import noop from "lodash/noop";
+
const data: Record = {};
/**
* Starts an iteration from `0` to `length - 1` with batch size `batch`
@@ -20,9 +22,9 @@ export const doWorkAsync = ({
}: {
name: string;
length: number;
- callback: Function;
- done?: Function;
- batchDone?: Function;
+ callback: (i: number, b?: boolean) => void;
+ done?: () => void;
+ batchDone?: () => void;
batch: number;
offsetStart?: number;
__pending?: boolean;
@@ -32,8 +34,8 @@ export const doWorkAsync = ({
const lastIndex = length - 1;
const offsetEndExclusive = offsetStart + stepLength;
- batchDone = batchDone || (() => {});
- done = done || (() => {});
+ batchDone = batchDone || noop;
+ done = done || noop;
if (!__pending && data[name]) {
cancelAnimationFrame(data[name]);
diff --git a/apps/web/lib/emails/email-manager.ts b/apps/web/lib/emails/email-manager.ts
index 6cb35484..ae230c1e 100644
--- a/apps/web/lib/emails/email-manager.ts
+++ b/apps/web/lib/emails/email-manager.ts
@@ -1,4 +1,3 @@
-import { recurringEvent } from "@calcom/prisma/zod-utils";
import type { CalendarEvent, Person, RecurringEvent } from "@calcom/types/Calendar";
import AttendeeAwaitingPaymentEmail from "@lib/emails/templates/attendee-awaiting-payment-email";
diff --git a/apps/web/lib/emails/templates/_base-email.ts b/apps/web/lib/emails/templates/_base-email.ts
index 3cd5b44e..58808c45 100644
--- a/apps/web/lib/emails/templates/_base-email.ts
+++ b/apps/web/lib/emails/templates/_base-email.ts
@@ -4,7 +4,7 @@ import { getErrorFromUnknown } from "@calcom/lib/errors";
import { serverConfig } from "@calcom/lib/serverConfig";
export default class BaseEmail {
- name: string = "";
+ name = "";
protected getNodeMailerPayload(): Record {
return {};
diff --git a/apps/web/lib/hooks/useTheme.tsx b/apps/web/lib/hooks/useTheme.tsx
index b0afafe6..5c93b746 100644
--- a/apps/web/lib/hooks/useTheme.tsx
+++ b/apps/web/lib/hooks/useTheme.tsx
@@ -1,5 +1,4 @@
import Head from "next/head";
-import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import { useEmbedTheme } from "@calcom/embed-core";
diff --git a/apps/web/lib/parseDate.ts b/apps/web/lib/parseDate.ts
index c0a05057..19de2750 100644
--- a/apps/web/lib/parseDate.ts
+++ b/apps/web/lib/parseDate.ts
@@ -2,7 +2,6 @@ import dayjs, { Dayjs } from "dayjs";
import { I18n } from "next-i18next";
import { RRule } from "rrule";
-import { recurringEvent } from "@calcom/prisma/zod-utils";
import { RecurringEvent } from "@calcom/types/Calendar";
import { detectBrowserTimeFormat } from "@lib/timeFormat";
@@ -29,6 +28,7 @@ export const parseRecurringDates = (
}: { startDate: string | null | Dayjs; recurringEvent: RecurringEvent; recurringCount: number },
i18n: I18n
): [string[], Date[]] => {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { count, ...restRecurringEvent } = recurringEvent;
const rule = new RRule({
...restRecurringEvent,
diff --git a/apps/web/lib/slots.ts b/apps/web/lib/slots.ts
index 2fb9920b..f7011edf 100644
--- a/apps/web/lib/slots.ts
+++ b/apps/web/lib/slots.ts
@@ -89,7 +89,7 @@ const getSlots = ({ inviteeDate, frequency, minimumBookingNotice, workingHours,
computedLocalWorkingHours.push(tempComputeTimeFrame);
}
});
- computedLocalWorkingHours.forEach((item, index) => {
+ computedLocalWorkingHours.forEach((item) => {
slotsTimeFrameAvailable.push(...splitAvailableTime(item.startTime, item.endTime, frequency, eventLength));
});
diff --git a/apps/web/lib/telemetry.ts b/apps/web/lib/telemetry.ts
index a54fdbbe..b7d66d0f 100644
--- a/apps/web/lib/telemetry.ts
+++ b/apps/web/lib/telemetry.ts
@@ -1,6 +1,11 @@
import { jitsuClient, JitsuClient } from "@jitsu/sdk-js";
import React, { useContext } from "react";
+declare global {
+ // eslint-disable-next-line no-var
+ var jitsu: JitsuClient | undefined;
+}
+
/**
* Enumeration of all event types that are being sent
* to telemetry collection.
@@ -49,7 +54,10 @@ function isLocalhost(host: string) {
* Collects page parameters and makes sure no sensitive data made it to telemetry
* @param route current next.js route
*/
-export function collectPageParameters(route?: string, extraData: Record = {}): any {
+export function collectPageParameters(
+ route?: string,
+ extraData: Record = {}
+): Record {
const host = document.location.hostname;
const maskedHost = isLocalhost(host) ? "localhost" : "masked";
//starts with ''
@@ -78,13 +86,7 @@ function createTelemetryClient(): TelemetryClient {
if (!window) {
console.warn("Jitsu has been called during SSR, this scenario isn't supported yet");
return;
- } else if (
- // FIXME
- // @ts-ignore
- !window["jitsu"]
- ) {
- // FIXME
- // @ts-ignore
+ } else if (!window["jitsu"]) {
window["jitsu"] = jitsuClient({
log_level: "ERROR",
tracking_host: "https://t.calendso.com",
@@ -93,8 +95,6 @@ function createTelemetryClient(): TelemetryClient {
capture_3rd_party_cookies: false,
});
}
- // FIXME
- // @ts-ignore
const res = callback(window["jitsu"]);
if (res && typeof res["catch"] === "function") {
res.catch((e) => {
diff --git a/apps/web/pages/[user].tsx b/apps/web/pages/[user].tsx
index 58854b3c..5d92b486 100644
--- a/apps/web/pages/[user].tsx
+++ b/apps/web/pages/[user].tsx
@@ -6,7 +6,7 @@ import { GetServerSidePropsContext } from "next";
import dynamic from "next/dynamic";
import Link from "next/link";
import { useRouter } from "next/router";
-import React, { useEffect, useState } from "react";
+import { useEffect, useState } from "react";
import { Toaster } from "react-hot-toast";
import { JSONObject } from "superjson/dist/types";
@@ -18,7 +18,6 @@ import defaultEvents, {
getUsernameSlugLink,
} from "@calcom/lib/defaultEvents";
import { useLocale } from "@calcom/lib/hooks/useLocale";
-import { RecurringEvent } from "@calcom/types/Calendar";
import { useExposePlanGlobally } from "@lib/hooks/useExposePlanGlobally";
import useTheme from "@lib/hooks/useTheme";
@@ -287,7 +286,7 @@ const getEventTypesWithHiddenFromDB = async (userId: number, plan: UserPlan) =>
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const ssr = await ssrInit(context);
- const crypto = require("crypto");
+ const crypto = await import("crypto");
const usernameList = getUsernameList(context.query.user as string);
const dataFetchStart = Date.now();
diff --git a/apps/web/pages/_app.tsx b/apps/web/pages/_app.tsx
index 77b39982..794102f2 100644
--- a/apps/web/pages/_app.tsx
+++ b/apps/web/pages/_app.tsx
@@ -1,7 +1,5 @@
import { DefaultSeo } from "next-seo";
import Head from "next/head";
-import { useEffect } from "react";
-// import { ReactQueryDevtools } from "react-query/devtools";
import superjson from "superjson";
import "@calcom/embed-core/src/embed-iframe";
diff --git a/apps/web/pages/_error.tsx b/apps/web/pages/_error.tsx
index 9b52f31c..16b292c7 100644
--- a/apps/web/pages/_error.tsx
+++ b/apps/web/pages/_error.tsx
@@ -34,7 +34,7 @@ const CustomError: NextPage = (props) => {
// getInitialProps is not called in case of
// https://github.com/vercel/next.js/issues/8592. As a workaround, we pass
// err via _app.tsx so it can be captured
- // eslint-disable-next-line no-unused-vars
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
const e = getErrorFromUnknown(err);
// can be captured here
// e.g. Sentry.captureException(e);
diff --git a/apps/web/pages/api/auth/[...nextauth].tsx b/apps/web/pages/api/auth/[...nextauth].tsx
index b30a18a3..ccd947bc 100644
--- a/apps/web/pages/api/auth/[...nextauth].tsx
+++ b/apps/web/pages/api/auth/[...nextauth].tsx
@@ -1,4 +1,3 @@
-import { PrismaAdapter } from "@next-auth/prisma-adapter";
import { IdentityProvider, UserPermissionRole } from "@prisma/client";
import { readFileSync } from "fs";
import Handlebars from "handlebars";
@@ -185,6 +184,7 @@ if (true) {
}
const calcomAdapter = CalComAdapter(prisma);
export default NextAuth({
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
adapter: calcomAdapter,
session: {
@@ -203,6 +203,7 @@ export default NextAuth({
const autoMergeIdentities = async () => {
if (!hostedCal) {
const existingUser = await prisma.user.findFirst({
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
where: { email: token.email! },
});
diff --git a/apps/web/pages/api/auth/saml/authorize.ts b/apps/web/pages/api/auth/saml/authorize.ts
index 3ed076e9..5fd4ac93 100644
--- a/apps/web/pages/api/auth/saml/authorize.ts
+++ b/apps/web/pages/api/auth/saml/authorize.ts
@@ -1,6 +1,8 @@
import { OAuthReqBody } from "@boxyhq/saml-jackson";
import { NextApiRequest, NextApiResponse } from "next";
+import { HttpError } from "@calcom/lib/http-error";
+
import jackson from "@lib/jackson";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
@@ -12,10 +14,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const { oauthController } = await jackson();
const { redirect_url } = await oauthController.authorize(req.query as unknown as OAuthReqBody);
res.redirect(302, redirect_url);
- } catch (err: any) {
- console.error("authorize error:", err);
- const { message, statusCode = 500 } = err;
-
- res.status(statusCode).send(message);
+ } catch (err: unknown) {
+ if (err instanceof HttpError) {
+ console.error("authorize error:", err);
+ const { message, statusCode = 500 } = err;
+ return res.status(statusCode).send(message);
+ }
+ return res.status(500).send("Unknown error");
}
}
diff --git a/apps/web/pages/api/auth/saml/callback.ts b/apps/web/pages/api/auth/saml/callback.ts
index 2b74d1f2..5221198d 100644
--- a/apps/web/pages/api/auth/saml/callback.ts
+++ b/apps/web/pages/api/auth/saml/callback.ts
@@ -1,5 +1,7 @@
import { NextApiRequest, NextApiResponse } from "next";
+import { HttpError } from "@calcom/lib/http-error";
+
import jackson from "@lib/jackson";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
@@ -12,10 +14,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const { redirect_url } = await oauthController.samlResponse(req.body);
res.redirect(302, redirect_url);
- } catch (err: any) {
- console.error("callback error:", err);
- const { message, statusCode = 500 } = err;
-
- res.status(statusCode).send(message);
+ } catch (err: unknown) {
+ if (err instanceof HttpError) {
+ console.error("callback error:", err);
+ const { message, statusCode = 500 } = err;
+ return res.status(statusCode).send(message);
+ }
+ return res.status(500).send("Unknown error");
}
}
diff --git a/apps/web/pages/api/book/confirm.ts b/apps/web/pages/api/book/confirm.ts
index 4e06c67e..8b8261dd 100644
--- a/apps/web/pages/api/book/confirm.ts
+++ b/apps/web/pages/api/book/confirm.ts
@@ -1,6 +1,5 @@
import { Prisma, User, Booking, SchedulingType, BookingStatus } from "@prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
-import rrule from "rrule";
import EventManager from "@calcom/core/EventManager";
import logger from "@calcom/lib/logger";
diff --git a/apps/web/pages/api/integrations/[...args].ts b/apps/web/pages/api/integrations/[...args].ts
index 27ebf58b..a03b5a96 100644
--- a/apps/web/pages/api/integrations/[...args].ts
+++ b/apps/web/pages/api/integrations/[...args].ts
@@ -25,7 +25,7 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (typeof handler !== "function")
throw new HttpError({ statusCode: 404, message: `API handler not found` });
- const response = await handler(req, res);
+ await handler(req, res);
return res.status(200);
} catch (error) {
diff --git a/apps/web/pages/api/upgrade.ts b/apps/web/pages/api/upgrade.ts
index 9baddda3..6e79f197 100644
--- a/apps/web/pages/api/upgrade.ts
+++ b/apps/web/pages/api/upgrade.ts
@@ -1,4 +1,3 @@
-import { Prisma } from "@prisma/client";
import type { NextApiRequest, NextApiResponse } from "next";
import { getStripeCustomerId } from "@calcom/stripe/customer";
diff --git a/apps/web/pages/availability/troubleshoot.tsx b/apps/web/pages/availability/troubleshoot.tsx
index 9d6330cc..1ec71249 100644
--- a/apps/web/pages/availability/troubleshoot.tsx
+++ b/apps/web/pages/availability/troubleshoot.tsx
@@ -2,8 +2,9 @@ import dayjs, { Dayjs } from "dayjs";
import utc from "dayjs/plugin/utc";
import { useEffect, useState } from "react";
+import { useLocale } from "@calcom/lib/hooks/useLocale";
+
import { QueryCell } from "@lib/QueryCell";
-import { useLocale } from "@lib/hooks/useLocale";
import { inferQueryOutput, trpc } from "@lib/trpc";
import Loader from "@components/Loader";
@@ -20,10 +21,10 @@ const AvailabilityView = ({ user }: { user: User }) => {
const [selectedDate, setSelectedDate] = useState(dayjs());
function convertMinsToHrsMins(mins: number) {
- let h = Math.floor(mins / 60);
- let m = mins % 60;
- let hs = h < 10 ? "0" + h : h;
- let ms = m < 10 ? "0" + m : m;
+ const h = Math.floor(mins / 60);
+ const m = mins % 60;
+ const hs = h < 10 ? "0" + h : h;
+ const ms = m < 10 ? "0" + m : m;
return `${hs}:${ms}`;
}
diff --git a/apps/web/pages/d/[link]/[slug].tsx b/apps/web/pages/d/[link]/[slug].tsx
index 49aa8136..4e779996 100644
--- a/apps/web/pages/d/[link]/[slug].tsx
+++ b/apps/web/pages/d/[link]/[slug].tsx
@@ -157,7 +157,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
eventTypeObject.schedule = null;
eventTypeObject.availability = [];
- let booking: GetBookingType | null = null;
+ const booking: GetBookingType | null = null;
const profile = {
name: user.name || user.username,
diff --git a/apps/web/pages/d/[link]/book.tsx b/apps/web/pages/d/[link]/book.tsx
index 48b0eafc..ed99d6c2 100644
--- a/apps/web/pages/d/[link]/book.tsx
+++ b/apps/web/pages/d/[link]/book.tsx
@@ -30,7 +30,6 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
const ssr = await ssrInit(context);
const link = asStringOrThrow(context.query.link as string);
const recurringEventCountQuery = asStringOrNull(context.query.count);
- const slug = context.query.slug as string;
const eventTypeSelect = Prisma.validator()({
id: true,
diff --git a/apps/web/pages/event-types/[type].tsx b/apps/web/pages/event-types/[type].tsx
index dae70aa5..c08f27de 100644
--- a/apps/web/pages/event-types/[type].tsx
+++ b/apps/web/pages/event-types/[type].tsx
@@ -21,13 +21,13 @@ import classNames from "classnames";
import dayjs from "dayjs";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
-import { isValidPhoneNumber, parsePhoneNumber } from "libphonenumber-js";
+import { isValidPhoneNumber } from "libphonenumber-js";
import { GetServerSidePropsContext } from "next";
import { useRouter } from "next/router";
import React, { useEffect, useState } from "react";
import { Controller, Noop, useForm, UseFormReturn } from "react-hook-form";
import { FormattedNumber, IntlProvider } from "react-intl";
-import short, { generate } from "short-uuid";
+import short from "short-uuid";
import { JSONObject } from "superjson/dist/types";
import { v5 as uuidv5 } from "uuid";
import { z } from "zod";
@@ -101,7 +101,44 @@ type OptionTypeBase = {
disabled?: boolean;
};
-const SuccessRedirectEdit = >({
+export type FormValues = {
+ title: string;
+ eventTitle: string;
+ smartContractAddress: string;
+ eventName: string;
+ slug: string;
+ length: number;
+ description: string;
+ disableGuests: boolean;
+ requiresConfirmation: boolean;
+ recurringEvent: RecurringEvent;
+ schedulingType: SchedulingType | null;
+ price: number;
+ currency: string;
+ hidden: boolean;
+ hideCalendarNotes: boolean;
+ hashedLink: string | undefined;
+ locations: { type: LocationType; address?: string; link?: string; hostPhoneNumber?: string }[];
+ customInputs: EventTypeCustomInput[];
+ users: string[];
+ schedule: number;
+ periodType: PeriodType;
+ periodDays: number;
+ periodCountCalendarDays: "1" | "0";
+ periodDates: { startDate: Date; endDate: Date };
+ minimumBookingNotice: number;
+ beforeBufferTime: number;
+ afterBufferTime: number;
+ slotInterval: number | null;
+ destinationCalendar: {
+ integration: string;
+ externalId: string;
+ };
+ successRedirectUrl: string;
+ giphyThankYouPage: string;
+};
+
+const SuccessRedirectEdit = >({
eventType,
formMethods,
}: {
@@ -524,42 +561,7 @@ const EventTypePage = (props: inferSSRProps) => {
avatar: `${process.env.NEXT_PUBLIC_WEBSITE_URL}/${username}/avatar.png`,
});
- const formMethods = useForm<{
- title: string;
- eventTitle: string;
- smartContractAddress: string;
- eventName: string;
- slug: string;
- length: number;
- description: string;
- disableGuests: boolean;
- requiresConfirmation: boolean;
- recurringEvent: RecurringEvent;
- schedulingType: SchedulingType | null;
- price: number;
- currency: string;
- hidden: boolean;
- hideCalendarNotes: boolean;
- hashedLink: string | undefined;
- locations: { type: LocationType; address?: string; link?: string; hostPhoneNumber?: string }[];
- customInputs: EventTypeCustomInput[];
- users: string[];
- schedule: number;
- periodType: PeriodType;
- periodDays: number;
- periodCountCalendarDays: "1" | "0";
- periodDates: { startDate: Date; endDate: Date };
- minimumBookingNotice: number;
- beforeBufferTime: number;
- afterBufferTime: number;
- slotInterval: number | null;
- destinationCalendar: {
- integration: string;
- externalId: string;
- };
- successRedirectUrl: string;
- giphyThankYouPage: string;
- }>({
+ const formMethods = useForm({
defaultValues: {
locations: eventType.locations || [],
recurringEvent: eventType.recurringEvent || {},
diff --git a/apps/web/pages/event-types/index.tsx b/apps/web/pages/event-types/index.tsx
index 8b1b077a..6c3dd0bd 100644
--- a/apps/web/pages/event-types/index.tsx
+++ b/apps/web/pages/event-types/index.tsx
@@ -2,22 +2,22 @@ import { CalendarIcon } from "@heroicons/react/outline";
import {
ArrowDownIcon,
ArrowUpIcon,
- DotsHorizontalIcon,
- ExternalLinkIcon,
- DuplicateIcon,
- LinkIcon,
- UploadIcon,
ClipboardCopyIcon,
- TrashIcon,
+ DotsHorizontalIcon,
+ DuplicateIcon,
+ ExternalLinkIcon,
+ LinkIcon,
PencilIcon,
- CodeIcon,
+ TrashIcon,
+ UploadIcon,
+ UsersIcon,
} from "@heroicons/react/solid";
-import { UsersIcon } from "@heroicons/react/solid";
+import { UserPlan } from "@prisma/client";
import { Trans } from "next-i18next";
import Head from "next/head";
import Link from "next/link";
import { useRouter } from "next/router";
-import React, { Fragment, useEffect, useRef, useState } from "react";
+import React, { Fragment, useEffect, useState } from "react";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -26,10 +26,10 @@ import { Button } from "@calcom/ui";
import { Alert } from "@calcom/ui/Alert";
import { Dialog, DialogTrigger } from "@calcom/ui/Dialog";
import Dropdown, {
- DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
+ DropdownMenuTrigger,
} from "@calcom/ui/Dropdown";
import { Tooltip } from "@calcom/ui/Tooltip";
@@ -49,13 +49,6 @@ import Avatar from "@components/ui/Avatar";
import AvatarGroup from "@components/ui/AvatarGroup";
import Badge from "@components/ui/Badge";
-type Profiles = inferQueryOutput<"viewer.eventTypes">["profiles"];
-
-interface CreateEventTypeProps {
- canAddEvents: boolean;
- profiles: Profiles;
-}
-
type EventTypeGroups = inferQueryOutput<"viewer.eventTypes">["eventTypeGroups"];
type EventTypeGroupProfile = EventTypeGroups[number]["profile"];
interface EventTypeListHeadingProps {
@@ -72,7 +65,7 @@ interface EventTypeListProps {
types: EventType[];
}
-const Item = ({ type, group, readOnly }: any) => {
+const Item = ({ type, group, readOnly }: { type: EventType; group: EventTypeGroup; readOnly: boolean }) => {
const { t } = useLocale();
return (
@@ -135,17 +128,19 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
}
utils.cancelQuery(["viewer.eventTypes"]);
- utils.setQueryData(["viewer.eventTypes"], (data) =>
- Object.assign(data, {
+ utils.setQueryData(["viewer.eventTypes"], (data) => {
+ // tRPC is very strict with the return signature...
+ if (!data)
+ return { eventTypeGroups: [], profiles: [], viewer: { canAddEvents: false, plan: UserPlan.FREE } };
+ return {
+ ...data,
eventTypesGroups: [
- data?.eventTypeGroups.slice(0, groupIndex),
- Object.assign(group, {
- eventTypes: newList,
- }),
- data?.eventTypeGroups.slice(groupIndex + 1),
+ ...data.eventTypeGroups.slice(0, groupIndex),
+ { ...group, eventTypes: newList },
+ ...data.eventTypeGroups.slice(groupIndex + 1),
],
- })
- );
+ };
+ });
mutation.mutate({
ids: newList.map((type) => type.id),
@@ -528,7 +523,7 @@ const EventTypeListHeading = ({ profile, membershipCount }: EventTypeListHeading
);
};
-const CreateFirstEventTypeView = ({ canAddEvents, profiles }: CreateEventTypeProps) => {
+const CreateFirstEventTypeView = () => {
const { t } = useLocale();
return (
@@ -603,10 +598,8 @@ const EventTypesPage = () => {
))}
- {data.eventTypeGroups.length === 0 && (
-
- )}
-
+ {data.eventTypeGroups.length === 0 && }
+
>
)}
/>
diff --git a/apps/web/pages/getting-started.tsx b/apps/web/pages/getting-started.tsx
index b8313674..807432a8 100644
--- a/apps/web/pages/getting-started.tsx
+++ b/apps/web/pages/getting-started.tsx
@@ -145,7 +145,6 @@ export default function Onboarding(props: inferSSRProps(null);
- const usernameRef = useRef(null);
const bioRef = useRef(null);
/** End Name */
/** TimeZone */
diff --git a/apps/web/pages/success.tsx b/apps/web/pages/success.tsx
index 618806a1..d7e7426b 100644
--- a/apps/web/pages/success.tsx
+++ b/apps/web/pages/success.tsx
@@ -63,8 +63,9 @@ function RedirectionToast({ url }: { url: string }) {
const parsedSuccessUrl = new URL(document.URL);
const parsedExternalUrl = new URL(url);
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
/* @ts-ignore */ //https://stackoverflow.com/questions/49218765/typescript-and-iterator-type-iterableiteratort-is-not-an-array-type
- for (let [name, value] of parsedExternalUrl.searchParams.entries()) {
+ for (const [name, value] of parsedExternalUrl.searchParams.entries()) {
parsedSuccessUrl.searchParams.set(name, value);
}
@@ -185,8 +186,9 @@ export default function Success(props: SuccessProps) {
useEffect(() => {
const users = eventType.users;
+ if (!sdkActionManager) return;
// TODO: We should probably make it consistent with Webhook payload. Some data is not available here, as and when requirement comes we can add
- sdkActionManager!.fire("bookingSuccessful", {
+ sdkActionManager.fire("bookingSuccessful", {
eventType,
date: date.toString(),
duration: eventType.length,
@@ -476,7 +478,10 @@ export default function Success(props: SuccessProps) {