From 8ad442f2bedba9d3beca24e98079083f447b525b Mon Sep 17 00:00:00 2001
From: Benny Joo
Date: Thu, 20 Mar 2025 20:30:51 -0400
Subject: [PATCH] feat: Upgrade to Next 15 (#18834)
* wip
* update layoutHOC
* wip
* remove app router related code no longer used
* remove more
* await cookies, headers, params, serachparams
* update yarn.lock
* await cookies, headers, params, serachparams more
* update yarn lock again
* downgrade next-auth to 4.22.1
* update yarn lock
* fix
* update yarn lock
* fix type checks
* update yarn lock
* await headers and cookies
* restore pages folder
* restore yarn.lock
* update yarn.lock
* await headers and cookies
* remove
* await params in API routes
* updates
* restore next.config.js
* remove i18n from next.config.js
* Fixed tests
* Fixed types
* Removed duplicate favicon.ico
* Fixing more types
* ImageResponse moved to next/og
* Fixed prisma import issues
* dynamic import for @ewsjs/xhr
* remove deasync dep
* dynamic import for @tryvital/vital-node
* fix type checks
* add back turbopack command
* Type fix
* Removed unneeded file
* fix turbopack relative path errors
* add comments
* remove unneeded code
* Fixed build errors
* await apis
* use Promise type in defaultResponderForAppDir util
* refactor scim api route
* fix type checks
* separate app-routing.config into client-config and server-config
* wip
* refactor routing forms components
* revert unneeded changes for easier review
* fix
* fix
* use CustomTrans
* fix type
* fix unit tests
* fix type error
* fix build error
* fix build error
* fix build error
* fix warnings
* fix warnings
* upgrade @tremor/react and tailwindcss
* numCols -> numItems
* fix forgot-password e2e test
* fix 1 more e2e test
* fix login e2e test
* fix e2e tests
* fix e2e tests
* clean up
* remove error
* use tremor/react 2.11.0
* fix
* rename CustomTrans to ServerTrans
* address comment
* fix test
* fix ServerTrans
* fix
* fix type
* fix ServerTrans usages 1
* fix translations
* fix type checks
* fix type checks
* link styling
* fix
---------
Co-authored-by: Keith Williams
Co-authored-by: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com>
---
.env.example | 7 -
.../[user]/[type]/embed/page.tsx | 2 +-
.../[user]/[type]/page.tsx | 6 +-
.../[user]/embed/page.tsx | 2 +-
.../(booking-page-wrapper)/[user]/page.tsx | 10 +-
.../web/app/(booking-page-wrapper)/layout.tsx | 2 +-
.../[orgSlug]/[user]/[type]/embed/page.tsx | 2 +-
.../org/[orgSlug]/[user]/[type]/page.tsx | 8 +-
.../org/[orgSlug]/[user]/embed/page.tsx | 2 +-
.../org/[orgSlug]/[user]/page.tsx | 8 +-
.../team/[slug]/[type]/page.tsx | 8 +-
.../team/[slug]/[type]/embed/page.tsx | 2 +-
.../team/[slug]/[type]/page.tsx | 8 +-
.../team/[slug]/embed/page.tsx | 2 +-
.../team/[slug]/page.tsx | 8 +-
.../(main-nav)/availability/page.tsx | 2 +-
.../(main-nav)/bookings/[status]/page.tsx | 2 +-
.../(main-nav)/event-types/page.tsx | 2 +-
.../(main-nav)/teams/page.tsx | 5 +-
.../(use-page-wrapper)/apps/[slug]/page.tsx | 4 +-
.../apps/[slug]/setup/page.tsx | 5 +-
.../apps/categories/page.tsx | 4 +-
.../apps/installation/[[...step]]/page.tsx | 6 +-
.../apps/installed/[category]/page.tsx | 2 +-
apps/web/app/(use-page-wrapper)/apps/page.tsx | 2 +-
.../routing-forms/[...pages]/FormProvider.tsx | 9 +
.../apps/routing-forms/[...pages]/page.tsx | 30 +-
.../(use-page-wrapper)/auth/error/page.tsx | 2 +-
.../auth/forgot-password/[id]/page.tsx | 2 +-
.../auth/forgot-password/page.tsx | 2 +-
.../(use-page-wrapper)/auth/login/page.tsx | 4 +-
.../(use-page-wrapper)/auth/logout/page.tsx | 4 +-
.../(use-page-wrapper)/auth/setup/page.tsx | 4 +-
.../(use-page-wrapper)/auth/signin/page.tsx | 2 +-
.../auth/sso/[provider]/page.tsx | 2 +-
.../auth/sso/direct/page.tsx | 2 +-
.../auth/verify-email-change/page.tsx | 4 +-
.../availability/[schedule]/page.tsx | 8 +-
.../booking/[uid]/embed/page.tsx | 2 +-
.../(use-page-wrapper)/booking/[uid]/page.tsx | 4 +-
.../d/[link]/[slug]/page.tsx | 4 +-
.../event-types/[type]/page.tsx | 4 +-
.../getting-started/[[...step]]/page.tsx | 2 +-
apps/web/app/(use-page-wrapper)/layout.tsx | 2 +-
.../(use-page-wrapper)/payment/[uid]/page.tsx | 8 +-
.../admin/organizations/[id]/edit/page.tsx | 4 +-
.../admin/users/[id]/edit/page.tsx | 4 +-
.../settings/(admin-layout)/layout.tsx | 2 +-
.../developer/webhooks/[id]/page.tsx | 3 +-
.../settings/(settings-layout)/layout.tsx | 2 +-
.../settings/license-key/new/page.tsx | 2 +-
.../settings/organizations/new/about/page.tsx | 2 +-
.../organizations/new/add-teams/page.tsx | 2 +-
.../organizations/new/handover/page.tsx | 2 +-
.../new/onboard-members/page.tsx | 2 +-
.../settings/organizations/new/page.tsx | 2 +-
.../organizations/new/status/page.tsx | 2 +-
.../settings/platform/new/page.tsx | 2 +-
.../app/(use-page-wrapper)/signup/page.tsx | 2 +-
.../(use-page-wrapper)/video/[uid]/page.tsx | 2 +-
.../video/meeting-ended/[uid]/page.tsx | 2 +-
.../video/meeting-not-started/[uid]/page.tsx | 4 +-
.../workflows/[workflow]/page.tsx | 6 +-
.../app/(use-page-wrapper)/workflows/page.tsx | 2 +-
apps/web/app/_types.ts | 6 +-
apps/web/app/_utils.tsx | 46 +-
.../api/auth/two-factor/totp/disable/route.ts | 2 +-
.../api/auth/two-factor/totp/enable/route.ts | 2 +-
.../api/auth/two-factor/totp/setup/route.ts | 2 +-
.../app/api/availability/calendar/route.ts | 2 +-
apps/web/app/api/avatar/[uuid]/route.ts | 4 +-
apps/web/app/api/cancel/route.ts | 2 +-
apps/web/app/api/customer-card/route.ts | 2 +-
.../app/api/defaultResponderForAppDir.test.ts | 9 +-
apps/web/app/api/defaultResponderForAppDir.ts | 4 +-
apps/web/app/api/future-opt-in/route.ts | 40 -
.../app/api/generate-referral-link/route.ts | 4 +-
apps/web/app/api/geolocation/route.ts | 2 +-
apps/web/app/api/intercom-hash/route.ts | 4 +-
apps/web/app/api/link/route.ts | 2 +-
apps/web/app/api/logo/route.ts | 2 +-
apps/web/app/api/me/route.ts | 2 +-
apps/web/app/api/plain-hash/route.ts | 2 +-
.../web/app/api/recorded-daily-video/route.ts | 2 +-
.../app/api/scim/v2.0/[...directory]/route.ts | 39 +-
apps/web/app/api/social/og/image/route.tsx | 16 +-
apps/web/app/api/sync/helpscout/route.ts | 2 +-
.../web/app/api/teams/[team]/upgrade/route.ts | 6 +-
.../teams/googleworkspace/callback/route.ts | 4 +-
apps/web/app/api/username/route.ts | 2 +-
.../web/app/api/verify-booking-token/route.ts | 2 +-
apps/web/app/icons/page.tsx | 1 -
apps/web/app/layout.tsx | 62 +-
apps/web/app/not-found.tsx | 4 +-
apps/web/app/page.tsx | 2 +-
apps/web/app/reschedule/[uid]/embed/page.tsx | 2 +-
apps/web/app/reschedule/[uid]/page.tsx | 2 +-
.../web/app/routing-forms/[...pages]/page.tsx | 4 +-
apps/web/components/PageWrapperAppDir.tsx | 2 +-
apps/web/components/ServerTrans.tsx | 376 ++++++++++
apps/web/components/booking/CancelBooking.tsx | 5 +-
.../steps-views/UserProfile.tsx | 5 +-
.../steps-views/UserSettings.tsx | 5 +-
.../settings/SecondaryEmailConfirmModal.tsx | 5 +-
apps/web/lib/app-providers-app-dir.tsx | 2 +-
apps/web/lib/app-providers.tsx | 2 +-
.../[[...step]]/getServerSideProps.ts | 4 +-
.../[...pages]/getServerSideProps.ts | 2 +-
.../tests/recorded-daily-video.test.ts | 5 +-
.../[[...step]]/getServerSideProps.tsx | 2 -
apps/web/lib/metadata.ts | 64 --
.../reschedule/[uid]/getServerSideProps.ts | 2 +-
.../moveTeamToOrg/getServerSideProps.tsx | 2 -
.../moveUserToOrg/getServerSideProps.tsx | 5 +-
.../removeTeamFromOrg/getServerSideProps.tsx | 5 +-
.../removeUserFromOrg/getServerSideProps.tsx | 5 +-
apps/web/modules/auth/login-view.tsx | 3 +-
.../connect-and-join-view.tsx | 20 +-
.../views/event-types-listing-view.tsx | 18 +-
.../[[...step]]/onboarding-view.tsx | 2 +-
.../teams/new/create-new-team-view.tsx | 3 +-
apps/web/modules/signup-view.tsx | 8 +-
apps/web/modules/team/team-view.tsx | 3 +-
apps/web/next.config.js | 18 +-
apps/web/package.json | 9 +-
apps/web/pages/404.tsx | 259 -------
apps/web/playwright/booking-seats.e2e.ts | 1 +
.../web/playwright/managed-event-types.e2e.ts | 5 +-
.../organization/team-management.e2e.ts | 5 +-
apps/web/public/favicon.ico | Bin 15086 -> 0 bytes
apps/web/public/static/locales/en/common.json | 51 +-
apps/web/scripts/vercel-app-router-deploy.sh | 23 -
.../[id]/getServerSideProps.tsx | 5 +-
apps/web/server/lib/getTranslations.ts | 22 -
apps/web/server/lib/ssr.ts | 15 +-
apps/web/styles/globals.css | 98 +--
apps/web/test/lib/plainTiers.test.ts | 8 +-
.../utils/bookingScenario/bookingScenario.ts | 1 -
.../alby/components/AlbyPaymentComponent.tsx | 2 +
.../exchangecalendar/lib/CalendarService.ts | 16 +-
packages/app-store/locations.ts | 2 +-
packages/app-store/make/pages/setup/index.tsx | 35 +-
.../getServerSidePropsSingleForm.ts | 1 -
.../pages/app-routing.client-config.tsx | 8 +
...nfig.tsx => app-routing.server-config.tsx} | 21 +-
.../pages/forms/getServerSideProps.ts | 4 +-
.../pages/layout-handler/[...appPages].tsx | 41 --
packages/app-store/server.ts | 2 +-
packages/app-store/vital/lib/client.ts | 6 +-
packages/app-store/vital/lib/reschedule.ts | 2 +-
.../wipemycalother/lib/reschedule.ts | 2 +-
.../app-store/zapier/pages/setup/index.tsx | 26 +-
packages/emails/email-manager.ts | 2 +-
packages/emails/lib/generateIcsFile.ts | 2 +-
packages/emails/lib/generateIcsString.ts | 2 +-
packages/emails/package.json | 2 +-
packages/emails/src/components/AppsStatus.tsx | 2 +-
.../emails/src/components/LocationInfo.tsx | 2 +-
.../src/components/UserFieldsResponses.tsx | 2 +-
packages/emails/src/components/WhenInfo.tsx | 2 +-
packages/emails/src/components/WhoInfo.tsx | 2 +-
.../AdminOrganizationNotificationEmail.tsx | 20 +-
.../src/templates/BaseScheduledEmail.tsx | 2 +-
.../src/templates/BrokenIntegrationEmail.tsx | 52 +-
.../DailyVideoDownloadRecordingEmail.tsx | 2 +-
.../DailyVideoDownloadTranscriptEmail.tsx | 2 +-
.../emails/src/templates/DisabledAppEmail.tsx | 2 +-
.../src/templates/ForgotPasswordEmail.tsx | 2 +-
.../src/templates/MonthlyDigestEmail.tsx | 2 +-
.../src/templates/OrgAutoInviteEmail.tsx | 2 +-
.../OrganizationAccountVerifyEmail.tsx | 2 +-
.../templates/OrganizationAdminNoSlots.tsx | 29 +-
.../templates/OrganizationCreationEmail.tsx | 49 +-
.../src/templates/SlugReplacementEmail.tsx | 42 +-
.../emails/src/templates/TeamInviteEmail.tsx | 127 ++--
.../src/templates/VerifyAccountEmail.tsx | 2 +-
.../src/templates/VerifyEmailChangeEmail.tsx | 2 +-
packages/emails/templates/_base-email.ts | 2 +-
.../emails/templates/account-verify-email.ts | 2 +-
.../admin-organization-notification.ts | 2 +-
...ee-daily-video-download-recording-email.ts | 2 +-
...e-daily-video-download-transcript-email.ts | 2 +-
.../templates/attendee-scheduled-email.ts | 2 +-
.../emails/templates/attendee-verify-email.ts | 2 +-
.../booking-redirect-notification.ts | 2 +-
.../templates/broken-integration-email.ts | 2 +-
.../templates/change-account-email-verify.ts | 2 +-
.../emails/templates/disabled-app-email.ts | 2 +-
.../emails/templates/forgot-password-email.ts | 2 +-
.../emails/templates/org-auto-join-invite.ts | 2 +-
.../organization-admin-no-slots-email.ts | 2 +-
.../templates/organization-creation-email.ts | 2 +-
.../organization-email-verification.ts | 2 +-
...er-daily-video-download-recording-email.ts | 2 +-
...r-daily-video-download-transcript-email.ts | 2 +-
.../templates/organizer-scheduled-email.ts | 2 +-
.../templates/slug-replacement-email.ts | 2 +-
.../emails/templates/team-invite-email.ts | 2 +-
.../embed-core/src/useCompatSearchParams.tsx | 3 +-
.../features/apps/components/appCard.test.tsx | 18 +-
.../features/auth/lib/passwordResetRequest.ts | 3 +-
.../BookEventForm/BookEventForm.tsx | 28 +-
.../BookEventForm/BookingFields.test.tsx | 3 +-
.../Booker/components/OutOfOfficeInSlots.tsx | 8 +-
.../Booker/components/hooks/useBookings.ts | 2 +
.../components/event-meta/Duration.tsx | 2 +-
.../bookings/lib/handleNewBooking/types.ts | 2 +-
.../ee/dsync/lib/inviteExistingUserToOrg.ts | 2 +-
.../lib/users/inviteExistingUserToOrg.ts | 2 +-
.../hooks/useLockedFieldsManager.tsx | 2 +-
.../createOrganizationFromOnboarding.test.ts | 26 -
.../pages/settings/admin/AdminOrgPage.tsx | 22 +-
.../ee/payments/components/Payment.tsx | 2 +
.../components/CreateANewPlatformForm.tsx | 3 +-
.../ee/teams/components/AddNewTeamMembers.tsx | 5 +-
.../components/MemberInvitationModal.tsx | 19 +-
.../create-button-with-teams-list.test.tsx | 14 +
.../features/ee/workflows/lib/getOptions.ts | 2 +-
.../ee/workflows/lib/getWorkflowReminders.ts | 8 +-
.../ee/workflows/lib/variableTranslations.ts | 2 +-
.../EditWeightsForAllTeamMembers.tsx | 24 +-
.../eventtypes/components/HostEditDialogs.tsx | 17 +-
.../eventtypes/components/Locations.tsx | 45 +-
.../components/WeightDescription.tsx | 22 +
.../components/dialogs/DeleteDialog.tsx | 18 +-
.../components/dialogs/ManagedEventDialog.tsx | 13 +-
.../tabs/advanced/DisableAllEmailsSetting.tsx | 18 +-
.../RequiresConfirmationController.tsx | 114 +--
.../components/tabs/apps/EventAppsTab.tsx | 38 +-
.../assignment/EventTeamAssignmentTab.tsx | 36 +-
.../tabs/webhooks/EventWebhooksTab.tsx | 44 +-
.../tabs/workflows/EventWorkfowsTab.tsx | 27 +-
.../form-builder/FormBuilderField.tsx | 2 +-
.../insights/components/RoutedToPerPeriod.tsx | 2 +-
.../settings/BookerLayoutSelector.tsx | 40 +-
.../outOfOffice/OutOfOfficeEntriesList.tsx | 15 +-
packages/lib/CalEventParser.test.ts | 2 +-
packages/lib/CalEventParser.ts | 2 +-
packages/lib/bookingSuccessRedirect.ts | 9 +-
packages/lib/constants.ts | 10 -
packages/lib/crmManager/crmManager.test.ts | 2 +-
.../event-types/utils/locationsResolver.ts | 2 +-
packages/lib/event.test.ts | 2 +-
packages/lib/event.ts | 2 +-
packages/lib/getSafe.ts | 6 +
packages/lib/hooks/useCompatSearchParams.tsx | 2 +
packages/lib/hooks/useLocale.ts | 2 +-
packages/lib/hooks/useTelemetry.ts | 5 +
packages/lib/package.json | 2 +-
packages/lib/recurringStrings.ts | 2 +-
packages/lib/server/i18n.ts | 52 +-
packages/lib/telemetry.ts | 3 -
packages/lib/test/builder.ts | 2 +-
.../hooks/usePlatformTabsNavigations.tsx | 2 +-
.../event-types/hooks/useTabsNavigations.tsx | 2 +-
.../wrappers/EventTypeWebWrapper.tsx | 3 +-
packages/prisma/client/index.js | 2 +-
packages/prisma/zod-utils.ts | 2 +-
.../bookings/requestReschedule.handler.ts | 2 +-
.../viewer/teams/inviteMember/utils.ts | 2 +-
packages/types/Calendar.d.ts | 2 +-
turbo.json | 3 -
yarn.lock | 693 +++++++++++++-----
263 files changed, 2002 insertions(+), 1663 deletions(-)
create mode 100644 apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormProvider.tsx
delete mode 100644 apps/web/app/api/future-opt-in/route.ts
create mode 100644 apps/web/components/ServerTrans.tsx
delete mode 100644 apps/web/lib/metadata.ts
delete mode 100644 apps/web/pages/404.tsx
delete mode 100644 apps/web/public/favicon.ico
delete mode 100755 apps/web/scripts/vercel-app-router-deploy.sh
delete mode 100644 apps/web/server/lib/getTranslations.ts
create mode 100644 packages/app-store/routing-forms/pages/app-routing.client-config.tsx
rename packages/app-store/routing-forms/pages/{app-routing.config.tsx => app-routing.server-config.tsx} (50%)
delete mode 100644 packages/app-store/routing-forms/pages/layout-handler/[...appPages].tsx
create mode 100644 packages/features/eventtypes/components/WeightDescription.tsx
create mode 100644 packages/lib/getSafe.ts
create mode 100644 packages/lib/hooks/useTelemetry.ts
diff --git a/.env.example b/.env.example
index 17d925407d..cb88791eb8 100644
--- a/.env.example
+++ b/.env.example
@@ -357,13 +357,6 @@ E2E_TEST_OIDC_USER_PASSWORD=
# ***********************************************************************************************************
-# provide a value between 0 and 100 to ensure the percentage of traffic
-# redirected from the legacy to the future pages
-AB_TEST_BUCKET_PROBABILITY=50
-APP_ROUTER_APPS_SLUG_SETUP_ENABLED=0
-APP_ROUTER_APPS_ENABLED=0
-APP_ROUTER_TEAM_ENABLED=0
-
# disable setry server source maps
SENTRY_DISABLE_SERVER_WEBPACK_PLUGIN=1
diff --git a/apps/web/app/(booking-page-wrapper)/[user]/[type]/embed/page.tsx b/apps/web/app/(booking-page-wrapper)/[user]/[type]/embed/page.tsx
index 0e78ce9f45..6f5d0bdc8d 100644
--- a/apps/web/app/(booking-page-wrapper)/[user]/[type]/embed/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/[user]/[type]/embed/page.tsx
@@ -11,7 +11,7 @@ import TypePage, { type PageProps as ClientPageProps } from "~/users/views/users
const getData = withEmbedSsrAppDir(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
};
diff --git a/apps/web/app/(booking-page-wrapper)/[user]/[type]/page.tsx b/apps/web/app/(booking-page-wrapper)/[user]/[type]/page.tsx
index bb0f0f63b4..deb6762d32 100644
--- a/apps/web/app/(booking-page-wrapper)/[user]/[type]/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/[user]/[type]/page.tsx
@@ -13,7 +13,7 @@ import type { PageProps as LegacyPageProps } from "~/users/views/users-type-publ
import LegacyPage from "~/users/views/users-type-public-view";
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(legacyCtx);
const { booking, isSEOIndexable = true, eventData, isBrandingHidden } = props;
@@ -31,7 +31,7 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
})),
],
};
- const decodedParams = decodeParams(params);
+ const decodedParams = decodeParams(await params);
const metadata = await generateMeetingMetadata(
meeting,
(t) => `${rescheduleUid && !!booking ? t("reschedule") : ""} ${title} | ${profileName}`,
@@ -52,7 +52,7 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(legacyCtx);
return ;
diff --git a/apps/web/app/(booking-page-wrapper)/[user]/embed/page.tsx b/apps/web/app/(booking-page-wrapper)/[user]/embed/page.tsx
index df9491b2e9..878bc8c508 100644
--- a/apps/web/app/(booking-page-wrapper)/[user]/embed/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/[user]/embed/page.tsx
@@ -11,7 +11,7 @@ import User, { type PageProps as ClientPageProps } from "~/users/views/users-pub
const getData = withEmbedSsrAppDir(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
};
diff --git a/apps/web/app/(booking-page-wrapper)/[user]/page.tsx b/apps/web/app/(booking-page-wrapper)/[user]/page.tsx
index 45c57cad0d..0e10610b39 100644
--- a/apps/web/app/(booking-page-wrapper)/[user]/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/[user]/page.tsx
@@ -13,7 +13,9 @@ import type { PageProps as LegacyPageProps } from "~/users/views/users-public-vi
import LegacyPage from "~/users/views/users-public-view";
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
const { profile, markdownStrippedBio, isOrgSEOIndexable, entity } = props;
const isOrg = !!profile?.organization;
@@ -31,7 +33,7 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
() => markdownStrippedBio,
false,
getOrgFullOrigin(entity.orgSlug ?? null),
- `/${decodeParams(params).user}`
+ `/${decodeParams(await params).user}`
);
return {
@@ -45,7 +47,9 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
};
diff --git a/apps/web/app/(booking-page-wrapper)/layout.tsx b/apps/web/app/(booking-page-wrapper)/layout.tsx
index b96ea2efac..9355b24469 100644
--- a/apps/web/app/(booking-page-wrapper)/layout.tsx
+++ b/apps/web/app/(booking-page-wrapper)/layout.tsx
@@ -3,7 +3,7 @@ import { headers } from "next/headers";
import PageWrapper from "@components/PageWrapperAppDir";
export default async function BookingPageWrapperLayout({ children }: { children: React.ReactNode }) {
- const h = headers();
+ const h = await headers();
const nonce = h.get("x-nonce") ?? undefined;
return (
diff --git a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/[type]/embed/page.tsx b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/[type]/embed/page.tsx
index e137cbaf7a..51d21aeaf0 100644
--- a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/[type]/embed/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/[type]/embed/page.tsx
@@ -15,7 +15,7 @@ const getData = withEmbedSsrAppDir(getServerSideProps);
export type ClientPageProps = UserTypePageProps | TeamTypePageProps;
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
if ((props as TeamTypePageProps)?.teamId) return ;
return ;
diff --git a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/[type]/page.tsx b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/[type]/page.tsx
index 65b7bdf34a..c07628f4cc 100644
--- a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/[type]/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/[type]/page.tsx
@@ -17,7 +17,7 @@ export type OrgTypePageProps = UserTypePageProps | TeamTypePageProps;
const getData = withAppDirSsr(getServerSideProps);
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(legacyCtx);
const { booking, isSEOIndexable = true, eventData, isBrandingHidden } = props;
@@ -36,7 +36,7 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
})),
],
};
- const decodedParams = decodeParams(params);
+ const decodedParams = decodeParams(await params);
const metadata = await generateMeetingMetadata(
meeting,
(t) => `${rescheduleUid && !!booking ? t("reschedule") : ""} ${title} | ${profileName}`,
@@ -56,7 +56,9 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
};
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
if ((props as TeamTypePageProps)?.teamId) {
return ;
}
diff --git a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/embed/page.tsx b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/embed/page.tsx
index 0b94bc02ee..1818008107 100644
--- a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/embed/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/embed/page.tsx
@@ -15,7 +15,7 @@ const getData = withEmbedSsrAppDir(getServerSideProps);
export type ClientPageProps = UserPageProps | TeamPageProps;
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
if ((props as TeamPageProps)?.team) return ;
return ;
diff --git a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/page.tsx b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/page.tsx
index a338de8f77..c25b58f8c3 100644
--- a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/[user]/page.tsx
@@ -18,7 +18,7 @@ export type OrgPageProps = UserPageProps | TeamPageProps;
const getData = withAppDirSsr(getServerSideProps);
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(legacyCtx);
if ((props as TeamPageProps)?.team) {
@@ -30,7 +30,7 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
image: getOrgOrTeamAvatar(team),
},
};
- const decodedParams = decodeParams(params);
+ const decodedParams = decodeParams(await params);
return {
...(await generateMeetingMetadata(
meeting,
@@ -78,7 +78,9 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
};
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
if ((props as TeamPageProps)?.team) {
return ;
}
diff --git a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/instant-meeting/team/[slug]/[type]/page.tsx b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/instant-meeting/team/[slug]/[type]/page.tsx
index 42aadb35fa..ad77d0a307 100644
--- a/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/instant-meeting/team/[slug]/[type]/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/org/[orgSlug]/instant-meeting/team/[slug]/[type]/page.tsx
@@ -12,7 +12,7 @@ import type { Props } from "~/org/[orgSlug]/instant-meeting/team/[slug]/[type]/i
import Page from "~/org/[orgSlug]/instant-meeting/team/[slug]/[type]/instant-meeting-view";
export const generateMetadata = async ({ params, searchParams }: _PageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const { isBrandingHidden, eventData } = await getData(context);
const profileName = eventData?.profile.name ?? "";
@@ -29,7 +29,7 @@ export const generateMetadata = async ({ params, searchParams }: _PageProps) =>
})),
],
};
- const decodedParams = decodeParams(params);
+ const decodedParams = decodeParams(await params);
const metadata = await generateMeetingMetadata(
meeting,
() => `${title} | ${profileName}`,
@@ -51,7 +51,9 @@ export const generateMetadata = async ({ params, searchParams }: _PageProps) =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: _PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
};
diff --git a/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/embed/page.tsx b/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/embed/page.tsx
index 307cc85da4..fdfd8df197 100644
--- a/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/embed/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/embed/page.tsx
@@ -10,7 +10,7 @@ import TypePage, { type PageProps as ClientPageProps } from "~/team/type-view";
const getData = withEmbedSsrAppDir(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
};
diff --git a/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/page.tsx b/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/page.tsx
index 72016bebc9..6f9436b8a7 100644
--- a/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/team/[slug]/[type]/page.tsx
@@ -12,7 +12,7 @@ import LegacyPage from "~/team/type-view";
import type { PageProps as LegacyPageProps } from "~/team/type-view";
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(legacyCtx);
const { booking, isSEOIndexable, eventData, isBrandingHidden } = props;
@@ -29,7 +29,7 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
})),
],
};
- const decodedParams = decodeParams(params);
+ const decodedParams = decodeParams(await params);
const metadata = await generateMeetingMetadata(
meeting,
(t) => `${booking?.uid && !!booking ? t("reschedule") : ""} ${title} | ${profileName}`,
@@ -51,7 +51,9 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
};
export default ServerPage;
diff --git a/apps/web/app/(booking-page-wrapper)/team/[slug]/embed/page.tsx b/apps/web/app/(booking-page-wrapper)/team/[slug]/embed/page.tsx
index 15d6a21f17..251c2a19c5 100644
--- a/apps/web/app/(booking-page-wrapper)/team/[slug]/embed/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/team/[slug]/embed/page.tsx
@@ -10,7 +10,7 @@ import TeamPage, { type PageProps as ClientPageProps } from "~/team/team-view";
const getData = withEmbedSsrAppDir(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
};
diff --git a/apps/web/app/(booking-page-wrapper)/team/[slug]/page.tsx b/apps/web/app/(booking-page-wrapper)/team/[slug]/page.tsx
index 70993de138..5f823ff15c 100644
--- a/apps/web/app/(booking-page-wrapper)/team/[slug]/page.tsx
+++ b/apps/web/app/(booking-page-wrapper)/team/[slug]/page.tsx
@@ -14,7 +14,7 @@ import LegacyPage from "~/team/team-view";
export const generateMetadata = async ({ params, searchParams }: _PageProps) => {
const { team, markdownStrippedBio, isSEOIndexable, currentOrgDomain } = await getData(
- buildLegacyCtx(headers(), cookies(), params, searchParams)
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
);
const meeting = {
@@ -24,7 +24,7 @@ export const generateMetadata = async ({ params, searchParams }: _PageProps) =>
image: getOrgOrTeamAvatar(team),
},
};
- const decodedParams = decodeParams(params);
+ const decodedParams = decodeParams(await params);
const metadata = await generateMeetingMetadata(
meeting,
(t) => team.name || t("nameless_team"),
@@ -45,7 +45,9 @@ export const generateMetadata = async ({ params, searchParams }: _PageProps) =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: _PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
};
export default ServerPage;
diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/availability/page.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/availability/page.tsx
index e7d7ac50df..24588e1eb1 100644
--- a/apps/web/app/(use-page-wrapper)/(main-nav)/availability/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/availability/page.tsx
@@ -17,7 +17,7 @@ export const generateMetadata = async () => {
};
const Page = async () => {
- // const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ // const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
// const userId = session?.user?.id;
// const orgId = session?.user?.org?.id;
// if (!userId || !orgId) {
diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/bookings/[status]/page.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/bookings/[status]/page.tsx
index 1355403f27..600a981330 100644
--- a/apps/web/app/(use-page-wrapper)/(main-nav)/bookings/[status]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/bookings/[status]/page.tsx
@@ -18,7 +18,7 @@ export const generateMetadata = async () =>
);
const Page = async ({ params }: PageProps) => {
- const parsed = querySchema.safeParse(params);
+ const parsed = querySchema.safeParse(await params);
if (!parsed.success) {
redirect("/bookings/upcoming");
}
diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx
index d975c7de60..b54b052147 100644
--- a/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/event-types/page.tsx
@@ -19,7 +19,7 @@ export const generateMetadata = async () =>
);
const Page = async ({ params, searchParams }: PageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const session = await getServerSession({ req: context.req });
if (!session?.user?.id) {
diff --git a/apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx b/apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx
index 3a5a13b7b3..c70d1f8d46 100644
--- a/apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/(main-nav)/teams/page.tsx
@@ -16,8 +16,9 @@ export const generateMetadata = async () =>
(t) => t("create_manage_teams_collaborative")
);
-const ServerPage = async ({ searchParams }: ServerPageProps) => {
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+const ServerPage = async ({ searchParams: _searchParams }: ServerPageProps) => {
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
+ const searchParams = await _searchParams;
const token = Array.isArray(searchParams?.token) ? searchParams.token[0] : searchParams?.token;
const callbackUrl = token ? `/teams?token=${encodeURIComponent(token)}` : null;
diff --git a/apps/web/app/(use-page-wrapper)/apps/[slug]/page.tsx b/apps/web/app/(use-page-wrapper)/apps/[slug]/page.tsx
index 94b15fd498..52b2bf83fb 100644
--- a/apps/web/app/(use-page-wrapper)/apps/[slug]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/apps/[slug]/page.tsx
@@ -12,7 +12,7 @@ const paramsSchema = z.object({
});
export const generateMetadata = async ({ params }: _PageProps) => {
- const p = paramsSchema.safeParse(params);
+ const p = paramsSchema.safeParse(await params);
if (!p.success) {
return notFound();
@@ -33,7 +33,7 @@ export const generateMetadata = async ({ params }: _PageProps) => {
};
async function Page({ params }: _PageProps) {
- const p = paramsSchema.safeParse(params);
+ const p = paramsSchema.safeParse(await params);
if (!p.success) {
return notFound();
diff --git a/apps/web/app/(use-page-wrapper)/apps/[slug]/setup/page.tsx b/apps/web/app/(use-page-wrapper)/apps/[slug]/setup/page.tsx
index 4410b8cc71..338fadcf5c 100644
--- a/apps/web/app/(use-page-wrapper)/apps/[slug]/setup/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/apps/[slug]/setup/page.tsx
@@ -9,7 +9,8 @@ import { buildLegacyCtx } from "@lib/buildLegacyCtx";
import SetupView, { type PageProps as ClientPageProps } from "~/apps/[slug]/setup/setup-view";
-export const generateMetadata = async ({ params }: ServerPageProps) => {
+export const generateMetadata = async ({ params: _params }: ServerPageProps) => {
+ const params = await _params;
const metadata = await _generateMetadata(
() => `${params.slug}`,
() => ""
@@ -26,7 +27,7 @@ export const generateMetadata = async ({ params }: ServerPageProps) => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const { dehydratedState, ...props } = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/apps/categories/page.tsx b/apps/web/app/(use-page-wrapper)/apps/categories/page.tsx
index 0f07252b77..d63fd02d17 100644
--- a/apps/web/app/(use-page-wrapper)/apps/categories/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/apps/categories/page.tsx
@@ -10,7 +10,9 @@ import Page from "~/apps/categories/categories-view";
const getData = withAppDirSsr(getServerSideProps);
async function ServerPage({ params, searchParams }: PageProps) {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
}
diff --git a/apps/web/app/(use-page-wrapper)/apps/installation/[[...step]]/page.tsx b/apps/web/app/(use-page-wrapper)/apps/installation/[[...step]]/page.tsx
index 591b0d52d7..41e30a28be 100644
--- a/apps/web/app/(use-page-wrapper)/apps/installation/[[...step]]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/apps/installation/[[...step]]/page.tsx
@@ -10,7 +10,7 @@ import type { OnboardingPageProps } from "~/apps/installation/[[...step]]/step-v
import Page from "~/apps/installation/[[...step]]/step-view";
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const { appMetadata } = await getData(legacyCtx);
return await _generateMetadata(
@@ -22,7 +22,9 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
};
export default ServerPage;
diff --git a/apps/web/app/(use-page-wrapper)/apps/installed/[category]/page.tsx b/apps/web/app/(use-page-wrapper)/apps/installed/[category]/page.tsx
index ff6d563bc9..28c3ca4aab 100644
--- a/apps/web/app/(use-page-wrapper)/apps/installed/[category]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/apps/installed/[category]/page.tsx
@@ -19,7 +19,7 @@ export const generateMetadata = async () => {
};
const InstalledAppsWrapper = async ({ params }: PageProps) => {
- const parsedParams = querySchema.safeParse(params);
+ const parsedParams = querySchema.safeParse(await params);
if (!parsedParams.success) {
redirect("/apps/installed/calendar");
diff --git a/apps/web/app/(use-page-wrapper)/apps/page.tsx b/apps/web/app/(use-page-wrapper)/apps/page.tsx
index 0117c797c9..8a9a6f027b 100644
--- a/apps/web/app/(use-page-wrapper)/apps/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/apps/page.tsx
@@ -18,7 +18,7 @@ export const generateMetadata = async () => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormProvider.tsx b/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormProvider.tsx
new file mode 100644
index 0000000000..1e34195c6a
--- /dev/null
+++ b/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/FormProvider.tsx
@@ -0,0 +1,9 @@
+"use client";
+
+import { FormProvider as ReactHookFormProvider, useForm } from "react-hook-form";
+
+export default function FormProvider({ children }: { children: React.ReactNode }) {
+ const methods = useForm();
+
+ return {children} ;
+}
diff --git a/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/page.tsx b/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/page.tsx
index cf9817f314..fbb217dce7 100644
--- a/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/apps/routing-forms/[...pages]/page.tsx
@@ -3,23 +3,25 @@ import type { PageProps as ServerPageProps } from "app/_types";
import { _generateMetadata } from "app/_utils";
import { cookies, headers } from "next/headers";
-import type { routingServerSidePropsConfig } from "@calcom/app-store/routing-forms/pages/app-routing.config";
-import LayoutHandler from "@calcom/app-store/routing-forms/pages/layout-handler/[...appPages]";
+import { routingFormsComponents } from "@calcom/app-store/routing-forms/pages/app-routing.client-config";
+import type { routingServerSidePropsConfig } from "@calcom/app-store/routing-forms/pages/app-routing.server-config";
import Shell from "@calcom/features/shell/Shell";
import { getServerSideProps } from "@lib/apps/routing-forms/[...pages]/getServerSideProps";
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
+import FormProvider from "./FormProvider";
+
const normalizePages = (pages: string[] | string | undefined) => {
const normalizedPages = Array.isArray(pages) ? pages : pages?.split("/") ?? [];
return {
- mainPage: normalizedPages[0],
+ mainPage: normalizedPages[0] ?? "forms",
subPages: normalizedPages.slice(1),
};
};
-export const generateMetadata = async ({ params }: { params: { pages: string[] } }) => {
- const { mainPage } = normalizePages(params.pages);
+export const generateMetadata = async ({ params }: { params: Promise<{ pages: string[] }> }) => {
+ const { mainPage } = normalizePages((await params).pages);
return await _generateMetadata(
// TODO: Need to show the actual form name instead of "Form"
(t) => (mainPage === "routing-link" ? `Form | Cal.com Forms` : `${t("routing_forms")} | Cal.com Forms`),
@@ -32,22 +34,24 @@ type GetServerSidePropsResult =
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
- const { mainPage, subPages } = normalizePages(params.pages);
+ const { mainPage } = normalizePages((await params).pages);
- const componentProps = {
- ...props,
- pages: subPages,
- };
+ const Component = await routingFormsComponents[mainPage as keyof typeof routingFormsComponents]();
+ const FinalComponent = () => (
+
+
+
+ );
if (mainPage === "routing-link") {
- return ;
+ return ;
}
return (
-
+
);
};
diff --git a/apps/web/app/(use-page-wrapper)/auth/error/page.tsx b/apps/web/app/(use-page-wrapper)/auth/error/page.tsx
index da2f209e9f..d5c59e22c8 100644
--- a/apps/web/app/(use-page-wrapper)/auth/error/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/error/page.tsx
@@ -21,7 +21,7 @@ const querySchema = z.object({
const ServerPage = async ({ searchParams }: PageProps) => {
const t = await getTranslate();
- const { error } = querySchema.parse({ error: searchParams?.error || undefined });
+ const { error } = querySchema.parse({ error: (await searchParams)?.error || undefined });
const errorMsg = t("error_during_login") + (error ? ` Error code: ${error}` : "");
return (
diff --git a/apps/web/app/(use-page-wrapper)/auth/forgot-password/[id]/page.tsx b/apps/web/app/(use-page-wrapper)/auth/forgot-password/[id]/page.tsx
index 4810f917a4..253dc85651 100644
--- a/apps/web/app/(use-page-wrapper)/auth/forgot-password/[id]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/forgot-password/[id]/page.tsx
@@ -19,7 +19,7 @@ export const generateMetadata = async () => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/auth/forgot-password/page.tsx b/apps/web/app/(use-page-wrapper)/auth/forgot-password/page.tsx
index 0b656a734f..11ad68f9ea 100644
--- a/apps/web/app/(use-page-wrapper)/auth/forgot-password/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/forgot-password/page.tsx
@@ -18,7 +18,7 @@ export const generateMetadata = async () => {
};
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const session = await getServerSession({ req: context.req });
if (session) {
diff --git a/apps/web/app/(use-page-wrapper)/auth/login/page.tsx b/apps/web/app/(use-page-wrapper)/auth/login/page.tsx
index 9ccefad02c..05c83861b4 100644
--- a/apps/web/app/(use-page-wrapper)/auth/login/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/login/page.tsx
@@ -20,7 +20,9 @@ export const generateMetadata = async () => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
};
diff --git a/apps/web/app/(use-page-wrapper)/auth/logout/page.tsx b/apps/web/app/(use-page-wrapper)/auth/logout/page.tsx
index 99639e5e10..f95c2e1957 100644
--- a/apps/web/app/(use-page-wrapper)/auth/logout/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/logout/page.tsx
@@ -17,8 +17,8 @@ export const generateMetadata = async () => {
const Page = async ({ params, searchParams }: PageProps) => {
// cookie will be cleared in `/apps/web/middleware.ts`
- const h = headers();
- const context = buildLegacyCtx(h, cookies(), params, searchParams);
+ const h = await headers();
+ const context = buildLegacyCtx(h, await cookies(), await params, await searchParams);
await ssrInit(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/auth/setup/page.tsx b/apps/web/app/(use-page-wrapper)/auth/setup/page.tsx
index ff6768e7cc..b7042b6829 100644
--- a/apps/web/app/(use-page-wrapper)/auth/setup/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/setup/page.tsx
@@ -20,7 +20,9 @@ export const generateMetadata = async () => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
};
diff --git a/apps/web/app/(use-page-wrapper)/auth/signin/page.tsx b/apps/web/app/(use-page-wrapper)/auth/signin/page.tsx
index aac25c869b..9ca95e4908 100644
--- a/apps/web/app/(use-page-wrapper)/auth/signin/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/signin/page.tsx
@@ -14,7 +14,7 @@ import type { PageProps as ClientPageProps } from "~/auth/signin-view";
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const session = await getServerSession({ req: context.req });
if (session) {
redirect("/");
diff --git a/apps/web/app/(use-page-wrapper)/auth/sso/[provider]/page.tsx b/apps/web/app/(use-page-wrapper)/auth/sso/[provider]/page.tsx
index cb3572e78f..d04832bcb6 100644
--- a/apps/web/app/(use-page-wrapper)/auth/sso/[provider]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/sso/[provider]/page.tsx
@@ -11,7 +11,7 @@ import SSOProviderView from "~/auth/sso/provider-view";
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/auth/sso/direct/page.tsx b/apps/web/app/(use-page-wrapper)/auth/sso/direct/page.tsx
index a80dac7d74..a855dca4b0 100644
--- a/apps/web/app/(use-page-wrapper)/auth/sso/direct/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/sso/direct/page.tsx
@@ -11,7 +11,7 @@ import SSODirectView from "~/auth/sso/direct-view";
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/auth/verify-email-change/page.tsx b/apps/web/app/(use-page-wrapper)/auth/verify-email-change/page.tsx
index f49468649f..761728d261 100644
--- a/apps/web/app/(use-page-wrapper)/auth/verify-email-change/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/auth/verify-email-change/page.tsx
@@ -19,7 +19,9 @@ export const generateMetadata = async () => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
};
export default ServerPage;
diff --git a/apps/web/app/(use-page-wrapper)/availability/[schedule]/page.tsx b/apps/web/app/(use-page-wrapper)/availability/[schedule]/page.tsx
index d3d443ec18..f948002f65 100644
--- a/apps/web/app/(use-page-wrapper)/availability/[schedule]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/availability/[schedule]/page.tsx
@@ -25,7 +25,7 @@ const querySchema = z.object({
const getSchedule = cache((id: number) => ScheduleRepository.findScheduleById({ id }));
export const generateMetadata = async ({ params }: PageProps) => {
- const parsed = querySchema.safeParse(params);
+ const parsed = querySchema.safeParse(await params);
if (!parsed.success) {
notFound();
}
@@ -43,13 +43,13 @@ export const generateMetadata = async ({ params }: PageProps) => {
};
const Page = async ({ params }: PageProps) => {
- const parsed = querySchema.safeParse(params);
+ const parsed = querySchema.safeParse(await params);
if (!parsed.success) {
notFound();
}
- // const scheduleId = Number(params.schedule);
+ // const scheduleId = Number(await params.schedule);
- // const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ // const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
// const userId = session?.user?.id;
// if (!userId) {
// notFound();
diff --git a/apps/web/app/(use-page-wrapper)/booking/[uid]/embed/page.tsx b/apps/web/app/(use-page-wrapper)/booking/[uid]/embed/page.tsx
index d0e4c69b5a..0520153bf9 100644
--- a/apps/web/app/(use-page-wrapper)/booking/[uid]/embed/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/booking/[uid]/embed/page.tsx
@@ -13,7 +13,7 @@ import {
const getEmbedData = withEmbedSsrAppDir(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getEmbedData(context);
return ;
};
diff --git a/apps/web/app/(use-page-wrapper)/booking/[uid]/page.tsx b/apps/web/app/(use-page-wrapper)/booking/[uid]/page.tsx
index f110db9557..af0c90f719 100644
--- a/apps/web/app/(use-page-wrapper)/booking/[uid]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/booking/[uid]/page.tsx
@@ -16,7 +16,7 @@ import {
export const generateMetadata = async ({ params, searchParams }: _PageProps) => {
const { bookingInfo, eventType, recurringBookings, orgSlug } = await getData(
- buildLegacyCtx(headers(), cookies(), params, searchParams)
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
);
const needsConfirmation = bookingInfo.status === BookingStatus.PENDING && eventType.requiresConfirmation;
@@ -33,7 +33,7 @@ export const generateMetadata = async ({ params, searchParams }: _PageProps) =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: _PageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
};
diff --git a/apps/web/app/(use-page-wrapper)/d/[link]/[slug]/page.tsx b/apps/web/app/(use-page-wrapper)/d/[link]/[slug]/page.tsx
index 68fc6cd3fd..93786d48f9 100644
--- a/apps/web/app/(use-page-wrapper)/d/[link]/[slug]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/d/[link]/[slug]/page.tsx
@@ -10,7 +10,7 @@ import { type PageProps } from "@lib/d/[link]/[slug]/getServerSideProps";
import Type from "~/d/[link]/d-type-view";
export const generateMetadata = async ({ params, searchParams }: _PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const pageProps = await getData(legacyCtx);
const { booking, eventData, isBrandingHidden } = pageProps;
@@ -27,7 +27,7 @@ export const generateMetadata = async ({ params, searchParams }: _PageProps) =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: _PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const pageProps = await getData(legacyCtx);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/event-types/[type]/page.tsx b/apps/web/app/(use-page-wrapper)/event-types/[type]/page.tsx
index 022fe291c3..2ef18d1964 100644
--- a/apps/web/app/(use-page-wrapper)/event-types/[type]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/event-types/[type]/page.tsx
@@ -22,7 +22,7 @@ const querySchema = z.object({
});
export const generateMetadata = async ({ params }: _PageProps) => {
- const parsed = querySchema.safeParse(params);
+ const parsed = querySchema.safeParse(await params);
if (!parsed.success) {
return await _generateMetadata(
(t) => `${t("event_type")}`,
@@ -43,7 +43,7 @@ export const generateMetadata = async ({ params }: _PageProps) => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: _PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(legacyCtx);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/getting-started/[[...step]]/page.tsx b/apps/web/app/(use-page-wrapper)/getting-started/[[...step]]/page.tsx
index 0a347eae7c..ba47708cfa 100644
--- a/apps/web/app/(use-page-wrapper)/getting-started/[[...step]]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/getting-started/[[...step]]/page.tsx
@@ -22,7 +22,7 @@ export const generateMetadata = async () => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/layout.tsx b/apps/web/app/(use-page-wrapper)/layout.tsx
index 2fc38abd52..b06a3a5fe6 100644
--- a/apps/web/app/(use-page-wrapper)/layout.tsx
+++ b/apps/web/app/(use-page-wrapper)/layout.tsx
@@ -3,7 +3,7 @@ import { headers } from "next/headers";
import PageWrapper from "@components/PageWrapperAppDir";
export default async function PageWrapperLayout({ children }: { children: React.ReactNode }) {
- const h = headers();
+ const h = await headers();
const nonce = h.get("x-nonce") ?? undefined;
return (
diff --git a/apps/web/app/(use-page-wrapper)/payment/[uid]/page.tsx b/apps/web/app/(use-page-wrapper)/payment/[uid]/page.tsx
index 008602773b..58712013e6 100644
--- a/apps/web/app/(use-page-wrapper)/payment/[uid]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/payment/[uid]/page.tsx
@@ -10,7 +10,9 @@ import { APP_NAME } from "@calcom/lib/constants";
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
export const generateMetadata = async ({ params, searchParams }: PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
const eventName = props.booking.title;
return await _generateMetadata(
(t) => `${t("payment")} | ${eventName} | ${APP_NAME}`,
@@ -21,7 +23,9 @@ export const generateMetadata = async ({ params, searchParams }: PageProps) => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ const props = await getData(
+ buildLegacyCtx(await headers(), await cookies(), await params, await searchParams)
+ );
return ;
};
diff --git a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/page.tsx
index 448902d771..0114306665 100644
--- a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/organizations/[id]/edit/page.tsx
@@ -11,7 +11,7 @@ import { OrganizationRepository } from "@calcom/lib/server/repository/organizati
const orgIdSchema = z.object({ id: z.coerce.number() });
export const generateMetadata = async ({ params }: { params: Params }) => {
- const input = orgIdSchema.safeParse(params);
+ const input = orgIdSchema.safeParse(await params);
if (!input.success) {
return await _generateMetadata(
(t) => t("editing_org"),
@@ -28,7 +28,7 @@ export const generateMetadata = async ({ params }: { params: Params }) => {
};
const Page = async ({ params }: { params: Params }) => {
- const input = orgIdSchema.safeParse(params);
+ const input = orgIdSchema.safeParse(await params);
if (!input.success) notFound();
diff --git a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/users/[id]/edit/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/users/[id]/edit/page.tsx
index d9a9f5d025..6be685d31d 100644
--- a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/users/[id]/edit/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/admin/users/[id]/edit/page.tsx
@@ -11,7 +11,7 @@ import { UserRepository } from "@calcom/lib/server/repository/user";
const userIdSchema = z.object({ id: z.coerce.number() });
export const generateMetadata = async ({ params }: { params: Params }) => {
- const input = userIdSchema.safeParse(params);
+ const input = userIdSchema.safeParse(await params);
if (!input.success) {
return await _generateMetadata(
(t) => t("editing_user"),
@@ -28,7 +28,7 @@ export const generateMetadata = async ({ params }: { params: Params }) => {
};
const Page = async ({ params }: { params: Params }) => {
- const input = userIdSchema.safeParse(params);
+ const input = userIdSchema.safeParse(await params);
if (!input.success) {
notFound();
diff --git a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/layout.tsx b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/layout.tsx
index 2f09486645..bf2bfed9fd 100644
--- a/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/layout.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/(admin-layout)/layout.tsx
@@ -12,7 +12,7 @@ import AdminLayoutAppDirClient from "./AdminLayoutAppDirClient";
type AdminLayoutAppDirProps = Omit;
export default async function AdminLayoutAppDir(props: AdminLayoutAppDirProps) {
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
const userRole = session?.user?.role;
return await SettingsLayoutAppDir({ children: });
diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/[id]/page.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/[id]/page.tsx
index 7263eb9279..6a8be3de09 100644
--- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/[id]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/developer/webhooks/[id]/page.tsx
@@ -12,8 +12,9 @@ export const generateMetadata = async () =>
(t) => t("add_webhook_description", { appName: APP_NAME })
);
-const Page = async ({ params }: PageProps) => {
+const Page = async ({ params: _params }: PageProps) => {
const t = await getTranslate();
+ const params = await _params;
const id = typeof params?.id === "string" ? params.id : undefined;
const webhook = await WebhookRepository.findByWebhookId(id);
diff --git a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/layout.tsx b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/layout.tsx
index b6ec56f778..b19a991418 100644
--- a/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/layout.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/(settings-layout)/layout.tsx
@@ -12,7 +12,7 @@ import SettingsLayoutAppDirClient from "./SettingsLayoutAppDirClient";
type SettingsLayoutAppDirProps = Omit;
export default async function SettingsLayoutAppDir(props: SettingsLayoutAppDirProps) {
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
const userId = session?.user?.id ?? -1;
const orgId = session?.user?.org?.id ?? -1;
diff --git a/apps/web/app/(use-page-wrapper)/settings/license-key/new/page.tsx b/apps/web/app/(use-page-wrapper)/settings/license-key/new/page.tsx
index 09d4940017..5a385244c6 100644
--- a/apps/web/app/(use-page-wrapper)/settings/license-key/new/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/license-key/new/page.tsx
@@ -19,7 +19,7 @@ export const generateMetadata = async () =>
const getData = withAppDirSsr>(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ await getData(buildLegacyCtx(await headers(), await cookies(), await params, await searchParams));
return (
diff --git a/apps/web/app/(use-page-wrapper)/settings/organizations/new/about/page.tsx b/apps/web/app/(use-page-wrapper)/settings/organizations/new/about/page.tsx
index ba189104c8..d7f855f431 100644
--- a/apps/web/app/(use-page-wrapper)/settings/organizations/new/about/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/organizations/new/about/page.tsx
@@ -17,7 +17,7 @@ export const generateMetadata = async () =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ await getData(buildLegacyCtx(await headers(), await cookies(), await params, await searchParams));
return (
diff --git a/apps/web/app/(use-page-wrapper)/settings/organizations/new/add-teams/page.tsx b/apps/web/app/(use-page-wrapper)/settings/organizations/new/add-teams/page.tsx
index 21c90a9430..b581f9864a 100644
--- a/apps/web/app/(use-page-wrapper)/settings/organizations/new/add-teams/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/organizations/new/add-teams/page.tsx
@@ -17,7 +17,7 @@ export const generateMetadata = async () =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ await getData(buildLegacyCtx(await headers(), await cookies(), await params, await searchParams));
return (
diff --git a/apps/web/app/(use-page-wrapper)/settings/organizations/new/handover/page.tsx b/apps/web/app/(use-page-wrapper)/settings/organizations/new/handover/page.tsx
index d5b06be456..eee663e5e7 100644
--- a/apps/web/app/(use-page-wrapper)/settings/organizations/new/handover/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/organizations/new/handover/page.tsx
@@ -18,7 +18,7 @@ export const generateMetadata = async () =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ await getData(buildLegacyCtx(await headers(), await cookies(), await params, await searchParams));
return (
diff --git a/apps/web/app/(use-page-wrapper)/settings/organizations/new/onboard-members/page.tsx b/apps/web/app/(use-page-wrapper)/settings/organizations/new/onboard-members/page.tsx
index d6aff7cb95..c99c48c497 100644
--- a/apps/web/app/(use-page-wrapper)/settings/organizations/new/onboard-members/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/organizations/new/onboard-members/page.tsx
@@ -17,7 +17,7 @@ export const generateMetadata = async () =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ await getData(buildLegacyCtx(await headers(), await cookies(), await params, await searchParams));
return (
diff --git a/apps/web/app/(use-page-wrapper)/settings/organizations/new/page.tsx b/apps/web/app/(use-page-wrapper)/settings/organizations/new/page.tsx
index 96da7ee472..d5b7ffd45f 100644
--- a/apps/web/app/(use-page-wrapper)/settings/organizations/new/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/organizations/new/page.tsx
@@ -23,7 +23,7 @@ type Props = {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ await getData(buildLegacyCtx(await headers(), await cookies(), await params, await searchParams));
return (
diff --git a/apps/web/app/(use-page-wrapper)/settings/organizations/new/status/page.tsx b/apps/web/app/(use-page-wrapper)/settings/organizations/new/status/page.tsx
index 69967aecd2..07879c2e39 100644
--- a/apps/web/app/(use-page-wrapper)/settings/organizations/new/status/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/organizations/new/status/page.tsx
@@ -17,7 +17,7 @@ export const generateMetadata = async () =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ await getData(buildLegacyCtx(await headers(), await cookies(), await params, await searchParams));
return (
diff --git a/apps/web/app/(use-page-wrapper)/settings/platform/new/page.tsx b/apps/web/app/(use-page-wrapper)/settings/platform/new/page.tsx
index d338805430..c1086eab92 100644
--- a/apps/web/app/(use-page-wrapper)/settings/platform/new/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/settings/platform/new/page.tsx
@@ -23,7 +23,7 @@ export const generateMetadata = async () =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- await getData(buildLegacyCtx(headers(), cookies(), params, searchParams));
+ await getData(buildLegacyCtx(await headers(), await cookies(), await params, await searchParams));
return (
diff --git a/apps/web/app/(use-page-wrapper)/signup/page.tsx b/apps/web/app/(use-page-wrapper)/signup/page.tsx
index afbb38cc80..284f821bc6 100644
--- a/apps/web/app/(use-page-wrapper)/signup/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/signup/page.tsx
@@ -18,7 +18,7 @@ export const generateMetadata = async () =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: PageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/video/[uid]/page.tsx b/apps/web/app/(use-page-wrapper)/video/[uid]/page.tsx
index 4e034265dc..3c525b0e5b 100644
--- a/apps/web/app/(use-page-wrapper)/video/[uid]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/video/[uid]/page.tsx
@@ -39,7 +39,7 @@ export const generateMetadata = async () => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/video/meeting-ended/[uid]/page.tsx b/apps/web/app/(use-page-wrapper)/video/meeting-ended/[uid]/page.tsx
index 89d44c95ff..ec528848d3 100644
--- a/apps/web/app/(use-page-wrapper)/video/meeting-ended/[uid]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/video/meeting-ended/[uid]/page.tsx
@@ -18,7 +18,7 @@ export const generateMetadata = async () =>
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/video/meeting-not-started/[uid]/page.tsx b/apps/web/app/(use-page-wrapper)/video/meeting-not-started/[uid]/page.tsx
index c31aec6264..a2464ca46e 100644
--- a/apps/web/app/(use-page-wrapper)/video/meeting-not-started/[uid]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/video/meeting-not-started/[uid]/page.tsx
@@ -18,7 +18,7 @@ const querySchema = z.object({
});
export const generateMetadata = async ({ params }: ServerPageProps) => {
- const parsed = querySchema.safeParse(params);
+ const parsed = querySchema.safeParse(await params);
if (!parsed.success) {
notFound();
}
@@ -35,7 +35,7 @@ export const generateMetadata = async ({ params }: ServerPageProps) => {
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async ({ params, searchParams }: ServerPageProps) => {
- const context = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
return ;
diff --git a/apps/web/app/(use-page-wrapper)/workflows/[workflow]/page.tsx b/apps/web/app/(use-page-wrapper)/workflows/[workflow]/page.tsx
index eafa40c528..5d1dcda480 100644
--- a/apps/web/app/(use-page-wrapper)/workflows/[workflow]/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/workflows/[workflow]/page.tsx
@@ -23,7 +23,7 @@ const querySchema = z.object({
const getWorkflow = cache((id: number) => WorkflowRepository.getById({ id }));
export const generateMetadata = async ({ params }: PageProps): Promise => {
- const parsed = querySchema.safeParse(params);
+ const parsed = querySchema.safeParse(await params);
if (!parsed.success) {
notFound();
}
@@ -38,9 +38,9 @@ export const generateMetadata = async ({ params }: PageProps): Promise {
- // const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ // const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
// const user = session?.user;
- const parsed = querySchema.safeParse(params);
+ const parsed = querySchema.safeParse(await params);
if (!parsed.success) {
notFound();
}
diff --git a/apps/web/app/(use-page-wrapper)/workflows/page.tsx b/apps/web/app/(use-page-wrapper)/workflows/page.tsx
index cdf5b195f7..cf89ad25b2 100644
--- a/apps/web/app/(use-page-wrapper)/workflows/page.tsx
+++ b/apps/web/app/(use-page-wrapper)/workflows/page.tsx
@@ -15,7 +15,7 @@ export const generateMetadata = async () =>
);
const Page = async ({ params, searchParams }: PageProps) => {
- // const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ // const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
// const user = session?.user;
// const filters = getTeamsFiltersFromQuery({ ...searchParams, ...params });
diff --git a/apps/web/app/_types.ts b/apps/web/app/_types.ts
index 0e6ce75a13..a90eaae620 100644
--- a/apps/web/app/_types.ts
+++ b/apps/web/app/_types.ts
@@ -7,8 +7,8 @@ export type SearchParams = {
};
export type PageProps = {
- params: Params;
- searchParams: SearchParams;
+ params: Promise;
+ searchParams: Promise;
};
-export type LayoutProps = { params: Params; children: React.ReactElement };
+export type LayoutProps = { params: Promise; children: React.ReactElement };
diff --git a/apps/web/app/_utils.tsx b/apps/web/app/_utils.tsx
index 3331e452bc..1884e95010 100644
--- a/apps/web/app/_utils.tsx
+++ b/apps/web/app/_utils.tsx
@@ -1,6 +1,4 @@
import { type TFunction } from "i18next";
-import i18next from "i18next";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { cookies, headers } from "next/headers";
import { getLocale } from "@calcom/features/auth/lib/getLocale";
@@ -8,48 +6,19 @@ import type { AppImageProps, MeetingImageProps } from "@calcom/lib/OgImages";
import { constructAppImage, constructGenericImage, constructMeetingImage } from "@calcom/lib/OgImages";
import { IS_CALCOM, WEBAPP_URL, APP_NAME, SEO_IMG_OGIMG, CAL_URL } from "@calcom/lib/constants";
import { buildCanonical } from "@calcom/lib/next-seo.config";
+import { getTranslation } from "@calcom/lib/server/i18n";
import { truncateOnWord } from "@calcom/lib/text";
-//@ts-expect-error no type definitions
-import config from "@calcom/web/next-i18next.config";
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
-const i18nInstanceCache: Record = {};
-
-const createI18nInstance = async (locale: string, ns: string) => {
- const cacheKey = `${locale}-${ns}`;
- // Check module-level cache first
- if (i18nInstanceCache[cacheKey]) {
- return i18nInstanceCache[cacheKey];
- }
-
- const { _nextI18Next } = await serverSideTranslations(locale, [ns], config);
-
- const _i18n = i18next.createInstance();
- await _i18n.init({
- lng: locale,
- resources: _nextI18Next?.initialI18nStore,
- fallbackLng: _nextI18Next?.userConfig?.i18n.defaultLocale,
- });
-
- // Cache the instance
- i18nInstanceCache[cacheKey] = _i18n;
- return _i18n;
-};
-
-const getTranslationWithCache = async (locale: string, ns = "common") => {
- const localeWithFallback = locale ?? "en";
- const i18n = await createI18nInstance(localeWithFallback, ns);
- return i18n.getFixedT(localeWithFallback, ns);
-};
-
export const getTranslate = async () => {
const headersList = await headers();
// If "x-locale" does not exist in header,
// ensure that config.matcher in middleware includes the page you are testing
- const locale = headersList.get("x-locale") ?? (await getLocale(buildLegacyRequest(headersList, cookies())));
- const t = await getTranslationWithCache(locale ?? "en");
- return t;
+ const locale =
+ headersList.get("x-locale") ?? (await getLocale(buildLegacyRequest(headersList, await cookies())));
+
+ return await getTranslation(locale ?? "en", "common");
};
const _generateMetadataWithoutImage = async (
@@ -59,11 +28,10 @@ const _generateMetadataWithoutImage = async (
origin?: string,
pathname?: string
) => {
- const h = headers();
+ const h = await headers();
const _pathname = h.get("x-pathname") ?? pathname ?? "";
const canonical = buildCanonical({ path: _pathname, origin: origin ?? CAL_URL });
- const locale = h.get("x-locale") ?? (await getLocale(buildLegacyRequest(h, cookies()))) ?? "en";
- const t = await getTranslationWithCache(locale);
+ const t = await getTranslate();
const title = getTitle(t);
const description = getDescription(t);
diff --git a/apps/web/app/api/auth/two-factor/totp/disable/route.ts b/apps/web/app/api/auth/two-factor/totp/disable/route.ts
index 4fe6507d9c..ce0551be13 100644
--- a/apps/web/app/api/auth/two-factor/totp/disable/route.ts
+++ b/apps/web/app/api/auth/two-factor/totp/disable/route.ts
@@ -16,7 +16,7 @@ import { buildLegacyRequest } from "@lib/buildLegacyCtx";
async function handler(req: NextRequest) {
const body = await parseRequestData(req);
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
if (!session) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 });
diff --git a/apps/web/app/api/auth/two-factor/totp/enable/route.ts b/apps/web/app/api/auth/two-factor/totp/enable/route.ts
index 07551665b4..79409e3ae4 100644
--- a/apps/web/app/api/auth/two-factor/totp/enable/route.ts
+++ b/apps/web/app/api/auth/two-factor/totp/enable/route.ts
@@ -14,7 +14,7 @@ import { buildLegacyRequest } from "@lib/buildLegacyCtx";
async function postHandler(req: NextRequest) {
const body = await parseRequestData(req);
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
if (!session) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 });
diff --git a/apps/web/app/api/auth/two-factor/totp/setup/route.ts b/apps/web/app/api/auth/two-factor/totp/setup/route.ts
index cfd8fc4a5d..ea665ef1dd 100644
--- a/apps/web/app/api/auth/two-factor/totp/setup/route.ts
+++ b/apps/web/app/api/auth/two-factor/totp/setup/route.ts
@@ -18,7 +18,7 @@ import { buildLegacyRequest } from "@lib/buildLegacyCtx";
async function postHandler(req: NextRequest) {
const body = await parseRequestData(req);
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
if (!session) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 });
diff --git a/apps/web/app/api/availability/calendar/route.ts b/apps/web/app/api/availability/calendar/route.ts
index 08cdae820a..23bd9840bd 100644
--- a/apps/web/app/api/availability/calendar/route.ts
+++ b/apps/web/app/api/availability/calendar/route.ts
@@ -23,7 +23,7 @@ const selectedCalendarSelectSchema = z.object({
});
async function authMiddleware() {
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
if (!session?.user?.id) {
throw new HttpError({ statusCode: 401, message: "Not authenticated" });
diff --git a/apps/web/app/api/avatar/[uuid]/route.ts b/apps/web/app/api/avatar/[uuid]/route.ts
index 1ec20964d0..ccd746d2d6 100644
--- a/apps/web/app/api/avatar/[uuid]/route.ts
+++ b/apps/web/app/api/avatar/[uuid]/route.ts
@@ -26,8 +26,8 @@ const handleValidationError = (error: z.ZodError): NextResponse => {
);
};
-async function handler(req: NextRequest, { params }: { params: Params }) {
- const result = querySchema.safeParse(params);
+async function handler(req: NextRequest, { params }: { params: Promise }) {
+ const result = querySchema.safeParse(await params);
if (!result.success) {
return handleValidationError(result.error);
}
diff --git a/apps/web/app/api/cancel/route.ts b/apps/web/app/api/cancel/route.ts
index be30753fee..32bd1e8096 100644
--- a/apps/web/app/api/cancel/route.ts
+++ b/apps/web/app/api/cancel/route.ts
@@ -15,7 +15,7 @@ async function handler(req: NextRequest) {
} catch (error) {
return NextResponse.json({ success: false, message: "Invalid JSON" }, { status: 400 });
}
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
const result = await handleCancelBooking({
appDirRequestBody,
userId: session?.user?.id || -1,
diff --git a/apps/web/app/api/customer-card/route.ts b/apps/web/app/api/customer-card/route.ts
index b4a1de8266..4f50541985 100644
--- a/apps/web/app/api/customer-card/route.ts
+++ b/apps/web/app/api/customer-card/route.ts
@@ -457,7 +457,7 @@ const inputSchema = z.object({
});
async function handler(request: NextRequest) {
- const headersList = headers();
+ const headersList = await headers();
const requestBody = await request.json();
// HMAC verification
diff --git a/apps/web/app/api/defaultResponderForAppDir.test.ts b/apps/web/app/api/defaultResponderForAppDir.test.ts
index 704d5a4c14..b30afb0dae 100644
--- a/apps/web/app/api/defaultResponderForAppDir.test.ts
+++ b/apps/web/app/api/defaultResponderForAppDir.test.ts
@@ -1,3 +1,4 @@
+import type { Params } from "app/_types";
import { NextResponse, type NextRequest } from "next/server";
import { describe, expect, it, vi } from "vitest";
@@ -21,7 +22,7 @@ describe("defaultResponderForAppDir", () => {
it("should return a JSON response when handler resolves with a result", async () => {
const f = vi.fn().mockResolvedValue(NextResponse.json({ success: true }));
const req = { method: "GET", url: "/api/test" } as unknown as NextRequest;
- const params = {};
+ const params = Promise.resolve({})
const response = await defaultResponderForAppDir(f)(req, { params });
const json = await response.json();
@@ -33,7 +34,7 @@ describe("defaultResponderForAppDir", () => {
it("should return an empty JSON response when handler resolves with no result", async () => {
const f = vi.fn().mockResolvedValue(null);
const req = { method: "GET", url: "/api/test" } as unknown as NextRequest;
- const params = {};
+ const params = Promise.resolve({})
const response = await defaultResponderForAppDir(f)(req, { params });
const json = await response.json();
@@ -45,7 +46,7 @@ describe("defaultResponderForAppDir", () => {
it("should respond with status code 409 for NoAvailableUsersFound", async () => {
const f = vi.fn().mockRejectedValue(new Error(ErrorCode.NoAvailableUsersFound));
const req = { method: "GET", url: "/api/test" } as unknown as NextRequest;
- const params = {};
+ const params = Promise.resolve({})
const response = await defaultResponderForAppDir(f)(req, { params });
const json = await response.json();
@@ -61,7 +62,7 @@ describe("defaultResponderForAppDir", () => {
it("should respond with a 429 status code for rate limit errors", async () => {
const f = vi.fn().mockRejectedValue(new TRPCError({ code: "TOO_MANY_REQUESTS" }));
const req = { method: "POST", url: "/api/test" } as unknown as NextRequest;
- const params = {};
+ const params = Promise.resolve({})
const response = await defaultResponderForAppDir(f)(req, { params });
const json = await response.json();
diff --git a/apps/web/app/api/defaultResponderForAppDir.ts b/apps/web/app/api/defaultResponderForAppDir.ts
index 1531254b55..7b72874ec2 100644
--- a/apps/web/app/api/defaultResponderForAppDir.ts
+++ b/apps/web/app/api/defaultResponderForAppDir.ts
@@ -9,14 +9,14 @@ import { performance } from "@calcom/lib/server/perfObserver";
type Handler = (
req: NextRequest,
- { params }: { params: Params }
+ { params }: { params: Promise }
) => Promise;
export const defaultResponderForAppDir = (
handler: Handler,
endpointRoute?: string
) => {
- return async (req: NextRequest, { params }: { params: Params }) => {
+ return async (req: NextRequest, { params }: { params: Promise }) => {
let ok = false;
try {
performance.mark("Start");
diff --git a/apps/web/app/api/future-opt-in/route.ts b/apps/web/app/api/future-opt-in/route.ts
deleted file mode 100644
index 86ebab38b7..0000000000
--- a/apps/web/app/api/future-opt-in/route.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import { defaultResponderForAppDir } from "app/api/defaultResponderForAppDir";
-import { cookies, headers } from "next/headers";
-import { NextResponse } from "next/server";
-
-import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
-import { FUTURE_ROUTES_OVERRIDE_COOKIE_NAME as COOKIE_NAME } from "@calcom/lib/constants";
-
-import { buildLegacyRequest } from "@lib/buildLegacyCtx";
-
-async function getHandler() {
- const headersList = headers();
- const cookiesList = cookies();
- const legacyReq = buildLegacyRequest(headersList, cookiesList);
-
- const session = await getServerSession({ req: legacyReq });
-
- if (!session || !session.user || !session.user.email) {
- return NextResponse.json({ message: "Not authenticated" }, { status: 401 });
- }
-
- let redirectUrl = "/";
-
- // We take you back where you came from if possible
- const referer = headersList.get("referer");
- if (referer) redirectUrl = referer;
-
- const response = NextResponse.redirect(redirectUrl);
-
- // If has the cookie, Opt-out of V2
- if (cookiesList.has(COOKIE_NAME) && cookiesList.get(COOKIE_NAME)?.value === "1") {
- response.cookies.set(COOKIE_NAME, "0", { maxAge: 0, path: "/" });
- } else {
- /* Opt-in to V2 */
- response.cookies.set(COOKIE_NAME, "1", { path: "/" });
- }
-
- return response;
-}
-
-export const GET = defaultResponderForAppDir(getHandler);
diff --git a/apps/web/app/api/generate-referral-link/route.ts b/apps/web/app/api/generate-referral-link/route.ts
index 6649b2c614..1390060a39 100644
--- a/apps/web/app/api/generate-referral-link/route.ts
+++ b/apps/web/app/api/generate-referral-link/route.ts
@@ -9,8 +9,8 @@ import prisma from "@calcom/prisma";
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
async function postHandler() {
- const headersList = headers();
- const cookiesList = cookies();
+ const headersList = await headers();
+ const cookiesList = await cookies();
const legacyReq = buildLegacyRequest(headersList, cookiesList);
const session = await getServerSession({ req: legacyReq });
diff --git a/apps/web/app/api/geolocation/route.ts b/apps/web/app/api/geolocation/route.ts
index 46c2b38587..1aa8215360 100644
--- a/apps/web/app/api/geolocation/route.ts
+++ b/apps/web/app/api/geolocation/route.ts
@@ -3,7 +3,7 @@ import { headers } from "next/headers";
import { NextResponse } from "next/server";
async function getHandler() {
- const headersList = headers();
+ const headersList = await headers();
const country = headersList.get("x-vercel-ip-country") || "Unknown";
const response = NextResponse.json({ country });
diff --git a/apps/web/app/api/intercom-hash/route.ts b/apps/web/app/api/intercom-hash/route.ts
index 35d01feab2..403e517429 100644
--- a/apps/web/app/api/intercom-hash/route.ts
+++ b/apps/web/app/api/intercom-hash/route.ts
@@ -8,8 +8,8 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
async function getHandler() {
- const headersList = headers();
- const cookiesList = cookies();
+ const headersList = await headers();
+ const cookiesList = await cookies();
const legacyReq = buildLegacyRequest(headersList, cookiesList);
const session = await getServerSession({ req: legacyReq });
diff --git a/apps/web/app/api/link/route.ts b/apps/web/app/api/link/route.ts
index 1efc9b1e40..eea61cebb1 100644
--- a/apps/web/app/api/link/route.ts
+++ b/apps/web/app/api/link/route.ts
@@ -79,7 +79,7 @@ async function handler(request: NextRequest) {
try {
/** @see https://trpc.io/docs/server-side-calls */
// Create a legacy request object for compatibility
- const legacyReq = buildLegacyRequest(headers(), cookies());
+ const legacyReq = buildLegacyRequest(await headers(), await cookies());
const res = {} as any; // Response is still mocked as it's not used in this context
const ctx = await createContext({ req: legacyReq, res }, sessionGetter);
diff --git a/apps/web/app/api/logo/route.ts b/apps/web/app/api/logo/route.ts
index 3fccb28427..8dd9fbd86d 100644
--- a/apps/web/app/api/logo/route.ts
+++ b/apps/web/app/api/logo/route.ts
@@ -168,7 +168,7 @@ async function getHandler(request: NextRequest) {
const parsedQuery = logoApiSchema.parse(Object.fromEntries(searchParams.entries()));
// Create a legacy request object for compatibility
- const legacyReq = buildLegacyRequest(headers(), cookies());
+ const legacyReq = buildLegacyRequest(await headers(), await cookies());
const { isValidOrgDomain } = orgDomainConfig(legacyReq);
const hostname = request.headers.get("host");
diff --git a/apps/web/app/api/me/route.ts b/apps/web/app/api/me/route.ts
index 7e8d816d05..55761a3bed 100644
--- a/apps/web/app/api/me/route.ts
+++ b/apps/web/app/api/me/route.ts
@@ -15,7 +15,7 @@ async function getHandler() {
const preSessionDate = performance.now();
// Create a legacy request object for compatibility
- const legacyReq = buildLegacyRequest(headers(), cookies());
+ const legacyReq = buildLegacyRequest(await headers(), await cookies());
const session = await getServerSession({ req: legacyReq });
if (!session) {
diff --git a/apps/web/app/api/plain-hash/route.ts b/apps/web/app/api/plain-hash/route.ts
index 2ff7bca488..6a239a7c5f 100644
--- a/apps/web/app/api/plain-hash/route.ts
+++ b/apps/web/app/api/plain-hash/route.ts
@@ -26,7 +26,7 @@ async function handler() {
return NextResponse.json({ error: "Plain Chat is not enabled" }, { status: 404 });
}
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
if (!session?.user?.email) {
return NextResponse.json({ error: "Unauthorized - No session email found" }, { status: 401 });
}
diff --git a/apps/web/app/api/recorded-daily-video/route.ts b/apps/web/app/api/recorded-daily-video/route.ts
index fd583fd185..72e8c92c90 100644
--- a/apps/web/app/api/recorded-daily-video/route.ts
+++ b/apps/web/app/api/recorded-daily-video/route.ts
@@ -62,7 +62,7 @@ export async function postHandler(request: NextRequest) {
return NextResponse.json({ message: "Test request successful" });
}
- const headersList = headers();
+ const headersList = await headers();
const testMode = process.env.NEXT_PUBLIC_IS_E2E || process.env.INTEGRATION_TEST_MODE;
if (!testMode) {
diff --git a/apps/web/app/api/scim/v2.0/[...directory]/route.ts b/apps/web/app/api/scim/v2.0/[...directory]/route.ts
index eb52d8433f..b4f27291c3 100644
--- a/apps/web/app/api/scim/v2.0/[...directory]/route.ts
+++ b/apps/web/app/api/scim/v2.0/[...directory]/route.ts
@@ -1,7 +1,9 @@
import type { DirectorySyncEvent, DirectorySyncRequest } from "@boxyhq/saml-jackson";
+import type { Params } from "app/_types";
import { defaultResponderForAppDir } from "app/api/defaultResponderForAppDir";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
+import { z } from "zod";
import handleGroupEvents from "@calcom/features/ee/dsync/lib/handleGroupEvents";
import handleUserEvents from "@calcom/features/ee/dsync/lib/handleUserEvents";
@@ -51,35 +53,40 @@ const handleEvents = async (event: DirectorySyncEvent) => {
}
};
+const querySchema = z.object({
+ directory: z.string().array(),
+});
+
// This is the handler for the SCIM API requests
-async function getHandler(request: NextRequest, { params }: { params: { directory?: string[] } }) {
- return handleScimRequest(request, "GET", params.directory);
+async function getHandler(request: NextRequest, { params }: { params: Promise }) {
+ return handleScimRequest(request, "GET", params);
}
-async function postHandler(request: NextRequest, { params }: { params: { directory?: string[] } }) {
- return handleScimRequest(request, "POST", params.directory);
+async function postHandler(request: NextRequest, { params }: { params: Promise }) {
+ return handleScimRequest(request, "POST", params);
}
-async function putHandler(request: NextRequest, { params }: { params: { directory?: string[] } }) {
- return handleScimRequest(request, "PUT", params.directory);
+async function putHandler(request: NextRequest, { params }: { params: Promise }) {
+ return handleScimRequest(request, "PUT", params);
}
-async function patchHandler(request: NextRequest, { params }: { params: { directory?: string[] } }) {
- return handleScimRequest(request, "PATCH", params.directory);
+async function patchHandler(request: NextRequest, { params }: { params: Promise }) {
+ return handleScimRequest(request, "PATCH", params);
}
-async function deleteHandler(request: NextRequest, { params }: { params: { directory?: string[] } }) {
- return handleScimRequest(request, "DELETE", params.directory);
+async function deleteHandler(request: NextRequest, { params }: { params: Promise }) {
+ return handleScimRequest(request, "DELETE", params);
}
-async function handleScimRequest(request: NextRequest, method: string, directoryParams?: string[]) {
- const { dsyncController } = await jackson();
-
- if (!directoryParams || directoryParams.length === 0) {
+async function handleScimRequest(request: NextRequest, method: string, params: Promise) {
+ const parsed = querySchema.safeParse(await params);
+ if (!parsed.success || parsed.data.directory.length === 0) {
return NextResponse.json({ error: "Missing directory parameters" }, { status: 400 });
}
- const [directoryId, path, resourceId] = directoryParams;
+ const { dsyncController } = await jackson();
+
+ const [directoryId, path, resourceId] = parsed.data.directory;
const shouldLog = DIRECTORY_IDS_TO_LOG.includes(directoryId);
const searchParams = request.nextUrl.searchParams;
@@ -90,7 +97,7 @@ async function handleScimRequest(request: NextRequest, method: string, directory
safeStringify({
method,
url: request.url,
- params: directoryParams,
+ params: parsed.data.directory,
searchParams: Object.fromEntries(searchParams.entries()),
body: request.body
? await request
diff --git a/apps/web/app/api/social/og/image/route.tsx b/apps/web/app/api/social/og/image/route.tsx
index 0f171742f0..6e100d795b 100644
--- a/apps/web/app/api/social/og/image/route.tsx
+++ b/apps/web/app/api/social/og/image/route.tsx
@@ -1,19 +1,11 @@
+import { ImageResponse } from "next/og";
import type { NextRequest } from "next/server";
-import { ImageResponse } from "next/server";
import type { SatoriOptions } from "satori";
import { z } from "zod";
import { Meeting, App, Generic } from "@calcom/lib/OgImages";
import { WEBAPP_URL } from "@calcom/lib/constants";
-const calFont = fetch(new URL("/fonts/cal.ttf", WEBAPP_URL)).then((res) => res.arrayBuffer());
-
-const interFont = fetch(new URL("/fonts/Inter-Regular.ttf", WEBAPP_URL)).then((res) => res.arrayBuffer());
-
-const interFontMedium = fetch(new URL("/fonts/Inter-Medium.ttf", WEBAPP_URL)).then((res) =>
- res.arrayBuffer()
-);
-
export const runtime = "edge";
const meetingSchema = z.object({
@@ -43,9 +35,9 @@ async function handler(req: NextRequest) {
const imageType = searchParams.get("type");
const [calFontData, interFontData, interFontMediumData] = await Promise.all([
- calFont,
- interFont,
- interFontMedium,
+ fetch(new URL("/fonts/cal.ttf", WEBAPP_URL)).then((res) => res.arrayBuffer()),
+ fetch(new URL("/fonts/Inter-Regular.ttf", WEBAPP_URL)).then((res) => res.arrayBuffer()),
+ fetch(new URL("/fonts/Inter-Medium.ttf", WEBAPP_URL)).then((res) => res.arrayBuffer()),
]);
const ogConfig = {
width: 1200,
diff --git a/apps/web/app/api/sync/helpscout/route.ts b/apps/web/app/api/sync/helpscout/route.ts
index c8ad361de0..1b4f5f0a9b 100644
--- a/apps/web/app/api/sync/helpscout/route.ts
+++ b/apps/web/app/api/sync/helpscout/route.ts
@@ -29,7 +29,7 @@ async function postHandler(request: NextRequest) {
if (!process.env.CALENDSO_ENCRYPTION_KEY)
return NextResponse.json({ message: "Missing encryption key" }, { status: 500 });
- const legacyRequest = buildLegacyRequest(headers(), cookies());
+ const legacyRequest = buildLegacyRequest(await headers(), await cookies());
// Get the raw request body
const rawBody = await getRawBody(legacyRequest);
diff --git a/apps/web/app/api/teams/[team]/upgrade/route.ts b/apps/web/app/api/teams/[team]/upgrade/route.ts
index cd0ebcec36..1f8b2eef01 100644
--- a/apps/web/app/api/teams/[team]/upgrade/route.ts
+++ b/apps/web/app/api/teams/[team]/upgrade/route.ts
@@ -21,11 +21,11 @@ const querySchema = z.object({
session_id: z.string().min(1),
});
-async function getHandler(req: NextRequest, { params }: { params: Params }) {
+async function getHandler(req: NextRequest, { params }: { params: Promise }) {
try {
const searchParams = req.nextUrl.searchParams;
const { team: id, session_id } = querySchema.parse({
- team: params.team,
+ team: (await params).team,
session_id: searchParams.get("session_id"),
});
@@ -86,7 +86,7 @@ async function getHandler(req: NextRequest, { params }: { params: Params }) {
}
}
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
if (!session) {
return NextResponse.json({ message: "Team upgraded successfully" });
diff --git a/apps/web/app/api/teams/googleworkspace/callback/route.ts b/apps/web/app/api/teams/googleworkspace/callback/route.ts
index b17b9adb22..89c72311a7 100644
--- a/apps/web/app/api/teams/googleworkspace/callback/route.ts
+++ b/apps/web/app/api/teams/googleworkspace/callback/route.ts
@@ -20,8 +20,8 @@ const stateSchema = z.object({
async function getHandler(request: NextRequest) {
try {
- const headersList = headers();
- const cookiesList = cookies();
+ const headersList = await headers();
+ const cookiesList = await cookies();
const legacyReq = buildLegacyRequest(headersList, cookiesList);
const session = await getServerSession({ req: legacyReq });
diff --git a/apps/web/app/api/username/route.ts b/apps/web/app/api/username/route.ts
index 10d123ecc5..26e399e692 100644
--- a/apps/web/app/api/username/route.ts
+++ b/apps/web/app/api/username/route.ts
@@ -19,7 +19,7 @@ async function postHandler(request: NextRequest) {
const body = await request.json();
const { username, orgSlug } = bodySchema.parse(body);
- const legacyReq = buildLegacyRequest(headers(), cookies());
+ const legacyReq = buildLegacyRequest(await headers(), await cookies());
// Get current org domain from request headers
const { currentOrgDomain } = orgDomainConfig(legacyReq);
diff --git a/apps/web/app/api/verify-booking-token/route.ts b/apps/web/app/api/verify-booking-token/route.ts
index 5fcba32d2f..3ecf29775d 100644
--- a/apps/web/app/api/verify-booking-token/route.ts
+++ b/apps/web/app/api/verify-booking-token/route.ts
@@ -118,7 +118,7 @@ async function handleBookingAction(
const createCaller = createCallerFactory(bookingsRouter);
// Use buildLegacyRequest to create a request object compatible with Pages Router
- const legacyReq = request ? buildLegacyRequest(headers(), cookies()) : ({} as any);
+ const legacyReq = request ? buildLegacyRequest(await headers(), await cookies()) : ({} as any);
const res = {} as any;
const ctx = await createContext({ req: legacyReq, res }, sessionGetter);
diff --git a/apps/web/app/icons/page.tsx b/apps/web/app/icons/page.tsx
index e8203e3aa4..e23250edc1 100644
--- a/apps/web/app/icons/page.tsx
+++ b/apps/web/app/icons/page.tsx
@@ -44,4 +44,3 @@ export default async function IconsPage() {
);
}
-export const dynamic = "force-static";
diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx
index e903ed22c6..1744aeed95 100644
--- a/apps/web/app/layout.tsx
+++ b/apps/web/app/layout.tsx
@@ -9,7 +9,6 @@ import { IconSprites } from "@calcom/ui/components/icon";
import { NotificationSoundHandler } from "@calcom/web/components/notification-sound-handler";
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
-import { prepareRootMetadata } from "@lib/metadata";
import { ssrInit } from "@server/lib/ssr";
@@ -26,7 +25,60 @@ const calFont = localFont({
weight: "600",
});
-export const generateMetadata = () => prepareRootMetadata();
+export const viewport = {
+ width: "device-width",
+ initialScale: 1.0,
+ maximumScale: 1.0,
+ userScalable: false,
+ viewportFit: "cover",
+ themeColor: [
+ {
+ media: "(prefers-color-scheme: light)",
+ color: "#f9fafb",
+ },
+ {
+ media: "(prefers-color-scheme: dark)",
+ color: "#1C1C1C",
+ },
+ ],
+};
+
+export const metadata = {
+ icons: {
+ icon: "/favicon.ico",
+ apple: "/api/logo?type=apple-touch-icon",
+ other: [
+ {
+ rel: "icon-mask",
+ url: "/safari-pinned-tab.svg",
+ color: "#000000",
+ },
+ {
+ url: "/api/logo?type=favicon-16",
+ sizes: "16x16",
+ type: "image/png",
+ },
+ {
+ url: "/api/logo?type=favicon-32",
+ sizes: "32x32",
+ type: "image/png",
+ },
+ ],
+ },
+ manifest: "/site.webmanifest",
+ other: {
+ "application-TileColor": "#ff0000",
+ },
+ twitter: {
+ site: "@calcom",
+ creator: "@calcom",
+ card: "summary_large_image",
+ },
+ robots: {
+ index: true,
+ follow: true,
+ },
+};
const getInitialProps = async (url: string) => {
const { pathname, searchParams } = new URL(url);
@@ -34,7 +86,7 @@ const getInitialProps = async (url: string) => {
const isEmbed = pathname.endsWith("/embed") || (searchParams?.get("embedType") ?? null) !== null;
const embedColorScheme = searchParams?.get("ui.color-scheme");
- const req = { headers: headers(), cookies: cookies() };
+ const req = { headers: await headers(), cookies: await cookies() };
const newLocale = await getLocale(req);
const direction = dir(newLocale);
@@ -49,7 +101,7 @@ const getFallbackProps = () => ({
});
export default async function RootLayout({ children }: { children: React.ReactNode }) {
- const h = headers();
+ const h = await headers();
const fullUrl = h.get("x-url") ?? "";
const nonce = h.get("x-csp") ?? "";
@@ -60,7 +112,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
? getFallbackProps()
: await getInitialProps(fullUrl);
- const ssr = await ssrInit(buildLegacyCtx(h, cookies(), {}, {}));
+ const ssr = await ssrInit(buildLegacyCtx(h, await cookies(), {}, {}));
return (
{
- const headersList = headers();
+ const headersList = await headers();
const pathname = headersList.get("x-pathname") ?? "";
const isInsights = pathname?.startsWith("/insights");
@@ -243,7 +243,7 @@ export const generateMetadata = async () => {
const ServerPage = async () => {
const t = await getTranslate();
- const h = headers();
+ const h = await headers();
const nonce = h.get("x-nonce") ?? undefined;
return (
diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx
index 6af803e9b2..95d99df6d9 100644
--- a/apps/web/app/page.tsx
+++ b/apps/web/app/page.tsx
@@ -6,7 +6,7 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
const RedirectPage = async () => {
- const session = await getServerSession({ req: buildLegacyRequest(headers(), cookies()) });
+ const session = await getServerSession({ req: buildLegacyRequest(await headers(), await cookies()) });
if (!session?.user?.id) {
redirect("/auth/login");
diff --git a/apps/web/app/reschedule/[uid]/embed/page.tsx b/apps/web/app/reschedule/[uid]/embed/page.tsx
index efc98cafb0..676f3ce290 100644
--- a/apps/web/app/reschedule/[uid]/embed/page.tsx
+++ b/apps/web/app/reschedule/[uid]/embed/page.tsx
@@ -8,7 +8,7 @@ import { getServerSideProps } from "@lib/reschedule/[uid]/getServerSideProps";
const getEmbedData = withEmbedSsrAppDir(getServerSideProps);
const Page = async ({ params, searchParams }: PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
await getEmbedData(legacyCtx);
return null;
diff --git a/apps/web/app/reschedule/[uid]/page.tsx b/apps/web/app/reschedule/[uid]/page.tsx
index 4e03ebe7a4..3ae0f6ab53 100644
--- a/apps/web/app/reschedule/[uid]/page.tsx
+++ b/apps/web/app/reschedule/[uid]/page.tsx
@@ -8,7 +8,7 @@ import { getServerSideProps } from "@lib/reschedule/[uid]/getServerSideProps";
const getData = withAppDirSsr(getServerSideProps);
const Page = async ({ params, searchParams }: PageProps) => {
- const legacyCtx = buildLegacyCtx(headers(), cookies(), params, searchParams);
+ const legacyCtx = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
await getData(legacyCtx);
diff --git a/apps/web/app/routing-forms/[...pages]/page.tsx b/apps/web/app/routing-forms/[...pages]/page.tsx
index ead2d36f73..7e8a156724 100644
--- a/apps/web/app/routing-forms/[...pages]/page.tsx
+++ b/apps/web/app/routing-forms/[...pages]/page.tsx
@@ -10,7 +10,7 @@ const paramsSchema = z
pages: [],
});
-export default function RoutingForms({ params }: PageProps) {
- const { pages } = paramsSchema.parse(params);
+export default async function RoutingForms({ params }: PageProps) {
+ const { pages } = paramsSchema.parse(await params);
redirect(`/apps/routing-forms/${pages.length ? pages.join("/") : ""}`);
}
diff --git a/apps/web/components/PageWrapperAppDir.tsx b/apps/web/components/PageWrapperAppDir.tsx
index 5628bee5be..53c9850fc6 100644
--- a/apps/web/components/PageWrapperAppDir.tsx
+++ b/apps/web/components/PageWrapperAppDir.tsx
@@ -1,6 +1,6 @@
"use client";
-import type { SSRConfig } from "next-i18next";
+import type { SSRConfig } from "next-i18next/dist/types/types";
// import I18nLanguageHandler from "@components/I18nLanguageHandler";
import { usePathname } from "next/navigation";
import Script from "next/script";
diff --git a/apps/web/components/ServerTrans.tsx b/apps/web/components/ServerTrans.tsx
new file mode 100644
index 0000000000..2cf5e08721
--- /dev/null
+++ b/apps/web/components/ServerTrans.tsx
@@ -0,0 +1,376 @@
+import type { TFunction } from "i18next";
+import type { ReactNode, ReactElement, FC } from "react";
+import React, { isValidElement, Fragment, createElement, cloneElement } from "react";
+
+type ServerTransProps = {
+ i18nKey: string; // Translation key
+ components?: ReactElement[] | Record; // Components to inject
+ t: TFunction;
+ values?: Record; // Values for interpolation
+ children?: ReactNode; // Children as fallback content
+ parent?: React.ElementType; // Parent element to wrap content in
+};
+
+/**
+ * A custom Trans component that doesn't use React Context
+ * Handles HTML tags and component interpolation in translations
+ */
+const ServerTrans: FC = ({
+ i18nKey,
+ components = [],
+ t,
+ values = {},
+ children,
+ parent,
+}) => {
+ const translationOptions = { ...values };
+ // Get translated content
+ const content = t(i18nKey, translationOptions);
+
+ // If no content at all, use children as fallback
+ if (!content && children) {
+ return <>{children}>;
+ }
+
+ // If no content, return empty fragment
+ if (!content) {
+ return <>>;
+ }
+
+ let result: ReactNode[];
+
+ // Process array-based components like <0>content0>
+ if (Array.isArray(components) && components.length > 0) {
+ result = parseArrayComponents(content, components);
+ }
+ // Process object-based components like content or {{tag}}
+ else if (isObject(components) && Object.keys(components).length > 0) {
+ result = parseObjectComponents(content, components as Record);
+ }
+ // Process just HTML tags
+ else {
+ result = parseHtmlTags(content);
+ }
+
+ // Wrap in parent element if specified
+ if (parent) {
+ const Parent = parent;
+ return {result} ;
+ }
+
+ return <>{result}>;
+};
+
+// Utility function to check if object
+const isObject = (obj: any): obj is Record =>
+ obj !== null && typeof obj === "object" && !Array.isArray(obj);
+
+// Parse array-based components like <0>content0>
+const parseArrayComponents = (content: string, components: ReactElement[]): ReactNode[] => {
+ const parts: ReactNode[] = [];
+ let currentText = "";
+
+ // Simple state machine parser to handle nested tags
+ const parseContent = (text: string) => {
+ for (let i = 0; i < text.length; i++) {
+ // Look for opening tag
+ if (text[i] === "<" && /\d/.test(text[i + 1])) {
+ // Found potential component tag
+ let tagIndex = "";
+ let j = i + 1;
+
+ // Read the tag index
+ while (j < text.length && /\d/.test(text[j])) {
+ tagIndex += text[j];
+ j++;
+ }
+
+ // Check if it's a valid tag
+ if (j < text.length && text[j] === ">") {
+ // It's an opening tag, save text before it
+ if (currentText) {
+ // Process any HTML in the text
+ parts.push(...parseHtmlTags(currentText));
+ currentText = "";
+ }
+
+ // Get the content inside the tag
+ const closingTag = `${tagIndex}>`;
+ const tagContent = getTextBetweenTags(text.substring(j + 1), tagIndex);
+
+ if (tagContent !== null) {
+ // We found the content, now add the component
+ const componentIndex = parseInt(tagIndex, 10);
+
+ if (componentIndex < components.length) {
+ const component = components[componentIndex];
+
+ if (isValidElement(component)) {
+ // Add the component with its content
+ parts.push(
+ cloneElement(
+ component,
+ {
+ ...(component.props || {}),
+ key: component.key || `comp-${componentIndex}`,
+ },
+ // Process any HTML in the inner content
+ ...parseHtmlTags(tagContent)
+ )
+ );
+ } else {
+ // If not a valid element, just add the content
+ parts.push(...parseHtmlTags(tagContent));
+ }
+ } else {
+ // Component index out of bounds, just add the content
+ parts.push(...parseHtmlTags(tagContent));
+ }
+
+ // Skip to after the closing tag
+ i = j + tagContent.length + closingTag.length;
+ continue;
+ }
+ }
+ }
+
+ // Regular character, add to current text
+ currentText += text[i];
+ }
+
+ // Add any remaining text
+ if (currentText) {
+ parts.push(...parseHtmlTags(currentText));
+ }
+ };
+
+ // Helper to find matching content between tags
+ const getTextBetweenTags = (text: string, tagIndex: string): string | null => {
+ let depth = 1;
+ let content = "";
+
+ for (let i = 0; i < text.length; i++) {
+ // Check for nested opening tag
+ if (
+ text[i] === "<" &&
+ text.substring(i + 1, i + 1 + tagIndex.length) === tagIndex &&
+ text[i + 1 + tagIndex.length] === ">"
+ ) {
+ depth++;
+ content += text.substring(i, i + 2 + tagIndex.length);
+ i += 1 + tagIndex.length;
+ continue;
+ }
+
+ // Check for closing tag
+ if (
+ text[i] === "<" &&
+ text.substring(i + 1, i + 2 + tagIndex.length) === `/${tagIndex}` &&
+ text[i + 2 + tagIndex.length] === ">"
+ ) {
+ depth--;
+
+ if (depth === 0) {
+ // Found the matching closing tag
+ return content;
+ }
+
+ content += text.substring(i, i + 3 + tagIndex.length);
+ i += 2 + tagIndex.length;
+ continue;
+ }
+
+ content += text[i];
+ }
+
+ return null; // No matching closing tag found
+ };
+
+ // Parse the content
+ parseContent(content);
+
+ return parts.length > 0 ? parts : [content];
+};
+
+// Parse object-based components like content or {{tag}}
+const parseObjectComponents = (content: string, components: Record): ReactNode[] => {
+ let processedContent = content;
+ const placeholders: Record = {};
+
+ // First handle {{tag}} interpolation
+ Object.keys(components).forEach((tag) => {
+ const interpolationRegex = new RegExp(`{{\\s*${tag}\\s*}}`, "g");
+ processedContent = processedContent.replace(interpolationRegex, (match) => {
+ const placeholder = `__INTERP_${tag}_${Math.random().toString(36).substring(2)}__`;
+
+ if (isValidElement(components[tag])) {
+ placeholders[placeholder] = cloneElement(components[tag], {
+ ...(components[tag].props || {}),
+ key: components[tag].key || `interp-${tag}`,
+ });
+ }
+
+ return placeholder;
+ });
+ });
+
+ // Then handle content
+ Object.keys(components).forEach((tag) => {
+ const tagRegex = new RegExp(`<${tag}>(.*?)<\\/${tag}>`, "gs");
+
+ processedContent = processedContent.replace(tagRegex, (match, content) => {
+ const placeholder = `__TAG_${tag}_${Math.random().toString(36).substring(2)}__`;
+
+ if (isValidElement(components[tag])) {
+ // Process any HTML in the content
+ const parsedContent = parseHtmlTags(content);
+
+ placeholders[placeholder] = cloneElement(
+ components[tag],
+ {
+ ...(components[tag].props || {}),
+ key: components[tag].key || `tag-${tag}`,
+ },
+ ...(parsedContent.length > 1 ? parsedContent : [content])
+ );
+ }
+
+ return placeholder;
+ });
+ });
+
+ // Replace placeholders with components and split text parts
+ const parts: ReactNode[] = [];
+ let lastIndex = 0;
+
+ // Find all placeholders in order
+ const placeholderRegex = /__(?:INTERP|TAG)_[^_]+_[a-z0-9]+__/g;
+ let match;
+
+ while ((match = placeholderRegex.exec(processedContent)) !== null) {
+ const [placeholder] = match;
+ const index = match.index;
+
+ // Add text before placeholder
+ if (index > lastIndex) {
+ const textBefore = processedContent.substring(lastIndex, index);
+ parts.push(...parseHtmlTags(textBefore));
+ }
+
+ // Add the component
+ if (placeholders[placeholder]) {
+ parts.push(placeholders[placeholder]);
+ }
+
+ lastIndex = index + placeholder.length;
+ }
+
+ // Add any remaining text
+ if (lastIndex < processedContent.length) {
+ const textAfter = processedContent.substring(lastIndex);
+ parts.push(...parseHtmlTags(textAfter));
+ }
+
+ return parts.length > 0 ? parts : [processedContent];
+};
+
+// Parse HTML tags like content
+const parseHtmlTags = (content: string): ReactNode[] => {
+ if (!content || typeof content !== "string") {
+ return [content].filter(Boolean);
+ }
+
+ // Check if there are any HTML tags
+ if (!/<[a-z][\s\S]*>/i.test(content)) {
+ return [content];
+ }
+
+ // HTML tags to process
+ const htmlTags = [
+ { tag: "strong", component: "strong" },
+ { tag: "b", component: "b" },
+ { tag: "i", component: "i" },
+ { tag: "em", component: "em" },
+ { tag: "p", component: "p" },
+ { tag: "br", component: "br", selfClosing: true },
+ { tag: "div", component: "div" },
+ { tag: "span", component: "span" },
+ { tag: "ul", component: "ul" },
+ { tag: "ol", component: "ol" },
+ { tag: "li", component: "li" },
+ ];
+
+ let processedContent = content;
+ const placeholders: Record = {};
+
+ // Process each HTML tag
+ htmlTags.forEach(({ tag, component, selfClosing }) => {
+ if (selfClosing) {
+ // Handle self-closing tags like
+ const selfClosingRegex = new RegExp(`<${tag}\\s*\\/>`, "g");
+
+ processedContent = processedContent.replace(selfClosingRegex, (match) => {
+ const placeholder = `__HTML_${tag}_${Math.random().toString(36).substring(2)}__`;
+ placeholders[placeholder] = createElement(component, { key: placeholder });
+ return placeholder;
+ });
+ } else {
+ // Handle regular tags like content
+ const tagRegex = new RegExp(`<${tag}>(.*?)<\\/${tag}>`, "gs");
+
+ processedContent = processedContent.replace(tagRegex, (match, content) => {
+ const placeholder = `__HTML_${tag}_${Math.random().toString(36).substring(2)}__`;
+
+ // Process nested tags recursively
+ const innerContent = parseHtmlTags(content);
+
+ placeholders[placeholder] = createElement(
+ component,
+ { key: placeholder },
+ ...(innerContent.length > 1 ? innerContent : [content])
+ );
+
+ return placeholder;
+ });
+ }
+ });
+
+ // If no tags were processed, return the original content
+ if (Object.keys(placeholders).length === 0) {
+ return [processedContent];
+ }
+
+ // Replace placeholders with components and split text parts
+ const parts: ReactNode[] = [];
+ let lastIndex = 0;
+
+ // Find all placeholders in order
+ const placeholderRegex = /__HTML_[^_]+_[a-z0-9]+__/g;
+ let match;
+
+ while ((match = placeholderRegex.exec(processedContent)) !== null) {
+ const [placeholder] = match;
+ const index = match.index;
+
+ // Add text before placeholder
+ if (index > lastIndex) {
+ parts.push(processedContent.substring(lastIndex, index));
+ }
+
+ // Add the component
+ if (placeholders[placeholder]) {
+ parts.push(placeholders[placeholder]);
+ }
+
+ lastIndex = index + placeholder.length;
+ }
+
+ // Add any remaining text
+ if (lastIndex < processedContent.length) {
+ parts.push(processedContent.substring(lastIndex));
+ }
+
+ return parts.length > 0 ? parts : [processedContent];
+};
+
+export default ServerTrans;
diff --git a/apps/web/components/booking/CancelBooking.tsx b/apps/web/components/booking/CancelBooking.tsx
index 50ab22eaaa..851a713f38 100644
--- a/apps/web/components/booking/CancelBooking.tsx
+++ b/apps/web/components/booking/CancelBooking.tsx
@@ -1,9 +1,12 @@
+"use client";
+
import { useCallback, useState } from "react";
import { sdkActionManager } from "@calcom/embed-core/embed-iframe";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useRefreshData } from "@calcom/lib/hooks/useRefreshData";
-import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
+import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
+import { collectPageParameters, telemetryEventTypes } from "@calcom/lib/telemetry";
import type { RecurringEvent } from "@calcom/types/Calendar";
import { Button } from "@calcom/ui/components/button";
import { Label, Select, TextArea } from "@calcom/ui/components/form";
diff --git a/apps/web/components/getting-started/steps-views/UserProfile.tsx b/apps/web/components/getting-started/steps-views/UserProfile.tsx
index edfa63946f..49033b8ae0 100644
--- a/apps/web/components/getting-started/steps-views/UserProfile.tsx
+++ b/apps/web/components/getting-started/steps-views/UserProfile.tsx
@@ -1,10 +1,13 @@
+"use client";
+
import { useRouter } from "next/navigation";
import { useRef, useState } from "react";
import { useForm } from "react-hook-form";
import { useLocale } from "@calcom/lib/hooks/useLocale";
+import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
import { md } from "@calcom/lib/markdownIt";
-import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
+import { telemetryEventTypes } from "@calcom/lib/telemetry";
import turndown from "@calcom/lib/turndownService";
import { trpc } from "@calcom/trpc/react";
import { UserAvatar } from "@calcom/ui/components/avatar";
diff --git a/apps/web/components/getting-started/steps-views/UserSettings.tsx b/apps/web/components/getting-started/steps-views/UserSettings.tsx
index a016ab7dc7..a40a39e713 100644
--- a/apps/web/components/getting-started/steps-views/UserSettings.tsx
+++ b/apps/web/components/getting-started/steps-views/UserSettings.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect } from "react";
import { useForm } from "react-hook-form";
@@ -8,7 +10,8 @@ import { useTimePreferences } from "@calcom/features/bookings/lib";
import { TimezoneSelect } from "@calcom/features/components/timezone-select";
import { FULL_NAME_LENGTH_MAX_LIMIT } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
-import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
+import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
+import { telemetryEventTypes } from "@calcom/lib/telemetry";
import { trpc } from "@calcom/trpc/react";
import { Input } from "@calcom/ui/components/form";
import { Button } from "@calcom/ui/components/button";
diff --git a/apps/web/components/settings/SecondaryEmailConfirmModal.tsx b/apps/web/components/settings/SecondaryEmailConfirmModal.tsx
index 38e40c9495..189bb6020e 100644
--- a/apps/web/components/settings/SecondaryEmailConfirmModal.tsx
+++ b/apps/web/components/settings/SecondaryEmailConfirmModal.tsx
@@ -1,7 +1,6 @@
-import { Trans } from "react-i18next";
-
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Dialog, DialogContent, DialogFooter, DialogClose } from "@calcom/ui/components/dialog";
+import ServerTrans from "@calcom/web/components/ServerTrans";
interface SecondaryEmailConfirmModalProps {
email: string;
@@ -15,7 +14,7 @@ const SecondaryEmailConfirmModal = ({ email, onCancel }: SecondaryEmailConfirmMo
}
+ description={ }
type="creation"
data-testid="secondary-email-confirm-dialog">
diff --git a/apps/web/lib/app-providers-app-dir.tsx b/apps/web/lib/app-providers-app-dir.tsx
index f27474d761..c0110e50f5 100644
--- a/apps/web/lib/app-providers-app-dir.tsx
+++ b/apps/web/lib/app-providers-app-dir.tsx
@@ -3,8 +3,8 @@ import { dir } from "i18next";
import type { Session } from "next-auth";
import { useSession } from "next-auth/react";
import { EventCollectionProvider } from "next-collect/client";
-import type { SSRConfig } from "next-i18next";
import { appWithTranslation } from "next-i18next";
+import type { SSRConfig } from "next-i18next/dist/types/types";
import { ThemeProvider } from "next-themes";
import type { AppProps as NextAppProps, AppProps as NextJsAppProps } from "next/app";
import type { ReadonlyURLSearchParams } from "next/navigation";
diff --git a/apps/web/lib/app-providers.tsx b/apps/web/lib/app-providers.tsx
index 2d926f54bd..0e5e085218 100644
--- a/apps/web/lib/app-providers.tsx
+++ b/apps/web/lib/app-providers.tsx
@@ -3,8 +3,8 @@ import { dir } from "i18next";
import type { Session } from "next-auth";
import { useSession } from "next-auth/react";
import { EventCollectionProvider } from "next-collect/client";
-import type { SSRConfig } from "next-i18next";
import { appWithTranslation } from "next-i18next";
+import type { SSRConfig } from "next-i18next/dist/types/types";
import { ThemeProvider } from "next-themes";
import type { AppProps as NextAppProps, AppProps as NextJsAppProps } from "next/app";
import dynamic from "next/dynamic";
diff --git a/apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts b/apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
index 55990675fc..13525879d0 100644
--- a/apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
+++ b/apps/web/lib/apps/installation/[[...step]]/getServerSideProps.ts
@@ -1,6 +1,4 @@
-import { Prisma } from "@prisma/client";
import type { GetServerSidePropsContext } from "next";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { z } from "zod";
import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData";
@@ -13,6 +11,7 @@ import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
import type { LocationObject } from "@calcom/lib/location";
import { UserRepository } from "@calcom/lib/server/repository/user";
import prisma from "@calcom/prisma";
+import { Prisma } from "@calcom/prisma/client";
import { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
import { STEPS } from "~/apps/installation/[[...step]]/constants";
@@ -307,7 +306,6 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
return {
props: {
- ...(await serverSideTranslations(locale, ["common"])),
app,
appMetadata,
showEventTypesStep,
diff --git a/apps/web/lib/apps/routing-forms/[...pages]/getServerSideProps.ts b/apps/web/lib/apps/routing-forms/[...pages]/getServerSideProps.ts
index 0afed87af6..a4c7392014 100644
--- a/apps/web/lib/apps/routing-forms/[...pages]/getServerSideProps.ts
+++ b/apps/web/lib/apps/routing-forms/[...pages]/getServerSideProps.ts
@@ -2,7 +2,7 @@ import type { GetServerSidePropsResult, GetServerSidePropsContext } from "next";
import { z } from "zod";
import { getAppWithMetadata } from "@calcom/app-store/_appRegistry";
-import { routingServerSidePropsConfig } from "@calcom/app-store/routing-forms/pages/app-routing.config";
+import { routingServerSidePropsConfig } from "@calcom/app-store/routing-forms/pages/app-routing.server-config";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import prisma from "@calcom/prisma";
import type { AppGetServerSidePropsContext } from "@calcom/types/AppGetServerSideProps";
diff --git a/apps/web/lib/daily-webhook/tests/recorded-daily-video.test.ts b/apps/web/lib/daily-webhook/tests/recorded-daily-video.test.ts
index 672fda8317..f55cc06ebd 100644
--- a/apps/web/lib/daily-webhook/tests/recorded-daily-video.test.ts
+++ b/apps/web/lib/daily-webhook/tests/recorded-daily-video.test.ts
@@ -161,10 +161,7 @@ function createNextRequest(mockReq: ReturnType["req"]): Next
});
// Create a NextRequest from the Request
- const nextRequest = new NextRequest(request, {
- ip: mockReq.socket?.remoteAddress || "127.0.0.1",
- geo: { city: "", country: "", region: "" },
- });
+ const nextRequest = new NextRequest(request);
return nextRequest;
}
diff --git a/apps/web/lib/getting-started/[[...step]]/getServerSideProps.tsx b/apps/web/lib/getting-started/[[...step]]/getServerSideProps.tsx
index b45b011c32..c64231bcea 100644
--- a/apps/web/lib/getting-started/[[...step]]/getServerSideProps.tsx
+++ b/apps/web/lib/getting-started/[[...step]]/getServerSideProps.tsx
@@ -1,5 +1,4 @@
import type { GetServerSidePropsContext } from "next";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { getLocale } from "@calcom/features/auth/lib/getLocale";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
@@ -31,7 +30,6 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
const locale = await getLocale(context.req);
return {
props: {
- ...(await serverSideTranslations(locale || "en", ["common"])),
trpcState: ssr.dehydrate(),
hasPendingInvites: user.teams.find((team) => team.accepted === false) ?? false,
},
diff --git a/apps/web/lib/metadata.ts b/apps/web/lib/metadata.ts
deleted file mode 100644
index 749d54e06c..0000000000
--- a/apps/web/lib/metadata.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import type { Metadata } from "next";
-
-export type PageMetadataRecipe = Readonly<{
- title: string;
- canonical: string;
- image: string;
- description: string;
- siteName: string;
- metadataBase: URL;
-}>;
-
-export const prepareRootMetadata = (): Metadata => ({
- icons: {
- icon: "/favicon.ico",
- apple: "/api/logo?type=apple-touch-icon",
- other: [
- {
- rel: "icon-mask",
- url: "/safari-pinned-tab.svg",
- color: "#000000",
- },
- {
- url: "/api/logo?type=favicon-16",
- sizes: "16x16",
- type: "image/png",
- },
- {
- url: "/api/logo?type=favicon-32",
- sizes: "32x32",
- type: "image/png",
- },
- ],
- },
- manifest: "/site.webmanifest",
- viewport: {
- width: "device-width",
- initialScale: 1.0,
- maximumScale: 1.0,
- userScalable: false,
- viewportFit: "cover",
- },
- other: {
- "application-TileColor": "#ff0000",
- },
- themeColor: [
- {
- media: "(prefers-color-scheme: light)",
- color: "#f9fafb",
- },
- {
- media: "(prefers-color-scheme: dark)",
- color: "#1C1C1C",
- },
- ],
- twitter: {
- site: "@calcom",
- creator: "@calcom",
- card: "summary_large_image",
- },
- robots: {
- index: true,
- follow: true,
- },
-});
diff --git a/apps/web/lib/reschedule/[uid]/getServerSideProps.ts b/apps/web/lib/reschedule/[uid]/getServerSideProps.ts
index 4fe7c5a5b2..0e930f06dd 100644
--- a/apps/web/lib/reschedule/[uid]/getServerSideProps.ts
+++ b/apps/web/lib/reschedule/[uid]/getServerSideProps.ts
@@ -4,9 +4,9 @@ import { URLSearchParams } from "url";
import { z } from "zod";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
-import { getSafe } from "@calcom/lib/bookingSuccessRedirect";
import { buildEventUrlFromBooking } from "@calcom/lib/bookings/buildEventUrlFromBooking";
import { getDefaultEvent } from "@calcom/lib/defaultEvents";
+import { getSafe } from "@calcom/lib/getSafe";
import { maybeGetBookingUidFromSeat } from "@calcom/lib/server/maybeGetBookingUidFromSeat";
import { UserRepository } from "@calcom/lib/server/repository/user";
import prisma, { bookingMinimalSelect } from "@calcom/prisma";
diff --git a/apps/web/lib/settings/admin/orgMigrations/moveTeamToOrg/getServerSideProps.tsx b/apps/web/lib/settings/admin/orgMigrations/moveTeamToOrg/getServerSideProps.tsx
index cb4ac548b5..ec46bdad79 100644
--- a/apps/web/lib/settings/admin/orgMigrations/moveTeamToOrg/getServerSideProps.tsx
+++ b/apps/web/lib/settings/admin/orgMigrations/moveTeamToOrg/getServerSideProps.tsx
@@ -1,6 +1,5 @@
import type { GetServerSidePropsContext } from "next";
import { getSession } from "next-auth/react";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { UserPermissionRole } from "@calcom/prisma/enums";
@@ -29,7 +28,6 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) {
error: null,
migrated: null,
userId: session.user.id,
- ...(await serverSideTranslations(ctx.locale || "en", ["common"])),
username: session.user.username,
},
};
diff --git a/apps/web/lib/settings/admin/orgMigrations/moveUserToOrg/getServerSideProps.tsx b/apps/web/lib/settings/admin/orgMigrations/moveUserToOrg/getServerSideProps.tsx
index be728f4d8c..7e23be070c 100644
--- a/apps/web/lib/settings/admin/orgMigrations/moveUserToOrg/getServerSideProps.tsx
+++ b/apps/web/lib/settings/admin/orgMigrations/moveUserToOrg/getServerSideProps.tsx
@@ -1,6 +1,5 @@
import type { GetServerSidePropsContext } from "next";
import { getSession } from "next-auth/react";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { UserPermissionRole } from "@calcom/prisma/enums";
@@ -25,8 +24,6 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) {
};
}
return {
- props: {
- ...(await serverSideTranslations(ctx.locale || "en", ["common"])),
- },
+ props: {},
};
}
diff --git a/apps/web/lib/settings/admin/orgMigrations/removeTeamFromOrg/getServerSideProps.tsx b/apps/web/lib/settings/admin/orgMigrations/removeTeamFromOrg/getServerSideProps.tsx
index be728f4d8c..7e23be070c 100644
--- a/apps/web/lib/settings/admin/orgMigrations/removeTeamFromOrg/getServerSideProps.tsx
+++ b/apps/web/lib/settings/admin/orgMigrations/removeTeamFromOrg/getServerSideProps.tsx
@@ -1,6 +1,5 @@
import type { GetServerSidePropsContext } from "next";
import { getSession } from "next-auth/react";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { UserPermissionRole } from "@calcom/prisma/enums";
@@ -25,8 +24,6 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) {
};
}
return {
- props: {
- ...(await serverSideTranslations(ctx.locale || "en", ["common"])),
- },
+ props: {},
};
}
diff --git a/apps/web/lib/settings/admin/orgMigrations/removeUserFromOrg/getServerSideProps.tsx b/apps/web/lib/settings/admin/orgMigrations/removeUserFromOrg/getServerSideProps.tsx
index be728f4d8c..7e23be070c 100644
--- a/apps/web/lib/settings/admin/orgMigrations/removeUserFromOrg/getServerSideProps.tsx
+++ b/apps/web/lib/settings/admin/orgMigrations/removeUserFromOrg/getServerSideProps.tsx
@@ -1,6 +1,5 @@
import type { GetServerSidePropsContext } from "next";
import { getSession } from "next-auth/react";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { UserPermissionRole } from "@calcom/prisma/enums";
@@ -25,8 +24,6 @@ export async function getServerSideProps(ctx: GetServerSidePropsContext) {
};
}
return {
- props: {
- ...(await serverSideTranslations(ctx.locale || "en", ["common"])),
- },
+ props: {},
};
}
diff --git a/apps/web/modules/auth/login-view.tsx b/apps/web/modules/auth/login-view.tsx
index 22c754219d..7a83f9a7fa 100644
--- a/apps/web/modules/auth/login-view.tsx
+++ b/apps/web/modules/auth/login-view.tsx
@@ -17,7 +17,8 @@ import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLastUsed, LastUsed } from "@calcom/lib/hooks/useLastUsed";
import { useLocale } from "@calcom/lib/hooks/useLocale";
-import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
+import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
+import { collectPageParameters, telemetryEventTypes } from "@calcom/lib/telemetry";
import { trpc } from "@calcom/trpc/react";
import { EmailField } from "@calcom/ui/components/form";
import { Alert } from "@calcom/ui/components/alert";
diff --git a/apps/web/modules/connect-and-join/connect-and-join-view.tsx b/apps/web/modules/connect-and-join/connect-and-join-view.tsx
index afaf9773af..2123d8ef15 100644
--- a/apps/web/modules/connect-and-join/connect-and-join-view.tsx
+++ b/apps/web/modules/connect-and-join/connect-and-join-view.tsx
@@ -1,7 +1,6 @@
"use client";
import { useSession } from "next-auth/react";
-import { Trans } from "next-i18next";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
@@ -13,6 +12,7 @@ import { trpc } from "@calcom/trpc";
import { Alert } from "@calcom/ui/components/alert";
import { Button } from "@calcom/ui/components/button";
import { EmptyScreen } from "@calcom/ui/components/empty-screen";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import { TRPCClientError } from "@trpc/client";
@@ -59,12 +59,18 @@ function ConnectAndJoin() {
{meetingUrl ? (
-
- Some other host already accepted the meeting. Do you still want to join?
-
- Continue to Meeting
-
-
+
+ Continue to Meeting
+ ,
+ ]}
+ />
) : (
- , ul:
}}>
-
- Members assigned to this event type will also have their event types deleted.
-
- Anyone who they've shared their link with will no longer be able to book using it.
-
+ {deleteDialogTypeSchedulingType === SchedulingType.MANAGED ? (
+
+ {t("delete_managed_event_type_description_1")}
+ {t("delete_managed_event_type_description_2")}
-
+ ) : (
+ t("delete_event_type_description")
+ )}
diff --git a/apps/web/modules/getting-started/[[...step]]/onboarding-view.tsx b/apps/web/modules/getting-started/[[...step]]/onboarding-view.tsx
index 56c4874a90..849d04e7c9 100644
--- a/apps/web/modules/getting-started/[[...step]]/onboarding-view.tsx
+++ b/apps/web/modules/getting-started/[[...step]]/onboarding-view.tsx
@@ -1,7 +1,7 @@
"use client";
import { signOut } from "next-auth/react";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { usePathname, useRouter } from "next/navigation";
import { Suspense } from "react";
import { Toaster } from "sonner";
diff --git a/apps/web/modules/settings/teams/new/create-new-team-view.tsx b/apps/web/modules/settings/teams/new/create-new-team-view.tsx
index 2650e67d45..903db49c98 100644
--- a/apps/web/modules/settings/teams/new/create-new-team-view.tsx
+++ b/apps/web/modules/settings/teams/new/create-new-team-view.tsx
@@ -8,7 +8,8 @@ import { CreateANewTeamForm } from "@calcom/features/ee/teams/components";
import { HOSTED_CAL_FEATURES } from "@calcom/lib/constants";
import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl";
import { useParamsWithFallback } from "@calcom/lib/hooks/useParamsWithFallback";
-import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
+import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
+import { telemetryEventTypes } from "@calcom/lib/telemetry";
import type { RouterOutputs } from "@calcom/trpc/react";
import { WizardLayout } from "@calcom/ui/components/layout";
diff --git a/apps/web/modules/signup-view.tsx b/apps/web/modules/signup-view.tsx
index bae04e8dbb..582b3644e4 100644
--- a/apps/web/modules/signup-view.tsx
+++ b/apps/web/modules/signup-view.tsx
@@ -3,7 +3,6 @@
import { Analytics as DubAnalytics } from "@dub/analytics/react";
import { zodResolver } from "@hookform/resolvers/zod";
import { signIn } from "next-auth/react";
-import { Trans } from "next-i18next";
import dynamic from "next/dynamic";
import Link from "next/link";
import { useRouter } from "next/navigation";
@@ -34,7 +33,8 @@ import { pushGTMEvent } from "@calcom/lib/gtm";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useDebounce } from "@calcom/lib/hooks/useDebounce";
import { useLocale } from "@calcom/lib/hooks/useLocale";
-import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
+import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
+import { collectPageParameters, telemetryEventTypes } from "@calcom/lib/telemetry";
import { IS_EUROPE } from "@calcom/lib/timezoneConstants";
import { signupSchema as apiSignupSchema } from "@calcom/prisma/zod-utils";
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
@@ -44,6 +44,7 @@ import { Button } from "@calcom/ui/components/button";
import { PasswordField, CheckboxField, TextField, Form } from "@calcom/ui/components/form";
import { Icon } from "@calcom/ui/components/icon";
import { showToast } from "@calcom/ui/components/toast";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import type { getServerSideProps } from "@lib/signup/getServerSideProps";
@@ -597,7 +598,8 @@ export default function Signup({
-
1mb, to improve dev mode performance/RAM usage
- serverComponentsExternalPackages: ["next-i18next"],
optimizePackageImports: ["@calcom/ui"],
- instrumentationHook: true,
- serverActions: true,
- },
- i18n: {
- ...i18n,
- defaultLocale: "en",
- locales: ["en"],
- localeDetection: false,
+ turbo: {},
},
productionBrowserSourceMaps: process.env.SENTRY_DISABLE_CLIENT_SOURCE_MAPS === "0",
/* We already do type check on GH actions */
@@ -275,7 +272,6 @@ const nextConfig = {
fs: false,
// ignore module resolve errors caused by the server component bundler
"pg-native": false,
- "superagent-proxy": false,
};
/**
diff --git a/apps/web/package.json b/apps/web/package.json
index 7e0c09dd92..ef1837570d 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -7,7 +7,7 @@
"analyze:server": "BUNDLE_ANALYZE=server next build",
"analyze:browser": "BUNDLE_ANALYZE=browser next build",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next",
- "dev": "next dev",
+ "dev": "next dev --turbopack",
"dev:cron": "ts-node cron-tester.ts",
"dev-https": "NODE_TLS_REJECT_UNAUTHORIZED=0 next dev --experimental-https",
"dx": "yarn dev",
@@ -71,7 +71,7 @@
"@stripe/react-stripe-js": "^1.10.0",
"@stripe/stripe-js": "^1.35.0",
"@tanstack/react-query": "^5.17.15",
- "@tremor/react": "^2.0.0",
+ "@tremor/react": "^2.11.0",
"@types/turndown": "^5.0.1",
"@unkey/ratelimit": "^0.1.1",
"@upstash/redis": "^1.21.0",
@@ -101,11 +101,11 @@
"memory-cache": "^0.2.0",
"micro": "^10.0.1",
"mime-types": "^2.1.35",
- "next": "^13.5.6",
+ "next": "^15.1.6",
"next-auth": "^4.22.1",
"next-axiom": "^0.17.0",
"next-collect": "^0.2.1",
- "next-i18next": "^13.2.2",
+ "next-i18next": "^15.4.2",
"next-seo": "^6.0.0",
"next-themes": "^0.2.0",
"nodemailer": "^6.7.8",
@@ -178,7 +178,6 @@
"autoprefixer": "^10.4.12",
"copy-webpack-plugin": "^11.0.0",
"cron": "^3.1.7",
- "deasync": "^0.1.30",
"detect-port": "^1.3.0",
"env-cmd": "^10.1.0",
"google-auth-library": "^9.15.0",
diff --git a/apps/web/pages/404.tsx b/apps/web/pages/404.tsx
deleted file mode 100644
index 5bfa86fb5e..0000000000
--- a/apps/web/pages/404.tsx
+++ /dev/null
@@ -1,259 +0,0 @@
-"use client";
-
-import type { GetStaticPropsContext } from "next";
-import Link from "next/link";
-import { usePathname } from "next/navigation";
-import { useEffect, useState } from "react";
-
-import {
- getOrgDomainConfigFromHostname,
- subdomainSuffix,
-} from "@calcom/features/ee/organizations/lib/orgDomains";
-import { DOCS_URL, IS_CALCOM, WEBSITE_URL } from "@calcom/lib/constants";
-import { useLocale } from "@calcom/lib/hooks/useLocale";
-import { HeadSeo } from "@calcom/ui/components/head-seo";
-import { Icon } from "@calcom/ui/components/icon";
-
-import PageWrapper from "@components/PageWrapper";
-
-import { getTranslations } from "@server/lib/getTranslations";
-
-enum pageType {
- ORG = "org",
- TEAM = "team",
- USER = "user",
- OTHER = "other",
-}
-
-export default function Custom404() {
- const pathname = usePathname();
- const { t } = useLocale();
- const [username, setUsername] = useState("");
- const [currentPageType, setCurrentPageType] = useState(pageType.USER);
-
- const links = [
- {
- title: t("enterprise"),
- description: "Learn more about organizations and subdomains in our enterprise plan.",
- icon: "shield" as const,
- href: `${WEBSITE_URL}/enterprise`,
- },
- {
- title: t("documentation"),
- description: t("documentation_description"),
- icon: "file-text" as const,
- href: DOCS_URL,
- },
- {
- title: t("blog"),
- description: t("blog_description"),
- icon: "book-open" as const,
- href: `${WEBSITE_URL}/blog`,
- },
- ];
-
- const [url, setUrl] = useState(`${WEBSITE_URL}/signup`);
- useEffect(() => {
- const { isValidOrgDomain, currentOrgDomain } = getOrgDomainConfigFromHostname({
- hostname: window.location.host,
- });
-
- const [routerUsername] = pathname?.replace("%20", "-").split(/[?#]/) ?? [];
- if (routerUsername && (!isValidOrgDomain || !currentOrgDomain)) {
- const splitPath = routerUsername.split("/");
- if (splitPath[1] === "team" && splitPath.length === 3) {
- // Accessing a non-existent team
- setUsername(splitPath[2]);
- setCurrentPageType(pageType.TEAM);
- setUrl(
- `${WEBSITE_URL}/signup?callbackUrl=settings/teams/new%3Fslug%3D${splitPath[2].replace("/", "")}`
- );
- } else {
- setUsername(routerUsername);
- setUrl(`${WEBSITE_URL}/signup?username=${routerUsername.replace("/", "")}`);
- }
- } else {
- setUsername(currentOrgDomain ?? "");
- setCurrentPageType(pageType.ORG);
- setUrl(
- `${WEBSITE_URL}/signup?callbackUrl=settings/organizations/new%3Fslug%3D${
- currentOrgDomain?.replace("/", "") ?? ""
- }`
- );
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, []);
-
- const isSuccessPage = pathname?.startsWith("/booking");
- const isSubpage = pathname?.includes("/", 2) || isSuccessPage;
-
- /**
- * If we're on 404 and the route is insights it means it is disabled
- * TODO: Abstract this for all disabled features
- **/
- const isInsights = pathname?.startsWith("/insights");
- if (isInsights) {
- return (
- <>
-
-
-
-
-
{t("error_404")}
-
- Feature is currently disabled
-
-
-
-
-
- {t("or_go_back_home")}
- →
-
-
-
-
-
- >
- );
- }
-
- if (!username) return null;
-
- return (
- <>
-
-
-
-
-
- {((!isSubpage && IS_CALCOM) ||
- currentPageType === pageType.ORG ||
- currentPageType === pageType.TEAM) && (
-
- )}
-
- {t("popular_pages")}
-
-
-
-
- {t("or_go_back_home")}
- →
-
-
-
-
-
- >
- );
-}
-
-Custom404.PageWrapper = PageWrapper;
-
-export const getStaticProps = async (context: GetStaticPropsContext) => {
- const i18n = await getTranslations(context);
-
- return {
- props: {
- i18n,
- },
- };
-};
diff --git a/apps/web/playwright/booking-seats.e2e.ts b/apps/web/playwright/booking-seats.e2e.ts
index 3c5b87a61f..97fe26ef07 100644
--- a/apps/web/playwright/booking-seats.e2e.ts
+++ b/apps/web/playwright/booking-seats.e2e.ts
@@ -227,6 +227,7 @@ test.describe("Reschedule for booking with seats", () => {
await page.goto(
`/booking/${booking.uid}?cancel=true&allRemainingBookings=false&seatReferenceUid=${bookingSeats[0].referenceUid}`
);
+ await page.waitForSelector("text=Reason for cancellation");
await expect(page.locator('text="Cancel event"')).toBeVisible();
diff --git a/apps/web/playwright/managed-event-types.e2e.ts b/apps/web/playwright/managed-event-types.e2e.ts
index 1085fcfa35..93276ce49c 100644
--- a/apps/web/playwright/managed-event-types.e2e.ts
+++ b/apps/web/playwright/managed-event-types.e2e.ts
@@ -34,10 +34,11 @@ test.describe("Managed Event Types", () => {
await page.getByTestId("new-event-type").click();
await page.getByTestId("option-team-1").click();
// Expecting we can add a managed event type as team owner
- await expect(page.locator('button[value="MANAGED"]')).toBeVisible();
+ const locator = page.locator('div:has(input[value="MANAGED"]) > button');
+ await expect(locator).toBeVisible();
// Actually creating a managed event type to test things further
- await page.click('button[value="MANAGED"]');
+ await locator.click();
await page.fill("[name=title]", "managed");
await page.click("[type=submit]");
diff --git a/apps/web/playwright/organization/team-management.e2e.ts b/apps/web/playwright/organization/team-management.e2e.ts
index 7985da5a4b..c6fc65b76f 100644
--- a/apps/web/playwright/organization/team-management.e2e.ts
+++ b/apps/web/playwright/organization/team-management.e2e.ts
@@ -69,8 +69,9 @@ test.describe("Teams", () => {
});
await test.step("Can finish team creation", async () => {
- await expect(page.locator('button[value="ROUND_ROBIN"]')).toBeVisible();
- await page.click('button[value="ROUND_ROBIN"]');
+ const locator = page.locator('div:has(input[value="ROUND_ROBIN"]) > button');
+ await expect(locator).toBeVisible();
+ await locator.click();
await page.fill("[name=title]", "roundRobin");
await page.getByTestId("finish-button").click();
await page.waitForURL(/\/settings\/teams\/(\d+)\/profile$/i);
diff --git a/apps/web/public/favicon.ico b/apps/web/public/favicon.ico
deleted file mode 100644
index 0760f8a241f733fe4e01f7716362d6299b144d8b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 15086
zcmeI3XKWQm5XX-|6e%H)kVK#)AN;}eX2A5`5xp1DY(%l>Unt+OKtN1KL_ny5Pz9nR
zfk3hoL?VJH0wJSNWCRK&Kuk9Xn9OhDbMg8RPA!?0Jnm&x?u4zW&1Vu4~;FT5>XSJE~=C~hkv#dBVC?eH0J8h#n{x}xGpG3VQ_yHw@%dt}h^BgNb(;@!!CEiqRcDsDz0|96yU=JdiS
zNm;z#YbE1TGCpCqfoj#N2?*tbU7L5c3)M$q
z-m6-*s(`w6>q?U*O$>2yaaKpYqXoZQ*RNk+nm2DQ@$vCFvev9wQ-Et*qecw@?z*T-
z`03cOqby#$SWcWcA(t;-Hk>?pQkE}YE*&~_FrMMPQKLpOckWy{b?TH{yLL^^ojWJ<
z=FO8SQ>Ms~BS&QC&YjYtMGNWLwX5viyH^ezI3WG{^|R-TivLNICdt*SS0%3lc?Jy{
zBn=xjG=AQ^d6TQ@ix)3)p1*hRp6O!v@Zpk`l_jrVzn1ai$4lkPl?#0w(0fu+lH9+4
z-}r$KbiQugI@z#cgPcBnT3)?+CGa$M>{wZ_V1c}S`_{lc^ge(7d^vOGjMdRexcJ8w
zTDEK{7cN{d-XA@BB(rACl6v*(<=8y>rf$@zQPQ+&Q@M2MlC?d1_N=sN)5dg)UfZ^9
zE7Wm>i~lNBs>qBPGi-dJyLRnbn}>dX;^rzm_U_$VGBY!2YUALy2hLMcQtV#1_-8IL
z*ErC9|Ni|2nS#wR>bd{;@ndVBoSdA?p5dQ5j&Si`yLN3!O-(hLH*VaJ)~#FT_`yIK
z7zgYnBO}Aw<7e=*$OSm3jw4+B*Q!-ZjvYH@G;iIyCGFa^3+dzV<6F0Gwf6Xx&6_uy
zPZ~00h-}%iMP9yqY4^g#KfVVa!}0w2b4g50%w-dSV?g^ZUAoA{ix=$~{Ls^gICy?%n0!!Gq>=83*R{{{8!9
z#flYj_wHTuQH*6#`+xXp(4c`FKYrZ!$IoxyzFoR?>t^+=3kD1rVDBs5%d8ii40Y<%
z5#$Vubl6))}<#)TxuSZ{Ob54BQLH`>R*4UXq@kZZcpK=n!9i{``4yHo+K8n>H=i
z{J@?VA4=qMvbp+^BS#iF|JXS6diLxoM~@ygTQ)&_KTn=Kv2kHd1CN38BG@%@g^PbD
z1MgjEE?c(D-V3}NI3G4_m|!pO%RBwS|GVnBySat9RUBJ2jIzKd!
znK5IH!uugVeMI^hr-w-MQ9{31#~z~6wo7a(q)okva{WAtV*ay~_cKw0*u%#P{;$%abbCr^M{=EuokzllI{8b=@Xxys(z)A1
zb9=1pt#QtrarY>x18(ole@@%{fPUF`8#88%#nyK0*da@oE*18R>5skdnKNhFUL||)
z#0ZI@_2|*V_PvQ~67!*-52epD#HqJ!+h%*n#3&v-cwlh~Voiew50*`vHd$keHQ=11FzEN~+t>7q?)~``*b#alpW(`tD>mjUSFV&*t5(UKJ9i3&KKggDZtMzs
zN5{yBE?nG_cpEViVraw<4<9}(H*ek)Y@?v|hm6GCi77&Z*bDP(_3G6|hZqs#M4n2Y
zK7B0Tf%%ADh$SsqvZO%vj}DM?(V|7BW9*9f7A1KL#1Y|Ccj!c*^L7Fvd7SgA{193(CmE-e6{g1!BlL@(;fA!xlInUqwrI_d~((A9x
z2CwG{h4C8
zB27`)dppcA_H2Gt@V#krBfIX;luy$gnPlB209sX~M{+iuG^Gh`_9@twh*9M1Q|N!q
z0uSZ6f`a{~e-!V#o@H(?ReYu3{~-MD>wTYf?RbVh?&srK*T=&GJnQ<%Rl0W~rCS5I
zb%3kOize;KRb`#zaymzk9&PzcQwti
zAb*YgpMCrG<@r2)k{?9dUAuN!J{fC$*7)R5a*iy>7>qtLK$n~daz*Hi^)YP$>m~9&
z8aHkna*gE1EEo;yxF4Xqg1#sJ4(Kni|4`T1Z;FEd#e`}X>>l%ndHbazMe#rptX;4=
O+A?n|Bp1Ll@$A2(WVaXq
diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json
index 1ee1408196..bab3543d5c 100644
--- a/apps/web/public/static/locales/en/common.json
+++ b/apps/web/public/static/locales/en/common.json
@@ -85,7 +85,7 @@
"payment_not_created_error": "Payment could not be created",
"couldnt_charge_card_error": "Could not charge card for Payment",
"no_available_users_found_error": "No available users found. Could you try another time slot?",
- "timeslot_unavailable_book_a_new_time": "The selected time slot is no longer available. <2>Please select a new time2>",
+ "timeslot_unavailable_book_a_new_time": "The selected time slot is no longer available. <0>Please select a new time0>",
"timeslot_unavailable_short": "Taken",
"unavailable_timeslot_title": "Unavailable timeslot",
"booking_time_out_of_bounds_error": "The event type cannot be booked at this time. Could you try another time slot?",
@@ -172,7 +172,7 @@
"meeting_url": "Meeting URL",
"meeting_url_not_found": "Meeting URL not found",
"token_not_found": "Token not found",
- "some_other_host_already_accepted_the_meeting": "Some other host already accepted the meeting. Do you still want to join? <1>Continue to Meeting1>",
+ "some_other_host_already_accepted_the_meeting": "Some other host already accepted the meeting. Do you still want to join? <0>Continue to Meeting0>",
"meeting_request_rejected": "Your meeting request has been rejected",
"rejected_event_type_with_organizer": "Rejected: {{eventType}} with {{organizer}} on {{date}}",
"hi": "Hi",
@@ -319,8 +319,8 @@
"yours": "Your account",
"available_apps": "Available Apps",
"available_apps_lower_case": "Available apps",
- "available_apps_desc": "View popular apps below and explore more in our <1>App Store1>",
- "fixed_host_helper": "Add anyone who needs to attend the event. <1>Learn more1>",
+ "available_apps_desc": "View popular apps below and explore more in our <0>App Store0>",
+ "fixed_host_helper": "Add anyone who needs to attend the event. <0>Learn more0>",
"round_robin_helper": "People in the group take turns and only one person will show up for the event.",
"check_email_reset_password": "Check your email. We sent you a link to reset your password.",
"finish": "Finish",
@@ -406,7 +406,7 @@
"bookerlayout_error_min_one_enabled": "At least one layout has to be enabled.",
"bookerlayout_error_default_not_enabled": "The layout you selected as the default view is not part of the enabled layouts.",
"bookerlayout_error_unknown_layout": "The layout you selected is not a valid layout.",
- "bookerlayout_override_global_settings": "You can manage this for all your event types in Settings -> <2>Appearance2> or <6>Override6> for this event only.",
+ "bookerlayout_override_global_settings": "You can manage this for all your event types in Settings -> <0>Appearance0> or <1>Override1> for this event only.",
"unexpected_error_try_again": "An unexpected error occurred. Try again.",
"sunday_time_error": "Invalid time on Sunday",
"monday_time_error": "Invalid time on Monday",
@@ -657,6 +657,7 @@
"edit_team": "Edit team",
"editing_user": "Editing user",
"editing_org": "Editing organization",
+ "edit_or_manage_webhooks": "If you wish to edit or manage your web hooks, please head over to <0>webhooks settings0>",
"reject": "Reject",
"reject_all": "Reject all",
"accept": "Accept",
@@ -692,7 +693,7 @@
"add_team_members_description": "Invite others to join your team",
"add_team_member": "Add team member",
"invite_new_member": "Invite a new team member",
- "invite_new_member_description": "Note: This will <1>cost an extra seat ($15/m)1> on your subscription.",
+ "invite_new_member_description": "Note: This will <0>cost an extra seat ($15/m)0> on your subscription.",
"invite_new_team_member": "Invite someone to your team.",
"upload_csv_file": "Upload a .csv file",
"invite_via_email": "Invite via email",
@@ -945,7 +946,7 @@
"hide_event_type": "Hide event type",
"edit_location": "Edit location",
"into_the_future": "into the future",
- "when_booked_with_less_than_notice": "When booked with less than notice",
+ "when_booked_with_less_than_notice": "When booked with less than <0>0> notice",
"within_date_range": "Within a date range",
"indefinitely_into_future": "Indefinitely into the future",
"add_new_custom_input_field": "Add new custom input field",
@@ -964,7 +965,8 @@
"delete_event_type": "Delete event type?",
"delete_managed_event_type": "Delete managed event type?",
"delete_event_type_description": "Anyone who you've shared this link with will no longer be able to book using it.",
- "delete_managed_event_type_description": "Members assigned to this event type will also have their event types deleted. Anyone who they've shared their link with will no longer be able to book using it. ",
+ "delete_managed_event_type_description_1": "Members assigned to this event type will also have their event types deleted.",
+ "delete_managed_event_type_description_2": "Anyone who they've shared their link with will no longer be able to book using it.",
"confirm_delete_event_type": "Yes, delete",
"delete_account": "Delete account",
"confirm_delete_account": "Yes, delete account",
@@ -1220,7 +1222,12 @@
"your_unique_api_key": "Your unique API key",
"copy_safe_api_key": "Copy this API key and save it somewhere safe. If you lose this key you have to generate a new one.",
"zapier_setup_instructions": "<0>Log into your Zapier account and create a new Zap.0><1>Select Cal.com as your Trigger app. Also choose a Trigger event.1><2>Choose your account and then enter your Unique API Key.2><3>Test your Trigger.3><4>You're set!4>",
- "make_setup_instructions": "<0>Go to <1><0>Make Invite Link0>1> and install the Cal.com app.0><1>Log into your Make account and create a new Scenario.1><2>Select Cal.com as your Trigger app. Also choose a Trigger event.2><3>Choose your account and then enter your Unique API Key.3><4>Test your Trigger.4><5>You're set!5>",
+ "make_setup_instructions_1": "Go to <0>Make Invite Link0> and install the Cal.com app.",
+ "make_setup_instructions_2": "Log into your Make account and create a new Scenario.",
+ "make_setup_instructions_3": "Select Cal.com as your Trigger app. Also choose a Trigger event.",
+ "make_setup_instructions_4": "Choose your account and then enter your Unique API Key.",
+ "make_setup_instructions_5": "Test your Trigger.",
+ "make_setup_instructions_6": "You're set!",
"install_zapier_app": "Please first install the Zapier App in the app store.",
"install_make_app": "Please first install the Make App in the app store.",
"app_not_installed": "App not installed",
@@ -1361,7 +1368,7 @@
"hour_one_short": "{{count}}h",
"hour_other": "{{count}} hours",
"invalid_input": "Invalid input",
- "broken_video_action": "We could not add the <1>{{location}}1> meeting link to your scheduled event. Contact your invitees or update your calendar event to add the details. You can either <3> change your location on the event type 3> or try <5>removing and adding the app again.5>",
+ "broken_video_action": "We could not add the {{location}} meeting link to your scheduled event. Contact your invitees or update your calendar event to add the details. You can either <0> change your location on the event type 0> or try <1>removing and adding the app again.1>",
"broken_calendar_action": "We could not update your <1>{{calendar}}1>. <2> Please check your calendar settings or remove and add your calendar again 2>",
"attendee_name": "Attendee's name",
"scheduler_full_name": "The full name of the person booking",
@@ -1699,7 +1706,7 @@
"how_long_after_user_no_show_minutes": "How long after the users don't show up on cal video meeting?",
"no_available_slots": "No Available slots",
"time_available": "Time available",
- "cant_find_the_right_conferencing_app_visit_our_app_store": "Can't find the right conferencing app? Visit our <1>App Store1>.",
+ "cant_find_the_right_conferencing_app_visit_our_app_store": "Can't find the right conferencing app? Visit our <0>App Store0>.",
"install_new_calendar_app": "Install new calendar app",
"make_phone_number_required": "Make phone number required for booking event",
"new_event_type_availability": "{{eventTypeTitle}} Availability",
@@ -1773,6 +1780,7 @@
"booking_limit_reached": "Booking Limit for this event type has been reached",
"duration_limit_reached": "Duration Limit for this event type has been reached",
"admin_has_disabled": "An admin has disabled {{appName}}",
+ "disable_attendees_emails_description": "This will disable all emails to {{recipient}}. This includes booking confirmations, requests, reschedules and reschedule requests, cancellation emails, and any other emails related to booking updates. It is your responsibility to ensure that your {{recipient}} are aware of any bookings and changes to their bookings.",
"disabled_app_affects_event_type": "An admin has disabled {{appName}} which affects your event type {{eventType}}",
"event_replaced_notice": "An admin has replaced one of your event types",
"email_subject_slug_replacement": "A team administrator has replaced your event /{{slug}}",
@@ -1871,7 +1879,7 @@
"new_attendee": "New Attendee",
"awaiting_approval": "Awaiting Approval",
"requires_google_calendar": "This app requires a Google Calendar connection",
- "event_type_requires_google_calendar": "The “Add to calendar” for this event type needs to be a Google Calendar for Meet to work. Connect it <1>here1>.",
+ "event_type_requires_google_calendar": "The “Add to calendar” for this event type needs to be a Google Calendar for Meet to work. Connect it <0>here0>.",
"connected_google_calendar": "You have connected a Google Calendar account.",
"using_meet_requires_calendar": "Using Google Meet requires a connected Google Calendar",
"continue_to_install_google_calendar": "Continue to install Google Calendar",
@@ -2436,7 +2444,10 @@
"create_your_org_description": "Upgrade to Organizations and receive a subdomain, unified billing, Insights, extensive whitelabeling and more",
"create_your_enterprise_description": "Upgrade to Enterprise and get access to Active Directory Sync, SCIM Automatic User provisioning, Cal.ai Voice Agents, Admin APIs and more!",
"other_payment_app_enabled": "You can only enable one payment app per event type",
- "admin_delete_organization_description": "Teams that are member of this organization will also be deleted along with their event-types Users that were part of the organization will not be deleted but their usernames would be changed to allow them to exist outside the organization User event-types created after the user was in the organization will be deleted Migrated user event-types will not be deleted ",
+ "admin_delete_organization_description_1": "Teams that are member of this organization will also be deleted along with their event-types",
+ "admin_delete_organization_description_2": "Users that were part of the organization will not be deleted but their usernames would be changed to allow them to exist outside the organization",
+ "admin_delete_organization_description_3": "User event-types created after the user was in the organization will be deleted",
+ "admin_delete_organization_description_4": "Migrated user event-types will not be deleted",
"admin_delete_organization_title": "Delete {{organizationName}}?",
"published": "Published",
"unpublished": "Unpublished",
@@ -2516,7 +2527,7 @@
"set_weight": "Set Weight",
"enable_weights": "Enable Weights",
"priority_for_user": "Priority for {{userName}}",
- "weights_description": "Weights determine how meetings are distributed among hosts. <1>Learn more1>",
+ "weights_description": "Weights determine how meetings are distributed among hosts. <0>Learn more0>",
"weight_for_user": "Weight for {{userName}}",
"change_priority": "change priority",
"field_identifiers_as_variables": "Use field identifiers as variables for your custom event redirect",
@@ -2552,8 +2563,8 @@
"email_team_invite|content|added_to_subteam": "{{invitedBy}} has added you to the team {{teamName}} in their organization {{parentTeamName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
"email_team_invite|content|invited_to_subteam": "{{invitedBy}} has invited you to join the team {{teamName}} in their organization {{parentTeamName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
"email_team_invite|content|invited_to_regular_team": "{{invitedBy}} has invited you to join their team {{teamName}} on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
- "email|existing_user_added_link_will_change": "On accepting the invite, your link will change to your organization domain but don't worry, all previous links will still work and redirect appropriately. Please note: All of your personal event types will be moved into the {teamName} organization, which may also include potential personal link. For personal events we recommend creating a new account with a personal email address.",
- "email|existing_user_added_link_changed": "Your link has been changed from {prevLinkWithoutProtocol} to {newLinkWithoutProtocol} but don't worry, all previous links still work and redirect appropriately. Please note: All of your personal event types have been moved into the {teamName} organisation, which may also include potential personal link. Please log in and make sure you have no private events on your new organisational account. For personal events we recommend creating a new account with a personal email address. Enjoy your new clean link: {newLinkWithoutProtocol} ",
+ "email|existing_user_added_link_will_change": "On accepting the invite, your link will change to your organization domain but don't worry, all previous links will still work and redirect appropriately. Please note: All of your personal event types will be moved into the {{teamName}} organization, which may also include potential personal link. For personal events we recommend creating a new account with a personal email address.",
+ "email|existing_user_added_link_changed": "Your link has been changed from {{a0}} to {{a1}} but don't worry, all previous links still work and redirect appropriately. Please note: All of your personal event types have been moved into the {{teamName}} organisation, which may also include potential personal link. Please log in and make sure you have no private events on your new organisational account. For personal events we recommend creating a new account with a personal email address. Enjoy your new clean link: {{a2}}",
"email_organization_created|subject": "Your organization has been created",
"your_current_plan": "Your current plan",
"organization_price_per_user_month": "$37 per user per month (30 seats minimum)",
@@ -2610,7 +2621,7 @@
"ooo_reasons_travel": "Travel",
"ooo_reasons_sick_leave": "Sick leave",
"ooo_reasons_public_holiday": "Public holiday",
- "ooo_forwarding_to": "Forwarding to {{username}} ",
+ "ooo_forwarding_to": "Forwarding to <0>{{username}}0>",
"ooo_not_forwarding": "No forwarding",
"ooo_empty_title": "Create an OOO",
"ooo_empty_description": "Communicate to your bookers when you're not available to take bookings. They can still book you upon your return or you can forward them to a team member.",
@@ -2940,7 +2951,7 @@
"dry_run_mode_active": "You are doing a test booking.",
"icon_showcase": "Icon showcase",
"icons_showcase": "Icons showcase",
- "migrating_from_team":"Migrating from team",
+ "migrating_from_team": "Migrating from team",
"feature_currently_disabled": "Feature is currently disabled",
"choose_an_option": "Choose an option",
"enter_option_value": "Enter option value",
@@ -3013,7 +3024,7 @@
"ooo_team_redirect_infinite_not_allowed": "There is already a reverse forwarding between these users.",
"previous_ooo_empty_title": "No previous OOO found",
"previous": "Previous",
- "rr_interval_successfully_updated":"Round Robin interval successfully updated",
+ "rr_interval_successfully_updated": "Round Robin interval successfully updated",
"trial_mode": "Trial mode",
"inactive_team_plan": "Inactive team plan",
"inactive_team_plan_description": "Your team plan is inactive. Check your subcription or reach out to customer support",
@@ -3026,4 +3037,4 @@
"user_has_no_team_yet": "You don't have a team yet",
"no_team_members": "You don't have team members yet",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
-}
+}
\ No newline at end of file
diff --git a/apps/web/scripts/vercel-app-router-deploy.sh b/apps/web/scripts/vercel-app-router-deploy.sh
deleted file mode 100755
index b9f36a543d..0000000000
--- a/apps/web/scripts/vercel-app-router-deploy.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-checkRoute () {
- if [ "$1" != '1' ]; then rm -rf $2; fi
-}
-
-# These conditionals are used to remove directories from the build that are not needed in production
-# This is to reduce the size of the build and prevent OOM errors
-checkRoute "$APP_ROUTER_APPS_SLUG_SETUP_ENABLED" app/future/apps/\[slug\]/setup
-checkRoute "$APP_ROUTER_TEAM_ENABLED" app/future/team
-
-# These are routes that don't have and environment variable to enable or disable them
-# Will stop removing gradually as we test and confirm that they are working
-rm -rf \
- app/future/d\
- app/future/enterprise\
- app/future/org\
- app/future/payment\
- app/future/reschedule\
- app/future/routing-forms\
- app/future/signup\
-
-exit 1
diff --git a/apps/web/server/lib/auth/forgot-password/[id]/getServerSideProps.tsx b/apps/web/server/lib/auth/forgot-password/[id]/getServerSideProps.tsx
index 0ae3cf1906..c511604ad9 100644
--- a/apps/web/server/lib/auth/forgot-password/[id]/getServerSideProps.tsx
+++ b/apps/web/server/lib/auth/forgot-password/[id]/getServerSideProps.tsx
@@ -1,8 +1,6 @@
import type { GetServerSidePropsContext } from "next";
import { getCsrfToken } from "next-auth/react";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
-import { getLocale } from "@calcom/features/auth/lib/getLocale";
import prisma from "@calcom/prisma";
export async function getServerSideProps(context: GetServerSidePropsContext) {
@@ -25,13 +23,12 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
} catch (e) {
resetPasswordRequest = null;
}
- const locale = await getLocale(context.req);
+
return {
props: {
isRequestExpired: !resetPasswordRequest,
requestId: id,
csrfToken: await getCsrfToken({ req: context.req }),
- ...(await serverSideTranslations(locale, ["common"])),
},
};
}
diff --git a/apps/web/server/lib/getTranslations.ts b/apps/web/server/lib/getTranslations.ts
deleted file mode 100644
index e8aaba052f..0000000000
--- a/apps/web/server/lib/getTranslations.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import type { GetStaticPropsContext } from "next";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
-
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const { i18n } = require("@calcom/config/next-i18next.config");
-
-export async function getTranslations(
- opts: GetStaticPropsContext
-) {
- const requestedLocale = opts.params?.locale || opts.locale || i18n.defaultLocale;
- const isSupportedLocale = i18n.locales.includes(requestedLocale);
- if (!isSupportedLocale) {
- console.warn(`Requested unsupported locale "${requestedLocale}"`);
- }
- const locale = isSupportedLocale ? requestedLocale : i18n.defaultLocale;
-
- const _i18n = await serverSideTranslations(locale, ["common"]);
-
- return {
- i18n: _i18n,
- };
-}
diff --git a/apps/web/server/lib/ssr.ts b/apps/web/server/lib/ssr.ts
index d99fb56983..42bc111b70 100644
--- a/apps/web/server/lib/ssr.ts
+++ b/apps/web/server/lib/ssr.ts
@@ -1,11 +1,9 @@
import type { GetServerSidePropsContext } from "next";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import superjson from "superjson";
import { forms } from "@calcom/app-store/routing-forms/trpc/procedures/forms";
import { getLocale } from "@calcom/features/auth/lib/getLocale";
import { map } from "@calcom/features/flags/server/procedures/map";
-import { CALCOM_VERSION } from "@calcom/lib/constants";
import { createContext } from "@calcom/trpc/server/createContext";
import { teamsAndUserProfilesQuery } from "@calcom/trpc/server/routers/loggedInViewer/procedures/teamsAndUserProfilesQuery";
import { event } from "@calcom/trpc/server/routers/publicViewer/procedures/event";
@@ -54,24 +52,13 @@ const routerSlice = router({
export async function ssrInit(context: GetServerSidePropsContext, options?: { noI18nPreload: boolean }) {
const ctx = await createContext(context);
const locale = await getLocale(context.req);
- const i18n = await serverSideTranslations(locale, ["common", "vital"]);
const ssr = createServerSideHelpers({
router: routerSlice,
transformer: superjson,
- ctx: { ...ctx, locale, i18n },
+ ctx: { ...ctx, locale },
});
- // i18n translations are already retrieved from serverSideTranslations call, there is no need to run a i18n.fetch
- // we can set query data directly to the queryClient
- const queryKey = [
- ["viewer", "public", "i18n"],
- { input: { locale, CalComVersion: CALCOM_VERSION }, type: "query" },
- ];
- if (!options?.noI18nPreload) {
- ssr.queryClient.setQueryData(queryKey, { i18n });
- }
-
await Promise.allSettled([
// So feature flags are available on first render
ssr.viewer.features.map.prefetch(),
diff --git a/apps/web/styles/globals.css b/apps/web/styles/globals.css
index 163fda356c..5446ff5955 100644
--- a/apps/web/styles/globals.css
+++ b/apps/web/styles/globals.css
@@ -1,3 +1,6 @@
+/* @import rules must precede all rules aside from @charset and @layer statements. */
+@import "./raqb.css";
+
@tailwind base;
@tailwind components;
@tailwind utilities;
@@ -9,48 +12,48 @@
--cal-spacing-0: 0px;
--cal-spacing-px: 1px;
--cal-spacing-0_5: 0.125rem; /* 2px */
- --cal-spacing-1: 0.25rem; /* 4px */
+ --cal-spacing-1: 0.25rem; /* 4px */
--cal-spacing-1_5: 0.375rem; /* 6px */
- --cal-spacing-2: 0.5rem; /* 8px */
+ --cal-spacing-2: 0.5rem; /* 8px */
--cal-spacing-2_5: 0.625rem; /* 10px */
- --cal-spacing-3: 0.75rem; /* 12px */
+ --cal-spacing-3: 0.75rem; /* 12px */
--cal-spacing-3_5: 0.875rem; /* 14px */
- --cal-spacing-4: 1rem; /* 16px */
- --cal-spacing-5: 1.25rem; /* 20px */
- --cal-spacing-6: 1.5rem; /* 24px */
- --cal-spacing-7: 1.75rem; /* 28px */
- --cal-spacing-8: 2rem; /* 32px */
- --cal-spacing-9: 2.25rem; /* 36px */
- --cal-spacing-10: 2.5rem; /* 40px */
- --cal-spacing-11: 2.75rem; /* 44px */
- --cal-spacing-12: 3rem; /* 48px */
- --cal-spacing-14: 3.5rem; /* 56px */
- --cal-spacing-16: 4rem; /* 64px */
- --cal-spacing-20: 5rem; /* 80px */
- --cal-spacing-24: 6rem; /* 96px */
- --cal-spacing-28: 7rem; /* 112px */
- --cal-spacing-32: 8rem; /* 128px */
- --cal-spacing-36: 9rem; /* 144px */
- --cal-spacing-40: 10rem; /* 160px */
- --cal-spacing-44: 11rem; /* 176px */
- --cal-spacing-48: 12rem; /* 192px */
- --cal-spacing-52: 13rem; /* 208px */
- --cal-spacing-56: 14rem; /* 224px */
- --cal-spacing-60: 15rem; /* 240px */
- --cal-spacing-64: 16rem; /* 256px */
- --cal-spacing-72: 18rem; /* 288px */
- --cal-spacing-80: 20rem; /* 320px */
- --cal-spacing-96: 24rem; /* 384px */
+ --cal-spacing-4: 1rem; /* 16px */
+ --cal-spacing-5: 1.25rem; /* 20px */
+ --cal-spacing-6: 1.5rem; /* 24px */
+ --cal-spacing-7: 1.75rem; /* 28px */
+ --cal-spacing-8: 2rem; /* 32px */
+ --cal-spacing-9: 2.25rem; /* 36px */
+ --cal-spacing-10: 2.5rem; /* 40px */
+ --cal-spacing-11: 2.75rem; /* 44px */
+ --cal-spacing-12: 3rem; /* 48px */
+ --cal-spacing-14: 3.5rem; /* 56px */
+ --cal-spacing-16: 4rem; /* 64px */
+ --cal-spacing-20: 5rem; /* 80px */
+ --cal-spacing-24: 6rem; /* 96px */
+ --cal-spacing-28: 7rem; /* 112px */
+ --cal-spacing-32: 8rem; /* 128px */
+ --cal-spacing-36: 9rem; /* 144px */
+ --cal-spacing-40: 10rem; /* 160px */
+ --cal-spacing-44: 11rem; /* 176px */
+ --cal-spacing-48: 12rem; /* 192px */
+ --cal-spacing-52: 13rem; /* 208px */
+ --cal-spacing-56: 14rem; /* 224px */
+ --cal-spacing-60: 15rem; /* 240px */
+ --cal-spacing-64: 16rem; /* 256px */
+ --cal-spacing-72: 18rem; /* 288px */
+ --cal-spacing-80: 20rem; /* 320px */
+ --cal-spacing-96: 24rem; /* 384px */
/* Border Radius */
--cal-radius-none: 0px;
- --cal-radius-sm: 0.125rem; /* 2px */
- --cal-radius: 0.25rem; /* 4px */
- --cal-radius-md: 0.375rem; /* 6px */
- --cal-radius-lg: 0.5rem; /* 8px */
- --cal-radius-xl: 0.75rem; /* 12px */
- --cal-radius-2xl: 1rem; /* 16px */
- --cal-radius-3xl: 1.5rem; /* 24px */
+ --cal-radius-sm: 0.125rem; /* 2px */
+ --cal-radius: 0.25rem; /* 4px */
+ --cal-radius-md: 0.375rem; /* 6px */
+ --cal-radius-lg: 0.5rem; /* 8px */
+ --cal-radius-xl: 0.75rem; /* 12px */
+ --cal-radius-2xl: 1rem; /* 16px */
+ --cal-radius-3xl: 1.5rem; /* 24px */
--cal-radius-full: 9999px;
/* Background Standard */
@@ -69,7 +72,7 @@
--cal-bg-brand: hsla(214, 30%, 16%, 1); /* gray-50 */
--cal-bg-brand-emphasis: hsla(220, 6%, 25%, 1); /* stone-100 */
--cal-bg-brand-muted: hsla(220, 14%, 94%, 1); /* stone-100 */
-
+
/* Background Semantic */
--cal-bg-semantic-info-subtle: hsla(212, 88%, 97%, 1); /* blue-100 */
--cal-bg-semantic-info-emphasis: hsla(236, 80%, 25%, 1); /* blue-500 */
@@ -135,8 +138,8 @@
--cal-text-visualization-7: hsla(0, 84%, 25%, 1); /* red-800 */
/* Border/Semantic Subtle */
- --cal-border-semantic-attention-subtle: hsla(32, 98%, 83%, 1);
- --cal-border-semantic-error-subtle: hsla(0, 96%, 89%, 1);
+ --cal-border-semantic-attention-subtle: hsla(32, 98%, 83%, 1);
+ --cal-border-semantic-error-subtle: hsla(0, 96%, 89%, 1);
/* Legacy Content/Text Components - Consider deprecating */
--cal-text-info: hsla(225, 57%, 33%, 1); /* #253985 - interactive text/icons */
@@ -209,11 +212,9 @@
/* Border Semantic */
--cal-border-semantic-error: hsla(0, 63%, 24%, 1); /* red-800 */
-
/* Border/Semantic Subtle */
- --cal-border-semantic-attention-subtle: hsla(15, 75%, 23%, 1);
- --cal-border-semantic-error-subtle: hsla(0, 63%, 24%, 1);
-
+ --cal-border-semantic-attention-subtle: hsla(15, 75%, 23%, 1);
+ --cal-border-semantic-error-subtle: hsla(0, 63%, 24%, 1);
/* Legacy Border - Consider deprecating */
--cal-border-error: hsla(0, 63%, 24%, 1); /* Keeping existing error border */
@@ -251,7 +252,7 @@
@layer base {
* {
- @apply border-default
+ @apply border-default;
}
}
@@ -275,7 +276,7 @@ body {
https://docs.todesktop.com/
*/
-html.todesktop-platform-win32 .todesktop\:\!bg-transparent{
+html.todesktop-platform-win32 .todesktop\:\!bg-transparent {
background: inherit !important;
}
@@ -308,7 +309,8 @@ html.todesktop header a {
-webkit-app-region: no-drag;
}
-html.todesktop-platform-darwin body, html.todesktop-platform-darwin aside {
+html.todesktop-platform-darwin body,
+html.todesktop-platform-darwin aside {
background: transparent !important;
}
@@ -634,12 +636,10 @@ select:focus {
@apply !border-r-default left-0.5 !border-y-0 !border-l-0;
}
-.intercom-lightweight-app {
+.intercom-lightweight-app {
@apply z-40 !important;
}
[data-radix-popper-content-wrapper] {
border: none;
}
-
-@import "./raqb.css";
diff --git a/apps/web/test/lib/plainTiers.test.ts b/apps/web/test/lib/plainTiers.test.ts
index 70addf52c4..6d67fec3f7 100644
--- a/apps/web/test/lib/plainTiers.test.ts
+++ b/apps/web/test/lib/plainTiers.test.ts
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import prismaMock from "../../../../tests/libs/__mocks__/prismaMock";
+import type { Params } from "app/_types";
import type { NextRequest } from "next/server";
import { describe, it, expect, vi, beforeAll, beforeEach } from "vitest";
@@ -76,13 +77,16 @@ describe("Plain Integration API", () => {
const userData = { id: 1, email: `${tier}@example.com`, name: `${tier} User` };
(getServerSession as any).mockResolvedValue({ user: userData });
prismaMock.user.findUnique.mockResolvedValue({ ...userData, teams });
+ const params = Promise.resolve({})
- const data = await (await POST({} as NextRequest, { params: {} })).json();
+ const data = await (await POST({} as NextRequest, { params })).json();
expect(data).toMatchObject({ userTier: tier, email: userData.email, fullName: userData.name });
});
it("should return 401 when no session exists", async () => {
(getServerSession as any).mockResolvedValue(null);
- expect((await POST({} as NextRequest, { params: {} })).status).toBe(401);
+ const params = Promise.resolve({})
+
+ expect((await POST({} as NextRequest, { params })).status).toBe(401);
});
});
diff --git a/apps/web/test/utils/bookingScenario/bookingScenario.ts b/apps/web/test/utils/bookingScenario/bookingScenario.ts
index 230849914c..190edfbaa2 100644
--- a/apps/web/test/utils/bookingScenario/bookingScenario.ts
+++ b/apps/web/test/utils/bookingScenario/bookingScenario.ts
@@ -1575,7 +1575,6 @@ export function mockNoTranslations() {
i18nMock.getTranslation.mockImplementation(() => {
return new Promise((resolve) => {
const identityFn = (key: string) => key;
- // @ts-expect-error FIXME
resolve(identityFn);
});
});
diff --git a/packages/app-store/alby/components/AlbyPaymentComponent.tsx b/packages/app-store/alby/components/AlbyPaymentComponent.tsx
index dd90b44567..e65d71e657 100644
--- a/packages/app-store/alby/components/AlbyPaymentComponent.tsx
+++ b/packages/app-store/alby/components/AlbyPaymentComponent.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import Link from "next/link";
import { useEffect, useState } from "react";
import QRCode from "react-qr-code";
diff --git a/packages/app-store/exchangecalendar/lib/CalendarService.ts b/packages/app-store/exchangecalendar/lib/CalendarService.ts
index e0dd65b07e..b781761e2e 100644
--- a/packages/app-store/exchangecalendar/lib/CalendarService.ts
+++ b/packages/app-store/exchangecalendar/lib/CalendarService.ts
@@ -1,4 +1,3 @@
-import { XhrApi } from "@ewsjs/xhr";
import type { FindFoldersResults, FindItemsResults } from "ews-javascript-api";
import {
Appointment,
@@ -55,7 +54,7 @@ export default class ExchangeCalendarService implements Calendar {
}
async createEvent(event: CalendarEvent): Promise {
- const appointment: Appointment = new Appointment(this.getExchangeService());
+ const appointment: Appointment = new Appointment(await this.getExchangeService());
appointment.Subject = event.title;
appointment.Start = DateTime.Parse(event.startTime);
appointment.End = DateTime.Parse(event.endTime);
@@ -91,7 +90,7 @@ export default class ExchangeCalendarService implements Calendar {
uid: string,
event: CalendarEvent
): Promise {
- const appointment: Appointment = await Appointment.Bind(this.getExchangeService(), new ItemId(uid));
+ const appointment: Appointment = await Appointment.Bind(await this.getExchangeService(), new ItemId(uid));
appointment.Subject = event.title;
appointment.Start = DateTime.Parse(event.startTime);
appointment.End = DateTime.Parse(event.endTime);
@@ -127,7 +126,7 @@ export default class ExchangeCalendarService implements Calendar {
}
async deleteEvent(uid: string): Promise {
- const appointment: Appointment = await Appointment.Bind(this.getExchangeService(), new ItemId(uid));
+ const appointment: Appointment = await Appointment.Bind(await this.getExchangeService(), new ItemId(uid));
return appointment.Delete(DeleteMode.MoveToDeletedItems).catch((reason) => {
this.log.error(reason);
throw reason;
@@ -143,7 +142,7 @@ export default class ExchangeCalendarService implements Calendar {
const promises: Promise[] = calendars
.filter((lcal) => selectedCalendars.some((rcal) => lcal.externalId == rcal.externalId))
.map(async (calendar) => {
- return this.getExchangeService()
+ return (await this.getExchangeService())
.FindAppointments(
new FolderId(calendar.externalId),
new CalendarView(DateTime.Parse(dateFrom), DateTime.Parse(dateTo))
@@ -167,7 +166,7 @@ export default class ExchangeCalendarService implements Calendar {
}
async listCalendars(): Promise {
- const service: ExchangeService = this.getExchangeService();
+ const service: ExchangeService = await this.getExchangeService();
const view: FolderView = new FolderView(1000);
view.PropertySet = new PropertySet(BasePropertySet.IdOnly);
view.PropertySet.Add(FolderSchema.ParentFolderId);
@@ -197,12 +196,13 @@ export default class ExchangeCalendarService implements Calendar {
});
}
- private getExchangeService(): ExchangeService {
+ private async getExchangeService(): Promise {
const service: ExchangeService = new ExchangeService(this.payload.exchangeVersion);
service.Credentials = new WebCredentials(this.payload.username, this.payload.password);
service.Url = new Uri(this.payload.url);
if (this.payload.authenticationMethod === ExchangeAuthentication.NTLM) {
- const xhr: XhrApi = new XhrApi({
+ const { XhrApi } = await import("@ewsjs/xhr");
+ const xhr = new XhrApi({
rejectUnauthorized: false,
}).useNtlmAuthentication(this.payload.username, this.payload.password);
service.XHRApi = xhr;
diff --git a/packages/app-store/locations.ts b/packages/app-store/locations.ts
index 52255bb273..bb5deeb94e 100644
--- a/packages/app-store/locations.ts
+++ b/packages/app-store/locations.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { z } from "zod";
import { appStoreMetadata } from "@calcom/app-store/bookerAppsMetaData";
diff --git a/packages/app-store/make/pages/setup/index.tsx b/packages/app-store/make/pages/setup/index.tsx
index e3589bd5fa..4eb737475d 100644
--- a/packages/app-store/make/pages/setup/index.tsx
+++ b/packages/app-store/make/pages/setup/index.tsx
@@ -1,5 +1,4 @@
import type { InferGetServerSidePropsType } from "next";
-import { Trans } from "next-i18next";
import Link from "next/link";
import { useState } from "react";
import { Toaster } from "sonner";
@@ -11,6 +10,7 @@ import { Button } from "@calcom/ui/components/button";
import { Icon } from "@calcom/ui/components/icon";
import { showToast } from "@calcom/ui/components/toast";
import { Tooltip } from "@calcom/ui/components/tooltip";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import type { getServerSideProps } from "./_getServerSideProps";
@@ -115,20 +115,25 @@ export default function MakeSetup({ inviteLink }: InferGetServerSidePropsType
-
-
- Go to
-
- Make Invite Link
-
- and install the Cal.com app.
-
- Log into your Make account and create a new Scenario.
- Select Cal.com as your Trigger app. Also choose a Trigger event.
- Choose your account and then enter your Unique API Key.
- Test your Trigger.
- You're set!
-
+
+
+ Make Invite Link
+ ,
+ ]}
+ />
+
+ {t("make_setup_instructions_2")}
+ {t("make_setup_instructions_3")}
+ {t("make_setup_instructions_4")}
+ {t("make_setup_instructions_5")}
+ {t("make_setup_instructions_6")}
{t("done")}
diff --git a/packages/app-store/routing-forms/components/getServerSidePropsSingleForm.ts b/packages/app-store/routing-forms/components/getServerSidePropsSingleForm.ts
index 582670de8f..b65bc23ca1 100644
--- a/packages/app-store/routing-forms/components/getServerSidePropsSingleForm.ts
+++ b/packages/app-store/routing-forms/components/getServerSidePropsSingleForm.ts
@@ -114,7 +114,6 @@ export const getServerSidePropsForSingleFormView = async function getServerSideP
return {
props: {
- trpcState: await ssr.dehydrate(),
form: await getSerializableForm({ form: formWithoutProfileInfo }),
enrichedWithUserProfileForm: await getSerializableForm({
form: enrichFormWithMigrationData(formWithUserInfoProfile),
diff --git a/packages/app-store/routing-forms/pages/app-routing.client-config.tsx b/packages/app-store/routing-forms/pages/app-routing.client-config.tsx
new file mode 100644
index 0000000000..d1e9da2043
--- /dev/null
+++ b/packages/app-store/routing-forms/pages/app-routing.client-config.tsx
@@ -0,0 +1,8 @@
+export const routingFormsComponents = {
+ "form-edit": () => import("./form-edit/[...appPages]").then((mod) => mod.default),
+ "route-builder": () => import("./route-builder/[...appPages]").then((mod) => mod.default),
+ "forms": () => import("./forms/[...appPages]").then((mod) => mod.default),
+ "routing-link": () => import("./routing-link/[...appPages]").then((mod) => mod.default),
+ "reporting": () => import("./reporting/[...appPages]").then((mod) => mod.default),
+ "incomplete-booking": () => import("./incomplete-booking/[...appPages]").then((mod) => mod.default),
+};
\ No newline at end of file
diff --git a/packages/app-store/routing-forms/pages/app-routing.config.tsx b/packages/app-store/routing-forms/pages/app-routing.server-config.tsx
similarity index 50%
rename from packages/app-store/routing-forms/pages/app-routing.config.tsx
rename to packages/app-store/routing-forms/pages/app-routing.server-config.tsx
index 2c7ba5f788..7945db3f6a 100644
--- a/packages/app-store/routing-forms/pages/app-routing.config.tsx
+++ b/packages/app-store/routing-forms/pages/app-routing.server-config.tsx
@@ -1,26 +1,11 @@
-//TODO: Generate this file automatically so that like in Next.js file based routing can work automatically
+import "server-only";
+
import type { AppGetServerSideProps } from "@calcom/types/AppGetServerSideProps";
import { getServerSidePropsForSingleFormView as getServerSidePropsSingleForm } from "../components/getServerSidePropsSingleForm";
-import * as formEdit from "./form-edit/[...appPages]";
-import * as forms from "./forms/[...appPages]";
-// extracts getServerSideProps function from the client component
import { getServerSideProps as getServerSidePropsForms } from "./forms/getServerSideProps";
-import * as IncompleteBooking from "./incomplete-booking/[...appPages]";
-import * as Reporting from "./reporting/[...appPages]";
-import * as RouteBuilder from "./route-builder/[...appPages]";
-import * as RoutingLink from "./routing-link/[...appPages]";
import { getServerSideProps as getServerSidePropsRoutingLink } from "./routing-link/getServerSideProps";
-const routingConfig = {
- "form-edit": formEdit,
- "route-builder": RouteBuilder,
- forms: forms,
- "routing-link": RoutingLink,
- reporting: Reporting,
- "incomplete-booking": IncompleteBooking,
-};
-
export const routingServerSidePropsConfig: Record = {
forms: getServerSidePropsForms,
"form-edit": getServerSidePropsSingleForm,
@@ -29,5 +14,3 @@ export const routingServerSidePropsConfig: Record
reporting: getServerSidePropsSingleForm,
"incomplete-booking": getServerSidePropsSingleForm,
};
-
-export default routingConfig;
diff --git a/packages/app-store/routing-forms/pages/forms/getServerSideProps.ts b/packages/app-store/routing-forms/pages/forms/getServerSideProps.ts
index 345c0b3e5f..725b220a3b 100644
--- a/packages/app-store/routing-forms/pages/forms/getServerSideProps.ts
+++ b/packages/app-store/routing-forms/pages/forms/getServerSideProps.ts
@@ -30,8 +30,6 @@ export const getServerSideProps = async function getServerSideProps(
// Prefetch this so that New Button is immediately available
await ssr.viewer.teamsAndUserProfilesQuery.prefetch();
return {
- props: {
- trpcState: await ssr.dehydrate(),
- },
+ props: {},
};
};
diff --git a/packages/app-store/routing-forms/pages/layout-handler/[...appPages].tsx b/packages/app-store/routing-forms/pages/layout-handler/[...appPages].tsx
deleted file mode 100644
index 48ec8d4ed4..0000000000
--- a/packages/app-store/routing-forms/pages/layout-handler/[...appPages].tsx
+++ /dev/null
@@ -1,41 +0,0 @@
-"use client";
-
-import type { GetServerSidePropsContext, GetServerSideProps } from "next";
-import type { ReactElement, ReactNode, ComponentType } from "react";
-import { FormProvider, useForm } from "react-hook-form";
-
-import { useParamsWithFallback } from "@calcom/lib/hooks/useParamsWithFallback";
-
-import RoutingFormsRoutingConfig from "../app-routing.config";
-
-const DEFAULT_ROUTE = "forms";
-
-type ComponentWithLayout = ComponentType & {
- getLayout?: (page: ReactElement) => ReactNode;
-};
-
-type Component = {
- default: ComponentWithLayout;
- getServerSideProps?: (
- context: GetServerSidePropsContext,
- ...rest: Parameters
- ) => ReturnType;
-};
-
-const getComponent = (route: string): Component => {
- return (RoutingFormsRoutingConfig as unknown as Record)[route];
-};
-
-export default function LayoutHandler(props: { [key: string]: unknown }) {
- const params = useParamsWithFallback();
- const methods = useForm();
- const pageKey = Array.isArray(params.pages)
- ? params.pages[0]
- : params.pages?.split("/")[0] ?? DEFAULT_ROUTE;
- const PageComponent = getComponent(pageKey).default;
- return (
-
-
-
- );
-}
diff --git a/packages/app-store/server.ts b/packages/app-store/server.ts
index e948427c8e..75261d1af3 100644
--- a/packages/app-store/server.ts
+++ b/packages/app-store/server.ts
@@ -1,5 +1,5 @@
import type { Prisma } from "@prisma/client";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { defaultVideoAppCategories } from "@calcom/app-store/utils";
import getEnabledAppsFromCredentials from "@calcom/lib/apps/getEnabledAppsFromCredentials";
diff --git a/packages/app-store/vital/lib/client.ts b/packages/app-store/vital/lib/client.ts
index 0196a8ec5d..5ae7384218 100644
--- a/packages/app-store/vital/lib/client.ts
+++ b/packages/app-store/vital/lib/client.ts
@@ -1,4 +1,3 @@
-import { VitalClient } from "@tryvital/vital-node";
import type { ClientConfig } from "@tryvital/vital-node/dist/lib/models";
import getAppKeysFromSlug from "../../_utils/getAppKeysFromSlug";
@@ -8,10 +7,10 @@ type VitalEnv = ClientConfig & {
webhook_secret: string;
};
-export let vitalClient: VitalClient | null = null;
+export let vitalClient: any = null;
export let vitalEnv: VitalEnv | null = null;
-export async function initVitalClient(): Promise {
+export async function initVitalClient() {
if (vitalClient) return vitalClient;
const appKeys = (await getAppKeysFromSlug("vital-automation")) as unknown as VitalEnv;
if (
@@ -23,6 +22,7 @@ export async function initVitalClient(): Promise {
)
throw Error("Missing properties in vital-automation DB keys");
vitalEnv = appKeys;
+ const { VitalClient } = await import("@tryvital/vital-node");
vitalClient = new VitalClient({
region: appKeys.region,
api_key: appKeys.api_key || "",
diff --git a/packages/app-store/vital/lib/reschedule.ts b/packages/app-store/vital/lib/reschedule.ts
index 655e105102..285ff44afa 100644
--- a/packages/app-store/vital/lib/reschedule.ts
+++ b/packages/app-store/vital/lib/reschedule.ts
@@ -1,5 +1,5 @@
import type { Booking, BookingReference, User } from "@prisma/client";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import dayjs from "@calcom/dayjs";
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails";
diff --git a/packages/app-store/wipemycalother/lib/reschedule.ts b/packages/app-store/wipemycalother/lib/reschedule.ts
index 1473b3b66a..8974608ee7 100644
--- a/packages/app-store/wipemycalother/lib/reschedule.ts
+++ b/packages/app-store/wipemycalother/lib/reschedule.ts
@@ -1,5 +1,5 @@
import type { Booking, BookingReference, User } from "@prisma/client";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import dayjs from "@calcom/dayjs";
import { sendRequestRescheduleEmailAndSMS } from "@calcom/emails";
diff --git a/packages/app-store/zapier/pages/setup/index.tsx b/packages/app-store/zapier/pages/setup/index.tsx
index c900b3c07e..12798cf44d 100644
--- a/packages/app-store/zapier/pages/setup/index.tsx
+++ b/packages/app-store/zapier/pages/setup/index.tsx
@@ -1,4 +1,3 @@
-import { Trans } from "next-i18next";
import Link from "next/link";
import { useState } from "react";
import { Toaster } from "sonner";
@@ -6,10 +5,11 @@ import { Toaster } from "sonner";
import AppNotInstalledMessage from "@calcom/app-store/_components/AppNotInstalledMessage";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
-import { Icon } from "@calcom/ui/components/icon";
-import { Tooltip } from "@calcom/ui/components/tooltip";
import { Button } from "@calcom/ui/components/button";
+import { Icon } from "@calcom/ui/components/icon";
import { showToast } from "@calcom/ui/components/toast";
+import { Tooltip } from "@calcom/ui/components/tooltip";
+import ServerTrans from "@calcom/web/components/ServerTrans";
export interface IZapierSetupProps {
inviteLink?: string;
@@ -124,13 +124,19 @@ export default function ZapierSetup(props: IZapierSetupProps) {
)}
-
- Log into your Zapier account and create a new Zap.
- Select Cal.com as your Trigger app. Also choose a Trigger event.
- Choose your account and then enter your Unique API Key.
- Test your Trigger.
- You're set!
-
+ Log into your Zapier account and create a new Zap.,
+
+ Select Cal.com as your Trigger app. Also choose a Trigger event.
+ ,
+ Choose your account and then enter your Unique API Key. ,
+ Test your Trigger. ,
+ You're set! ,
+ ]}
+ />
{t("done")}
diff --git a/packages/emails/email-manager.ts b/packages/emails/email-manager.ts
index d45cfc3ac0..2870182071 100644
--- a/packages/emails/email-manager.ts
+++ b/packages/emails/email-manager.ts
@@ -1,6 +1,6 @@
// eslint-disable-next-line no-restricted-imports
import { cloneDeep } from "lodash";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import type { z } from "zod";
import type BaseEmail from "@calcom/emails/templates/_base-email";
diff --git a/packages/emails/lib/generateIcsFile.ts b/packages/emails/lib/generateIcsFile.ts
index 53f2e32f09..022e20ff27 100644
--- a/packages/emails/lib/generateIcsFile.ts
+++ b/packages/emails/lib/generateIcsFile.ts
@@ -1,5 +1,5 @@
import type { EventStatus } from "ics";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import type { CalendarEvent } from "@calcom/types/Calendar";
diff --git a/packages/emails/lib/generateIcsString.ts b/packages/emails/lib/generateIcsString.ts
index d3e327f544..f4563f66f1 100644
--- a/packages/emails/lib/generateIcsString.ts
+++ b/packages/emails/lib/generateIcsString.ts
@@ -1,6 +1,6 @@
import type { DateArray, ParticipationRole, EventStatus, ParticipationStatus } from "ics";
import { createEvent } from "ics";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { RRule } from "rrule";
import { getRichDescription } from "@calcom/lib/CalEventParser";
diff --git a/packages/emails/package.json b/packages/emails/package.json
index 8327255745..1031261fe1 100644
--- a/packages/emails/package.json
+++ b/packages/emails/package.json
@@ -9,7 +9,7 @@
"dependencies": {
"@calcom/dayjs": "*",
"@calcom/lib": "*",
- "next-i18next": "^13.2.2",
+ "next-i18next": "^15.4.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rrule": "^2.7.1"
diff --git a/packages/emails/src/components/AppsStatus.tsx b/packages/emails/src/components/AppsStatus.tsx
index a42d8aefa9..e7f4e0d1fb 100644
--- a/packages/emails/src/components/AppsStatus.tsx
+++ b/packages/emails/src/components/AppsStatus.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import type { CalendarEvent } from "@calcom/types/Calendar";
diff --git a/packages/emails/src/components/LocationInfo.tsx b/packages/emails/src/components/LocationInfo.tsx
index 0766f905ca..999d523deb 100644
--- a/packages/emails/src/components/LocationInfo.tsx
+++ b/packages/emails/src/components/LocationInfo.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { guessEventLocationType } from "@calcom/app-store/locations";
import { getVideoCallUrlFromCalEvent } from "@calcom/lib/CalEventParser";
diff --git a/packages/emails/src/components/UserFieldsResponses.tsx b/packages/emails/src/components/UserFieldsResponses.tsx
index 0df70b467b..6d3fd92281 100644
--- a/packages/emails/src/components/UserFieldsResponses.tsx
+++ b/packages/emails/src/components/UserFieldsResponses.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import getLabelValueMapFromResponses from "@calcom/lib/getLabelValueMapFromResponses";
import type { CalendarEvent } from "@calcom/types/Calendar";
diff --git a/packages/emails/src/components/WhenInfo.tsx b/packages/emails/src/components/WhenInfo.tsx
index 5f27015d47..801df21731 100644
--- a/packages/emails/src/components/WhenInfo.tsx
+++ b/packages/emails/src/components/WhenInfo.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { RRule } from "rrule";
import dayjs from "@calcom/dayjs";
diff --git a/packages/emails/src/components/WhoInfo.tsx b/packages/emails/src/components/WhoInfo.tsx
index 0b3f199221..27341a1933 100644
--- a/packages/emails/src/components/WhoInfo.tsx
+++ b/packages/emails/src/components/WhoInfo.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import isSmsCalEmail from "@calcom/lib/isSmsCalEmail";
import type { CalendarEvent } from "@calcom/types/Calendar";
diff --git a/packages/emails/src/templates/AdminOrganizationNotificationEmail.tsx b/packages/emails/src/templates/AdminOrganizationNotificationEmail.tsx
index b6e9198e56..bbafb9e8cc 100644
--- a/packages/emails/src/templates/AdminOrganizationNotificationEmail.tsx
+++ b/packages/emails/src/templates/AdminOrganizationNotificationEmail.tsx
@@ -1,8 +1,7 @@
-"use client";
-
-import { Trans, type TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import { BaseEmailHtml, CallToAction } from "../components";
@@ -92,20 +91,7 @@ export const AdminOrganizationNotificationEmail = ({
<>{language("hi_admin")}!>
-
- An organization with slug {`"${orgSlug}"`} was created.
-
-
- Please be sure to configure your DNS registry to point the subdomain corresponding to the new
- organization to where the main app is running. Otherwise the organization will not work.
-
-
- Here are just the very basic options to configure a subdomain to point to their app so it loads the
- organization profile page.
-
-
- You can do it either with the A Record:
-
+
{dnsTable("A", orgSlug, webappIPAddress, language)}
diff --git a/packages/emails/src/templates/BaseScheduledEmail.tsx b/packages/emails/src/templates/BaseScheduledEmail.tsx
index 492317757e..14be1911c5 100644
--- a/packages/emails/src/templates/BaseScheduledEmail.tsx
+++ b/packages/emails/src/templates/BaseScheduledEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import dayjs from "@calcom/dayjs";
import { formatPrice } from "@calcom/lib/price";
diff --git a/packages/emails/src/templates/BrokenIntegrationEmail.tsx b/packages/emails/src/templates/BrokenIntegrationEmail.tsx
index d7ebe70026..cfdbcca8c8 100644
--- a/packages/emails/src/templates/BrokenIntegrationEmail.tsx
+++ b/packages/emails/src/templates/BrokenIntegrationEmail.tsx
@@ -1,11 +1,9 @@
-"use client";
-
-import type { TFunction } from "next-i18next";
-import { Trans } from "react-i18next";
+import type { TFunction } from "i18next";
import { AppStoreLocationType } from "@calcom/app-store/locations";
import { WEBAPP_URL } from "@calcom/lib/constants";
import type { CalendarEvent, Person } from "@calcom/types/Calendar";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import { BaseScheduledEmail } from "./BaseScheduledEmail";
@@ -17,18 +15,27 @@ export function getEnumKeyByEnumValue(myEnum: any, enumValue: number | string):
const BrokenVideoIntegration = (props: { location: string; eventTypeId?: number | null; t: TFunction }) => {
return (
-
- We could not add the {props.location} meeting link to your scheduled event. Contact your
- invitees or update your calendar event to add the details. You can either
-
- change your location on the event type
-
- or try
- removing and adding the app again.
-
+
+ change your location on the event type
+ ,
+
+ removing and adding the app again.
+ ,
+ ]}
+ />
);
};
@@ -40,12 +47,13 @@ const BrokenCalendarIntegration = (props: {
const { t } = props;
return (
-
- We could not update your {props.calendar} .{" "}
-
- Please check your calendar settings or remove and add your calendar again
-
-
+
+ {t("broken_calendar_action", {
+ calendar: props.calendar,
+ calendarSettingsLink: `${WEBAPP_URL}/apps/installed`,
+ interpolation: { escapeValue: false },
+ })}
+
);
};
diff --git a/packages/emails/src/templates/DailyVideoDownloadRecordingEmail.tsx b/packages/emails/src/templates/DailyVideoDownloadRecordingEmail.tsx
index d84c8a1f50..7d8bf81415 100644
--- a/packages/emails/src/templates/DailyVideoDownloadRecordingEmail.tsx
+++ b/packages/emails/src/templates/DailyVideoDownloadRecordingEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { WEBAPP_URL, APP_NAME, COMPANY_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/src/templates/DailyVideoDownloadTranscriptEmail.tsx b/packages/emails/src/templates/DailyVideoDownloadTranscriptEmail.tsx
index 3c9fa5ae9f..fe583a14d3 100644
--- a/packages/emails/src/templates/DailyVideoDownloadTranscriptEmail.tsx
+++ b/packages/emails/src/templates/DailyVideoDownloadTranscriptEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { WEBAPP_URL, COMPANY_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/src/templates/DisabledAppEmail.tsx b/packages/emails/src/templates/DisabledAppEmail.tsx
index 345ea0a76c..f24d7f8fc4 100644
--- a/packages/emails/src/templates/DisabledAppEmail.tsx
+++ b/packages/emails/src/templates/DisabledAppEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { WEBAPP_URL } from "@calcom/lib/constants";
diff --git a/packages/emails/src/templates/ForgotPasswordEmail.tsx b/packages/emails/src/templates/ForgotPasswordEmail.tsx
index e04c336dd1..575ad42d05 100644
--- a/packages/emails/src/templates/ForgotPasswordEmail.tsx
+++ b/packages/emails/src/templates/ForgotPasswordEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, SUPPORT_MAIL_ADDRESS } from "@calcom/lib/constants";
diff --git a/packages/emails/src/templates/MonthlyDigestEmail.tsx b/packages/emails/src/templates/MonthlyDigestEmail.tsx
index 86e7c21a2e..78978a9e81 100644
--- a/packages/emails/src/templates/MonthlyDigestEmail.tsx
+++ b/packages/emails/src/templates/MonthlyDigestEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, SENDER_NAME, SUPPORT_MAIL_ADDRESS } from "@calcom/lib/constants";
diff --git a/packages/emails/src/templates/OrgAutoInviteEmail.tsx b/packages/emails/src/templates/OrgAutoInviteEmail.tsx
index 7bed163473..913e357dd5 100644
--- a/packages/emails/src/templates/OrgAutoInviteEmail.tsx
+++ b/packages/emails/src/templates/OrgAutoInviteEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, WEBAPP_URL, IS_PRODUCTION } from "@calcom/lib/constants";
diff --git a/packages/emails/src/templates/OrganizationAccountVerifyEmail.tsx b/packages/emails/src/templates/OrganizationAccountVerifyEmail.tsx
index aa7ef5d989..8b0eb91c25 100644
--- a/packages/emails/src/templates/OrganizationAccountVerifyEmail.tsx
+++ b/packages/emails/src/templates/OrganizationAccountVerifyEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, SUPPORT_MAIL_ADDRESS, COMPANY_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/src/templates/OrganizationAdminNoSlots.tsx b/packages/emails/src/templates/OrganizationAdminNoSlots.tsx
index d0da37e2aa..9770f1f746 100644
--- a/packages/emails/src/templates/OrganizationAdminNoSlots.tsx
+++ b/packages/emails/src/templates/OrganizationAdminNoSlots.tsx
@@ -1,5 +1,6 @@
-import type { TFunction } from "next-i18next";
-import { Trans } from "next-i18next";
+import type { TFunction } from "i18next";
+
+import ServerTrans from "@calcom/web/components/ServerTrans";
import { BaseEmailHtml, CallToAction } from "../components";
@@ -30,25 +31,11 @@ export const OrganizationAdminNoSlotsEmail = (
<>{props.language("org_admin_no_slots|heading", { name: props.user })}>
-
- Hello Organization Admins,
-
-
- Please note: It has been brought to our attention that {props.user} has not had any availability
- when a user has visited {props.teamSlug}/{props.slug}.
-
- Start time: {props.startTime}
-
- End time: {props.endTime}
-
-
- There’s a few reasons why this could be happening:
-
-
- The user does not have any calendars connected
- Their schedules attached to this event are not enabled
-
-
+
{isNewUser ? (
-
+ <>
Enjoy your new organization link: {newLinkWithoutProtocol}
-
+ >
) : (
-
- Your link has been changed from {prevLinkWithoutProtocol} to{" "}
- {newLinkWithoutProtocol} but don't worry, all previous links
- still work and redirect appropriately.
-
-
- Please note: All of your personal event types have been moved into the
- {teamName}
- {" "}
- organisation, which may also include potential personal link.
-
-
- Please log in and make sure you have no private events on your new organisational account.
-
-
- For personal events we recommend creating a new account with a personal email address.
-
-
- Enjoy your new clean link: {newLinkWithoutProtocol}
-
+
+ {prevLinkWithoutProtocol}
+
+ ),
+ a1: (
+
+ {newLinkWithoutProtocol}
+
+ ),
+ a2: (
+
+ {newLinkWithoutProtocol}
+
+ ),
+ }}
+ values={{ teamName }}
+ />
)}
diff --git a/packages/emails/src/templates/SlugReplacementEmail.tsx b/packages/emails/src/templates/SlugReplacementEmail.tsx
index b8707a3b26..f1c65011eb 100644
--- a/packages/emails/src/templates/SlugReplacementEmail.tsx
+++ b/packages/emails/src/templates/SlugReplacementEmail.tsx
@@ -1,9 +1,7 @@
-"use client";
-
-import type { TFunction } from "next-i18next";
-import { Trans } from "next-i18next";
+import type { TFunction } from "i18next";
import { WEBAPP_URL } from "@calcom/lib/constants";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import { BaseEmailHtml, CallToAction } from "../components";
@@ -23,22 +21,14 @@ export const SlugReplacementEmail = (
headerType="teamCircle"
title={t("event_replaced_notice")}>
<>
-
- Hi {name}
- ,
-
-
-
- An administrator on the {teamName} team has replaced your event type{" "}
- /{slug} with a managed event type that they control.
-
-
-
-
- Your link will continue to work but some settings for it may have changed. You can review it in
- event types.
-
-
+
+
+
+ ,
+
+
+
+ {t("email_body_slug_replacement_info")}
-
-
- If you have any questions about the event type, please reach out to your administrator.
-
-
- Happy scheduling,
- The Cal.com team
-
-
+
+
+
{/*
<>{t("email_body_slug_replacement_suggestion")}>
*/}
diff --git a/packages/emails/src/templates/TeamInviteEmail.tsx b/packages/emails/src/templates/TeamInviteEmail.tsx
index 77ee69c4b0..2e403a3e0d 100644
--- a/packages/emails/src/templates/TeamInviteEmail.tsx
+++ b/packages/emails/src/templates/TeamInviteEmail.tsx
@@ -1,7 +1,7 @@
-import type { TFunction } from "next-i18next";
-import { Trans } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, WEBAPP_URL, IS_PRODUCTION } from "@calcom/lib/constants";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import { getSubject, getTypeOfInvite } from "../../templates/team-invite-email";
import { V2BaseEmailHtml, CallToAction } from "../components";
@@ -157,49 +157,48 @@ export const TeamInviteEmail = (
<>
{autoJoinType == "added" ? (
<>
-
- {invitedBy} has added you to the {teamName} organization.
- {" "}
-
- Your link has been changed from {prevLinkWithoutProtocol} to{" "}
- {newLinkWithoutProtocol} but don't worry, all previous
- links still work and redirect appropriately.
-
-
- Please note: All of your personal event types have been moved into the{" "}
- {teamName} organisation, which may also include potential personal link.
-
-
- Please log in and make sure you have no private events on your new organisational account.
-
-
- For personal events we recommend creating a new account with a personal email address.
-
-
- Enjoy your new clean link:{" "}
- {newLinkWithoutProtocol}
-
+ {" "}
+
+ {prevLinkWithoutProtocol}
+
+ ),
+ a1: (
+
+ {newLinkWithoutProtocol}
+
+ ),
+ a2: (
+
+ {newLinkWithoutProtocol}
+
+ ),
+ }}
+ values={{ teamName, appName: APP_NAME }}
+ />
>
) : (
<>
-
- {invitedBy} has invited you to join the {teamName} organization.
- {" "}
- {" "}
+
- On accepting the invite, your link will change to your organization domain but don't
- worry, all previous links will still work and redirect appropriately.
-
-
- Please note: All of your personal event types will be moved into the{" "}
- {teamName} organisation, which may also include potential personal link.
-
-
- For personal events we recommend creating a new account with a personal email address.
-
+ values={{ teamName, appName: APP_NAME }}
+ />
>
)}
>
@@ -208,18 +207,20 @@ export const TeamInviteEmail = (
return (
<>
{autoJoinType === "added" ? (
-
- {invitedBy} has added you to the {teamName} organization.
-
+
) : (
-
- {invitedBy} has invited you to join the {teamName} organization.
-
+
)}{" "}
-
- {appName} is the event-juggling scheduler that enables you and your team to schedule meetings
- without the email tennis.
-
+ {appName} is the event-juggling scheduler that enables you and your team to schedule meetings
+ without the email tennis.
>
);
}
@@ -228,20 +229,20 @@ export const TeamInviteEmail = (
return (
<>
{autoJoinType === "added" ? (
-
- {invitedBy} has added you to the team {teamName} in their organization{" "}
- {parentTeamName} .
-
+
) : (
-
- {invitedBy} has invited you to the team {teamName} in their organization{" "}
- {parentTeamName} .
-
+
)}{" "}
-
- {appName} is the event-juggling scheduler that enables you and your team to schedule meetings
- without the email tennis.
-
+ {appName} is the event-juggling scheduler that enables you and your team to schedule meetings
+ without the email tennis.
>
);
}
diff --git a/packages/emails/src/templates/VerifyAccountEmail.tsx b/packages/emails/src/templates/VerifyAccountEmail.tsx
index fa82f353a0..b145f75106 100644
--- a/packages/emails/src/templates/VerifyAccountEmail.tsx
+++ b/packages/emails/src/templates/VerifyAccountEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, SENDER_NAME, SUPPORT_MAIL_ADDRESS } from "@calcom/lib/constants";
diff --git a/packages/emails/src/templates/VerifyEmailChangeEmail.tsx b/packages/emails/src/templates/VerifyEmailChangeEmail.tsx
index d0c62c710e..bc5fe0d023 100644
--- a/packages/emails/src/templates/VerifyEmailChangeEmail.tsx
+++ b/packages/emails/src/templates/VerifyEmailChangeEmail.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, SENDER_NAME, SUPPORT_MAIL_ADDRESS } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/_base-email.ts b/packages/emails/templates/_base-email.ts
index 74c3a6e6f7..d2150c0856 100644
--- a/packages/emails/templates/_base-email.ts
+++ b/packages/emails/templates/_base-email.ts
@@ -1,5 +1,4 @@
import { decodeHTML } from "entities";
-import { createTransport } from "nodemailer";
import { z } from "zod";
import dayjs from "@calcom/dayjs";
@@ -71,6 +70,7 @@ export default class BaseEmail {
},
...(parseSubject.success && { subject: decodeHTML(parseSubject.data) }),
};
+ const { createTransport } = await import("nodemailer");
await new Promise((resolve, reject) =>
createTransport(this.getMailerOptions().transport).sendMail(
payloadWithUnEscapedSubject,
diff --git a/packages/emails/templates/account-verify-email.ts b/packages/emails/templates/account-verify-email.ts
index cbad2a6b1b..57909dc90d 100644
--- a/packages/emails/templates/account-verify-email.ts
+++ b/packages/emails/templates/account-verify-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, COMPANY_NAME, EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/admin-organization-notification.ts b/packages/emails/templates/admin-organization-notification.ts
index 7c277a04f8..11f916d406 100644
--- a/packages/emails/templates/admin-organization-notification.ts
+++ b/packages/emails/templates/admin-organization-notification.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/attendee-daily-video-download-recording-email.ts b/packages/emails/templates/attendee-daily-video-download-recording-email.ts
index f89819dde6..ddfc108d8b 100644
--- a/packages/emails/templates/attendee-daily-video-download-recording-email.ts
+++ b/packages/emails/templates/attendee-daily-video-download-recording-email.ts
@@ -1,5 +1,5 @@
// TODO: We should find a way to keep App specific email templates within the App itself
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { TimeFormat } from "@calcom/lib/timeFormat";
import type { CalendarEvent, Person } from "@calcom/types/Calendar";
diff --git a/packages/emails/templates/attendee-daily-video-download-transcript-email.ts b/packages/emails/templates/attendee-daily-video-download-transcript-email.ts
index 4fc2404934..4fb52a1b25 100644
--- a/packages/emails/templates/attendee-daily-video-download-transcript-email.ts
+++ b/packages/emails/templates/attendee-daily-video-download-transcript-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { TimeFormat } from "@calcom/lib/timeFormat";
import type { CalendarEvent, Person } from "@calcom/types/Calendar";
diff --git a/packages/emails/templates/attendee-scheduled-email.ts b/packages/emails/templates/attendee-scheduled-email.ts
index 907cb1242c..a1a3b715cc 100644
--- a/packages/emails/templates/attendee-scheduled-email.ts
+++ b/packages/emails/templates/attendee-scheduled-email.ts
@@ -1,6 +1,6 @@
// eslint-disable-next-line no-restricted-imports
import { cloneDeep } from "lodash";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { getRichDescription } from "@calcom/lib/CalEventParser";
import { TimeFormat } from "@calcom/lib/timeFormat";
diff --git a/packages/emails/templates/attendee-verify-email.ts b/packages/emails/templates/attendee-verify-email.ts
index 5024fe0089..f362db3724 100644
--- a/packages/emails/templates/attendee-verify-email.ts
+++ b/packages/emails/templates/attendee-verify-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, COMPANY_NAME, EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/booking-redirect-notification.ts b/packages/emails/templates/booking-redirect-notification.ts
index 4369d06391..25375da3bb 100644
--- a/packages/emails/templates/booking-redirect-notification.ts
+++ b/packages/emails/templates/booking-redirect-notification.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/broken-integration-email.ts b/packages/emails/templates/broken-integration-email.ts
index 14555256ce..801844cbf5 100644
--- a/packages/emails/templates/broken-integration-email.ts
+++ b/packages/emails/templates/broken-integration-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { getRichDescription } from "@calcom/lib/CalEventParser";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/change-account-email-verify.ts b/packages/emails/templates/change-account-email-verify.ts
index e5c75230f8..ae792fc273 100644
--- a/packages/emails/templates/change-account-email-verify.ts
+++ b/packages/emails/templates/change-account-email-verify.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, COMPANY_NAME, EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/disabled-app-email.ts b/packages/emails/templates/disabled-app-email.ts
index 85c75bbd61..a6510db62b 100644
--- a/packages/emails/templates/disabled-app-email.ts
+++ b/packages/emails/templates/disabled-app-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/forgot-password-email.ts b/packages/emails/templates/forgot-password-email.ts
index 2fde8e3baf..909b8c50f2 100644
--- a/packages/emails/templates/forgot-password-email.ts
+++ b/packages/emails/templates/forgot-password-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/org-auto-join-invite.ts b/packages/emails/templates/org-auto-join-invite.ts
index c295eca9d8..9615dff07e 100644
--- a/packages/emails/templates/org-auto-join-invite.ts
+++ b/packages/emails/templates/org-auto-join-invite.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/organization-admin-no-slots-email.ts b/packages/emails/templates/organization-admin-no-slots-email.ts
index 5170724da6..e9494013ca 100644
--- a/packages/emails/templates/organization-admin-no-slots-email.ts
+++ b/packages/emails/templates/organization-admin-no-slots-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/organization-creation-email.ts b/packages/emails/templates/organization-creation-email.ts
index c6adc77430..bcc7a5d859 100644
--- a/packages/emails/templates/organization-creation-email.ts
+++ b/packages/emails/templates/organization-creation-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/organization-email-verification.ts b/packages/emails/templates/organization-email-verification.ts
index 0722662477..70a32c10a2 100644
--- a/packages/emails/templates/organization-email-verification.ts
+++ b/packages/emails/templates/organization-email-verification.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/organizer-daily-video-download-recording-email.ts b/packages/emails/templates/organizer-daily-video-download-recording-email.ts
index ff80acf5c1..28a25f6a69 100644
--- a/packages/emails/templates/organizer-daily-video-download-recording-email.ts
+++ b/packages/emails/templates/organizer-daily-video-download-recording-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
import { TimeFormat } from "@calcom/lib/timeFormat";
diff --git a/packages/emails/templates/organizer-daily-video-download-transcript-email.ts b/packages/emails/templates/organizer-daily-video-download-transcript-email.ts
index 763387306e..f1320a73e9 100644
--- a/packages/emails/templates/organizer-daily-video-download-transcript-email.ts
+++ b/packages/emails/templates/organizer-daily-video-download-transcript-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
import { TimeFormat } from "@calcom/lib/timeFormat";
diff --git a/packages/emails/templates/organizer-scheduled-email.ts b/packages/emails/templates/organizer-scheduled-email.ts
index 4c62a4219f..24d6effde7 100644
--- a/packages/emails/templates/organizer-scheduled-email.ts
+++ b/packages/emails/templates/organizer-scheduled-email.ts
@@ -1,6 +1,6 @@
// eslint-disable-next-line no-restricted-imports
import { cloneDeep } from "lodash";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { getRichDescription } from "@calcom/lib/CalEventParser";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/slug-replacement-email.ts b/packages/emails/templates/slug-replacement-email.ts
index 90133beee2..053aacd144 100644
--- a/packages/emails/templates/slug-replacement-email.ts
+++ b/packages/emails/templates/slug-replacement-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/emails/templates/team-invite-email.ts b/packages/emails/templates/team-invite-email.ts
index 145a4b44e2..52f0130eb6 100644
--- a/packages/emails/templates/team-invite-email.ts
+++ b/packages/emails/templates/team-invite-email.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { APP_NAME, EMAIL_FROM_NAME } from "@calcom/lib/constants";
diff --git a/packages/embeds/embed-core/src/useCompatSearchParams.tsx b/packages/embeds/embed-core/src/useCompatSearchParams.tsx
index ef6c6587ef..c1076f6df8 100644
--- a/packages/embeds/embed-core/src/useCompatSearchParams.tsx
+++ b/packages/embeds/embed-core/src/useCompatSearchParams.tsx
@@ -1,4 +1,5 @@
-// this file is copied from '@calcom/lib/hooks/useCompatSearchParams.tsx'
+"use client";
+
import { ReadonlyURLSearchParams, useParams, useSearchParams } from "next/navigation";
export const useCompatSearchParams = () => {
diff --git a/packages/features/apps/components/appCard.test.tsx b/packages/features/apps/components/appCard.test.tsx
index fc3760651a..3f1661ef85 100644
--- a/packages/features/apps/components/appCard.test.tsx
+++ b/packages/features/apps/components/appCard.test.tsx
@@ -1,11 +1,19 @@
/* eslint-disable playwright/missing-playwright-await */
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { render, screen } from "@testing-library/react";
+import { vi, describe, expect } from "vitest";
import type { AppFrontendPayload } from "@calcom/types/App";
import { AppCard } from "./AppCard";
+vi.mock("next/navigation", () => ({
+ useRouter: vi.fn().mockReturnValue({
+ push: vi.fn(),
+ }),
+ usePathname: vi.fn(),
+}));
+
describe("Tests for AppCard component", () => {
const mockApp: AppFrontendPayload = {
logo: "/path/to/logo.png",
@@ -34,7 +42,7 @@ describe("Tests for AppCard component", () => {
};
describe("Tests for app description", () => {
- test("Should render the app name correctly and display app logo with correct alt text", () => {
+ it("Should render the app name correctly and display app logo with correct alt text", () => {
renderAppCard();
const appLogo = screen.getByAltText("Test App Logo");
const appName = screen.getByText("Test App");
@@ -43,14 +51,14 @@ describe("Tests for AppCard component", () => {
expect(appName).toBeInTheDocument();
});
- test("Should render details button with correct href", () => {
+ it("Should render details button with correct href", () => {
renderAppCard();
const detailsButton = screen.getByText("details");
expect(detailsButton).toBeInTheDocument();
expect(detailsButton.closest("a")).toHaveAttribute("href", "/apps/test-app");
});
- test("Should highlight the app name based on searchText", () => {
+ it("Should highlight the app name based on searchText", () => {
renderAppCard({}, { searchText: "test" });
const highlightedText = screen.getByTestId("highlighted-text");
expect(highlightedText).toBeInTheDocument();
@@ -58,13 +66,13 @@ describe("Tests for AppCard component", () => {
});
describe("Tests for app categories", () => {
- test("Should show 'Template' badge if app is a template", () => {
+ it("Should show 'Template' badge if app is a template", () => {
renderAppCard({ isTemplate: true });
const templateBadge = screen.getByText("Template");
expect(templateBadge).toBeInTheDocument();
});
- test("Should show 'default' badge if app is default or global", () => {
+ it("Should show 'default' badge if app is default or global", () => {
renderAppCard({ isDefault: true });
const defaultBadge = screen.getByText("default");
expect(defaultBadge).toBeInTheDocument();
diff --git a/packages/features/auth/lib/passwordResetRequest.ts b/packages/features/auth/lib/passwordResetRequest.ts
index 3c4f3509a7..e1e5b1d259 100644
--- a/packages/features/auth/lib/passwordResetRequest.ts
+++ b/packages/features/auth/lib/passwordResetRequest.ts
@@ -1,7 +1,6 @@
import type { User } from "@prisma/client";
import dayjs from "@calcom/dayjs";
-import { sendPasswordResetEmail } from "@calcom/emails";
import { getTranslation } from "@calcom/lib/server/i18n";
import prisma from "@calcom/prisma";
@@ -40,6 +39,8 @@ const passwordResetRequest = async (user: Pick
- The selected time slot is no longer available.{" "}
-
- Please select a new time
-
-
+
+ Please select a new time
+ ,
+ ]}
+ />
}
/>
@@ -154,7 +161,8 @@ export const BookEventForm = ({
{!isPlatform && (
-
{
{fromUser?.displayName && toUser?.displayName && (
- username]}
/>
diff --git a/packages/features/bookings/Booker/components/hooks/useBookings.ts b/packages/features/bookings/Booker/components/hooks/useBookings.ts
index a8bc894570..47b7444979 100644
--- a/packages/features/bookings/Booker/components/hooks/useBookings.ts
+++ b/packages/features/bookings/Booker/components/hooks/useBookings.ts
@@ -1,3 +1,5 @@
+"use client";
+
import { useMutation } from "@tanstack/react-query";
import { useRouter } from "next/navigation";
import { useRef, useState, useEffect } from "react";
diff --git a/packages/features/bookings/components/event-meta/Duration.tsx b/packages/features/bookings/components/event-meta/Duration.tsx
index 853364c6b4..7e8bf9be14 100644
--- a/packages/features/bookings/components/event-meta/Duration.tsx
+++ b/packages/features/bookings/components/event-meta/Duration.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { useEffect, useRef } from "react";
import { useIsPlatform } from "@calcom/atoms/hooks/useIsPlatform";
diff --git a/packages/features/bookings/lib/handleNewBooking/types.ts b/packages/features/bookings/lib/handleNewBooking/types.ts
index ace8788910..83f40475bc 100644
--- a/packages/features/bookings/lib/handleNewBooking/types.ts
+++ b/packages/features/bookings/lib/handleNewBooking/types.ts
@@ -1,6 +1,6 @@
import type { App } from "@prisma/client";
import type { Prisma } from "@prisma/client";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import type { EventTypeAppsList } from "@calcom/app-store/utils";
import type { PaymentAppData } from "@calcom/lib/getPaymentAppData";
diff --git a/packages/features/ee/dsync/lib/inviteExistingUserToOrg.ts b/packages/features/ee/dsync/lib/inviteExistingUserToOrg.ts
index 3ccb8a1b5f..c2b8733e55 100644
--- a/packages/features/ee/dsync/lib/inviteExistingUserToOrg.ts
+++ b/packages/features/ee/dsync/lib/inviteExistingUserToOrg.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { createAProfileForAnExistingUser } from "@calcom/lib/createAProfileForAnExistingUser";
import prisma from "@calcom/prisma";
diff --git a/packages/features/ee/dsync/lib/users/inviteExistingUserToOrg.ts b/packages/features/ee/dsync/lib/users/inviteExistingUserToOrg.ts
index 452441ecd8..a382b7f1c9 100644
--- a/packages/features/ee/dsync/lib/users/inviteExistingUserToOrg.ts
+++ b/packages/features/ee/dsync/lib/users/inviteExistingUserToOrg.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { createAProfileForAnExistingUser } from "@calcom/lib/createAProfileForAnExistingUser";
import prisma from "@calcom/prisma";
diff --git a/packages/features/ee/managed-event-types/hooks/useLockedFieldsManager.tsx b/packages/features/ee/managed-event-types/hooks/useLockedFieldsManager.tsx
index ba4eb344f3..a26044d99b 100644
--- a/packages/features/ee/managed-event-types/hooks/useLockedFieldsManager.tsx
+++ b/packages/features/ee/managed-event-types/hooks/useLockedFieldsManager.tsx
@@ -1,6 +1,6 @@
// eslint-disable-next-line no-restricted-imports
import { get } from "lodash";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import type { Dispatch, SetStateAction } from "react";
import { useState } from "react";
import type { UseFormReturn } from "react-hook-form";
diff --git a/packages/features/ee/organizations/lib/server/createOrganizationFromOnboarding.test.ts b/packages/features/ee/organizations/lib/server/createOrganizationFromOnboarding.test.ts
index 94724870ea..2923a02561 100644
--- a/packages/features/ee/organizations/lib/server/createOrganizationFromOnboarding.test.ts
+++ b/packages/features/ee/organizations/lib/server/createOrganizationFromOnboarding.test.ts
@@ -30,32 +30,6 @@ vi.mock("@calcom/trpc/server/routers/viewer/organizations/createTeams.handler",
createTeamsHandler: vi.fn(),
}));
-vi.mock("next-i18next", () => ({
- serverSideTranslations: vi.fn().mockImplementation(async () => {
- return {
- _nextI18Next: {
- initialI18nStore: {
- en: {
- common: {},
- },
- },
- userConfig: {
- i18n: {
- defaultLocale: "en",
- locales: ["en"],
- },
- },
- },
- };
- }),
- i18n: {
- language: "en",
- languages: ["en"],
- defaultLocale: "en",
- getFixedT: () => (key: string) => key,
- },
-}));
-
vi.mock("@calcom/lib/domainManager/organization", () => ({
createDomain: vi.fn(),
}));
diff --git a/packages/features/ee/organizations/pages/settings/admin/AdminOrgPage.tsx b/packages/features/ee/organizations/pages/settings/admin/AdminOrgPage.tsx
index df14aa3e8a..5743ef36fe 100644
--- a/packages/features/ee/organizations/pages/settings/admin/AdminOrgPage.tsx
+++ b/packages/features/ee/organizations/pages/settings/admin/AdminOrgPage.tsx
@@ -1,6 +1,5 @@
"use client";
-import { Trans } from "next-i18next";
import { useState } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -9,6 +8,7 @@ import { Badge } from "@calcom/ui/components/badge";
import { Dialog, ConfirmationDialogContent } from "@calcom/ui/components/dialog";
import { DropdownActions, Table } from "@calcom/ui/components/table";
import { showToast } from "@calcom/ui/components/toast";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import { subdomainSuffix } from "../../../../organizations/lib/orgDomains";
@@ -251,20 +251,12 @@ const DeleteOrgDialog = ({
cancelBtnText={t("cancel")}
variety="danger"
onConfirm={onConfirm}>
- , ul: }}>
-
-
- Teams that are member of this organization will also be deleted along with their event-types
-
-
- Users that were part of the organization will not be deleted and their event-types will also
- remain intact.
-
- Usernames would be changed to allow them to exist outside the organization
-
-
+
+ {t("admin_delete_organization_description_1")}
+ {t("admin_delete_organization_description_2")}
+ {t("admin_delete_organization_description_3")}
+ {t("admin_delete_organization_description_4")}
+
);
diff --git a/packages/features/ee/payments/components/Payment.tsx b/packages/features/ee/payments/components/Payment.tsx
index 92c4b30694..7f6f561bf6 100644
--- a/packages/features/ee/payments/components/Payment.tsx
+++ b/packages/features/ee/payments/components/Payment.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import type { EventType, Payment } from "@prisma/client";
import { Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
import type { StripeElementLocale, StripeElements, StripePaymentElementOptions } from "@stripe/stripe-js";
diff --git a/packages/features/ee/platform/components/CreateANewPlatformForm.tsx b/packages/features/ee/platform/components/CreateANewPlatformForm.tsx
index b25b868c04..344bf5d973 100644
--- a/packages/features/ee/platform/components/CreateANewPlatformForm.tsx
+++ b/packages/features/ee/platform/components/CreateANewPlatformForm.tsx
@@ -10,8 +10,9 @@ import { uuid } from "short-uuid";
import { deriveOrgNameFromEmail } from "@calcom/ee/organizations/components/CreateANewOrganizationForm";
import { deriveSlugFromEmail } from "@calcom/ee/organizations/components/CreateANewOrganizationForm";
import { useLocale } from "@calcom/lib/hooks/useLocale";
+import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
import slugify from "@calcom/lib/slugify";
-import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
+import { telemetryEventTypes } from "@calcom/lib/telemetry";
import { UserPermissionRole } from "@calcom/prisma/enums";
import { CreationSource } from "@calcom/prisma/enums";
import { trpc } from "@calcom/trpc/react";
diff --git a/packages/features/ee/teams/components/AddNewTeamMembers.tsx b/packages/features/ee/teams/components/AddNewTeamMembers.tsx
index 07103e0c02..554d93e26c 100644
--- a/packages/features/ee/teams/components/AddNewTeamMembers.tsx
+++ b/packages/features/ee/teams/components/AddNewTeamMembers.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { keepPreviousData } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
@@ -9,7 +11,8 @@ import { MemberInvitationModalWithoutMembers } from "@calcom/features/ee/teams/c
import { APP_NAME } from "@calcom/lib/constants";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
-import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
+import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
+import { telemetryEventTypes } from "@calcom/lib/telemetry";
import { MembershipRole } from "@calcom/prisma/enums";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
diff --git a/packages/features/ee/teams/components/MemberInvitationModal.tsx b/packages/features/ee/teams/components/MemberInvitationModal.tsx
index dcdf77562a..92bdbde216 100644
--- a/packages/features/ee/teams/components/MemberInvitationModal.tsx
+++ b/packages/features/ee/teams/components/MemberInvitationModal.tsx
@@ -1,5 +1,4 @@
import { useSession } from "next-auth/react";
-import { Trans } from "next-i18next";
import type { FormEvent } from "react";
import { useMemo, useRef, useState } from "react";
import { Controller, useForm } from "react-hook-form";
@@ -13,10 +12,10 @@ import { CreationSource } from "@calcom/prisma/enums";
import type { RouterOutputs } from "@calcom/trpc";
import { trpc } from "@calcom/trpc";
import { isEmail } from "@calcom/trpc/server/routers/viewer/teams/util";
-import { TextAreaField } from "@calcom/ui/components/form";
-import { Button } from "@calcom/ui/components/button";
import classNames from "@calcom/ui/classNames";
+import { Button } from "@calcom/ui/components/button";
import { Dialog, DialogContent, DialogFooter } from "@calcom/ui/components/dialog";
+import { TextAreaField } from "@calcom/ui/components/form";
import { Form } from "@calcom/ui/components/form";
import { Label } from "@calcom/ui/components/form";
import { TextField } from "@calcom/ui/components/form";
@@ -24,6 +23,7 @@ import { Select } from "@calcom/ui/components/form";
import { ToggleGroup } from "@calcom/ui/components/form";
import { Icon } from "@calcom/ui/components/icon";
import { showToast } from "@calcom/ui/components/toast";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import type { PendingMember } from "../lib/types";
import { GoogleWorkspaceInviteButton } from "./GoogleWorkspaceInviteButton";
@@ -205,10 +205,15 @@ export default function MemberInvitationModal(props: MemberInvitationModalProps)
description={
IS_TEAM_BILLING_ENABLED_CLIENT && !currentOrg ? (
-
- Note: This will cost an extra seat ($15/m) {" "}
- on your subscription.
-
+
+ cost an extra seat ($15/m)
+ ,
+ ]}
+ />
) : null
}>
diff --git a/packages/features/ee/teams/components/createButton/create-button-with-teams-list.test.tsx b/packages/features/ee/teams/components/createButton/create-button-with-teams-list.test.tsx
index d2eb778bc8..2db6c2062e 100644
--- a/packages/features/ee/teams/components/createButton/create-button-with-teams-list.test.tsx
+++ b/packages/features/ee/teams/components/createButton/create-button-with-teams-list.test.tsx
@@ -5,6 +5,20 @@ import { vi } from "vitest";
import type { CreateBtnProps } from "./CreateButton";
import { CreateButtonWithTeamsList } from "./CreateButtonWithTeamsList";
+const mockRouter = {
+ push: vi.fn((path: string) => {
+ return;
+ }),
+};
+
+vi.mock("next/navigation", async (importOriginal) => {
+ const actual = await importOriginal
();
+ return {
+ ...actual,
+ useRouter: vi.fn(() => mockRouter),
+ };
+});
+
const runtimeMock = async (data: Array) => {
const updatedTrpc = {
viewer: {
diff --git a/packages/features/ee/workflows/lib/getOptions.ts b/packages/features/ee/workflows/lib/getOptions.ts
index c1a58dc01b..cda37286a0 100644
--- a/packages/features/ee/workflows/lib/getOptions.ts
+++ b/packages/features/ee/workflows/lib/getOptions.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import type { WorkflowActions } from "@calcom/prisma/enums";
import { WorkflowTemplates, WorkflowTriggerEvents } from "@calcom/prisma/enums";
diff --git a/packages/features/ee/workflows/lib/getWorkflowReminders.ts b/packages/features/ee/workflows/lib/getWorkflowReminders.ts
index 0dbaab08c6..e41ca972bc 100644
--- a/packages/features/ee/workflows/lib/getWorkflowReminders.ts
+++ b/packages/features/ee/workflows/lib/getWorkflowReminders.ts
@@ -89,9 +89,9 @@ export async function getAllRemindersToDelete(): Promise()({
referenceId: true,
- };
+ });
const remindersToDelete = await getWorkflowReminders(whereFilter, select);
@@ -109,10 +109,10 @@ export async function getAllRemindersToCancel(): Promise()({
referenceId: true,
id: true,
- };
+ });
const remindersToCancel = await getWorkflowReminders(whereFilter, select);
diff --git a/packages/features/ee/workflows/lib/variableTranslations.ts b/packages/features/ee/workflows/lib/variableTranslations.ts
index 29810cd615..7e030bc36a 100644
--- a/packages/features/ee/workflows/lib/variableTranslations.ts
+++ b/packages/features/ee/workflows/lib/variableTranslations.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { DYNAMIC_TEXT_VARIABLES, FORMATTED_DYNAMIC_TEXT_VARIABLES } from "./constants";
diff --git a/packages/features/eventtypes/components/EditWeightsForAllTeamMembers.tsx b/packages/features/eventtypes/components/EditWeightsForAllTeamMembers.tsx
index 96fd1aaf5a..24ff64b7cf 100644
--- a/packages/features/eventtypes/components/EditWeightsForAllTeamMembers.tsx
+++ b/packages/features/eventtypes/components/EditWeightsForAllTeamMembers.tsx
@@ -1,6 +1,5 @@
"use client";
-import { Trans } from "next-i18next";
import Link from "next/link";
import { useState, useEffect, useRef, useMemo } from "react";
@@ -24,6 +23,7 @@ import {
SheetTitle,
} from "@calcom/ui/components/sheet";
import { showToast } from "@calcom/ui/components/toast";
+import ServerTrans from "@calcom/web/components/ServerTrans";
type TeamMemberItemProps = {
member: Omit & { weight?: number };
@@ -302,15 +302,19 @@ export const EditWeightsForAllTeamMembers = ({
{t("edit_team_member_weights")}
-
- Weights determine how meetings are distributed among hosts.
-
- Learn more
-
-
+
+ Learn more
+ ,
+ ]}
+ />
diff --git a/packages/features/eventtypes/components/HostEditDialogs.tsx b/packages/features/eventtypes/components/HostEditDialogs.tsx
index db068d08da..daff7c02eb 100644
--- a/packages/features/eventtypes/components/HostEditDialogs.tsx
+++ b/packages/features/eventtypes/components/HostEditDialogs.tsx
@@ -1,5 +1,3 @@
-import { Trans } from "next-i18next";
-import Link from "next/link";
import type { Dispatch, SetStateAction } from "react";
import { useState } from "react";
import { useFormContext } from "react-hook-form";
@@ -19,6 +17,7 @@ import classNames from "@calcom/ui/classNames";
import { Dialog, DialogContent, DialogFooter, DialogClose } from "@calcom/ui/components/dialog";
import type { CheckedSelectOption } from "./CheckedTeamSelect";
+import WeightDescription from "./WeightDescription";
interface IDialog {
isOpenDialog: boolean;
@@ -99,18 +98,6 @@ export const PriorityDialog = (
);
};
-export const weightDescription = (
-
- Weights determine how meetings are distributed among hosts.
-
- Learn more
-
-
-);
-
export function sortHosts(
hostA: { priority: number | null; weight: number | null },
hostB: { priority: number | null; weight: number | null },
@@ -167,7 +154,7 @@ export const WeightDialog = (props: IDialog & { customClassNames?: WeightDialogC
return (
-
+ }>
{t("weight_for_user", { userName: option.label })}
diff --git a/packages/features/eventtypes/components/Locations.tsx b/packages/features/eventtypes/components/Locations.tsx
index bde47c7fdb..f2332072c8 100644
--- a/packages/features/eventtypes/components/Locations.tsx
+++ b/packages/features/eventtypes/components/Locations.tsx
@@ -1,6 +1,5 @@
import { useAutoAnimate } from "@formkit/auto-animate/react";
import { ErrorMessage } from "@hookform/error-message";
-import { Trans } from "next-i18next";
import Link from "next/link";
import { useEffect, useState } from "react";
import { Controller, useFieldArray } from "react-hook-form";
@@ -23,11 +22,12 @@ import type {
import LocationSelect from "@calcom/features/form/components/LocationSelect";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
-import { Input } from "@calcom/ui/components/form";
-import { Button } from "@calcom/ui/components/button";
import classNames from "@calcom/ui/classNames";
+import { Button } from "@calcom/ui/components/button";
+import { Input } from "@calcom/ui/components/form";
import { Icon } from "@calcom/ui/components/icon";
import { showToast } from "@calcom/ui/components/toast";
+import ServerTrans from "@calcom/web/components/ServerTrans";
export type TEventTypeLocation = Pick;
export type TLocationOptions = Pick["locationOptions"];
@@ -443,14 +443,18 @@ const Locations: React.FC = ({
-
- The “Add to calendar” for this event type needs to be a Google Calendar for Meet to work.
- Connect it
-
- here
-
- .
-
+
+ here
+ ,
+ ]}
+ />
)}
@@ -480,13 +484,18 @@ const Locations: React.FC = ({
{props.showAppStoreLink && !isPlatorm && (
-
- Can't find the right conferencing app? Visit our
-
- App Store
-
- .
-
+
+ App Store
+ ,
+ ]}
+ />
)}
diff --git a/packages/features/eventtypes/components/WeightDescription.tsx b/packages/features/eventtypes/components/WeightDescription.tsx
new file mode 100644
index 0000000000..2b1aec5b84
--- /dev/null
+++ b/packages/features/eventtypes/components/WeightDescription.tsx
@@ -0,0 +1,22 @@
+import type { TFunction } from "i18next";
+import Link from "next/link";
+
+import ServerTrans from "@calcom/web/components/ServerTrans";
+
+export default function WeightDescription({ t }: { t: TFunction }) {
+ return (
+
+ Learn more
+ ,
+ ]}
+ />
+ );
+}
diff --git a/packages/features/eventtypes/components/dialogs/DeleteDialog.tsx b/packages/features/eventtypes/components/dialogs/DeleteDialog.tsx
index dc7f2eef9e..cf58700c45 100644
--- a/packages/features/eventtypes/components/dialogs/DeleteDialog.tsx
+++ b/packages/features/eventtypes/components/dialogs/DeleteDialog.tsx
@@ -1,8 +1,8 @@
-import { Trans } from "next-i18next";
-
import { useLocale } from "@calcom/lib/hooks/useLocale";
+import classNames from "@calcom/ui/classNames";
import type { DialogProps } from "@calcom/ui/components/dialog";
import { ConfirmationDialogContent, Dialog } from "@calcom/ui/components/dialog";
+import ServerTrans from "@calcom/web/components/ServerTrans";
export function DeleteDialog({
isManagedEvent,
@@ -32,14 +32,14 @@ export function DeleteDialog({
onDelete(eventTypeId);
}}>
- , ul:
}}>
-
- Members assigned to this event type will also have their event types deleted.
- Anyone who they've shared their link with will no longer be able to book using it.
+ {isManagedEvent ? (
+
+ {t("delete_managed_event_type_description_1")}
+ {t("delete_managed_event_type_description_2")}
-
+ ) : (
+ t("delete_event_type_description")
+ )}
diff --git a/packages/features/eventtypes/components/dialogs/ManagedEventDialog.tsx b/packages/features/eventtypes/components/dialogs/ManagedEventDialog.tsx
index 81d19e1564..e337507f89 100644
--- a/packages/features/eventtypes/components/dialogs/ManagedEventDialog.tsx
+++ b/packages/features/eventtypes/components/dialogs/ManagedEventDialog.tsx
@@ -1,8 +1,7 @@
-import { Trans } from "next-i18next";
-
import type { ChildrenEventType } from "@calcom/features/eventtypes/components/ChildrenEventTypeSelect";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { ConfirmationDialogContent, Dialog } from "@calcom/ui/components/dialog";
+import ServerTrans from "@calcom/web/components/ServerTrans";
interface ManagedEventDialogProps {
slugExistsChildrenDialogOpen: ChildrenEventType[];
@@ -31,8 +30,13 @@ export default function ManagedEventDialog(props: ManagedEventDialogProps) {
cancelBtnText={t("go_back")}
onConfirm={onConfirm}>
- 1
+ ? "managed_event_dialog_information_other"
+ : "managed_event_dialog_information_one"
+ }
values={{
names: `${slugExistsChildrenDialogOpen
.map((ch) => ch.owner.name)
@@ -42,7 +46,6 @@ export default function ManagedEventDialog(props: ManagedEventDialogProps) {
} ${slugExistsChildrenDialogOpen.map((ch) => ch.owner.name).slice(-1)}`,
slug,
}}
- count={slugExistsChildrenDialogOpen.length}
/>
{" "}
{t("managed_event_dialog_clarification")}
diff --git a/packages/features/eventtypes/components/tabs/advanced/DisableAllEmailsSetting.tsx b/packages/features/eventtypes/components/tabs/advanced/DisableAllEmailsSetting.tsx
index e2265481f5..785250d8e8 100644
--- a/packages/features/eventtypes/components/tabs/advanced/DisableAllEmailsSetting.tsx
+++ b/packages/features/eventtypes/components/tabs/advanced/DisableAllEmailsSetting.tsx
@@ -1,13 +1,13 @@
-import type { TFunction } from "next-i18next";
-import { Trans } from "next-i18next";
+import type { TFunction } from "i18next";
import { useState } from "react";
import type { InputClassNames, SettingsToggleClassNames } from "@calcom/features/eventtypes/lib/types";
-import { InputField } from "@calcom/ui/components/form";
-import { Button } from "@calcom/ui/components/button";
import classNames from "@calcom/ui/classNames";
+import { Button } from "@calcom/ui/components/button";
import { Dialog, DialogContent, DialogFooter, DialogClose } from "@calcom/ui/components/dialog";
+import { InputField } from "@calcom/ui/components/form";
import { SettingsToggle } from "@calcom/ui/components/form";
+import ServerTrans from "@calcom/web/components/ServerTrans";
export type EmailNotificationToggleCustomClassNames = SettingsToggleClassNames & {
confirmationDialog?: {
@@ -53,15 +53,7 @@ export const DisableAllEmailsSetting = ({
className={customClassNames?.confirmationDialog?.container}>
-
- This will disable all emails to {recipient}. This includes booking confirmations, requests,
- reschedules and reschedule requests, cancellation emails, and any other emails related to
- booking updates.
-
-
- It is your responsibility to ensure that your {recipient} are aware of any bookings and changes
- to their bookings.
-
+
-
- {
- const val = Number(evt.target?.value);
+ components={[
+
+ {
+ const val = Number(evt.target?.value);
+ setRequiresConfirmationSetup({
+ unit:
+ requiresConfirmationSetup?.unit ??
+ defaultRequiresConfirmationSetup.unit,
+ time: val,
+ });
+ formMethods.setValue(
+ "metadata.requiresConfirmationThreshold.time",
+ val,
+ { shouldDirty: true }
+ );
+ }}
+ className={classNames(
+ "border-default h-9! !m-0 block w-16 rounded-r-none border-r-0 text-sm [appearance:textfield] focus:z-10 focus:border-r",
+ customClassNames?.conditionalConfirmationRadio?.timeInput
+ )}
+ defaultValue={metadata?.requiresConfirmationThreshold?.time || 30}
+ />
+
+ {
setRequiresConfirmationSetup({
- unit:
- requiresConfirmationSetup?.unit ??
- defaultRequiresConfirmationSetup.unit,
- time: val,
+ time:
+ requiresConfirmationSetup?.time ??
+ defaultRequiresConfirmationSetup.time,
+ unit: opt?.value as UnitTypeLongPlural,
});
formMethods.setValue(
- "metadata.requiresConfirmationThreshold.time",
- val,
+ "metadata.requiresConfirmationThreshold.unit",
+ opt?.value as UnitTypeLongPlural,
{ shouldDirty: true }
);
}}
- className={classNames(
- "border-default h-9! !m-0 block w-16 rounded-r-none border-r-0 text-sm [appearance:textfield] focus:z-10 focus:border-r",
- customClassNames?.conditionalConfirmationRadio?.timeInput
- )}
- defaultValue={metadata?.requiresConfirmationThreshold?.time || 30}
+ defaultValue={defaultValue}
/>
-
- {
- setRequiresConfirmationSetup({
- time:
- requiresConfirmationSetup?.time ??
- defaultRequiresConfirmationSetup.time,
- unit: opt?.value as UnitTypeLongPlural,
- });
- formMethods.setValue(
- "metadata.requiresConfirmationThreshold.unit",
- opt?.value as UnitTypeLongPlural,
- { shouldDirty: true }
- );
- }}
- defaultValue={defaultValue}
- />
-
-
- ),
- }}
+
+ ,
+ ]}
/>
>
}
diff --git a/packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx b/packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx
index 6999d840ac..e4074ad581 100644
--- a/packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx
+++ b/packages/features/eventtypes/components/tabs/apps/EventAppsTab.tsx
@@ -1,4 +1,3 @@
-import { Trans } from "next-i18next";
import Link from "next/link";
import { useFormContext } from "react-hook-form";
@@ -10,9 +9,10 @@ import type { FormValues, EventTypeSetupProps } from "@calcom/features/eventtype
import useAppsData from "@calcom/lib/hooks/useAppsData";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
-import { EmptyScreen } from "@calcom/ui/components/empty-screen";
import { Alert } from "@calcom/ui/components/alert";
import { Button } from "@calcom/ui/components/button";
+import { EmptyScreen } from "@calcom/ui/components/empty-screen";
+import ServerTrans from "@calcom/web/components/ServerTrans";
export type EventType = Pick["eventType"] &
EventTypeAppCardComponentProps["eventType"];
@@ -97,22 +97,19 @@ export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
severity={appsDisableProps.isLocked ? "neutral" : "info"}
className="mb-2"
title={
-
- {lockedText[0].toUpperCase()}
- {lockedText.slice(1)} {isManagedEventType ? "for members" : "by team admins"}
-
+
}
actions={{appsDisableProps.LockedIcon}
}
message={
-
- {isManagedEventType ? "Members" : "You"}{" "}
- {appsDisableProps.isLocked
- ? "will be able to see the active apps but will not be able to edit any app settings"
- : "will be able to see the active apps and will be able to edit any app settings"}
-
+ }_description`}
+ />
}
/>
)}
@@ -162,12 +159,15 @@ export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
{t("available_apps_lower_case")}
-
- View popular apps below and explore more in our
-
- App Store
-
-
+
+ App Store
+ ,
+ ]}
+ />
>
) : null}
diff --git a/packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx b/packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx
index c128ac31bf..2ce396de5f 100644
--- a/packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx
+++ b/packages/features/eventtypes/components/tabs/assignment/EventTeamAssignmentTab.tsx
@@ -1,4 +1,4 @@
-import { Trans } from "next-i18next";
+import type { TFunction } from "i18next";
import Link from "next/link";
import { useEffect, useRef, useState } from "react";
import type { ComponentProps, Dispatch, SetStateAction } from "react";
@@ -12,7 +12,7 @@ import AddMembersWithSwitch, {
import AssignAllTeamMembers from "@calcom/features/eventtypes/components/AssignAllTeamMembers";
import type { ChildrenEventTypeSelectCustomClassNames } from "@calcom/features/eventtypes/components/ChildrenEventTypeSelect";
import ChildrenEventTypeSelect from "@calcom/features/eventtypes/components/ChildrenEventTypeSelect";
-import { sortHosts, weightDescription } from "@calcom/features/eventtypes/components/HostEditDialogs";
+import { sortHosts } from "@calcom/features/eventtypes/components/HostEditDialogs";
import type {
FormValues,
TeamMember,
@@ -28,8 +28,10 @@ import { Label } from "@calcom/ui/components/form";
import { Select } from "@calcom/ui/components/form";
import { SettingsToggle } from "@calcom/ui/components/form";
import { RadioAreaGroup as RadioArea } from "@calcom/ui/components/radio";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import { EditWeightsForAllTeamMembers } from "../../EditWeightsForAllTeamMembers";
+import WeightDescription from "../../WeightDescription";
export type EventTeamAssignmentTabCustomClassNames = {
assignmentType?: {
@@ -114,16 +116,20 @@ const ChildrenEventTypesList = ({
);
};
-const FixedHostHelper = (
-
- Add anyone who needs to attend the event.
-
- Learn more
-
-
+const FixedHostHelper = ({ t }: { t: TFunction }) => (
+
+ Learn more
+ ,
+ ]}
+ />
);
type FixedHostsCustomClassNames = SettingsToggleClassNames & {
@@ -172,7 +178,7 @@ const FixedHosts = ({
"text-subtle max-w-full break-words text-sm leading-tight",
customClassNames?.description
)}>
- {FixedHostHelper}
+
@@ -212,7 +218,7 @@ const FixedHosts = ({
data-testid="fixed-hosts-switch"
toggleSwitchAtTheEnd={true}
title={t("fixed_hosts")}
- description={FixedHostHelper}
+ description={
}
checked={isDisabled && !assignAllTeamMembers}
hideSwitch={assignAllTeamMembers}
labelClassName={classNames("text-sm", customClassNames?.label)}
@@ -334,7 +340,7 @@ const RoundRobinHosts = ({
render={({ field: { value: isRRWeightsEnabled, onChange } }) => (
}
checked={isRRWeightsEnabled}
switchContainerClassName={customClassNames?.enableWeights?.container}
labelClassName={customClassNames?.enableWeights?.label}
diff --git a/packages/features/eventtypes/components/tabs/webhooks/EventWebhooksTab.tsx b/packages/features/eventtypes/components/tabs/webhooks/EventWebhooksTab.tsx
index 70d73e9a5b..4641521097 100644
--- a/packages/features/eventtypes/components/tabs/webhooks/EventWebhooksTab.tsx
+++ b/packages/features/eventtypes/components/tabs/webhooks/EventWebhooksTab.tsx
@@ -1,5 +1,4 @@
import type { Webhook } from "@prisma/client";
-import { Trans } from "next-i18next";
import Link from "next/link";
import { useState } from "react";
import { useFormContext } from "react-hook-form";
@@ -13,11 +12,12 @@ import { subscriberUrlReserved } from "@calcom/features/webhooks/lib/subscriberU
import { APP_NAME } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
-import { showToast } from "@calcom/ui/components/toast";
import { Alert } from "@calcom/ui/components/alert";
import { Button } from "@calcom/ui/components/button";
import { Dialog, DialogContent } from "@calcom/ui/components/dialog";
import { EmptyScreen } from "@calcom/ui/components/empty-screen";
+import { showToast } from "@calcom/ui/components/toast";
+import ServerTrans from "@calcom/web/components/ServerTrans";
export const EventWebhooksTab = ({ eventType }: Pick
) => {
const { t } = useLocale();
@@ -122,25 +122,21 @@ export const EventWebhooksTab = ({ eventType }: Pick
- {lockedText[0].toUpperCase()}
- {lockedText.slice(1)} {isManagedEventType ? "for members" : "by team admins"}
-
+
}
actions={
{webhooksDisableProps.LockedIcon}
}
message={
-
- {isManagedEventType ? "Members" : "You"}{" "}
- {webhooksDisableProps.isLocked
- ? "will be able to see the active webhooks but will not be able to edit any webhook settings"
- : "will be able to see the active webhooks and will be able to edit any webhook settings"}
-
+ }_description`}
+ />
}
/>
)}
@@ -181,14 +177,18 @@ export const EventWebhooksTab = ({ eventType }: Pick
-
- If you wish to edit or manage your web hooks, please head over to
-
- webhooks settings
-
-
+
+ webhooks settings
+ ,
+ ]}
+ />
>
diff --git a/packages/features/eventtypes/components/tabs/workflows/EventWorkfowsTab.tsx b/packages/features/eventtypes/components/tabs/workflows/EventWorkfowsTab.tsx
index 3780f72223..da9a4af164 100644
--- a/packages/features/eventtypes/components/tabs/workflows/EventWorkfowsTab.tsx
+++ b/packages/features/eventtypes/components/tabs/workflows/EventWorkfowsTab.tsx
@@ -2,7 +2,6 @@ import Link from "next/link";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { useFormContext } from "react-hook-form";
-import { Trans } from "react-i18next";
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
import useLockedFieldsManager from "@calcom/features/ee/managed-event-types/hooks/useLockedFieldsManager";
@@ -15,14 +14,15 @@ import { HttpError } from "@calcom/lib/http-error";
import { WorkflowActions } from "@calcom/prisma/enums";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
-import { Icon } from "@calcom/ui/components/icon";
-import { Tooltip } from "@calcom/ui/components/tooltip";
+import classNames from "@calcom/ui/classNames";
import { Alert } from "@calcom/ui/components/alert";
import { Button } from "@calcom/ui/components/button";
-import classNames from "@calcom/ui/classNames";
import { EmptyScreen } from "@calcom/ui/components/empty-screen";
import { Switch } from "@calcom/ui/components/form";
+import { Icon } from "@calcom/ui/components/icon";
import { showToast } from "@calcom/ui/components/toast";
+import { Tooltip } from "@calcom/ui/components/tooltip";
+import ServerTrans from "@calcom/web/components/ServerTrans";
type PartialWorkflowType = Pick;
@@ -252,22 +252,19 @@ function EventWorkflowsTab(props: Props) {
severity={workflowsDisableProps.isLocked ? "neutral" : "info"}
className="mb-2"
title={
-
- {lockedText[0].toUpperCase()}
- {lockedText.slice(1)} {isManagedEventType ? "for members" : "by team admins"}
-
+
}
actions={{workflowsDisableProps.LockedIcon}
}
message={
-
- {isManagedEventType ? "Members" : "You"}{" "}
- {workflowsDisableProps.isLocked
- ? "will be able to see the active workflows but will not be able to edit any workflow settings"
- : "will be able to see the active workflow and will be able to edit any workflow settings"}
-
+ }_description`}
+ />
}
/>
)}
diff --git a/packages/features/form-builder/FormBuilderField.tsx b/packages/features/form-builder/FormBuilderField.tsx
index da5ab3779a..65413d5cbd 100644
--- a/packages/features/form-builder/FormBuilderField.tsx
+++ b/packages/features/form-builder/FormBuilderField.tsx
@@ -1,5 +1,5 @@
import { ErrorMessage } from "@hookform/error-message";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { Controller, useFormContext } from "react-hook-form";
import type { z } from "zod";
diff --git a/packages/features/insights/components/RoutedToPerPeriod.tsx b/packages/features/insights/components/RoutedToPerPeriod.tsx
index 7ccadb47b5..002506d7ef 100644
--- a/packages/features/insights/components/RoutedToPerPeriod.tsx
+++ b/packages/features/insights/components/RoutedToPerPeriod.tsx
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { useQueryState } from "nuqs";
import { type ReactNode, useMemo, useRef, useState } from "react";
diff --git a/packages/features/settings/BookerLayoutSelector.tsx b/packages/features/settings/BookerLayoutSelector.tsx
index 802e3329d6..9562fcc1a4 100644
--- a/packages/features/settings/BookerLayoutSelector.tsx
+++ b/packages/features/settings/BookerLayoutSelector.tsx
@@ -1,5 +1,4 @@
import * as RadioGroup from "@radix-ui/react-radio-group";
-import { Trans } from "next-i18next";
import Link from "next/link";
import { useCallback, useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
@@ -8,10 +7,11 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { BookerLayouts, defaultBookerLayoutSettings } from "@calcom/prisma/zod-utils";
import { bookerLayoutOptions, type BookerLayoutSettings } from "@calcom/prisma/zod-utils";
import type { RouterOutputs } from "@calcom/trpc/react";
-import { Label } from "@calcom/ui/components/form";
-import { Button } from "@calcom/ui/components/button";
import classNames from "@calcom/ui/classNames";
+import { Button } from "@calcom/ui/components/button";
+import { Label } from "@calcom/ui/components/form";
import { CheckboxField } from "@calcom/ui/components/form";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import SectionBottomActions from "./SectionBottomActions";
@@ -229,20 +229,26 @@ const BookerLayoutFields = ({
{disableFields && (
-
- You can manage this for all your event types in Settings {"-> "}
-
- Appearance
- {" "}
- or{" "}
-
- Override
- {" "}
- for this event only.
-
+
+ Appearance
+ ,
+
+ Override
+ ,
+ ]}
+ />
)}
diff --git a/packages/features/settings/outOfOffice/OutOfOfficeEntriesList.tsx b/packages/features/settings/outOfOffice/OutOfOfficeEntriesList.tsx
index 69003e0531..9f51ba3781 100644
--- a/packages/features/settings/outOfOffice/OutOfOfficeEntriesList.tsx
+++ b/packages/features/settings/outOfOffice/OutOfOfficeEntriesList.tsx
@@ -7,7 +7,6 @@ import {
getFilteredRowModel,
useReactTable,
} from "@tanstack/react-table";
-import { Trans } from "next-i18next";
import { useEffect, useMemo, useRef, useState } from "react";
import { useFormState } from "react-hook-form";
@@ -25,13 +24,14 @@ import { getUserAvatarUrl } from "@calcom/lib/getAvatarUrl";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
-import { Icon } from "@calcom/ui/components/icon";
-import { SkeletonText } from "@calcom/ui/components/skeleton";
-import { Tooltip } from "@calcom/ui/components/tooltip";
import { Avatar } from "@calcom/ui/components/avatar";
import { Button } from "@calcom/ui/components/button";
import { EmptyScreen } from "@calcom/ui/components/empty-screen";
+import { Icon } from "@calcom/ui/components/icon";
+import { SkeletonText } from "@calcom/ui/components/skeleton";
import { showToast } from "@calcom/ui/components/toast";
+import { Tooltip } from "@calcom/ui/components/tooltip";
+import ServerTrans from "@calcom/web/components/ServerTrans";
import CreateNewOutOfOfficeEntryButton from "./CreateNewOutOfOfficeEntryButton";
import { CreateOrEditOutOfOfficeEntryModal } from "./CreateOrEditOutOfOfficeModal";
@@ -197,14 +197,13 @@ function OutOfOfficeEntriesListContent() {
{item.toUser?.username ? (
- ,
- }}
+ components={[ ]}
/>
) : (
<>{t("ooo_not_forwarding")}>
diff --git a/packages/lib/CalEventParser.test.ts b/packages/lib/CalEventParser.test.ts
index 8732bd3e18..716584b71b 100644
--- a/packages/lib/CalEventParser.test.ts
+++ b/packages/lib/CalEventParser.test.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { describe, expect, it } from "vitest";
import type { CalendarEvent } from "@calcom/types/Calendar";
diff --git a/packages/lib/CalEventParser.ts b/packages/lib/CalEventParser.ts
index 3de4a1016b..c7a52e2771 100644
--- a/packages/lib/CalEventParser.ts
+++ b/packages/lib/CalEventParser.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import short from "short-uuid";
import { v5 as uuidv5 } from "uuid";
diff --git a/packages/lib/bookingSuccessRedirect.ts b/packages/lib/bookingSuccessRedirect.ts
index 9dc57a5e85..c1e0dcb1d0 100644
--- a/packages/lib/bookingSuccessRedirect.ts
+++ b/packages/lib/bookingSuccessRedirect.ts
@@ -8,6 +8,8 @@ import type { BookingResponse } from "@calcom/features/bookings/types";
import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams";
import { navigateInTopWindow } from "@calcom/lib/navigateInTopWindow";
+import { getSafe } from "./getSafe";
+
function getNewSearchParams(args: {
query: Record;
searchParams?: URLSearchParams;
@@ -43,13 +45,6 @@ type ResultType = {
attendeeLastName?: string | null;
};
-export function getSafe(obj: unknown, path: (string | number)[]): T | undefined {
- return path.reduce(
- (acc, key) => (typeof acc === "object" && acc !== null ? (acc as any)[key] : undefined),
- obj
- ) as T | undefined;
-}
-
export const getBookingRedirectExtraParams = (booking: SuccessRedirectBookingType) => {
const redirectQueryParamKeys: BookingResponseKey[] = [
"title",
diff --git a/packages/lib/constants.ts b/packages/lib/constants.ts
index 316e472e23..fffc5c4408 100644
--- a/packages/lib/constants.ts
+++ b/packages/lib/constants.ts
@@ -148,14 +148,6 @@ export const DEFAULT_DARK_BRAND_COLOR = "#fafafa";
export const TOP_BANNER_HEIGHT = 40;
-const defaultOnNaN = (testedValue: number, defaultValue: number) =>
- !Number.isNaN(testedValue) ? testedValue : defaultValue;
-
-export const AB_TEST_BUCKET_PROBABILITY = defaultOnNaN(
- parseInt(process.env.AB_TEST_BUCKET_PROBABILITY ?? "10", 10),
- 10
-);
-
export const IS_PREMIUM_USERNAME_ENABLED =
(IS_CALCOM || (process.env.NEXT_PUBLIC_IS_E2E && IS_STRIPE_ENABLED)) &&
process.env.NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE_MONTHLY;
@@ -164,8 +156,6 @@ export const IS_PREMIUM_USERNAME_ENABLED =
export const MAX_NB_INVITES = 100;
export const URL_PROTOCOL_REGEX = /(^\w+:|^)\/\//;
-export const FUTURE_ROUTES_OVERRIDE_COOKIE_NAME = "x-calcom-future-routes-override";
-export const FUTURE_ROUTES_ENABLED_COOKIE_NAME = "x-calcom-future-routes-enabled";
export const IS_VISUAL_REGRESSION_TESTING = Boolean(globalThis.window?.Meticulous?.isRunningAsTest);
diff --git a/packages/lib/crmManager/crmManager.test.ts b/packages/lib/crmManager/crmManager.test.ts
index 62143d771d..7e143fafff 100644
--- a/packages/lib/crmManager/crmManager.test.ts
+++ b/packages/lib/crmManager/crmManager.test.ts
@@ -1,6 +1,6 @@
import { mockCrmApp } from "@calcom/web/test/utils/bookingScenario/bookingScenario";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { describe, expect, test, vi } from "vitest";
import { getCrm } from "@calcom/app-store/_utils/getCrm";
diff --git a/packages/lib/event-types/utils/locationsResolver.ts b/packages/lib/event-types/utils/locationsResolver.ts
index d533ab0f17..2aded2b2ca 100644
--- a/packages/lib/event-types/utils/locationsResolver.ts
+++ b/packages/lib/event-types/utils/locationsResolver.ts
@@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-empty-function */
import { isValidPhoneNumber } from "libphonenumber-js";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
// eslint-disable-next-line @calcom/eslint/deprecated-imports-next-router
import { z } from "zod";
diff --git a/packages/lib/event.test.ts b/packages/lib/event.test.ts
index 6d1168a5af..93380af141 100644
--- a/packages/lib/event.test.ts
+++ b/packages/lib/event.test.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { describe, expect, it, vi } from "vitest";
import * as event from "./event";
diff --git a/packages/lib/event.ts b/packages/lib/event.ts
index d65c0e68e7..d4ae8ad5ad 100644
--- a/packages/lib/event.ts
+++ b/packages/lib/event.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import z from "zod";
import { guessEventLocationType } from "@calcom/app-store/locations";
diff --git a/packages/lib/getSafe.ts b/packages/lib/getSafe.ts
new file mode 100644
index 0000000000..10b1d6f6d3
--- /dev/null
+++ b/packages/lib/getSafe.ts
@@ -0,0 +1,6 @@
+export function getSafe(obj: unknown, path: (string | number)[]): T | undefined {
+ return path.reduce(
+ (acc, key) => (typeof acc === "object" && acc !== null ? (acc as any)[key] : undefined),
+ obj
+ ) as T | undefined;
+}
diff --git a/packages/lib/hooks/useCompatSearchParams.tsx b/packages/lib/hooks/useCompatSearchParams.tsx
index 3112bb3827..6a637ae1a1 100644
--- a/packages/lib/hooks/useCompatSearchParams.tsx
+++ b/packages/lib/hooks/useCompatSearchParams.tsx
@@ -1,3 +1,5 @@
+"use client";
+
import { ReadonlyURLSearchParams, useParams, useSearchParams } from "next/navigation";
export const useCompatSearchParams = () => {
diff --git a/packages/lib/hooks/useLocale.ts b/packages/lib/hooks/useLocale.ts
index 6721972301..723e269215 100644
--- a/packages/lib/hooks/useLocale.ts
+++ b/packages/lib/hooks/useLocale.ts
@@ -1,4 +1,4 @@
-import { useTranslation } from "next-i18next";
+import { useTranslation } from "react-i18next";
import { useAtomsContext } from "@calcom/atoms/hooks/useAtomsContext";
diff --git a/packages/lib/hooks/useTelemetry.ts b/packages/lib/hooks/useTelemetry.ts
new file mode 100644
index 0000000000..cd7f287ca0
--- /dev/null
+++ b/packages/lib/hooks/useTelemetry.ts
@@ -0,0 +1,5 @@
+"use client";
+
+import { useCollector } from "next-collect/client";
+
+export const useTelemetry = useCollector;
diff --git a/packages/lib/package.json b/packages/lib/package.json
index 34f32e5e80..4df48f8898 100644
--- a/packages/lib/package.json
+++ b/packages/lib/package.json
@@ -25,7 +25,7 @@
"ics": "^2.37.0",
"jimp": "^0.16.1",
"next-collect": "^0.2.1",
- "next-i18next": "^13.2.2",
+ "next-i18next": "^15.4.2",
"rrule": "^2.7.1",
"sonner": "^1.7.4",
"tsdav": "2.0.3",
diff --git a/packages/lib/recurringStrings.ts b/packages/lib/recurringStrings.ts
index a72ae4430d..6a27273995 100644
--- a/packages/lib/recurringStrings.ts
+++ b/packages/lib/recurringStrings.ts
@@ -1,4 +1,4 @@
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { Frequency } from "@calcom/prisma/zod-utils";
import type { RecurringEvent } from "@calcom/types/Calendar";
diff --git a/packages/lib/server/i18n.ts b/packages/lib/server/i18n.ts
index b49658d07e..972f6bfd71 100644
--- a/packages/lib/server/i18n.ts
+++ b/packages/lib/server/i18n.ts
@@ -1,18 +1,42 @@
-import i18next from "i18next";
-import { i18n as nexti18next } from "next-i18next";
-import { serverSideTranslations } from "next-i18next/serverSideTranslations";
+import { createInstance } from "i18next";
+
+import { WEBAPP_URL } from "@calcom/lib/constants";
+
+const i18nInstanceCache = new Map();
+
+async function loadTranslations(locale: string, ns: string) {
+ try {
+ const url = `${WEBAPP_URL}/static/locales/${locale}/${ns}.json`;
+ const response = await fetch(url);
+ return await response.json();
+ } catch (error) {
+ const res = await fetch(`${WEBAPP_URL}/static/locales/en/common.json`);
+ if (res) {
+ return await res.json();
+ }
+ return {};
+ }
+}
export const getTranslation = async (locale: string, ns: string) => {
- const create = async () => {
- const { _nextI18Next } = await serverSideTranslations(locale, [ns]);
- const _i18n = i18next.createInstance();
- _i18n.init({
- lng: locale,
- resources: _nextI18Next?.initialI18nStore,
- fallbackLng: _nextI18Next?.userConfig?.i18n.defaultLocale,
- });
- return _i18n;
- };
- const _i18n = nexti18next != null ? nexti18next : await create();
+ const cacheKey = `${locale}-${ns}`;
+ if (i18nInstanceCache.has(cacheKey)) {
+ return i18nInstanceCache.get(cacheKey).getFixedT(locale, ns);
+ }
+
+ const resources = await loadTranslations(locale, ns);
+
+ const _i18n = createInstance();
+ _i18n.init({
+ lng: locale,
+ resources: {
+ [locale]: {
+ [ns]: resources,
+ },
+ },
+ fallbackLng: "en",
+ });
+
+ i18nInstanceCache.set(cacheKey, _i18n);
return _i18n.getFixedT(locale, ns);
};
diff --git a/packages/lib/telemetry.ts b/packages/lib/telemetry.ts
index 8816bfd489..959f3acfe8 100644
--- a/packages/lib/telemetry.ts
+++ b/packages/lib/telemetry.ts
@@ -1,6 +1,5 @@
import type { NextApiRequest, NextApiResponse } from "next";
import type { CollectOpts, EventHandler } from "next-collect";
-import { useCollector } from "next-collect/client";
// Importing types so we're not directly importing next/server
import type { NextRequest, NextResponse } from "next/server";
@@ -112,5 +111,3 @@ export const extendEventData = (
utc_time: new Date().toISOString(),
};
};
-
-export const useTelemetry = useCollector;
diff --git a/packages/lib/test/builder.ts b/packages/lib/test/builder.ts
index fb2759a900..0da24b1c10 100644
--- a/packages/lib/test/builder.ts
+++ b/packages/lib/test/builder.ts
@@ -1,6 +1,6 @@
import { faker } from "@faker-js/faker";
import type { Booking, EventType, Prisma, Webhook, BookingReference } from "@prisma/client";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import getICalUID from "@calcom/emails/lib/getICalUID";
import { CreationSource } from "@calcom/prisma/enums";
diff --git a/packages/platform/atoms/event-types/hooks/usePlatformTabsNavigations.tsx b/packages/platform/atoms/event-types/hooks/usePlatformTabsNavigations.tsx
index 4e28d0c1b0..02eb6dce88 100644
--- a/packages/platform/atoms/event-types/hooks/usePlatformTabsNavigations.tsx
+++ b/packages/platform/atoms/event-types/hooks/usePlatformTabsNavigations.tsx
@@ -2,7 +2,7 @@
// eslint-disable-next-line @calcom/eslint/deprecated-imports-next-router
// eslint-disable-next-line @calcom/eslint/deprecated-imports-next-router
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { useMemo, useState, useEffect } from "react";
import type { UseFormReturn } from "react-hook-form";
diff --git a/packages/platform/atoms/event-types/hooks/useTabsNavigations.tsx b/packages/platform/atoms/event-types/hooks/useTabsNavigations.tsx
index 38c59be3df..1b3941adcc 100644
--- a/packages/platform/atoms/event-types/hooks/useTabsNavigations.tsx
+++ b/packages/platform/atoms/event-types/hooks/useTabsNavigations.tsx
@@ -1,7 +1,7 @@
"use client";
// eslint-disable-next-line @calcom/eslint/deprecated-imports-next-router
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { useMemo } from "react";
import type { UseFormReturn } from "react-hook-form";
diff --git a/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx b/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx
index d89549e4dd..4080061624 100644
--- a/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx
+++ b/packages/platform/atoms/event-types/wrappers/EventTypeWebWrapper.tsx
@@ -11,9 +11,10 @@ import { EventType as EventTypeComponent } from "@calcom/features/eventtypes/com
import type { EventTypeSetupProps } from "@calcom/features/eventtypes/lib/types";
import { WEBSITE_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
+import { useTelemetry } from "@calcom/lib/hooks/useTelemetry";
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
import { HttpError } from "@calcom/lib/http-error";
-import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
+import { telemetryEventTypes } from "@calcom/lib/telemetry";
import { SchedulingType } from "@calcom/prisma/enums";
import { trpc } from "@calcom/trpc/react";
import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery";
diff --git a/packages/prisma/client/index.js b/packages/prisma/client/index.js
index b98f8c8fc6..fcab163dab 100644
--- a/packages/prisma/client/index.js
+++ b/packages/prisma/client/index.js
@@ -1 +1 @@
-export * from "../../../node_modules/.prisma/client";
+export * from "@prisma/client";
diff --git a/packages/prisma/zod-utils.ts b/packages/prisma/zod-utils.ts
index 87fd2e6b98..3ec0f0aa1b 100644
--- a/packages/prisma/zod-utils.ts
+++ b/packages/prisma/zod-utils.ts
@@ -1,6 +1,6 @@
import type { Prisma } from "@prisma/client";
import type { UnitTypeLongPlural } from "dayjs";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import z, { ZodNullable, ZodObject, ZodOptional } from "zod";
import type {
AnyZodObject,
diff --git a/packages/trpc/server/routers/viewer/bookings/requestReschedule.handler.ts b/packages/trpc/server/routers/viewer/bookings/requestReschedule.handler.ts
index c8bf4a9111..2c52b5721d 100644
--- a/packages/trpc/server/routers/viewer/bookings/requestReschedule.handler.ts
+++ b/packages/trpc/server/routers/viewer/bookings/requestReschedule.handler.ts
@@ -1,5 +1,5 @@
import type { BookingReference, EventType } from "@prisma/client";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { getCalendar } from "@calcom/app-store/_utils/getCalendar";
import dayjs from "@calcom/dayjs";
diff --git a/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts b/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
index 9129c6a865..dc6f103b26 100644
--- a/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
+++ b/packages/trpc/server/routers/viewer/teams/inviteMember/utils.ts
@@ -1,5 +1,5 @@
import { randomBytes } from "crypto";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import { getOrgFullOrigin } from "@calcom/ee/organizations/lib/orgDomains";
import { sendTeamInviteEmail } from "@calcom/emails";
diff --git a/packages/types/Calendar.d.ts b/packages/types/Calendar.d.ts
index a7dfc7a797..16fbc60de3 100644
--- a/packages/types/Calendar.d.ts
+++ b/packages/types/Calendar.d.ts
@@ -7,7 +7,7 @@ import type {
} from "@prisma/client";
import type { Dayjs } from "dayjs";
import type { Time } from "ical.js";
-import type { TFunction } from "next-i18next";
+import type { TFunction } from "i18next";
import type { Frequency } from "rrule";
import type z from "zod";
diff --git a/turbo.json b/turbo.json
index f725dea3eb..0fb4b204b5 100644
--- a/turbo.json
+++ b/turbo.json
@@ -239,12 +239,9 @@
},
"globalDependencies": ["yarn.lock"],
"globalEnv": [
- "AB_TEST_BUCKET_PROBABILITY",
"ALLOWED_HOSTNAMES",
"ANALYZE",
"API_KEY_PREFIX",
- "APP_ROUTER_APPS_SLUG_SETUP_ENABLED",
- "APP_ROUTER_TEAM_ENABLED",
"APP_USER_NAME",
"BASECAMP3_CLIENT_ID",
"BASECAMP3_CLIENT_SECRET",
diff --git a/yarn.lock b/yarn.lock
index c9b408a22e..69c5f3a68e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1931,6 +1931,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.21.0":
+ version: 7.26.10
+ resolution: "@babel/runtime@npm:7.26.10"
+ dependencies:
+ regenerator-runtime: ^0.14.0
+ checksum: 22d2e0abb86e90de489ab16bb578db6fe2b63a88696db431198b24963749820c723f1982298cdbbea187f7b2b80fb4d98a514faf114ddb2fdc14a4b96277b955
+ languageName: node
+ linkType: hard
+
"@babel/runtime@npm:^7.23.2":
version: 7.23.5
resolution: "@babel/runtime@npm:7.23.5"
@@ -2769,7 +2778,7 @@ __metadata:
"@calcom/lib": "*"
"@calcom/tsconfig": "*"
"@calcom/types": "*"
- next-i18next: ^13.2.2
+ next-i18next: ^15.4.2
react: ^18.2.0
react-dom: ^18.2.0
rrule: ^2.7.1
@@ -3151,7 +3160,7 @@ __metadata:
ics: ^2.37.0
jimp: ^0.16.1
next-collect: ^0.2.1
- next-i18next: ^13.2.2
+ next-i18next: ^15.4.2
rrule: ^2.7.1
sonner: ^1.7.4
tsdav: 2.0.3
@@ -3804,7 +3813,7 @@ __metadata:
"@stripe/stripe-js": ^1.35.0
"@tanstack/react-query": ^5.17.15
"@testing-library/react": ^13.3.0
- "@tremor/react": ^2.0.0
+ "@tremor/react": ^2.11.0
"@types/accept-language-parser": 1.5.2
"@types/async": ^3.2.15
"@types/bcryptjs": ^2.4.2
@@ -3841,7 +3850,6 @@ __metadata:
classnames: ^2.3.1
copy-webpack-plugin: ^11.0.0
cron: ^3.1.7
- deasync: ^0.1.30
detect-port: ^1.3.0
dompurify: ^3.1.7
dotenv-cli: ^6.0.0
@@ -3865,11 +3873,11 @@ __metadata:
mime-types: ^2.1.35
module-alias: ^2.2.2
msw: ^0.42.3
- next: ^13.5.6
+ next: ^15.1.6
next-auth: ^4.22.1
next-axiom: ^0.17.0
next-collect: ^0.2.1
- next-i18next: ^13.2.2
+ next-i18next: ^15.4.2
next-seo: ^6.0.0
next-themes: ^0.2.0
node-html-parser: ^6.1.10
@@ -4363,6 +4371,15 @@ __metadata:
languageName: node
linkType: hard
+"@emnapi/runtime@npm:^1.2.0":
+ version: 1.3.1
+ resolution: "@emnapi/runtime@npm:1.3.1"
+ dependencies:
+ tslib: ^2.4.0
+ checksum: 9a16ae7905a9c0e8956cf1854ef74e5087fbf36739abdba7aa6b308485aafdc993da07c19d7af104cd5f8e425121120852851bb3a0f78e2160e420a36d47f42f
+ languageName: node
+ linkType: hard
+
"@emotion/babel-plugin@npm:^11.7.1":
version: 11.7.2
resolution: "@emotion/babel-plugin@npm:11.7.2"
@@ -5387,6 +5404,181 @@ __metadata:
languageName: node
linkType: hard
+"@img/sharp-darwin-arm64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-darwin-arm64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-darwin-arm64": 1.0.4
+ dependenciesMeta:
+ "@img/sharp-libvips-darwin-arm64":
+ optional: true
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@img/sharp-darwin-x64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-darwin-x64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-darwin-x64": 1.0.4
+ dependenciesMeta:
+ "@img/sharp-libvips-darwin-x64":
+ optional: true
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-darwin-arm64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-darwin-arm64@npm:1.0.4"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-darwin-x64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-darwin-x64@npm:1.0.4"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linux-arm64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linux-arm64@npm:1.0.4"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linux-arm@npm:1.0.5":
+ version: 1.0.5
+ resolution: "@img/sharp-libvips-linux-arm@npm:1.0.5"
+ conditions: os=linux & cpu=arm & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linux-s390x@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linux-s390x@npm:1.0.4"
+ conditions: os=linux & cpu=s390x & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linux-x64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linux-x64@npm:1.0.4"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linuxmusl-arm64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linuxmusl-arm64@npm:1.0.4"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@img/sharp-libvips-linuxmusl-x64@npm:1.0.4":
+ version: 1.0.4
+ resolution: "@img/sharp-libvips-linuxmusl-x64@npm:1.0.4"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linux-arm64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linux-arm64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linux-arm64": 1.0.4
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-arm64":
+ optional: true
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linux-arm@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linux-arm@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linux-arm": 1.0.5
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-arm":
+ optional: true
+ conditions: os=linux & cpu=arm & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linux-s390x@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linux-s390x@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linux-s390x": 1.0.4
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-s390x":
+ optional: true
+ conditions: os=linux & cpu=s390x & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linux-x64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linux-x64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linux-x64": 1.0.4
+ dependenciesMeta:
+ "@img/sharp-libvips-linux-x64":
+ optional: true
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linuxmusl-arm64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linuxmusl-arm64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linuxmusl-arm64": 1.0.4
+ dependenciesMeta:
+ "@img/sharp-libvips-linuxmusl-arm64":
+ optional: true
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@img/sharp-linuxmusl-x64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-linuxmusl-x64@npm:0.33.5"
+ dependencies:
+ "@img/sharp-libvips-linuxmusl-x64": 1.0.4
+ dependenciesMeta:
+ "@img/sharp-libvips-linuxmusl-x64":
+ optional: true
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
+"@img/sharp-wasm32@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-wasm32@npm:0.33.5"
+ dependencies:
+ "@emnapi/runtime": ^1.2.0
+ conditions: cpu=wasm32
+ languageName: node
+ linkType: hard
+
+"@img/sharp-win32-ia32@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-win32-ia32@npm:0.33.5"
+ conditions: os=win32 & cpu=ia32
+ languageName: node
+ linkType: hard
+
+"@img/sharp-win32-x64@npm:0.33.5":
+ version: 0.33.5
+ resolution: "@img/sharp-win32-x64@npm:0.33.5"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
"@inquirer/confirm@npm:^5.0.0":
version: 5.1.6
resolution: "@inquirer/confirm@npm:5.1.6"
@@ -7122,6 +7314,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/env@npm:15.2.1":
+ version: 15.2.1
+ resolution: "@next/env@npm:15.2.1"
+ checksum: 32aee52cad88cfff7c473f7089eff7fa0662f4d3d40a257ec6214e46f0df8d65f23486f73772a5efeb9d6750e8bdbdb7dff2cda08495b510299c267a17696f65
+ languageName: node
+ linkType: hard
+
"@next/eslint-plugin-next@npm:13.2.1":
version: 13.2.1
resolution: "@next/eslint-plugin-next@npm:13.2.1"
@@ -7154,6 +7353,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-darwin-arm64@npm:15.2.1":
+ version: 15.2.1
+ resolution: "@next/swc-darwin-arm64@npm:15.2.1"
+ conditions: os=darwin & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@next/swc-darwin-x64@npm:13.5.7":
version: 13.5.7
resolution: "@next/swc-darwin-x64@npm:13.5.7"
@@ -7168,6 +7374,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-darwin-x64@npm:15.2.1":
+ version: 15.2.1
+ resolution: "@next/swc-darwin-x64@npm:15.2.1"
+ conditions: os=darwin & cpu=x64
+ languageName: node
+ linkType: hard
+
"@next/swc-linux-arm64-gnu@npm:13.5.7":
version: 13.5.7
resolution: "@next/swc-linux-arm64-gnu@npm:13.5.7"
@@ -7182,6 +7395,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-linux-arm64-gnu@npm:15.2.1":
+ version: 15.2.1
+ resolution: "@next/swc-linux-arm64-gnu@npm:15.2.1"
+ conditions: os=linux & cpu=arm64 & libc=glibc
+ languageName: node
+ linkType: hard
+
"@next/swc-linux-arm64-musl@npm:13.5.7":
version: 13.5.7
resolution: "@next/swc-linux-arm64-musl@npm:13.5.7"
@@ -7196,6 +7416,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-linux-arm64-musl@npm:15.2.1":
+ version: 15.2.1
+ resolution: "@next/swc-linux-arm64-musl@npm:15.2.1"
+ conditions: os=linux & cpu=arm64 & libc=musl
+ languageName: node
+ linkType: hard
+
"@next/swc-linux-x64-gnu@npm:13.5.7":
version: 13.5.7
resolution: "@next/swc-linux-x64-gnu@npm:13.5.7"
@@ -7210,6 +7437,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-linux-x64-gnu@npm:15.2.1":
+ version: 15.2.1
+ resolution: "@next/swc-linux-x64-gnu@npm:15.2.1"
+ conditions: os=linux & cpu=x64 & libc=glibc
+ languageName: node
+ linkType: hard
+
"@next/swc-linux-x64-musl@npm:13.5.7":
version: 13.5.7
resolution: "@next/swc-linux-x64-musl@npm:13.5.7"
@@ -7224,6 +7458,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-linux-x64-musl@npm:15.2.1":
+ version: 15.2.1
+ resolution: "@next/swc-linux-x64-musl@npm:15.2.1"
+ conditions: os=linux & cpu=x64 & libc=musl
+ languageName: node
+ linkType: hard
+
"@next/swc-win32-arm64-msvc@npm:13.5.7":
version: 13.5.7
resolution: "@next/swc-win32-arm64-msvc@npm:13.5.7"
@@ -7238,6 +7479,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-win32-arm64-msvc@npm:15.2.1":
+ version: 15.2.1
+ resolution: "@next/swc-win32-arm64-msvc@npm:15.2.1"
+ conditions: os=win32 & cpu=arm64
+ languageName: node
+ linkType: hard
+
"@next/swc-win32-ia32-msvc@npm:13.5.7":
version: 13.5.7
resolution: "@next/swc-win32-ia32-msvc@npm:13.5.7"
@@ -7266,6 +7514,13 @@ __metadata:
languageName: node
linkType: hard
+"@next/swc-win32-x64-msvc@npm:15.2.1":
+ version: 15.2.1
+ resolution: "@next/swc-win32-x64-msvc@npm:15.2.1"
+ conditions: os=win32 & cpu=x64
+ languageName: node
+ linkType: hard
+
"@next/third-parties@npm:^14.2.5":
version: 14.2.5
resolution: "@next/third-parties@npm:14.2.5"
@@ -12981,13 +13236,22 @@ __metadata:
languageName: node
linkType: hard
-"@swc/counter@npm:^0.1.3":
+"@swc/counter@npm:0.1.3, @swc/counter@npm:^0.1.3":
version: 0.1.3
resolution: "@swc/counter@npm:0.1.3"
checksum: df8f9cfba9904d3d60f511664c70d23bb323b3a0803ec9890f60133954173047ba9bdeabce28cd70ba89ccd3fd6c71c7b0bd58be85f611e1ffbe5d5c18616598
languageName: node
linkType: hard
+"@swc/helpers@npm:0.5.15":
+ version: 0.5.15
+ resolution: "@swc/helpers@npm:0.5.15"
+ dependencies:
+ tslib: ^2.8.0
+ checksum: 1a9e0dbb792b2d1e0c914d69c201dbc96af3a0e6e6e8cf5a7f7d6a5d7b0e8b762915cd4447acb6b040e2ecc1ed49822875a7239f99a2d63c96c3c3407fb6fccf
+ languageName: node
+ linkType: hard
+
"@swc/helpers@npm:0.5.2":
version: 0.5.2
resolution: "@swc/helpers@npm:0.5.2"
@@ -13223,9 +13487,9 @@ __metadata:
languageName: node
linkType: hard
-"@tremor/react@npm:^2.0.0":
- version: 2.0.2
- resolution: "@tremor/react@npm:2.0.2"
+"@tremor/react@npm:^2.11.0":
+ version: 2.11.0
+ resolution: "@tremor/react@npm:2.11.0"
dependencies:
"@floating-ui/react": ^0.19.1
date-fns: ^2.28.0
@@ -13234,7 +13498,8 @@ __metadata:
tailwind-merge: ^1.9.1
peerDependencies:
react: ^18.0.0
- checksum: 4002a062a3bcdc164904187ffe53934d26edbb8d342a3f756b99c32beb0d997bf0937fdda39526d964e34cc996231b485fc68fc4a580c1d009b4a2fcb8ebdc27
+ react-dom: ">=16.6.0"
+ checksum: 76bee230a819289a5e87204f51161724b49bcc281308b4c41a5918e57e93497e2e97eb85b951bd750b918093784fdb28a2d1060b89502544f1a9cf76232da6d3
languageName: node
linkType: hard
@@ -13843,6 +14108,16 @@ __metadata:
languageName: node
linkType: hard
+"@types/hoist-non-react-statics@npm:^3.3.6":
+ version: 3.3.6
+ resolution: "@types/hoist-non-react-statics@npm:3.3.6"
+ dependencies:
+ "@types/react": "*"
+ hoist-non-react-statics: ^3.3.0
+ checksum: f03e43bd081876c49584ffa0eb690d69991f258203efca44dcc30efdda49a50653ff06402917d1edc9cb7e2adebbe9e2d1d0e739bc99c1b5372103b1cc534e47
+ languageName: node
+ linkType: hard
+
"@types/http-assert@npm:*":
version: 1.5.5
resolution: "@types/http-assert@npm:1.5.5"
@@ -16960,15 +17235,6 @@ __metadata:
languageName: node
linkType: hard
-"bindings@npm:^1.5.0":
- version: 1.5.0
- resolution: "bindings@npm:1.5.0"
- dependencies:
- file-uri-to-path: 1.0.0
- checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7
- languageName: node
- linkType: hard
-
"biskviit@npm:1.0.1":
version: 1.0.1
resolution: "biskviit@npm:1.0.1"
@@ -17701,6 +17967,13 @@ __metadata:
languageName: node
linkType: hard
+"caniuse-lite@npm:^1.0.30001579":
+ version: 1.0.30001704
+ resolution: "caniuse-lite@npm:1.0.30001704"
+ checksum: ac8c1b625198c9fdf03f55ef631a0917d29d368ded8e8b2e6a3111cb7433c30b2ef16a6dc44077fb6176e76881a51818d55f24efd04478f5e98b6724b64a8f5c
+ languageName: node
+ linkType: hard
+
"caniuse-lite@npm:^1.0.30001587, caniuse-lite@npm:^1.0.30001591":
version: 1.0.30001597
resolution: "caniuse-lite@npm:1.0.30001597"
@@ -18103,7 +18376,7 @@ __metadata:
languageName: node
linkType: hard
-"classnames@npm:^2.2.5, classnames@npm:^2.2.6":
+"classnames@npm:^2.2.6":
version: 2.3.2
resolution: "classnames@npm:2.3.2"
checksum: 2c62199789618d95545c872787137262e741f9db13328e216b093eea91c85ef2bfb152c1f9e63027204e2559a006a92eb74147d46c800a9f96297ae1d9f96f4e
@@ -18430,7 +18703,7 @@ __metadata:
languageName: node
linkType: hard
-"color-string@npm:^1.6.0":
+"color-string@npm:^1.6.0, color-string@npm:^1.9.0":
version: 1.9.1
resolution: "color-string@npm:1.9.1"
dependencies:
@@ -18459,6 +18732,16 @@ __metadata:
languageName: node
linkType: hard
+"color@npm:^4.2.3":
+ version: 4.2.3
+ resolution: "color@npm:4.2.3"
+ dependencies:
+ color-convert: ^2.0.1
+ color-string: ^1.9.0
+ checksum: 0579629c02c631b426780038da929cca8e8d80a40158b09811a0112a107c62e10e4aad719843b791b1e658ab4e800558f2e87ca4522c8b32349d497ecb6adeb4
+ languageName: node
+ linkType: hard
+
"colorette@npm:^2.0.16":
version: 2.0.16
resolution: "colorette@npm:2.0.16"
@@ -19274,13 +19557,6 @@ __metadata:
languageName: node
linkType: hard
-"css-unit-converter@npm:^1.1.1":
- version: 1.1.2
- resolution: "css-unit-converter@npm:1.1.2"
- checksum: 07888033346a5128f34dbe2f72884c966d24e9f29db24416dcde92860242490617ef9a178ac193a92f730834bbeea026cdc7027701d92ba9bbbe59db7a37eb2a
- languageName: node
- linkType: hard
-
"css-what@npm:^6.1.0":
version: 6.1.0
resolution: "css-what@npm:6.1.0"
@@ -19556,9 +19832,11 @@ __metadata:
linkType: hard
"date-fns@npm:^2.28.0":
- version: 2.29.3
- resolution: "date-fns@npm:2.29.3"
- checksum: e01cf5b62af04e05dfff921bb9c9933310ed0e1ae9a81eb8653452e64dc841acf7f6e01e1a5ae5644d0337e9a7f936175fd2cb6819dc122fdd9c5e86c56be484
+ version: 2.30.0
+ resolution: "date-fns@npm:2.30.0"
+ dependencies:
+ "@babel/runtime": ^7.21.0
+ checksum: f7be01523282e9bb06c0cd2693d34f245247a29098527d4420628966a2d9aad154bd0e90a6b1cf66d37adcb769cd108cf8a7bd49d76db0fb119af5cdd13644f4
languageName: node
linkType: hard
@@ -19597,16 +19875,6 @@ __metadata:
languageName: node
linkType: hard
-"deasync@npm:^0.1.30":
- version: 0.1.30
- resolution: "deasync@npm:0.1.30"
- dependencies:
- bindings: ^1.5.0
- node-addon-api: ^1.7.1
- checksum: 1faeb20e1ec1c6ebde35a44f309e1b544804c782b25b513536e5a7313f89a45eb1565f228d06a1a233b285673137731822f81c6629a52a729f4fffb94f433549
- languageName: node
- linkType: hard
-
"debounce-fn@npm:^4.0.0":
version: 4.0.0
resolution: "debounce-fn@npm:4.0.0"
@@ -19936,7 +20204,7 @@ __metadata:
languageName: node
linkType: hard
-"detect-libc@npm:^2.0.1":
+"detect-libc@npm:^2.0.1, detect-libc@npm:^2.0.3":
version: 2.0.3
resolution: "detect-libc@npm:2.0.3"
checksum: 2ba6a939ae55f189aea996ac67afceb650413c7a34726ee92c40fb0deb2400d57ef94631a8a3f052055eea7efb0f99a9b5e6ce923415daa3e68221f963cfc27d
@@ -20081,15 +20349,6 @@ __metadata:
languageName: node
linkType: hard
-"dom-helpers@npm:^3.4.0":
- version: 3.4.0
- resolution: "dom-helpers@npm:3.4.0"
- dependencies:
- "@babel/runtime": ^7.1.2
- checksum: 58d9f1c4a96daf77eddc63ae1236b826e1cddd6db66bbf39b18d7e21896d99365b376593352d52a60969d67fa4a8dbef26adc1439fa2c1b355efa37cacbaf637
- languageName: node
- linkType: hard
-
"dom-helpers@npm:^5.0.1":
version: 5.2.1
resolution: "dom-helpers@npm:5.2.1"
@@ -22122,10 +22381,10 @@ __metadata:
languageName: node
linkType: hard
-"fast-equals@npm:^4.0.3":
- version: 4.0.3
- resolution: "fast-equals@npm:4.0.3"
- checksum: 3d5935b757f9f2993e59b5164a7a9eeda0de149760495375cde14a4ed725186a7e6c1c0d58f7d42d2f91deb97f3fce1e0aad5591916ef0984278199a85c87c87
+"fast-equals@npm:^5.0.1":
+ version: 5.2.2
+ resolution: "fast-equals@npm:5.2.2"
+ checksum: 7156bcade0be5ee4dc335969d255a5815348d57080e1876fa1584451eafd0c92588de5f5840e55f81841b6d907ade2a49a46e4ec33e6f7a283a209c0fd8f8a59
languageName: node
linkType: hard
@@ -22438,13 +22697,6 @@ __metadata:
languageName: node
linkType: hard
-"file-uri-to-path@npm:1.0.0":
- version: 1.0.0
- resolution: "file-uri-to-path@npm:1.0.0"
- checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144
- languageName: node
- linkType: hard
-
"filelist@npm:^1.0.4":
version: 1.0.4
resolution: "filelist@npm:1.0.4"
@@ -24489,10 +24741,10 @@ __metadata:
languageName: node
linkType: hard
-"i18next-fs-backend@npm:^2.1.1":
- version: 2.1.3
- resolution: "i18next-fs-backend@npm:2.1.3"
- checksum: df3586f0958b5967674fa46aa7a579276156328b3f25e744c125b98bbeb8330c7a18a513a6224841e5732860c7bd54cb4a04b8d5a9eb521046dc37c254b67349
+"i18next-fs-backend@npm:^2.6.0":
+ version: 2.6.0
+ resolution: "i18next-fs-backend@npm:2.6.0"
+ checksum: 2a34a6f0563f7cc5c98de93e66fff66696eaf19b295d073fb1fef426db75783ecfab10b0251272957c307cbb3ffb4e9b5073c17ddb10be2e352d9b6e6ee71a5a
languageName: node
linkType: hard
@@ -29332,39 +29584,21 @@ __metadata:
languageName: node
linkType: hard
-"next-i18next@npm:13.3.0":
- version: 13.3.0
- resolution: "next-i18next@npm:13.3.0"
+"next-i18next@npm:^15.4.2":
+ version: 15.4.2
+ resolution: "next-i18next@npm:15.4.2"
dependencies:
- "@babel/runtime": ^7.20.13
- "@types/hoist-non-react-statics": ^3.3.1
+ "@babel/runtime": ^7.23.2
+ "@types/hoist-non-react-statics": ^3.3.6
core-js: ^3
hoist-non-react-statics: ^3.3.2
- i18next-fs-backend: ^2.1.1
+ i18next-fs-backend: ^2.6.0
peerDependencies:
- i18next: ^22.0.6
+ i18next: ">= 23.7.13"
next: ">= 12.0.0"
react: ">= 17.0.2"
- react-i18next: ^12.2.0
- checksum: 4c3aa5bbbc12964ed6f61f37d33f4319abd04932d6871baba9f209183952b286470fff80f90a94ccddba736c8fb13a9238effa1e8247dfb08e2239cbdc4fb769
- languageName: node
- linkType: hard
-
-"next-i18next@patch:next-i18next@npm%3A13.3.0#./.yarn/patches/next-i18next-npm-13.3.0-bf25b0943c.patch::locator=calcom-monorepo%40workspace%3A.":
- version: 13.3.0
- resolution: "next-i18next@patch:next-i18next@npm%3A13.3.0#./.yarn/patches/next-i18next-npm-13.3.0-bf25b0943c.patch::version=13.3.0&hash=bcbde7&locator=calcom-monorepo%40workspace%3A."
- dependencies:
- "@babel/runtime": ^7.20.13
- "@types/hoist-non-react-statics": ^3.3.1
- core-js: ^3
- hoist-non-react-statics: ^3.3.2
- i18next-fs-backend: ^2.1.1
- peerDependencies:
- i18next: ^22.0.6
- next: ">= 12.0.0"
- react: ">= 17.0.2"
- react-i18next: ^12.2.0
- checksum: 7dcb7e2ec14a0164e2c803b5eb4be3d3198ff0db266fecd6225dfa99ec53bf923fe50230c413f2e9b9a795266fb4e31f129572865181df1eadcf8721ad138b3e
+ react-i18next: ">= 13.5.0"
+ checksum: d5c3d675b66ae4c65f96c040a031df0c81c23d2562c398f560c3e629e47fb67061053c0bb58cce41b9e45106a0c9cf7db05ef464991a6908ed5bb8fd85f50634
languageName: node
linkType: hard
@@ -29545,6 +29779,67 @@ __metadata:
languageName: node
linkType: hard
+"next@npm:^15.1.6":
+ version: 15.2.1
+ resolution: "next@npm:15.2.1"
+ dependencies:
+ "@next/env": 15.2.1
+ "@next/swc-darwin-arm64": 15.2.1
+ "@next/swc-darwin-x64": 15.2.1
+ "@next/swc-linux-arm64-gnu": 15.2.1
+ "@next/swc-linux-arm64-musl": 15.2.1
+ "@next/swc-linux-x64-gnu": 15.2.1
+ "@next/swc-linux-x64-musl": 15.2.1
+ "@next/swc-win32-arm64-msvc": 15.2.1
+ "@next/swc-win32-x64-msvc": 15.2.1
+ "@swc/counter": 0.1.3
+ "@swc/helpers": 0.5.15
+ busboy: 1.6.0
+ caniuse-lite: ^1.0.30001579
+ postcss: 8.4.31
+ sharp: ^0.33.5
+ styled-jsx: 5.1.6
+ peerDependencies:
+ "@opentelemetry/api": ^1.1.0
+ "@playwright/test": ^1.41.2
+ babel-plugin-react-compiler: "*"
+ react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
+ sass: ^1.3.0
+ dependenciesMeta:
+ "@next/swc-darwin-arm64":
+ optional: true
+ "@next/swc-darwin-x64":
+ optional: true
+ "@next/swc-linux-arm64-gnu":
+ optional: true
+ "@next/swc-linux-arm64-musl":
+ optional: true
+ "@next/swc-linux-x64-gnu":
+ optional: true
+ "@next/swc-linux-x64-musl":
+ optional: true
+ "@next/swc-win32-arm64-msvc":
+ optional: true
+ "@next/swc-win32-x64-msvc":
+ optional: true
+ sharp:
+ optional: true
+ peerDependenciesMeta:
+ "@opentelemetry/api":
+ optional: true
+ "@playwright/test":
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ sass:
+ optional: true
+ bin:
+ next: dist/bin/next
+ checksum: 277aabc5f8c0aea6c2309adb4d251676652bb6eee2b625985a01d9039f945e1fbae7bc33ed7dde44de63a9f21da49bcc280df750bba76c3380c65ab0bce8d25e
+ languageName: node
+ linkType: hard
+
"nice-try@npm:^1.0.4":
version: 1.0.5
resolution: "nice-try@npm:1.0.5"
@@ -29575,15 +29870,6 @@ __metadata:
languageName: node
linkType: hard
-"node-addon-api@npm:^1.7.1":
- version: 1.7.2
- resolution: "node-addon-api@npm:1.7.2"
- dependencies:
- node-gyp: latest
- checksum: 938922b3d7cb34ee137c5ec39df6289a3965e8cab9061c6848863324c21a778a81ae3bc955554c56b6b86962f6ccab2043dd5fa3f33deab633636bd28039333f
- languageName: node
- linkType: hard
-
"node-domexception@npm:1.0.0":
version: 1.0.0
resolution: "node-domexception@npm:1.0.0"
@@ -31643,13 +31929,6 @@ __metadata:
languageName: node
linkType: hard
-"postcss-value-parser@npm:^3.3.0":
- version: 3.3.1
- resolution: "postcss-value-parser@npm:3.3.1"
- checksum: 62cd26e1cdbcf2dcc6bcedf3d9b409c9027bc57a367ae20d31dd99da4e206f730689471fd70a2abe866332af83f54dc1fa444c589e2381bf7f8054c46209ce16
- languageName: node
- linkType: hard
-
"postcss-value-parser@npm:^4.0.0, postcss-value-parser@npm:^4.0.2, postcss-value-parser@npm:^4.2.0":
version: 4.2.0
resolution: "postcss-value-parser@npm:4.2.0"
@@ -32869,7 +33148,7 @@ __metadata:
languageName: node
linkType: hard
-"react-is@npm:^16.10.2, react-is@npm:^16.13.1, react-is@npm:^16.7.0":
+"react-is@npm:^16.13.1, react-is@npm:^16.7.0":
version: 16.13.1
resolution: "react-is@npm:16.13.1"
checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f
@@ -32890,10 +33169,10 @@ __metadata:
languageName: node
linkType: hard
-"react-lifecycles-compat@npm:^3.0.4":
- version: 3.0.4
- resolution: "react-lifecycles-compat@npm:3.0.4"
- checksum: a904b0fc0a8eeb15a148c9feb7bc17cec7ef96e71188280061fc340043fd6d8ee3ff233381f0e8f95c1cf926210b2c4a31f38182c8f35ac55057e453d6df204f
+"react-is@npm:^18.3.1":
+ version: 18.3.1
+ resolution: "react-is@npm:18.3.1"
+ checksum: e20fe84c86ff172fc8d898251b7cc2c43645d108bf96d0b8edf39b98f9a2cae97b40520ee7ed8ee0085ccc94736c4886294456033304151c3f94978cec03df21
languageName: node
linkType: hard
@@ -33095,18 +33374,6 @@ __metadata:
languageName: node
linkType: hard
-"react-resize-detector@npm:^8.0.4":
- version: 8.0.4
- resolution: "react-resize-detector@npm:8.0.4"
- dependencies:
- lodash: ^4.17.21
- peerDependencies:
- react: ^16.0.0 || ^17.0.0 || ^18.0.0
- react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
- checksum: f53a99cc5413844a6fc2a713b0b1094d23947897c14ab64481938632f4e77fadded52d91a6619055abf6240c7cacd6cc7dd492ea866639b302f81df680709d45
- languageName: node
- linkType: hard
-
"react-schemaorg@npm:^2.0.0":
version: 2.0.0
resolution: "react-schemaorg@npm:2.0.0"
@@ -33158,17 +33425,17 @@ __metadata:
languageName: node
linkType: hard
-"react-smooth@npm:^2.0.2":
- version: 2.0.2
- resolution: "react-smooth@npm:2.0.2"
+"react-smooth@npm:^4.0.4":
+ version: 4.0.4
+ resolution: "react-smooth@npm:4.0.4"
dependencies:
- fast-equals: ^4.0.3
- react-transition-group: 2.9.0
+ fast-equals: ^5.0.1
+ prop-types: ^15.8.1
+ react-transition-group: ^4.4.5
peerDependencies:
- prop-types: ^15.6.0
- react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
- react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
- checksum: 6b0a40a17314657ac6a187a3ad01fcdaa61d498979b6a07c424e20832110c99b4394c33209a0b39b897c13d113d8cb044e7a691b4965386a11b15bbfbacfba25
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ checksum: 909305d40bae79a011ff21a10c4bc7ddadc87ac5ff093b4a5f827f730f093ec4e044c4330688d29b3ad2db83aab8997c3bb1bae550a9c66de74521b8ed52cc53
languageName: node
linkType: hard
@@ -33244,21 +33511,6 @@ __metadata:
languageName: node
linkType: hard
-"react-transition-group@npm:2.9.0":
- version: 2.9.0
- resolution: "react-transition-group@npm:2.9.0"
- dependencies:
- dom-helpers: ^3.4.0
- loose-envify: ^1.4.0
- prop-types: ^15.6.2
- react-lifecycles-compat: ^3.0.4
- peerDependencies:
- react: ">=15.0.0"
- react-dom: ">=15.0.0"
- checksum: d8c9e50aabdc2cfc324e5cdb0ad1c6eecb02e1c0cd007b26d5b30ccf49015e900683dd489348c71fba4055858308d9ba7019e0d37d0e8d37bd46ed098788f670
- languageName: node
- linkType: hard
-
"react-transition-group@npm:^4.3.0":
version: 4.4.2
resolution: "react-transition-group@npm:4.4.2"
@@ -33536,23 +33788,21 @@ __metadata:
linkType: hard
"recharts@npm:^2.3.2":
- version: 2.5.0
- resolution: "recharts@npm:2.5.0"
+ version: 2.15.1
+ resolution: "recharts@npm:2.15.1"
dependencies:
- classnames: ^2.2.5
+ clsx: ^2.0.0
eventemitter3: ^4.0.1
- lodash: ^4.17.19
- react-is: ^16.10.2
- react-resize-detector: ^8.0.4
- react-smooth: ^2.0.2
+ lodash: ^4.17.21
+ react-is: ^18.3.1
+ react-smooth: ^4.0.4
recharts-scale: ^0.4.4
- reduce-css-calc: ^2.1.8
+ tiny-invariant: ^1.3.1
victory-vendor: ^36.6.8
peerDependencies:
- prop-types: ^15.6.0
- react: ^16.0.0 || ^17.0.0 || ^18.0.0
- react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0
- checksum: a40d1788589926fa8a5844868a338aae75a2077a2bc2ac57fc5d61ad21fb62660aed6f00ae8d8a94948b9143255c1760db0d386ecb257ed8290dd7f164b5bd5f
+ react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ checksum: c288012087424e7067bf4a48a3d50a7c0ea231188ecaaf17685d93711ef1846aedd37509dfc25c046052f671e7e19dd2de5d8b9c1e497a64c39995c9c338b40a
languageName: node
linkType: hard
@@ -33630,16 +33880,6 @@ __metadata:
languageName: node
linkType: hard
-"reduce-css-calc@npm:^2.1.8":
- version: 2.1.8
- resolution: "reduce-css-calc@npm:2.1.8"
- dependencies:
- css-unit-converter: ^1.1.1
- postcss-value-parser: ^3.3.0
- checksum: 8fd27c06c4b443b84749a69a8b97d10e6ec7d142b625b41923a8807abb22b9e37e44df14e26cc606a802957be07bdce5e8ee2976a6952a7b438a7727007101e9
- languageName: node
- linkType: hard
-
"redux-immutable@npm:^4.0.0":
version: 4.0.0
resolution: "redux-immutable@npm:4.0.0"
@@ -34717,6 +34957,15 @@ __metadata:
languageName: node
linkType: hard
+"semver@npm:^7.6.3":
+ version: 7.7.1
+ resolution: "semver@npm:7.7.1"
+ bin:
+ semver: bin/semver.js
+ checksum: 586b825d36874007c9382d9e1ad8f93888d8670040add24a28e06a910aeebd673a2eb9e3bf169c6679d9245e66efb9057e0852e70d9daa6c27372aab1dda7104
+ languageName: node
+ linkType: hard
+
"semver@npm:~2.3.1":
version: 2.3.2
resolution: "semver@npm:2.3.2"
@@ -34907,6 +35156,75 @@ __metadata:
languageName: node
linkType: hard
+"sharp@npm:^0.33.5":
+ version: 0.33.5
+ resolution: "sharp@npm:0.33.5"
+ dependencies:
+ "@img/sharp-darwin-arm64": 0.33.5
+ "@img/sharp-darwin-x64": 0.33.5
+ "@img/sharp-libvips-darwin-arm64": 1.0.4
+ "@img/sharp-libvips-darwin-x64": 1.0.4
+ "@img/sharp-libvips-linux-arm": 1.0.5
+ "@img/sharp-libvips-linux-arm64": 1.0.4
+ "@img/sharp-libvips-linux-s390x": 1.0.4
+ "@img/sharp-libvips-linux-x64": 1.0.4
+ "@img/sharp-libvips-linuxmusl-arm64": 1.0.4
+ "@img/sharp-libvips-linuxmusl-x64": 1.0.4
+ "@img/sharp-linux-arm": 0.33.5
+ "@img/sharp-linux-arm64": 0.33.5
+ "@img/sharp-linux-s390x": 0.33.5
+ "@img/sharp-linux-x64": 0.33.5
+ "@img/sharp-linuxmusl-arm64": 0.33.5
+ "@img/sharp-linuxmusl-x64": 0.33.5
+ "@img/sharp-wasm32": 0.33.5
+ "@img/sharp-win32-ia32": 0.33.5
+ "@img/sharp-win32-x64": 0.33.5
+ color: ^4.2.3
+ detect-libc: ^2.0.3
+ semver: ^7.6.3
+ dependenciesMeta:
+ "@img/sharp-darwin-arm64":
+ optional: true
+ "@img/sharp-darwin-x64":
+ optional: true
+ "@img/sharp-libvips-darwin-arm64":
+ optional: true
+ "@img/sharp-libvips-darwin-x64":
+ optional: true
+ "@img/sharp-libvips-linux-arm":
+ optional: true
+ "@img/sharp-libvips-linux-arm64":
+ optional: true
+ "@img/sharp-libvips-linux-s390x":
+ optional: true
+ "@img/sharp-libvips-linux-x64":
+ optional: true
+ "@img/sharp-libvips-linuxmusl-arm64":
+ optional: true
+ "@img/sharp-libvips-linuxmusl-x64":
+ optional: true
+ "@img/sharp-linux-arm":
+ optional: true
+ "@img/sharp-linux-arm64":
+ optional: true
+ "@img/sharp-linux-s390x":
+ optional: true
+ "@img/sharp-linux-x64":
+ optional: true
+ "@img/sharp-linuxmusl-arm64":
+ optional: true
+ "@img/sharp-linuxmusl-x64":
+ optional: true
+ "@img/sharp-wasm32":
+ optional: true
+ "@img/sharp-win32-ia32":
+ optional: true
+ "@img/sharp-win32-x64":
+ optional: true
+ checksum: 04beae89910ac65c5f145f88de162e8466bec67705f497ace128de849c24d168993e016f33a343a1f3c30b25d2a90c3e62b017a9a0d25452371556f6cd2471e4
+ languageName: node
+ linkType: hard
+
"shebang-command@npm:^1.2.0":
version: 1.2.0
resolution: "shebang-command@npm:1.2.0"
@@ -36019,6 +36337,22 @@ __metadata:
languageName: node
linkType: hard
+"styled-jsx@npm:5.1.6":
+ version: 5.1.6
+ resolution: "styled-jsx@npm:5.1.6"
+ dependencies:
+ client-only: 0.0.1
+ peerDependencies:
+ react: ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0"
+ peerDependenciesMeta:
+ "@babel/core":
+ optional: true
+ babel-plugin-macros:
+ optional: true
+ checksum: 879ad68e3e81adcf4373038aaafe55f968294955593660e173fbf679204aff158c59966716a60b29af72dc88795cfb2c479b6d2c3c87b2b2d282f3e27cc66461
+ languageName: node
+ linkType: hard
+
"stylis@npm:4.0.13":
version: 4.0.13
resolution: "stylis@npm:4.0.13"
@@ -36354,9 +36688,9 @@ __metadata:
linkType: hard
"tailwind-merge@npm:^1.9.1":
- version: 1.10.0
- resolution: "tailwind-merge@npm:1.10.0"
- checksum: 80eb30d0300ca912b4b910460497a1d5fb4e697c3aedb01513e633973328684fa7ddf9bfb8550dca28176971c93bcb7ecb7eec3097c01d9c55c191563c693aab
+ version: 1.14.0
+ resolution: "tailwind-merge@npm:1.14.0"
+ checksum: 8cf5d37f51b3b32e4bdd5544feaed34357bfba2f64f14834cc4a21ac29b0ae22d7255386467a0f1dadb3e38499389efbbabeddcd0b16571af5a0d346a4921877
languageName: node
linkType: hard
@@ -37354,6 +37688,13 @@ __metadata:
languageName: node
linkType: hard
+"tslib@npm:^2.8.0":
+ version: 2.8.1
+ resolution: "tslib@npm:2.8.1"
+ checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a
+ languageName: node
+ linkType: hard
+
"tslog@npm:^4.9.2":
version: 4.9.2
resolution: "tslog@npm:4.9.2"