Merge branch 'main' into 10-26-chore_Adds_dayjs_as_fixture

This commit is contained in:
Omar López 2023-11-16 14:28:26 -07:00 committed by GitHub
commit 88125851dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 301 additions and 128 deletions

View File

@ -1,5 +1,5 @@
import type { NextApiRequest, NextApiResponse } from "next";
export default async function CalcomApi(_: NextApiRequest, res: NextApiResponse) {
res.status(201).json({ message: "Welcome to Cal.com API - docs are at https://developer.cal.com/api" });
res.status(200).json({ message: "Welcome to Cal.com API - docs are at https://developer.cal.com/api" });
}

View File

@ -1,4 +1,4 @@
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import type { ReactNode } from "react";
import { useEffect, useRef, useState } from "react";
import { z } from "zod";
@ -6,6 +6,7 @@ import { z } from "zod";
import type { CredentialOwner } from "@calcom/app-store/types";
import classNames from "@calcom/lib/classNames";
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
import { Badge, ListItemText, Avatar } from "@calcom/ui";
@ -56,7 +57,7 @@ export default function AppListCard(props: AppListCardProps) {
const router = useRouter();
const [highlight, setHighlight] = useState(shouldHighlight && hl === slug);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const pathname = usePathname();
useEffect(() => {

View File

@ -1,10 +1,12 @@
import { usePathname, useSearchParams } from "next/navigation";
import { usePathname } from "next/navigation";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
export default function useIsBookingPage(): boolean {
const pathname = usePathname();
const isBookingPage = ["/booking/", "/cancel", "/reschedule"].some((route) => pathname?.startsWith(route));
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const userParam = Boolean(searchParams?.get("user"));
const teamParam = Boolean(searchParams?.get("team"));

View File

@ -1,8 +1,10 @@
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import { useCallback } from "react";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
export default function useRouterQuery<T extends string>(name: T) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const pathname = usePathname();
const router = useRouter();

View File

@ -1,7 +1,7 @@
import { useSearchParams } from "next/navigation";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
export function useToggleQuery(name: string) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
return {
isOn: searchParams?.get(name) === "1",

View File

@ -1,7 +1,7 @@
import Head from "next/head";
import { useSearchParams } from "next/navigation";
import { APP_NAME } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, showToast } from "@calcom/ui";
import { Copy } from "@calcom/ui/components/icon";
@ -9,7 +9,7 @@ import { Copy } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
export default function Error500() {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t } = useLocale();
return (

View File

@ -1,15 +1,16 @@
import type { InferGetServerSidePropsType } from "next";
import { useSession } from "next-auth/react";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { AppSetupPage } from "@calcom/app-store/_pages/setup";
import { getServerSideProps } from "@calcom/app-store/_pages/setup/_getServerSideProps";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { HeadSeo } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
export default function SetupInformation(props: InferGetServerSidePropsType<typeof getServerSideProps>) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const router = useRouter();
const slug = searchParams?.get("slug") as string;
const { status } = useSession();

View File

@ -1,10 +1,10 @@
import { Prisma } from "@prisma/client";
import type { GetStaticPropsContext, InferGetStaticPropsType } from "next";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { getAppRegistry } from "@calcom/app-store/_appRegistry";
import Shell from "@calcom/features/shell/Shell";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import prisma from "@calcom/prisma";
import { AppCategories } from "@calcom/prisma/enums";
@ -13,7 +13,7 @@ import { AppCard, SkeletonText } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
export default function Apps({ apps }: InferGetStaticPropsType<typeof getStaticProps>) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t, isLocaleReady } = useLocale();
const category = searchParams?.get("category");

View File

@ -1,8 +1,8 @@
import { useSearchParams } from "next/navigation";
import { useReducer } from "react";
import { z } from "zod";
import DisconnectIntegrationModal from "@calcom/features/apps/components/DisconnectIntegrationModal";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { AppCategories } from "@calcom/prisma/enums";
import { trpc } from "@calcom/trpc/react";
@ -122,7 +122,7 @@ type ModalState = {
};
export default function InstalledApps() {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t } = useLocale();
const category = searchParams?.get("category") as querySchemaType["category"];
const categoryList: AppCategories[] = Object.values(AppCategories).filter((category) => {

View File

@ -1,8 +1,8 @@
import type { GetStaticPropsContext } from "next";
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import z from "zod";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button } from "@calcom/ui";
import { X } from "@calcom/ui/components/icon";
@ -18,7 +18,7 @@ const querySchema = z.object({
export default function Error() {
const { t } = useLocale();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { error } = querySchema.parse(searchParams);
const isTokenVerificationError = error?.toLowerCase() === "verification";
const errorMsg = isTokenVerificationError ? t("token_invalid_expired") : t("error_during_login");

View File

@ -4,7 +4,7 @@ import { jwtVerify } from "jose";
import type { GetServerSidePropsContext } from "next";
import { getCsrfToken, signIn } from "next-auth/react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import type { CSSProperties } from "react";
import { useState } from "react";
import { FormProvider, useForm } from "react-hook-form";
@ -17,6 +17,7 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { isSAMLLoginEnabled, samlProductID, samlTenantID } from "@calcom/features/ee/sso/lib/saml";
import { WEBAPP_URL, WEBSITE_URL, HOSTED_CAL_FEATURES } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import prisma from "@calcom/prisma";
@ -53,7 +54,7 @@ export default function Login({
totpEmail,
}: // eslint-disable-next-line @typescript-eslint/ban-types
inferSSRProps<typeof _getServerSideProps> & WithNonceProps<{}>) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t } = useLocale();
const router = useRouter();
const formSchema = z

View File

@ -1,9 +1,9 @@
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import { useSearchParams } from "next/navigation";
import { useState, useEffect } from "react";
import { APP_NAME } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Avatar, Button, Select } from "@calcom/ui";
@ -16,7 +16,7 @@ export default function Authorize() {
const { status } = useSession();
const router = useRouter();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const client_id = searchParams?.get("client_id") as string;
const state = searchParams?.get("state") as string;

View File

@ -1,12 +1,13 @@
import { signIn } from "next-auth/react";
import { useSearchParams } from "next/navigation";
import { useEffect } from "react";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import PageWrapper from "@components/PageWrapper";
// To handle the IdP initiated login flow callback
export default function Page() {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
useEffect(() => {
const code = searchParams?.get("code");

View File

@ -1,11 +1,12 @@
import type { GetServerSidePropsContext } from "next";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import { useState } from "react";
import AdminAppsList from "@calcom/features/apps/AdminAppsList";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { getDeploymentKey } from "@calcom/features/ee/deployment/lib/getDeploymentKey";
import { APP_NAME } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import prisma from "@calcom/prisma";
import { UserPermissionRole } from "@calcom/prisma/enums";
@ -21,7 +22,7 @@ import { ssrInit } from "@server/lib/ssr";
function useSetStep() {
const router = useRouter();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const pathname = usePathname();
const setStep = (newStep = 1) => {
const _searchParams = new URLSearchParams(searchParams ?? undefined);

View File

@ -1,6 +1,6 @@
import type { GetServerSidePropsContext } from "next";
import { signIn } from "next-auth/react";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { getPremiumMonthlyPlanPriceId } from "@calcom/app-store/stripepayment/lib/utils";
@ -9,6 +9,7 @@ import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomain
import stripe from "@calcom/features/ee/payments/server/stripe";
import { hostedCal, isSAMLLoginEnabled, samlProductID, samlTenantID } from "@calcom/features/ee/sso/lib/saml";
import { ssoTenantProduct } from "@calcom/features/ee/sso/lib/sso";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { checkUsername } from "@calcom/lib/server/checkUsername";
import prisma from "@calcom/prisma";
@ -22,7 +23,7 @@ import { ssrInit } from "@server/lib/ssr";
export type SSOProviderPageProps = inferSSRProps<typeof getServerSideProps>;
export default function Provider(props: SSOProviderPageProps) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const router = useRouter();
useEffect(() => {

View File

@ -1,10 +1,11 @@
import { signIn } from "next-auth/react";
import Head from "next/head";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import z from "zod";
import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
import { trpc } from "@calcom/trpc/react";
import { Button, showToast } from "@calcom/ui";
@ -54,7 +55,7 @@ const querySchema = z.object({
});
export default function Verify() {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const pathname = usePathname();
const router = useRouter();
const routerQuery = useRouterQuery();

View File

@ -1,4 +1,4 @@
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { Controller, useFieldArray, useForm } from "react-hook-form";
@ -8,6 +8,7 @@ import Schedule from "@calcom/features/schedules/components/Schedule";
import Shell from "@calcom/features/shell/Shell";
import { classNames } from "@calcom/lib";
import { availabilityAsString } from "@calcom/lib/availability";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HttpError } from "@calcom/lib/http-error";
import { trpc } from "@calcom/trpc/react";
@ -83,7 +84,7 @@ const DateOverride = ({ workingHours }: { workingHours: WorkingHours[] }) => {
};
export default function Availability() {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t, i18n } = useLocale();
const router = useRouter();
const utils = trpc.useContext();

View File

@ -1,11 +1,12 @@
import { useAutoAnimate } from "@formkit/auto-animate/react";
import { useRouter, useSearchParams, usePathname } from "next/navigation";
import { useRouter, usePathname } from "next/navigation";
import { useCallback } from "react";
import { getLayout } from "@calcom/features/MainLayout";
import { NewScheduleButton, ScheduleListItem } from "@calcom/features/schedules";
import { ShellMain } from "@calcom/features/shell/Shell";
import { AvailabilitySliderTable } from "@calcom/features/timezone-buddy/components/AvailabilitySliderTable";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HttpError } from "@calcom/lib/http-error";
import type { RouterOutputs } from "@calcom/trpc/react";
@ -131,7 +132,7 @@ const WithQuery = withQuery(trpc.viewer.availability.list as any);
export default function AvailabilityPage() {
const { t } = useLocale();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const router = useRouter();
const pathname = usePathname();

View File

@ -4,7 +4,7 @@ import { createEvent } from "ics";
import type { GetServerSidePropsContext } from "next";
import { useSession } from "next-auth/react";
import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { RRule } from "rrule";
import { z } from "zod";
@ -36,6 +36,7 @@ import {
} from "@calcom/lib/date-fns";
import { getDefaultEvent } from "@calcom/lib/defaultEvents";
import useGetBrandingColours from "@calcom/lib/getBrandColours";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
import useTheme from "@calcom/lib/hooks/useTheme";
@ -98,7 +99,7 @@ export default function Success(props: SuccessProps) {
const router = useRouter();
const routerQuery = useRouterQuery();
const pathname = usePathname();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const {
allRemainingBookings,
isSuccessBookingPage,

View File

@ -2,7 +2,7 @@ import { useAutoAnimate } from "@formkit/auto-animate/react";
import type { User } from "@prisma/client";
import { Trans } from "next-i18next";
import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import type { FC } from "react";
import { memo, useEffect, useState } from "react";
import { z } from "zod";
@ -19,6 +19,7 @@ import { getTeamsFiltersFromQuery } from "@calcom/features/filters/lib/getTeamsF
import { ShellMain } from "@calcom/features/shell/Shell";
import { APP_NAME, CAL_URL, WEBAPP_URL } from "@calcom/lib/constants";
import { useBookerUrl } from "@calcom/lib/hooks/useBookerUrl";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useMediaQuery from "@calcom/lib/hooks/useMediaQuery";
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
@ -208,7 +209,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
const { t } = useLocale();
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const orgBranding = useOrgBranding();
const [parent] = useAutoAnimate<HTMLUListElement>();
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
@ -840,7 +841,7 @@ const Main = ({
filters: ReturnType<typeof getTeamsFiltersFromQuery>;
}) => {
const isMobile = useMediaQuery("(max-width: 768px)");
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const orgBranding = useOrgBranding();
if (!data || status === "loading") {
@ -904,7 +905,7 @@ const Main = ({
const EventTypesPage = () => {
const { t } = useLocale();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { open } = useIntercom();
const { data: user } = useMeQuery();
const [showProfileBanner, setShowProfileBanner] = useState(false);

View File

@ -1,7 +1,6 @@
import { zodResolver } from "@hookform/resolvers/zod";
import type { GetServerSidePropsContext } from "next";
import { signIn } from "next-auth/react";
import { useSearchParams } from "next/navigation";
import type { CSSProperties } from "react";
import type { SubmitHandler } from "react-hook-form";
import { FormProvider, useForm } from "react-hook-form";
@ -13,6 +12,7 @@ import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
import { useFlagMap } from "@calcom/features/flags/context/provider";
import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
import { IS_SELF_HOSTED, WEBAPP_URL } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import slugify from "@calcom/lib/slugify";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
@ -53,7 +53,7 @@ function addOrUpdateQueryParam(url: string, key: string, value: string) {
}
export default function Signup({ prepopulateFormValues, token, orgSlug, orgAutoAcceptEmail }: SignupProps) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const telemetry = useTelemetry();
const { t, i18n } = useLocale();
const flags = useFlagMap();

View File

@ -7,10 +7,10 @@
],
"functions": {
"pages/api/trpc/public/[trpc].ts": {
"memory": 3008
"memory": 768
},
"pages/api/trpc/slots/[trpc].ts": {
"memory": 3008
"memory": 768
}
}
}

View File

@ -1,11 +1,11 @@
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
import QRCode from "react-qr-code";
import z from "zod";
import type { PaymentPageProps } from "@calcom/features/ee/payments/pages/payment";
import { useBookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useCopy } from "@calcom/lib/hooks/useCopy";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc";
@ -130,7 +130,7 @@ type PaymentCheckerProps = PaymentPageProps;
function PaymentChecker(props: PaymentCheckerProps) {
// TODO: move booking success code to a common lib function
// TODO: subscribe rather than polling
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const bookingSuccessRedirect = useBookingSuccessRedirect();
const utils = trpc.useContext();
const { t } = useLocale();

View File

@ -1,10 +1,10 @@
import { auth, Client, webln } from "@getalby/sdk";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useSearchParams } from "next/navigation";
import { useState, useCallback, useEffect } from "react";
import { Toaster } from "react-hot-toast";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc";
import { Badge, Button, showToast } from "@calcom/ui";
@ -20,7 +20,7 @@ export interface IAlbySetupProps {
}
export default function AlbySetup(props: IAlbySetupProps) {
const params = useSearchParams();
const params = useCompatSearchParams();
if (params?.get("callback") === "true") {
return <AlbySetupCallback />;
}
@ -30,7 +30,7 @@ export default function AlbySetup(props: IAlbySetupProps) {
function AlbySetupCallback() {
const [error, setError] = useState<string | null>(null);
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
useEffect(() => {
if (!searchParams) {

View File

@ -1,5 +1,5 @@
import type { App_RoutingForms_Form } from "@prisma/client";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import { createContext, forwardRef, useContext, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { v4 as uuidv4 } from "uuid";
@ -9,6 +9,7 @@ import { useOrgBranding } from "@calcom/features/ee/organizations/context/provid
import { RoutingFormEmbedButton, RoutingFormEmbedDialog } from "@calcom/features/embed/RoutingFormEmbed";
import { classNames } from "@calcom/lib";
import { CAL_URL } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
import { trpc } from "@calcom/trpc/react";
@ -46,7 +47,7 @@ const newFormModalQuerySchema = z.object({
export const useOpenModal = () => {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const openModal = (option: z.infer<typeof newFormModalQuerySchema>) => {
const newQuery = new URLSearchParams(searchParams ?? undefined);
newQuery.set("dialog", "new-form");

View File

@ -1,5 +1,5 @@
import Head from "next/head";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import type { FormEvent } from "react";
import { useEffect, useRef, useState } from "react";
import { Toaster } from "react-hot-toast";
@ -9,6 +9,7 @@ import { sdkActionManager, useIsEmbed } from "@calcom/embed-core/embed-iframe";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import classNames from "@calcom/lib/classNames";
import useGetBrandingColours from "@calcom/lib/getBrandColours";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import { trpc } from "@calcom/trpc/react";
@ -296,7 +297,7 @@ export const getServerSideProps = async function getServerSideProps(
};
const usePrefilledResponse = (form: Props["form"]) => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const prefillResponse: Response = {};
// Prefill the form from query params

View File

@ -48,17 +48,7 @@ export default class BaseEmail {
const payload = this.getNodeMailerPayload();
const parseSubject = z.string().safeParse(payload?.subject);
const payloadWithUnEscapedSubject = {
headers: {
"X-SMTPAPI": JSON.stringify({
filters: {
bypass_list_management: {
settings: {
enable: 1,
},
},
},
}),
},
headers: this.getMailerOptions().headers,
...payload,
...(parseSubject.success && { subject: decodeHTML(parseSubject.data) }),
};
@ -84,6 +74,7 @@ export default class BaseEmail {
return {
transport: serverConfig.transport,
from: serverConfig.from,
headers: serverConfig.headers,
};
}

View File

@ -1,10 +1,10 @@
import { useRouter } from "next/navigation";
import { useSearchParams } from "next/navigation";
import { useEffect, useRef, useState, useCallback } from "react";
import type { Message } from "./embed";
import { sdkActionManager } from "./sdk-event";
import type { EmbedThemeConfig, UiConfig, EmbedNonStylesConfig, BookerLayouts, EmbedStyles } from "./types";
import { useCompatSearchParams } from "./useCompatSearchParams";
type SetStyles = React.Dispatch<React.SetStateAction<EmbedStyles>>;
type setNonStylesConfig = React.Dispatch<React.SetStateAction<EmbedNonStylesConfig>>;
@ -208,7 +208,7 @@ const useUrlChange = (callback: (newUrl: string) => void) => {
};
export const useEmbedTheme = () => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const [theme, setTheme] = useState(
embedStore.theme || (searchParams?.get("theme") as typeof embedStore.theme)
);

View File

@ -0,0 +1,21 @@
// this file is copied from '@calcom/lib/hooks/useCompatSearchParams.tsx'
import { ReadonlyURLSearchParams, useParams, useSearchParams } from "next/navigation";
export const useCompatSearchParams = () => {
const _searchParams = useSearchParams() ?? new URLSearchParams();
const params = useParams() ?? {};
const searchParams = new URLSearchParams(_searchParams.toString());
Object.getOwnPropertyNames(params).forEach((key) => {
searchParams.delete(key);
const param = params[key];
const paramArr = typeof param === "string" ? param.split("/") : param;
paramArr.forEach((p) => {
searchParams.append(key, p);
});
});
return new ReadonlyURLSearchParams(searchParams);
};

View File

@ -1,6 +1,7 @@
{
"extends": "@calcom/tsconfig/base.json",
"compilerOptions": {
"jsx": "react",
"target": "ES2015",
"module": "esnext",
"moduleResolution": "Node",

View File

@ -1,6 +1,7 @@
{
"extends": "@calcom/tsconfig/base.json",
"compilerOptions": {
"jsx": "react",
"target": "ES2015",
"baseUrl": ".",
"module": "ESNext",

View File

@ -1,7 +1,6 @@
import { zodResolver } from "@hookform/resolvers/zod";
// eslint-disable-next-line no-restricted-imports
import { noop } from "lodash";
import { useSearchParams } from "next/navigation";
import type { FC } from "react";
import { useReducer, useState } from "react";
import { Controller, useForm } from "react-hook-form";
@ -10,6 +9,7 @@ import { z } from "zod";
import AppCategoryNavigation from "@calcom/app-store/_components/AppCategoryNavigation";
import { appKeysSchemas } from "@calcom/app-store/apps.keys-schemas.generated";
import { classNames as cs } from "@calcom/lib";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { AppCategories } from "@calcom/prisma/enums";
import type { RouterOutputs } from "@calcom/trpc/react";
@ -266,7 +266,7 @@ interface EditModalState extends Pick<App, "keys"> {
}
const AdminAppsListContainer = () => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t } = useLocale();
const category = searchParams?.get("category") || AppCategories.calendar;

View File

@ -1,7 +1,8 @@
import { useSearchParams, usePathname } from "next/navigation";
import { usePathname } from "next/navigation";
import { shallow } from "zustand/shallow";
import { useSchedule } from "@calcom/features/schedules";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { trpc } from "@calcom/trpc/react";
import { useTimePreferences } from "../../lib/timePreferences";
@ -61,7 +62,7 @@ export const useScheduleForEvent = ({
(state) => [state.username, state.eventSlug, state.month, state.selectedDuration],
shallow
);
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const rescheduleUid = searchParams?.get("rescheduleUid");
const pathname = usePathname();

View File

@ -2,13 +2,14 @@ import type { Payment } from "@prisma/client";
import type { EventType } from "@prisma/client";
import { Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
import type { StripeElementLocale } from "@stripe/stripe-js";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import type { SyntheticEvent } from "react";
import { useEffect, useState } from "react";
import getStripe from "@calcom/app-store/stripepayment/lib/client";
import { getBookingRedirectExtraParams, useBookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
import { CAL_URL } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, CheckboxField } from "@calcom/ui";
@ -69,7 +70,7 @@ const PaymentForm = (props: Props) => {
} = props;
const { t, i18n } = useLocale();
const router = useRouter();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const [state, setState] = useState<States>({ status: "idle" });
const [isCanceling, setIsCanceling] = useState<boolean>(false);
const stripe = useStripe();

View File

@ -1,5 +1,5 @@
import { useSession } from "next-auth/react";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { useOrgBranding } from "@calcom/features/ee/organizations/context/provider";
@ -8,6 +8,7 @@ import MemberInvitationModal from "@calcom/features/ee/teams/components/MemberIn
import { classNames } from "@calcom/lib";
import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants";
import { useBookerUrl } from "@calcom/lib/hooks/useBookerUrl";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { MembershipRole } from "@calcom/prisma/enums";
import type { RouterOutputs } from "@calcom/trpc/react";
@ -30,7 +31,7 @@ type FormValues = {
};
const AddNewTeamMembers = () => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const session = useSession();
const teamId = searchParams?.get("id") ? Number(searchParams.get("id")) : -1;
const teamQuery = trpc.viewer.teams.get.useQuery(
@ -49,7 +50,7 @@ export const AddNewTeamMembersForm = ({
defaultValues: FormValues;
teamId: number;
}) => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t, i18n } = useLocale();
const router = useRouter();

View File

@ -1,5 +1,4 @@
import Link from "next/link";
import { useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { useState } from "react";
@ -7,6 +6,7 @@ import InviteLinkSettingsModal from "@calcom/ee/teams/components/InviteLinkSetti
import MemberInvitationModal from "@calcom/ee/teams/components/MemberInvitationModal";
import classNames from "@calcom/lib/classNames";
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { MembershipRole } from "@calcom/prisma/enums";
import type { RouterOutputs } from "@calcom/trpc/react";
@ -53,7 +53,7 @@ interface Props {
}
export default function TeamListItem(props: Props) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t, i18n } = useLocale();
const utils = trpc.useContext();
const team = props.team;

View File

@ -1,7 +1,8 @@
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { useEffect, useMemo, useState } from "react";
import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Alert, Button, ButtonGroup, EmptyScreen, Label, showToast } from "@calcom/ui";
@ -12,7 +13,7 @@ import SkeletonLoaderTeamList from "./SkeletonloaderTeamList";
import TeamList from "./TeamList";
export function TeamsListing() {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const token = searchParams?.get("token");
const { t } = useLocale();
const trpcContext = trpc.useContext();

View File

@ -1,7 +1,8 @@
import { useSession } from "next-auth/react";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { useState } from "react";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useParamsWithFallback } from "@calcom/lib/hooks/useParamsWithFallback";
import { MembershipRole } from "@calcom/prisma/enums";
@ -73,7 +74,7 @@ function MembersList(props: MembersListProps) {
}
const MembersView = () => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t, i18n } = useLocale();
const router = useRouter();

View File

@ -1,7 +1,7 @@
import { Collapsible, CollapsibleContent } from "@radix-ui/react-collapsible";
import classNames from "classnames";
import { useSession } from "next-auth/react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import type { RefObject } from "react";
import { createRef, useRef, useState } from "react";
import type { ControlProps } from "react-select";
@ -21,6 +21,7 @@ import { useNonEmptyScheduleDays } from "@calcom/features/schedules";
import { useSlotsForDate } from "@calcom/features/schedules/lib/use-schedule/useSlotsForDate";
import { APP_NAME, CAL_URL } from "@calcom/lib/constants";
import { weekdayToWeekIndex } from "@calcom/lib/date-fns";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { BookerLayouts } from "@calcom/prisma/zod-utils";
import type { RouterOutputs } from "@calcom/trpc/react";
@ -57,7 +58,7 @@ const queryParamsForDialog = ["embedType", "embedTabName", "embedUrl", "eventId"
function useRouterHelpers() {
const router = useRouter();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const pathname = usePathname();
const goto = (newSearchParams: Record<string, string>) => {
@ -507,7 +508,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
types: EmbedTypes;
}) => {
const { t } = useLocale();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const pathname = usePathname();
const { goto, removeQueryParams } = useRouterHelpers();
const iframeRef = useRef<HTMLIFrameElement>(null);
@ -1095,7 +1096,7 @@ export const EmbedDialog = ({
tabs: EmbedTabs;
eventTypeHideOptionDisabled: boolean;
}) => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const embedUrl = searchParams?.get("embedUrl") as string;
return (
<Dialog name="embed" clearQueryParamsOnClose={queryParamsForDialog}>

View File

@ -1,9 +1,9 @@
import { useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
import { HttpError } from "@calcom/lib/http-error";
@ -33,7 +33,7 @@ const querySchema = z.object({
});
const DuplicateDialog = () => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t } = useLocale();
const router = useRouter();
const [firstRender, setFirstRender] = useState(true);

View File

@ -1,8 +1,9 @@
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import { useState } from "react";
import { z } from "zod";
import dayjs from "@calcom/dayjs";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { trpc } from "@calcom/trpc";
import type { FilterContextType } from "./provider";
@ -21,7 +22,7 @@ const querySchema = z.object({
export function FiltersProvider({ children }: { children: React.ReactNode }) {
// searchParams to get initial values from query params
const utils = trpc.useContext();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const router = useRouter();
const pathname = usePathname();

View File

@ -82,21 +82,22 @@ const DateOverrideForm = ({
const form = useForm({
values: {
range: value
? value.map((range) => ({
start: new Date(
dayjs
.utc()
.hour(range.start.getUTCHours())
.minute(range.start.getUTCMinutes())
.second(0)
.format()
),
end: new Date(
dayjs.utc().hour(range.end.getUTCHours()).minute(range.end.getUTCMinutes()).second(0).format()
),
}))
: defaultRanges,
range:
value && value[0].start.valueOf() !== value[0].end.valueOf()
? value.map((range) => ({
start: new Date(
dayjs
.utc()
.hour(range.start.getUTCHours())
.minute(range.start.getUTCMinutes())
.second(0)
.format()
),
end: new Date(
dayjs.utc().hour(range.end.getUTCHours()).minute(range.end.getUTCMinutes()).second(0).format()
),
}))
: defaultRanges,
},
});
@ -128,7 +129,7 @@ const DateOverrideForm = ({
? selectedDates.map((date) => {
return {
start: date.utc(true).startOf("day").toDate(),
end: date.utc(true).startOf("day").add(1, "day").toDate(),
end: date.utc(true).startOf("day").toDate(),
};
})
: datesInRanges

View File

@ -1,7 +1,7 @@
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@radix-ui/react-collapsible";
import { useSession } from "next-auth/react";
import Link from "next/link";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import type { ComponentProps } from "react";
import React, { Suspense, useEffect, useState } from "react";
@ -10,6 +10,7 @@ import Shell from "@calcom/features/shell/Shell";
import { classNames } from "@calcom/lib";
import { HOSTED_CAL_FEATURES, WEBAPP_URL } from "@calcom/lib/constants";
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { IdentityProvider, MembershipRole, UserPermissionRole } from "@calcom/prisma/enums";
import { trpc } from "@calcom/trpc/react";
@ -194,7 +195,7 @@ const SettingsSidebarContainer = ({
navigationIsOpenedOnMobile,
bannersHeight,
}: SettingsSidebarContainerProps) => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t } = useLocale();
const tabsWithPermissions = useTabs();
const [teamMenuState, setTeamMenuState] =

View File

@ -1,6 +1,7 @@
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { APP_NAME } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Meta, showToast, SkeletonContainer } from "@calcom/ui";
@ -11,7 +12,7 @@ import WebhookForm from "../components/WebhookForm";
import { subscriberUrlReserved } from "../lib/subscriberUrlReserved";
const EditWebhook = () => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const id = searchParams?.get("id");
if (!id) return <SkeletonContainer />;

View File

@ -1,7 +1,8 @@
import { useSession } from "next-auth/react";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { APP_NAME } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Meta, showToast, SkeletonContainer, SkeletonText } from "@calcom/ui";
@ -23,7 +24,7 @@ const SkeletonLoader = ({ title, description }: { title: string; description: st
);
};
const NewWebhookView = () => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t } = useLocale();
const utils = trpc.useContext();
const router = useRouter();

View File

@ -1,8 +1,9 @@
import type { EventType } from "@prisma/client";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import type { PaymentPageProps } from "@calcom/ee/payments/pages/payment";
import type { BookingResponse } from "@calcom/features/bookings/types";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
function getNewSeachParams(args: {
query: Record<string, string | null | undefined | boolean>;
@ -41,7 +42,7 @@ export const getBookingRedirectExtraParams = (booking: SuccessRedirectBookingTyp
export const useBookingSuccessRedirect = () => {
const router = useRouter();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const bookingSuccessRedirect = ({
successRedirectUrl,
query,

View File

@ -0,0 +1,21 @@
type EmailHostHeaders = {
[key: string]: {
[subKey: string]: string;
};
};
export function getAdditionalEmailHeaders(): EmailHostHeaders {
return {
"smtp.sendgrid.net": {
"X-SMTPAPI": JSON.stringify({
filters: {
bypass_list_management: {
settings: {
enable: 1,
},
},
},
}),
},
};
}

View File

@ -0,0 +1,67 @@
import { renderHook } from "@testing-library/react-hooks";
import { vi } from "vitest";
import { describe, expect, it } from "vitest";
import { useCompatSearchParams } from "./useCompatSearchParams";
vi.mock("next/navigation", () => ({
ReadonlyURLSearchParams: vi.fn((a) => a),
}));
describe("useCompatSearchParams hook", () => {
it("should return the searchParams in next@13.4.6 Pages Router, SSR", async () => {
const navigation = await import("next/navigation");
navigation.useSearchParams = vi.fn().mockReturnValue(new URLSearchParams("a=a&b=b"));
navigation.useParams = vi.fn().mockReturnValue(null);
const { result } = renderHook(() => useCompatSearchParams());
expect(result.current.toString()).toEqual("a=a&b=b");
});
it("should return both searchParams and params in next@13.4.6 App Router, SSR", async () => {
const navigation = await import("next/navigation");
navigation.useSearchParams = vi.fn().mockReturnValue(new URLSearchParams("a=a"));
navigation.useParams = vi.fn().mockReturnValue({ b: "b" });
const { result } = renderHook(() => useCompatSearchParams());
expect(result.current.toString()).toEqual("a=a&b=b");
});
it("params should always override searchParams in case of conflicting keys", async () => {
const navigation = await import("next/navigation");
navigation.useSearchParams = vi.fn().mockReturnValue(new URLSearchParams("a=a"));
navigation.useParams = vi.fn().mockReturnValue({ a: "b" });
const { result } = renderHook(() => useCompatSearchParams());
expect(result.current.toString()).toEqual("a=b");
});
it("should split paramsseparated with '/' (catch-all segments) in next@13.4.6 App Router, SSR", async () => {
const navigation = await import("next/navigation");
navigation.useSearchParams = vi.fn().mockReturnValue(new URLSearchParams());
// in next@13.4.6 useParams will return params separated by `/`
navigation.useParams = vi.fn().mockReturnValue({ a: "a/b/c" });
const { result } = renderHook(() => useCompatSearchParams());
expect(result.current.getAll("a")).toEqual(["a", "b", "c"]);
});
it("should include params and searchParams in next@13.5.4, Pages/App Router, SSR", async () => {
const navigation = await import("next/navigation");
navigation.useSearchParams = vi.fn().mockReturnValue(new URLSearchParams("a=a"));
navigation.useParams = vi.fn().mockReturnValue({ b: "b" });
const { result } = renderHook(() => useCompatSearchParams());
expect(result.current.toString()).toEqual("a=a&b=b");
});
});

View File

@ -0,0 +1,20 @@
import { ReadonlyURLSearchParams, useParams, useSearchParams } from "next/navigation";
export const useCompatSearchParams = () => {
const _searchParams = useSearchParams() ?? new URLSearchParams();
const params = useParams() ?? {};
const searchParams = new URLSearchParams(_searchParams.toString());
Object.getOwnPropertyNames(params).forEach((key) => {
searchParams.delete(key);
const param = params[key];
const paramArr = typeof param === "string" ? param.split("/") : param;
paramArr.forEach((p) => {
searchParams.append(key, p);
});
});
return new ReadonlyURLSearchParams(searchParams);
};

View File

@ -1,4 +1,4 @@
import { useSearchParams } from "next/navigation";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
/**
* An alternative to Object.fromEntries that allows duplicate keys.
@ -35,7 +35,7 @@ function fromEntriesWithDuplicateKeys(entries: IterableIterator<[string, string]
* @returns {Object} routerQuery
*/
export const useRouterQuery = () => {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const routerQuery = fromEntriesWithDuplicateKeys(searchParams?.entries() ?? null);
return routerQuery;
};

View File

@ -1,12 +1,14 @@
"use client";
import { usePathname, useSearchParams } from "next/navigation";
import { usePathname } from "next/navigation";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
export const useUrlMatchesCurrentUrl = (url: string) => {
// I don't know why usePathname ReturnType doesn't include null.
// It can certainly have null value https://nextjs.org/docs/app/api-reference/functions/use-pathname#:~:text=usePathname%20can%20return%20null%20when%20a%20fallback%20route%20is%20being%20rendered%20or%20when%20a%20pages%20directory%20page%20has%20been%20automatically%20statically%20optimized%20by%20Next.js%20and%20the%20router%20is%20not%20ready.
const pathname = usePathname() as null | string;
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const query = searchParams?.toString();
let pathnameWithQuery;
if (query) {

View File

@ -3,6 +3,8 @@ import type SMTPConnection from "nodemailer/lib/smtp-connection";
import { isENVDev } from "@calcom/lib/env";
import { getAdditionalEmailHeaders } from "./getAdditionalEmailHeaders";
function detectTransport(): SendmailTransport.Options | SMTPConnection.Options | string {
if (process.env.EMAIL_SERVER) {
return process.env.EMAIL_SERVER;
@ -41,4 +43,5 @@ function detectTransport(): SendmailTransport.Options | SMTPConnection.Options |
export const serverConfig = {
transport: detectTransport(),
from: process.env.EMAIL_FROM,
headers: getAdditionalEmailHeaders()[process.env.EMAIL_SERVER_HOST || ""] || undefined,
};

View File

@ -64,7 +64,7 @@ export function createNextApiHandler(router: AnyRouter, isPublic = false, namesp
const cacheRules = {
session: "no-cache",
i18n: `max-age=${ONE_YEAR_IN_SECONDS}`,
i18n: process.env.NODE_ENV === "development" ? "no-cache" : `max-age=${ONE_YEAR_IN_SECONDS}`,
// FIXME: Using `max-age=1, stale-while-revalidate=60` fails some booking tests.
"slots.getSchedule": `no-cache`,

View File

@ -1,11 +1,12 @@
import { useAutoAnimate } from "@formkit/auto-animate/react";
import type { AppCategories } from "@prisma/client";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import type { UIEvent } from "react";
import { useEffect, useRef, useState } from "react";
import type { UserAdminTeams } from "@calcom/features/ee/teams/lib/getUserAdminTeams";
import { classNames } from "@calcom/lib";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { AppFrontendPayload as App } from "@calcom/types/App";
import type { CredentialFrontendPayload as Credential } from "@calcom/types/Credential";
@ -55,7 +56,7 @@ interface CategoryTabProps {
function CategoryTab({ selectedCategory, categories, searchText }: CategoryTabProps) {
const pathname = usePathname();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t } = useLocale();
const router = useRouter();
const { ref, calculateScroll, leftVisible, rightVisible } = useShouldShowArrows();
@ -140,7 +141,7 @@ function CategoryTab({ selectedCategory, categories, searchText }: CategoryTabPr
}
export function AllApps({ apps, searchText, categories, userAdminTeams }: AllAppsPropsType) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { t } = useLocale();
const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [appsContainerRef, enableAnimation] = useAutoAnimate<HTMLDivElement>();

View File

@ -1,6 +1,7 @@
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import { useBookerUrl } from "@calcom/lib/hooks/useBookerUrl";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { ButtonColor } from "@calcom/ui";
import {
@ -40,7 +41,7 @@ export type CreateBtnProps = {
export function CreateButton(props: CreateBtnProps) {
const { t } = useLocale();
const router = useRouter();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const pathname = usePathname();
const bookerUrl = useBookerUrl();

View File

@ -1,9 +1,10 @@
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import type { ReactNode } from "react";
import React, { useState } from "react";
import classNames from "@calcom/lib/classNames";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { SVGComponent } from "@calcom/types/SVGComponent";
@ -27,7 +28,7 @@ const enum DIALOG_STATE {
export function Dialog(props: DialogProps) {
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const newSearchParams = new URLSearchParams(searchParams ?? undefined);
const { children, name, ...dialogProps } = props;

View File

@ -3,6 +3,12 @@ import { vi } from "vitest";
import { Dialog, DialogClose, DialogContent, DialogFooter, DialogHeader } from "./Dialog";
vi.mock("@calcom/lib/hooks/useCompatSearchParams", () => ({
useCompatSearchParams() {
return new URLSearchParams();
},
}));
vi.mock("next/navigation", () => ({
usePathname() {
return "";

View File

@ -1,10 +1,11 @@
// eslint-disable-next-line no-restricted-imports
import { noop } from "lodash";
import { useRouter, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import type { Dispatch, SetStateAction } from "react";
import { useEffect, useState } from "react";
import classNames from "@calcom/lib/classNames";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { Button, Steps } from "../../..";
@ -28,7 +29,7 @@ function WizardForm<T extends DefaultStep>(props: {
finishLabel?: string;
stepLabel?: React.ComponentProps<typeof Steps>["stepLabel"];
}) {
const searchParams = useSearchParams();
const searchParams = useCompatSearchParams();
const { href, steps, nextLabel = "Next", finishLabel = "Finish", prevLabel = "Back", stepLabel } = props;
const router = useRouter();
const step = parseInt((searchParams?.get("step") as string) || "1");

View File

@ -4,6 +4,12 @@ import { vi } from "vitest";
import WizardForm from "./WizardForm";
vi.mock("@calcom/lib/hooks/useCompatSearchParams", () => ({
useCompatSearchParams() {
return { get: vi.fn().mockReturnValue(currentStepNavigation) };
},
}));
vi.mock("next/navigation", () => ({
useRouter() {
return { replace: vi.fn() };

View File

@ -72,6 +72,7 @@ const workspaces = packagedEmbedTestsOnly
name: "@calcom/packages/lib/hooks",
include: ["packages/lib/hooks/**/*.{test,spec}.{ts,js}"],
environment: "jsdom",
setupFiles: [],
},
},
];