Compare commits

...
76 Commits
Author SHA1 Message Date
Peer Richelsen 1a7911e9e2 Update package.json
release.yml / release (push) Canceled after 0s
2023-04-19 08:57:31 +02:00
Crowdin Bot cb09b5bc5f New Crowdin translations by Github Action 2023-04-19 06:47:15 +00:00
Efraín Rochín a99031bdd2 fix: [CAL-1490] Google Cal/Outlook not actively syncing/self hosted (#8305) 2023-04-19 08:46:17 +02:00
ada8a98362 chore: add database indexes (#8361)
Co-authored-by: Mythie <me@lucasjamessmith.me>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-04-18 16:50:42 -07:00
Yagiz Nizipli e176e81bae perf: improve bookings performance (#8362) 2023-04-18 16:48:53 -07:00
zomars b64dd66c2c Fixes bundle comments
https://github.com/hashicorp/nextjs-bundle-analysis/issues/52#issuecomment-1513913373
2023-04-18 16:40:06 -07:00
Crowdin Bot 7fd162601b New Crowdin translations by Github Action 2023-04-18 23:29:50 +00:00
c1f346c935 Cal 1099 availability section defined hour mismatch (#7416)
* CAL-1099 Add prop for availability in formMethods

* fix: show correct availabilty name

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>

* CAL - 1099 / fix 12 hr time format bug

* fix: remove useEffect and fix vertical tab item ui

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>

* Fixes merge conflicts

* Update index.tsx

* More conflict fixes

* Update packages/ui/components/navigation/tabs/VerticalTabs.tsx

* Type fixes

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: zomars <zomars@me.com>
2023-04-18 23:29:02 +00:00
Keith Williams 36d47bd2d8 v2.8.3
release.yml / release (push) Canceled after 0s
2023-04-18 18:22:24 -03:00
26cdb6521f perf: Adds PageWrapper to pages (#8344)
* Adds PageWrapper to pages

* Add missing PageWrapper

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-04-18 15:45:32 -03:00
Leo Giovanetti 014f1986de Adding missing mutation (#8357)
* Adding missing mutation

* Returning to prop for disabled
2023-04-18 16:48:19 +00:00
Carina WollendorferandCarinaWolli 3ef328421f Date override fixes (#8330)
* fix date override for fixed round robin + time zone in date override

* check if slot is within working hours of fixed hosts

* add test for date override in different time zone

* fix date overrides for not fixed hosts (round robin)

* code clean up

* fix added test

* use the correct timezone of user for date overrides

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-04-18 17:21:27 +02:00
Ben HybertandHariom Balhara c4fe69d826 Add Plausible (Custom) App (#8189)
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-04-18 19:24:51 +05:30
Hariom Balhara 6fd64b2209 Fix: cssVars API not working correctly on Booker Timeslot selection page (#8296)
* Use a method out of react scope to set CSS vars as that doesnt need react

* Refactor
2023-04-18 12:53:46 +00:00
Crowdin Bot 585e36793a New Crowdin translations by Github Action 2023-04-18 12:53:33 +00:00
Crowdin Bot 09b9370e13 New Crowdin translations by Github Action 2023-04-18 12:52:43 +00:00
Udit Takkar a76a4996b4 fix: address input (#8349)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-04-18 18:21:46 +05:30
Hariom Balhara b28d60b6dc API Support: Manage Booking Questions and responses (#8115) 2023-04-18 18:05:06 +05:30
Nafees Nazik a716eda14c fix: use the correct timezone of the user in booking detail page (#7915)
* fix: send timezone in query

* fiz: timezone

* fix: remove tz from createPayment

* fix: send timezone in query

* fiz: timezone

* fix: remove tz

* fix: remove tz

* fix: remove timezone query

* fix: timezone
2023-04-18 14:29:26 +02:00
Crowdin Bot 99f1524183 New Crowdin translations by Github Action 2023-04-18 12:10:14 +00:00
Peer Richelsen 7ce6454915 Update package.json
release.yml / release (push) Canceled after 0s
2023-04-18 14:09:25 +02:00
Crowdin Bot 93cb21f55a New Crowdin translations by Github Action 2023-04-18 10:09:05 +00:00
0aca769d06 Allow editing workflow templates (#8028)
* add event end time as variable

* add timezone as new variable

* add first version of template prefill

* set template body when template is updated

* set reminder template body and subject when creating workflow

* set email subject when changes templates

* save emailBody and emailsubject for all templates + fix duplicate template text

* add more flexibility for templates

* remove console.log

* fix {ORAGANIZER} and {ATTENDEE} variable

* make sure to always send reminder body and not default template

* fix import

* remove email body text and match variables in templates

* handle translations of formatted variables

* fix email reminder template

* add cancel and reschedule link as variable

* add cancel and reschedule link for scheduled emails/sms

* make sure empty empty body and subject are set for reminder template

* add info message for testing workflow

* fix typo

* add sms template

* add migration to remove reminderBody and emailSubject

* add branding

* code clean up

* add hide branding everywhere

* fix sms reminder template

* set sms reminder template if sms body is empty

* fix custom inputs variables everywhere

* fix variable translations + other small fixes

* fix some type errors

* fix more type errors

* fix everything missing around cron job scheduling

* make sure to always use custom template for sms messages

* fix type error

* code clean up

* rename link to url

* Add debug logs

* Update handleNewBooking.ts

* Add debug logs

* removed unneded responses

* fix booking questions + UI improvements

* remove html email body when changing to sms action

* code clean up + comments

* code clean up

* code clean up

* remove comment

* more clear info message for timezone variable

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: zomars <zomars@me.com>
Co-authored-by: alannnc <alannnc@gmail.com>
2023-04-18 11:08:09 +01:00
Nafees Nazik c0bda6257e Fix: dark mode issues (#8348)
* fix: dark mode

* fix: dark mode
2023-04-18 09:12:12 +00:00
Yagiz Nizipliandzomars ae22246f05 perf: improve application toggle flow (#8302)
* perf: improve application toggle flow

* Reverses logic for enabled apps

---------

Co-authored-by: zomars <zomars@me.com>
2023-04-18 01:17:16 -07:00
Crowdin Bot e2931d9fa2 New Crowdin translations by Github Action 2023-04-18 07:54:34 +00:00
Crowdin Bot e6a8a31b53 New Crowdin translations by Github Action 2023-04-18 07:53:41 +00:00
Crowdin Bot ee86c751f7 New Crowdin translations by Github Action 2023-04-18 07:52:53 +00:00
Crowdin Bot 073b212c05 New Crowdin translations by Github Action 2023-04-18 07:52:00 +00:00
Nafees NazikandBailey Pumfleet cd8e2124c4 fix: check box (#8328)
Co-authored-by: Bailey Pumfleet <bailey@pumfleet.co.uk>
2023-04-18 08:51:03 +01:00
JoeandOmar López 9dd36bd20e fix: signup form submiting after api error (#8298)
Co-authored-by: Omar López <zomars@me.com>
2023-04-18 01:58:54 +00:00
Crowdin Bot b1404356ff New Crowdin translations by Github Action 2023-04-18 01:55:59 +00:00
Nafees Nazikandzomars f467bb7957 perf: use LRU cache for getServerSession (#8339)
* chore: add lru package

* feat: use LRU cache

* fix: type

* Updates package json

---------

Co-authored-by: zomars <zomars@me.com>
2023-04-18 01:55:01 +00:00
597b14cf4c perf: improve application list execution (#8301)
* perf: improve application list execution

* Removed unused interface

* Type fix

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: zomars <zomars@me.com>
2023-04-18 00:54:15 +00:00
2bdd6df755 avoid calendar cache on cold starts (#8311)
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
2023-04-17 23:56:08 +00:00
Yagiz NizipliandEfraín Rochín ad958f10bd perf: improve booking confirm authorization (#8304)
* perf: improve booking confirm authorization

* removes unreachable code

---------

Co-authored-by: Efraín Rochín <roae.85@gmail.com>
2023-04-17 23:50:34 +00:00
e5eb7c3906 perf: use getSlimServerSession for session retrieval (#8308)
* perf: use getSlimServerSession for session retrieval

Creates a new `getSlimServerSession` method and replaces all calls to `getServerSession`.

The new method is much faster than `getServerSession` with it not requiring the NextAuth options object which includes a number of additional packages.

Additionally introduces a primitive in-memory cache for slim sessions.

* fix: account for seconds in token.exp

* Reverts diffs

* Replaces getServerSession with slimmer version

* Update disable.ts

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: zomars <zomars@me.com>
2023-04-17 23:48:00 +00:00
zomars 667d42d5da Update yarn.lock 2023-04-17 15:46:43 -07:00
zomars a23a9ad15a Reverts PR checks limit 2023-04-17 15:26:17 -07:00
Crowdin Bot 4482ffc66b New Crowdin translations by Github Action 2023-04-17 22:23:34 +00:00
Udit Takkar 493efabd2e perf: remove sentry (#8334) 2023-04-17 22:22:44 +00:00
Crowdin Bot a0355e276d New Crowdin translations by Github Action 2023-04-17 19:55:05 +00:00
b5c993e153 perf: replace notIn with equals on booking (#8303)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-04-17 16:54:14 -03:00
Crowdin Bot da3ee3f1fe New Crowdin translations by Github Action 2023-04-17 16:20:34 +00:00
Udit TakkarandPeer Richelsen d9fc595444 fix: undo showRecordingsButton (#8262)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-04-17 16:19:24 +00:00
06d13e0f6e feat: Added option to select the exchange server version (#7908)
* Added option to select the exchange server version

* Fixed linting issues

* Removed yarn changes

* Update packages/app-store/exchangecalendar/lib/CalendarService.ts

Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>

* Removed requested change

---------

Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-04-17 10:21:14 -04:00
Udit Takkar 7dc3266133 fix: use text-emphasis (#8332)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-04-17 14:54:39 +01:00
Hariom Balhara 2c96444058 Fix/Keep themes in peace across embed and booking pages and App (#8108) 2023-04-17 17:46:54 +05:30
Nafees Nazik 39c48e7f79 fix: some ui regressions (#8260)
* fix: icon size

* fix: icon size

* fix: border
2023-04-17 12:09:30 +00:00
Hariom Balhara b6e1989f17 Invalidate the form query on toggle to update toggle state in UI (#8325) 2023-04-17 17:34:25 +05:30
Nafees Nazik 45b5b2a376 fix: giphy input dark color 2023-04-17 17:27:30 +05:30
JoeandPeer Richelsen 05726ec94c fix: varients to layer (#8171)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-04-16 22:22:10 +00:00
Peer RichelsenandAlex van Andel 6340ff43d8 removed page_view tracker (#8267)
* removed page_view tracker

* Removed unused useTelemetry

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-04-16 21:58:47 +00:00
Peer Richelsen e64b26c7e1 fixed dark mode booker (#8315) 2023-04-16 21:47:07 +00:00
Joe c829a7de82 fix: remove line-clamp from plugins (#8309) 2023-04-16 23:05:44 +02:00
JoeandPeer Richelsen 0205bfb066 fix: MobileSettingsContainer height (#8295)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-04-16 20:18:56 +00:00
5fd7d63388 correction of position on 'Adding events to' button (#8290)
* correction to position

* Update apps/web/components/settings/CalendarSwitch.tsx

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-04-16 20:06:02 +00:00
e1ea2cb532 chore: UI username RTL (#8300)
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-04-16 19:35:17 +00:00
Joe 88d151aa35 fix: scroll-bar class for editor compnent (#8310) 2023-04-16 21:17:07 +02:00
Crowdin Bot 4e7c93a322 New Crowdin translations by Github Action 2023-04-16 18:50:25 +00:00
Peer Richelsen 281c7628c1 fixed bg 2023-04-16 20:49:12 +02:00
Crowdin Bot 1b24bc14cd New Crowdin translations by Github Action 2023-04-15 13:23:37 +00:00
Hariom Balhara be3d2fca05 Use name to generate unique for attribute for label (#8265) 2023-04-15 13:22:51 +00:00
Crowdin Bot 327e11e7c7 New Crowdin translations by Github Action 2023-04-15 11:51:04 +00:00
Peer Richelsen bd999345f4 Update package.json
release.yml / release (push) Canceled after 0s
2023-04-15 13:50:06 +02:00
Keith Williams 081776b4f9 Fixing syntax error in stale issue cron action (#8269) 2023-04-15 13:49:16 +02:00
Peer Richelsen 8c328ce5d7 fixed yarn dx (#8293) 2023-04-15 11:48:44 +00:00
Crowdin Bot 0fa2a6aea3 New Crowdin translations by Github Action
release.yml / release (push) Canceled after 0s
2023-04-15 09:21:02 +00:00
Peer Richelsen 440251f9c3 Update package.json 2023-04-15 11:20:06 +02:00
Omar LópezandLeo Giovanetti 7f6847f7c7 In-app users admin (#8035)
* WIP

* WIP

* Update trpc-router.ts

* Fixes

* Update trpc-router.ts

* Update zod-utils.ts

* Apply suggestions from code review

Co-authored-by: Leo Giovanetti <hello@leog.me>

* Feedback and dark mode fixes

* Feedback

* Fixes

* Update UserForm.tsx

---------

Co-authored-by: Leo Giovanetti <hello@leog.me>
2023-04-14 17:04:48 -07:00
zomars 9f1fa83a97 Update pr.yml 2023-04-14 17:04:35 -07:00
Joe Au-Yeung f00b112792 Change Stripe <CardElement /> to <PaymentElement /> (#8268)
* Use Stripe PaymentElement

* Only show needs confirmation, if the booking needs it

* Clean up

* Type fix

* More type fixes
2023-04-14 21:56:16 +00:00
Yagiz Nizipli 5339a489f5 perf: reduce array iteration on bookings router (#8276) 2023-04-14 21:29:43 +00:00
Yagiz Nizipli f7df204e0b perf: parallelize database calls to improve speed (#8275) 2023-04-14 21:27:10 +00:00
Alex van Andel 4975aba5e0 Move some dependencies into async (#8270)
* Move some dependencies into async

* Also remove jackson & jose from global scope
2023-04-14 14:25:15 -07:00
Omar López 29d61ad67b Update CODEOWNERS 2023-04-14 14:18:06 -07:00
229 changed files with 3776 additions and 1616 deletions
-3
View File
@@ -160,9 +160,6 @@ CLOSECOM_API_KEY=
# Sendgrid internal sync service
SENDGRID_SYNC_API_KEY=
# Sentry
NEXT_PUBLIC_SENTRY_DSN=
SENTRY_IGNORE_API_RESOLUTION_ERROR=
# Change your Brand
NEXT_PUBLIC_APP_NAME="Cal.com"
+2 -1
View File
@@ -5,7 +5,8 @@
# the repo. Unless a later match takes precedence,
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
* @calcom/reviewers
# ⬇️ Removed so we can manually trigger checks
# * @calcom/reviewers
.github/ @calcom/core
.husky/ @calcom/core
+1 -1
View File
@@ -20,4 +20,4 @@ jobs:
days-before-pr-stale: 14
days-before-pr-close: 7
stale-pr-message: "This PR is being marked as stale due to inactivity."
close-pr-message: "This PR is being closed due to inactivity. Please reopen if work is intended to be continued.
close-pr-message: "This PR is being closed due to inactivity. Please reopen if work is intended to be continued."
+2 -2
View File
@@ -24,7 +24,7 @@ jobs:
- name: Analyze bundle
run: |
cd apps/web
npx -p nextjs-bundle-analysis report
npx -p nextjs-bundle-analysis@0.5.0 report
- name: Upload bundle
uses: actions/upload-artifact@v2
@@ -76,7 +76,7 @@ jobs:
id: fc
with:
issue-number: ${{ github.event.number }}
body-includes: "<!-- __NEXTJS_BUNDLE -->"
body-includes: "<!-- __NEXTJS_BUNDLE_@calcom/web -->"
- name: Create Comment
uses: peter-evans/create-or-update-comment@v1.4.4
-1
View File
@@ -2,7 +2,6 @@ name: PR Update
on:
pull_request_target:
types: [review_requested]
branches:
- main
paths-ignore:
-2
View File
@@ -68,5 +68,3 @@ public/embed
# Copied app-store images
public/app-store
# Sentry
.sentryclirc
+99
View File
@@ -0,0 +1,99 @@
import { DefaultSeo } from "next-seo";
import { Inter } from "next/font/google";
import localFont from "next/font/local";
import Script from "next/script";
import "@calcom/embed-core/src/embed-iframe";
import { useEmbedUiConfig } from "@calcom/embed-core/src/embed-iframe";
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
import type { AppProps } from "@lib/app-providers";
import AppProviders from "@lib/app-providers";
import { seoConfig } from "@lib/config/next-seo.config";
import I18nLanguageHandler from "@components/I18nLanguageHandler";
export interface CalPageWrapper {
(props?: any): JSX.Element;
PageWrapper?: AppProps["Component"]["PageWrapper"];
}
const interFont = Inter({ subsets: ["latin"], variable: "--font-inter", preload: true, display: "swap" });
const calFont = localFont({
src: "../fonts/CalSans-SemiBold.woff2",
variable: "--font-cal",
preload: true,
display: "swap",
});
function PageWrapper(props: AppProps) {
const { Component, pageProps, err, router } = props;
let pageStatus = "200";
const { cssVarsPerTheme } = useEmbedUiConfig();
const cssVarsStyle = [];
if (cssVarsPerTheme) {
for (const [themeName, cssVars] of Object.entries(cssVarsPerTheme)) {
cssVarsStyle.push(`.${themeName} {`);
for (const [cssVarName, value] of Object.entries(cssVars)) {
cssVarsStyle.push(`--${cssVarName}: ${value};`);
}
cssVarsStyle.push(`}`);
}
}
if (router.pathname === "/404") {
pageStatus = "404";
} else if (router.pathname === "/500") {
pageStatus = "500";
}
// On client side don't let nonce creep into DOM
// It also avoids hydration warning that says that Client has the nonce value but server has "" because browser removes nonce attributes before DOM is built
// See https://github.com/kentcdodds/nonce-hydration-issues
// Set "" only if server had it set otherwise keep it undefined because server has to match with client to avoid hydration error
const nonce = typeof window !== "undefined" ? (pageProps.nonce ? "" : undefined) : pageProps.nonce;
const providerProps = {
...props,
pageProps: {
...props.pageProps,
nonce,
},
};
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
return (
<AppProviders {...providerProps}>
<DefaultSeo {...seoConfig.defaultNextSeo} />
<I18nLanguageHandler />
<Script
nonce={nonce}
id="page-status"
dangerouslySetInnerHTML={{ __html: `window.CalComPageStatus = '${pageStatus}'` }}
/>
<style jsx global>{`
:root {
--font-inter: ${interFont.style.fontFamily};
--font-cal: ${calFont.style.fontFamily};
}
`}</style>
<style jsx global>
{`
${cssVarsStyle.join("")}
`}
</style>
{getLayout(
Component.requiresLicense ? (
<LicenseRequired>
<Component {...pageProps} err={err} />
</LicenseRequired>
) : (
<Component {...pageProps} err={err} />
),
router
)}
</AppProviders>
);
}
export default PageWrapper;
+1 -1
View File
@@ -238,7 +238,7 @@ const Component = ({
</span>
)}
<div className="prose-sm prose prose-headings:text-emphasis prose-code:text-default prose-strong:text-default text-default mt-8">
<div className="prose-sm prose prose-a:text-default prose-headings:text-emphasis prose-code:text-default prose-strong:text-default text-default mt-8">
{body}
</div>
<h4 className="text-emphasis mt-8 font-semibold ">{t("pricing")}</h4>
@@ -264,7 +264,7 @@ export function CalendarListContainer(props: { heading?: boolean; fromOnboarding
{!!data.connectedCalendars.length || !!installedCalendars.data?.items.length ? (
<>
{heading && (
<div className="flex flex-col gap-6 rounded-md border p-7">
<div className="border-default flex flex-col gap-6 rounded-md border p-7">
<ShellSubHeading
title={t("calendar")}
subtitle={t("installed_app_calendar_description")}
@@ -258,7 +258,12 @@ function BookingListItem(booking: BookingItemProps) {
};
const title = booking.title;
const showRecordingsButtons = booking.isRecorded && isPast && isConfirmed;
// To be used after we run query on legacy bookings
// const showRecordingsButtons = booking.isRecorded && isPast && isConfirmed;
const showRecordingsButtons =
(booking.location === "integrations:daily" || booking?.location?.trim() === "") && isPast && isConfirmed;
return (
<>
<RescheduleDialog
@@ -2,7 +2,6 @@ import { useRouter } from "next/router";
import { useCallback, useState } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import type { RecurringEvent } from "@calcom/types/Calendar";
import { Button, TextArea } from "@calcom/ui";
@@ -34,7 +33,6 @@ export default function CancelBooking(props: Props) {
const [loading, setLoading] = useState(false);
const telemetry = useTelemetry();
const [error, setError] = useState<string | null>(booking ? null : t("booking_already_cancelled"));
useTheme(props.theme);
const cancelBookingRef = useCallback((node: HTMLTextAreaElement) => {
if (node !== null) {
@@ -21,7 +21,6 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import notEmpty from "@calcom/lib/notEmpty";
import { getRecurringFreq } from "@calcom/lib/recurringStrings";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import { detectBrowserTimeFormat, setIs24hClockInLocalStorage, TimeFormat } from "@calcom/lib/timeFormat";
import { trpc } from "@calcom/trpc";
import { HeadSeo, NumberInput, useCalcomTheme } from "@calcom/ui";
@@ -105,8 +104,9 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
const [recurringEventCount, setRecurringEventCount] = useState(eventType.recurringEvent?.count);
/*
const telemetry = useTelemetry();
useEffect(() => {
useEffect(() => {
if (top !== window) {
//page_view will be collected automatically by _middleware.ts
telemetry.event(
@@ -114,7 +114,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
collectPageParameters("/availability", { isTeamBooking: document.URL.includes("team/") })
);
}
}, [telemetry]);
}, [telemetry]); */
const embedUiConfig = useEmbedUiConfig();
// get dynamic user list here
const userList = eventType.users ? eventType.users.map((user) => user.username).filter(notEmpty) : [];
@@ -39,7 +39,7 @@ import useTheme from "@calcom/lib/hooks/useTheme";
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
import { HttpError } from "@calcom/lib/http-error";
import { getEveryFreqFor } from "@calcom/lib/recurringStrings";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import { TimeFormat } from "@calcom/lib/timeFormat";
import { trpc } from "@calcom/trpc";
import { Button, Form, Tooltip, useCalcomTheme } from "@calcom/ui";
@@ -252,13 +252,13 @@ const BookingPage = ({
}
useEffect(() => {
if (top !== window) {
/* if (top !== window) {
//page_view will be collected automatically by _middleware.ts
telemetry.event(
telemetryEventTypes.embedView,
collectPageParameters("/book", { isTeamBooking: document.URL.includes("team/") })
);
}
} */
reserveSlot();
const interval = setInterval(reserveSlot, parseInt(MINUTES_TO_BOOK) * 60 * 1000 - 2000);
return () => {
@@ -547,7 +547,7 @@ const BookingPage = ({
<div
className={classNames(
"main",
isBackgroundTransparent ? "" : "bg-default",
isBackgroundTransparent ? "" : "bg-default dark:bg-muted",
"border-booker sm:border-booker-width rounded-md"
)}>
<div className="sm:flex">
@@ -1,21 +1,23 @@
import { SchedulingType } from "@prisma/client";
import type { FormValues, EventTypeSetup } from "pages/event-types/[type]";
import type { EventTypeSetup, FormValues } from "pages/event-types/[type]";
import { useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import type { OptionProps, SingleValueProps } from "react-select";
import { components } from "react-select";
import dayjs from "@calcom/dayjs";
import useLockedFieldsManager from "@calcom/features/ee/managed-event-types/hooks/useLockedFieldsManager";
import { NewScheduleButton } from "@calcom/features/schedules";
import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { weekdayNames } from "@calcom/lib/weekday";
import { trpc } from "@calcom/trpc/react";
import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery";
import { Badge, Button, Select, SettingsToggle, SkeletonText, EmptyScreen } from "@calcom/ui";
import { ExternalLink, Globe, Clock } from "@calcom/ui/components/icon";
import { Badge, Button, Select, SettingsToggle, SkeletonText } from "@calcom/ui";
import { ExternalLink, Globe } from "@calcom/ui/components/icon";
type AvailabilityOption = {
import { SelectSkeletonLoader } from "@components/availability/SkeletonLoader";
export type AvailabilityOption = {
label: string;
value: number;
isDefault: boolean;
@@ -62,40 +64,12 @@ const SingleValue = ({ ...props }: SingleValueProps<AvailabilityOption>) => {
);
};
const AvailabilitySelect = ({
className = "",
options,
value,
...props
}: {
className?: string;
name: string;
value: AvailabilityOption | undefined;
options: AvailabilityOption[];
isDisabled?: boolean;
onBlur: () => void;
onChange: (value: AvailabilityOption | null) => void;
}) => {
const { t } = useLocale();
return (
<Select
placeholder={t("select")}
options={options}
isDisabled={props.isDisabled}
isSearchable={false}
onChange={props.onChange}
className={classNames("block w-full min-w-0 flex-1 rounded-sm text-sm", className)}
defaultValue={value}
components={{ Option, SingleValue }}
isMulti={false}
/>
);
};
const format = (date: Date, hour12: boolean) =>
Intl.DateTimeFormat(undefined, { hour: "numeric", minute: "numeric", hour12 }).format(
new Date(dayjs.utc(date).format("YYYY-MM-DDTHH:mm:ss"))
);
Intl.DateTimeFormat(undefined, {
hour: "numeric",
minute: "numeric",
hourCycle: hour12 ? "h12" : "h24",
}).format(new Date(dayjs.utc(date).format("YYYY-MM-DDTHH:mm:ss")));
const EventTypeScheduleDetails = ({
isManagedEventType,
@@ -188,61 +162,57 @@ const EventTypeSchedule = ({ eventType }: { eventType: EventTypeSetup }) => {
);
const { watch } = useFormContext<FormValues>();
const watchSchedule = watch("schedule");
const formMethods = useFormContext<FormValues>();
const [options, setOptions] = useState<AvailabilityOption[]>([]);
const { data, isLoading } = trpc.viewer.availability.list.useQuery();
const { isLoading } = trpc.viewer.availability.list.useQuery(undefined, {
onSuccess: ({ schedules }) => {
const options = schedules.map((schedule) => ({
value: schedule.id,
label: schedule.name,
isDefault: schedule.isDefault,
isManaged: false,
}));
if (!data?.schedules.length && !isLoading)
return (
<EmptyScreen
Icon={Clock}
headline={t("new_schedule_heading")}
description={t("new_schedule_description")}
buttonRaw={<NewScheduleButton fromEventType />}
border={false}
/>
);
// We are showing a managed event for a team admin, so adding the option to let members choose their schedule
if (isManagedEventType) {
options.push({
value: 0,
label: t("members_default_schedule"),
isDefault: false,
isManaged: false,
});
}
const schedules = data?.schedules || [];
// We are showing a managed event for a member and team owner selected their own schedule, so adding
// the managed schedule option
if (
isChildrenManagedEventType &&
watchSchedule &&
!schedules.find((schedule) => schedule.id === watchSchedule)
) {
options.push({
value: watchSchedule,
label: eventType.scheduleName ?? t("default_schedule_name"),
isDefault: false,
isManaged: false,
});
}
const options = schedules.map((schedule) => ({
value: schedule.id,
label: schedule.name,
isDefault: schedule.isDefault,
isManaged: false,
}));
setOptions(options);
// We are showing a managed event for a team admin, so adding the option to let members choose their schedule
if (isManagedEventType) {
options.push({
value: 0,
label: t("members_default_schedule"),
isDefault: false,
isManaged: false,
});
}
const scheduleId = formMethods.getValues("schedule");
const value = options.find((option) =>
scheduleId
? option.value === scheduleId
: option.value === schedules.find((schedule) => schedule.isDefault)?.id
);
// We are showing a managed event for a member and team owner selected their own schedule, so adding
// the managed schedule option
if (
isChildrenManagedEventType &&
watchSchedule &&
!schedules.find((schedule) => schedule.id === watchSchedule)
) {
options.push({
value: watchSchedule,
label: eventType.scheduleName ?? t("default_schedule_name"),
isDefault: false,
isManaged: false,
});
}
formMethods.setValue("availability", value);
},
});
const value = options.find((option) =>
watchSchedule
? option.value === watchSchedule
: isManagedEventType
? option.value === 0
: option.value === schedules.find((schedule) => schedule.isDefault)?.id
);
const availabilityValue = formMethods.watch("availability");
return (
<div className="space-y-4">
@@ -251,27 +221,33 @@ const EventTypeSchedule = ({ eventType }: { eventType: EventTypeSetup }) => {
{t("availability")}
{shouldLockIndicator("availability")}
</label>
<Controller
name="schedule"
render={({ field }) => (
<>
<AvailabilitySelect
value={value}
options={options}
onBlur={field.onBlur}
isDisabled={shouldLockDisableProps("schedule").disabled}
name={field.name}
onChange={(selected) => {
field.onChange(selected?.value || null);
}}
/>
</>
)}
/>
{isLoading && <SelectSkeletonLoader />}
{!isLoading && (
<Controller
name="schedule"
render={({ field }) => {
return (
<Select
placeholder={t("select")}
options={options}
isSearchable={false}
onChange={(selected) => {
field.onChange(selected?.value || null);
if (selected?.value) formMethods.setValue("availability", selected);
}}
className="block w-full min-w-0 flex-1 rounded-sm text-sm"
value={availabilityValue}
components={{ Option, SingleValue }}
isMulti={false}
/>
);
}}
/>
)}
</div>
{value?.value !== 0 ? (
{availabilityValue?.value !== 0 ? (
<EventTypeScheduleDetails
selectedScheduleValue={value}
selectedScheduleValue={availabilityValue}
isManagedEventType={isManagedEventType || isChildrenManagedEventType}
/>
) : (
@@ -51,6 +51,7 @@ import {
} from "@calcom/ui/components/icon";
import { EmbedButton, EmbedDialog } from "@components/Embed";
import type { AvailabilityOption } from "@components/eventtype/EventAvailabilityTab";
type Props = {
children: React.ReactNode;
@@ -63,6 +64,7 @@ type Props = {
enabledWorkflowsNumber: number;
formMethods: UseFormReturn<FormValues>;
isUpdateMutationLoading?: boolean;
availability?: AvailabilityOption;
};
function getNavigation(props: {
@@ -71,8 +73,10 @@ function getNavigation(props: {
enabledAppsNumber: number;
enabledWorkflowsNumber: number;
installedAppsNumber: number;
availability: AvailabilityOption | undefined;
}) {
const { eventType, t, enabledAppsNumber, installedAppsNumber, enabledWorkflowsNumber } = props;
const { eventType, t, enabledAppsNumber, installedAppsNumber, enabledWorkflowsNumber, availability } =
props;
const duration =
eventType.metadata?.multipleDuration?.map((duration) => ` ${duration}`) || eventType.length;
@@ -128,6 +132,7 @@ function EventTypeSingleLayout({
enabledWorkflowsNumber,
isUpdateMutationLoading,
formMethods,
availability,
}: Props) {
const utils = trpc.useContext();
const { t } = useLocale();
@@ -171,6 +176,7 @@ function EventTypeSingleLayout({
enabledAppsNumber,
installedAppsNumber,
enabledWorkflowsNumber,
availability,
});
navigation.splice(1, 0, {
name: "availability",
@@ -214,7 +220,7 @@ function EventTypeSingleLayout({
});
}
return navigation;
}, [t, eventType, installedAppsNumber, enabledAppsNumber, enabledWorkflowsNumber, team]);
}, [t, eventType, installedAppsNumber, enabledAppsNumber, enabledWorkflowsNumber, team, availability]);
const permalink = `${CAL_URL}/${team ? `team/${team.slug}` : eventType.users[0].username}/${
eventType.slug
@@ -374,6 +380,8 @@ function EventTypeSingleLayout({
tabs={EventTypeTabs}
sticky
linkProps={{ shallow: true }}
itemClassname="items-start"
iconClassName="md:mt-px"
/>
</div>
<div className="p-2 md:mx-0 md:p-0 xl:hidden">
@@ -75,8 +75,8 @@ export function CalendarSwitch(props: {
/>
{props.defaultSelected && (
<Badge variant="gray">
<div className="flex">
<ArrowLeft className="text-default mr-1" /> {t("adding_events_to")}
<div className="flex items-center">
<ArrowLeft className="text-default mr-1 h-4 w-4" /> {t("adding_events_to")}
</div>
</Badge>
)}
@@ -79,7 +79,7 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
const ActionButtons = () => {
return usernameIsAvailable && currentUsername !== inputUsernameValue ? (
<div className="rlt:space-x-reverse ms-2 me-2 mt-px flex flex-row space-x-2 rtl:space-x-reverse">
<div className="ms-2 me-2 mt-px flex flex-row space-x-2">
<Button
type="button"
onClick={() => setOpenDialogSaveUsername(true)}
@@ -123,7 +123,7 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
autoCapitalize="none"
autoCorrect="none"
className={classNames(
"mb-0 mt-0 rounded-md ltr:rounded-l-none rtl:rounded-r-none",
"mb-0 mt-0 rounded-md rounded-l-none",
markAsError
? "focus:shadow-0 focus:ring-shadow-0 border-red-500 focus:border-red-500 focus:outline-none focus:ring-0"
: ""
+41 -17
View File
@@ -27,8 +27,10 @@ const I18nextAdapter = appWithTranslation<NextJsAppProps<SSRConfig> & { children
export type AppProps = Omit<NextAppProps<WithNonceProps & Record<string, unknown>>, "Component"> & {
Component: NextAppProps["Component"] & {
requiresLicense?: boolean;
isThemeSupported?: boolean | ((arg: { router: NextRouter }) => boolean);
isThemeSupported?: boolean;
isBookingPage?: boolean | ((arg: { router: NextRouter }) => boolean);
getLayout?: (page: React.ReactElement, router: NextRouter) => ReactNode;
PageWrapper?: (props: AppProps) => JSX.Element;
};
/** Will be defined only is there was an error */
@@ -61,45 +63,66 @@ const CustomI18nextProvider = (props: AppPropsWithChildren) => {
return <I18nextAdapter {...passedProps} />;
};
const enum ThemeSupport {
// e.g. Login Page
None = "none",
// Entire App except Booking Pages
App = "systemOnly",
// Booking Pages(including Routing Forms)
Booking = "userConfigured",
}
const CalcomThemeProvider = (
props: PropsWithChildren<
WithNonceProps & { isThemeSupported?: boolean | ((arg: { router: NextRouter }) => boolean) }
WithNonceProps & {
isBookingPage?: boolean | ((arg: { router: NextRouter }) => boolean);
isThemeSupported?: boolean;
}
>
) => {
// We now support the inverse of how we handled it in the past. Setting this to false will disable theme.
// undefined or true means we use system theme
const router = useRouter();
const isThemeSupported = (() => {
if (typeof props.isThemeSupported === "function") {
return props.isThemeSupported({ router: router });
const isBookingPage = (() => {
if (typeof props.isBookingPage === "function") {
return props.isBookingPage({ router: router });
}
if (typeof props.isThemeSupported === "undefined") {
return true;
}
return props.isThemeSupported;
return props.isBookingPage;
})();
const forcedTheme = !isThemeSupported ? "light" : undefined;
const themeSupport = isBookingPage
? ThemeSupport.Booking
: // if isThemeSupported is explicitly false, we don't use theme there
props.isThemeSupported === false
? ThemeSupport.None
: ThemeSupport.App;
const forcedTheme = themeSupport === ThemeSupport.None ? "light" : undefined;
// Use namespace of embed to ensure same namespaced embed are displayed with same theme. This allows different embeds on the same website to be themed differently
// One such example is our Embeds Demo and Testing page at http://localhost:3100
// Having `getEmbedNamespace` defined on window before react initializes the app, ensures that embedNamespace is available on the first mount and can be used as part of storageKey
const embedNamespace = typeof window !== "undefined" ? window.getEmbedNamespace() : null;
const isEmbedMode = typeof embedNamespace === "string";
// If embedNamespace is not defined, we use the default storageKey -> The default storage key changs based on if we force light mode or not
// This is done to ensure that the default theme is light when we force light mode and as soon as you navigate to a page that is dark we dont need a hard refresh to change
const storageKey = isEmbedMode
? `embed-theme-${embedNamespace}`
: !isThemeSupported
? "cal-light"
: "theme";
: themeSupport === ThemeSupport.App
? "app-theme"
: themeSupport === ThemeSupport.Booking
? "booking-theme"
: undefined;
return (
<ThemeProvider
nonce={props.nonce}
enableColorScheme={false}
enableSystem={isThemeSupported}
enableSystem={themeSupport !== ThemeSupport.None}
forcedTheme={forcedTheme}
storageKey={storageKey}
// next-themes doesn't listen to changes on storageKey. So we need to force a re-render when storageKey changes
// This is how login to dashboard soft navigation changes theme from light to dark
key={storageKey}
attribute="class">
{/* Embed Mode can be detected reliably only on client side here as there can be static generated pages as well which can't determine if it's embed mode at backend */}
{/* color-scheme makes background:transparent not work in iframe which is required by embed. */}
@@ -134,7 +157,8 @@ const AppProviders = (props: AppPropsWithChildren) => {
<TooltipProvider>
<CalcomThemeProvider
nonce={props.pageProps.nonce}
isThemeSupported={props.Component.isThemeSupported}>
isThemeSupported={props.Component.isThemeSupported}
isBookingPage={props.Component.isBookingPage}>
<FeatureFlagsProvider>
<MetaProvider>{props.children}</MetaProvider>
</FeatureFlagsProvider>
+1 -4
View File
@@ -13,9 +13,6 @@ function getCspPolicy(nonce: string) {
// We can remove 'unsafe-inline' from style-src when we add nonces to all style tags
// Maybe see how @next-safe/middleware does it if it's supported.
const useNonStrictPolicy = CSP_POLICY === "non-strict";
const SENTRY_ENDPOINT = process.env.NEXT_PUBLIC_SENTRY_DSN
? new URL(process.env.NEXT_PUBLIC_SENTRY_DSN, "http://base_url").origin
: "";
// We add WEBAPP_URL to img-src because of booking pages, which end up loading images from app.cal.com on cal.com
// FIXME: Write a layer to extract out EventType Analytics tracking endpoints and add them to img-src or connect-src as needed. e.g. fathom, Google Analytics and others
@@ -36,7 +33,7 @@ function getCspPolicy(nonce: string) {
} app.cal.com;
font-src 'self';
img-src 'self' ${WEBAPP_URL} https://www.gravatar.com https://img.youtube.com https://eu.ui-avatars.com/api/ data:;
connect-src 'self' ${SENTRY_ENDPOINT}
connect-src 'self'
`;
}
+1 -19
View File
@@ -1,6 +1,5 @@
require("dotenv").config({ path: "../../.env" });
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { withSentryConfig } = require("@sentry/nextjs");
const os = require("os");
const { withAxiom } = require("next-axiom");
@@ -318,21 +317,4 @@ const nextConfig = {
},
};
const sentryWebpackPluginOptions = {
silent: true, // Suppresses all logs
};
const moduleExports = () => plugins.reduce((acc, next) => next(acc), nextConfig);
if (process.env.NEXT_PUBLIC_SENTRY_DSN) {
nextConfig.sentry = {
hideSourceMaps: true,
// Prevents Sentry from running on this Edge function, where Sentry doesn't work yet (build whould crash the api route).
excludeServerRoutes: [/\/api\/social\/og\/image\/?/],
};
}
// Sentry should be the last thing to export to catch everything right
module.exports = process.env.NEXT_PUBLIC_SENTRY_DSN
? withSentryConfig(moduleExports, sentryWebpackPluginOptions)
: moduleExports;
module.exports = () => plugins.reduce((acc, next) => next(acc), nextConfig);
+1 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@calcom/web",
"version": "2.7.18",
"version": "2.8.4",
"private": true,
"scripts": {
"analyze": "ANALYZE=true next build",
@@ -57,7 +57,6 @@
"@radix-ui/react-switch": "^1.0.0",
"@radix-ui/react-toggle-group": "^1.0.0",
"@radix-ui/react-tooltip": "^1.0.0",
"@sentry/nextjs": "^7.20.0",
"@stripe/react-stripe-js": "^1.10.0",
"@stripe/stripe-js": "^1.35.0",
"@tanstack/react-query": "^4.3.9",
+4
View File
@@ -8,6 +8,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { HeadSeo } from "@calcom/ui";
import { BookOpen, Check, ChevronRight, FileText } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
import { ssgInit } from "@server/lib/ssg";
export default function Custom404() {
@@ -366,6 +368,8 @@ export default function Custom404() {
);
}
Custom404.PageWrapper = PageWrapper;
export const getStaticProps = async (context: GetStaticPropsContext) => {
const ssr = await ssgInit(context);
+4
View File
@@ -6,6 +6,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, showToast } from "@calcom/ui";
import { Copy } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
export default function Error500() {
const { t } = useLocale();
const router = useRouter();
@@ -52,3 +54,5 @@ export default function Error500() {
</div>
);
}
Error500.PageWrapper = PageWrapper;
+9 -5
View File
@@ -3,7 +3,6 @@ import classNames from "classnames";
import type { GetServerSidePropsContext } from "next";
import Link from "next/link";
import { useRouter } from "next/router";
import { useEffect } from "react";
import { Toaster } from "react-hot-toast";
import {
@@ -24,7 +23,6 @@ import defaultEvents, {
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import prisma from "@calcom/prisma";
import { baseEventTypeSelect } from "@calcom/prisma/selects";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
@@ -34,6 +32,8 @@ import { ArrowRight } from "@calcom/ui/components/icon";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import type { EmbedProps } from "@lib/withEmbedSsr";
import PageWrapper from "@components/PageWrapper";
import { ssrInit } from "@server/lib/ssr";
export default function User(props: inferSSRProps<typeof getServerSideProps> & EmbedProps) {
@@ -93,14 +93,15 @@ export default function User(props: inferSSRProps<typeof getServerSideProps> & E
const query = { ...router.query };
delete query.user; // So it doesn't display in the Link (and make tests fail)
const nameOrUsername = user.name || user.username || "";
const telemetry = useTelemetry();
useEffect(() => {
/*
const telemetry = useTelemetry();
useEffect(() => {
if (top !== window) {
//page_view will be collected automatically by _middleware.ts
telemetry.event(telemetryEventTypes.embedView, collectPageParameters("/[user]"));
}
}, [telemetry, router.asPath]);
}, [telemetry, router.asPath]); */
const isEventListEmpty = eventTypes.length === 0;
return (
<>
@@ -196,6 +197,9 @@ export default function User(props: inferSSRProps<typeof getServerSideProps> & E
);
}
User.isBookingPage = true;
User.PageWrapper = PageWrapper;
const getEventTypesWithHiddenFromDB = async (userId: number) => {
return (
await prisma.eventType.findMany({
+4
View File
@@ -12,6 +12,7 @@ import { isBrandingHidden } from "@lib/isBrandingHidden";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import type { EmbedProps } from "@lib/withEmbedSsr";
import PageWrapper from "@components/PageWrapper";
import AvailabilityPage from "@components/booking/pages/AvailabilityPage";
export type AvailabilityPageProps = inferSSRProps<typeof getStaticProps> & EmbedProps;
@@ -54,6 +55,9 @@ export default function Type(props: AvailabilityPageProps) {
);
}
Type.isBookingPage = true;
Type.PageWrapper = PageWrapper;
const paramsSchema = z.object({ type: z.string(), user: z.string() });
async function getUserPageProps(context: GetStaticPropsContext) {
// load server side dependencies
+4
View File
@@ -26,6 +26,7 @@ import {
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
import BookingPage from "@components/booking/pages/BookingPage";
import { ssrInit } from "@server/lib/ssr";
@@ -69,6 +70,9 @@ export default function Book(props: BookPageProps) {
);
}
Book.isBookingPage = true;
Book.PageWrapper = PageWrapper;
const querySchema = z.object({
bookingUid: z.string().optional(),
count: z.coerce.number().optional(),
+3 -91
View File
@@ -1,101 +1,13 @@
import { DefaultSeo } from "next-seo";
import { Inter } from "next/font/google";
import localFont from "next/font/local";
import Head from "next/head";
import Script from "next/script";
import "@calcom/embed-core/src/embed-iframe";
import { useEmbedUiConfig } from "@calcom/embed-core/src/embed-iframe";
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
import { trpc } from "@calcom/trpc/react";
import type { AppProps } from "@lib/app-providers";
import AppProviders from "@lib/app-providers";
import { seoConfig } from "@lib/config/next-seo.config";
import I18nLanguageHandler from "@components/I18nLanguageHandler";
import "../styles/globals.css";
const interFont = Inter({ subsets: ["latin"], variable: "--font-inter", preload: true, display: "swap" });
const calFont = localFont({
src: "../fonts/CalSans-SemiBold.woff2",
variable: "--font-cal",
preload: true,
display: "swap",
});
function MyApp(props: AppProps) {
const { Component, pageProps, err, router } = props;
let pageStatus = "200";
const { cssVarsPerTheme } = useEmbedUiConfig();
const cssVarsStyle = [];
if (cssVarsPerTheme) {
for (const [themeName, cssVars] of Object.entries(cssVarsPerTheme)) {
cssVarsStyle.push(`.${themeName} {`);
for (const [cssVarName, value] of Object.entries(cssVars)) {
cssVarsStyle.push(`--${cssVarName}: ${value};`);
}
cssVarsStyle.push(`}`);
}
}
if (router.pathname === "/404") {
pageStatus = "404";
} else if (router.pathname === "/500") {
pageStatus = "500";
}
// On client side don't let nonce creep into DOM
// It also avoids hydration warning that says that Client has the nonce value but server has "" because browser removes nonce attributes before DOM is built
// See https://github.com/kentcdodds/nonce-hydration-issues
// Set "" only if server had it set otherwise keep it undefined because server has to match with client to avoid hydration error
const nonce = typeof window !== "undefined" ? (pageProps.nonce ? "" : undefined) : pageProps.nonce;
const providerProps = {
...props,
pageProps: {
...props.pageProps,
nonce,
},
};
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
return (
<AppProviders {...providerProps}>
<DefaultSeo {...seoConfig.defaultNextSeo} />
<I18nLanguageHandler />
<Script
nonce={nonce}
id="page-status"
dangerouslySetInnerHTML={{ __html: `window.CalComPageStatus = '${pageStatus}'` }}
/>
<style jsx global>{`
:root {
--font-inter: ${interFont.style.fontFamily};
--font-cal: ${calFont.style.fontFamily};
}
`}</style>
<style jsx global>
{`
${cssVarsStyle.join("")}
`}
</style>
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
</Head>
{getLayout(
Component.requiresLicense ? (
<LicenseRequired>
<Component {...pageProps} err={err} />
</LicenseRequired>
) : (
<Component {...pageProps} err={err} />
),
router
)}
</AppProviders>
);
const { Component, pageProps } = props;
if (Component.PageWrapper !== undefined) return Component.PageWrapper(props);
return <Component {...pageProps} />;
}
export default trpc.withTRPC(MyApp);
+11 -5
View File
@@ -1,6 +1,6 @@
import type { NextPageContext } from "next";
import type { DocumentContext, DocumentProps } from "next/document";
import Document, { Head, Html, Main, NextScript } from "next/document";
import Script from "next/script";
import { z } from "zod";
import { getDirFromLang } from "@calcom/lib/i18n";
@@ -8,15 +8,22 @@ import { getDirFromLang } from "@calcom/lib/i18n";
import { csp } from "@lib/csp";
type Props = Record<string, unknown> & DocumentProps;
function setHeader(ctx: NextPageContext, name: string, value: string) {
try {
ctx.res?.setHeader(name, value);
} catch (e) {
// Getting "Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client" when revalidate calendar chache
console.log(`Error setting header ${name}=${value} for ${ctx.asPath || "unknown asPath"}`, e);
}
}
class MyDocument extends Document<Props> {
static async getInitialProps(ctx: DocumentContext) {
const { nonce } = csp(ctx.req || null, ctx.res || null);
if (!process.env.CSP_POLICY) {
ctx.res?.setHeader("x-csp", "not-opted-in");
setHeader(ctx, "x-csp", "not-opted-in");
} else if (!ctx.res?.getHeader("x-csp")) {
// If x-csp not set by gSSP, then it's initialPropsOnly
ctx.res?.setHeader("x-csp", "initialPropsOnly");
setHeader(ctx, "x-csp", "initialPropsOnly");
}
const asPath = ctx.asPath || "";
// Use a dummy URL as default so that URL parsing works for relative URLs as well. We care about searchParams and pathname only
@@ -42,7 +49,6 @@ class MyDocument extends Document<Props> {
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#000000" />
<meta name="msapplication-TileColor" content="#ff0000" />
<meta name="theme-color" content="var(--cal-bg)" />
<Script src="/embed-init-iframe.js" strategy="beforeInteractive" />
</Head>
<body
-2
View File
@@ -2,7 +2,6 @@
* Typescript class based component for custom-error
* @link https://nextjs.org/docs/advanced-features/custom-error-page
*/
import * as Sentry from "@sentry/nextjs";
import type { NextPage, NextPageContext } from "next";
import type { ErrorProps } from "next/error";
import NextError from "next/error";
@@ -50,7 +49,6 @@ const CustomError: NextPage<CustomErrorProps> = (props) => {
*/
CustomError.getInitialProps = async (ctx: AugmentedNextPageContext) => {
const { res, err, asPath } = ctx;
await Sentry.captureUnderscoreErrorException(ctx);
const errorInitialProps = (await NextError.getInitialProps({
res,
err,
+11 -6
View File
@@ -9,13 +9,16 @@ import type { AppGetServerSideProps } from "@calcom/types/AppGetServerSideProps"
import type { AppProps } from "@lib/app-providers";
import PageWrapper from "@components/PageWrapper";
import { ssrInit } from "@server/lib/ssr";
type AppPageType = {
getServerSideProps: AppGetServerSideProps;
// A component than can accept any properties
// eslint-disable-next-line @typescript-eslint/no-explicit-any
default: ((props: any) => JSX.Element) & Pick<AppProps["Component"], "isThemeSupported" | "getLayout">;
default: ((props: any) => JSX.Element) &
Pick<AppProps["Component"], "isBookingPage" | "getLayout" | "PageWrapper">;
};
type Found = {
@@ -70,17 +73,17 @@ const AppPage: AppPageType["default"] = function AppPage(props) {
return <route.Component {...componentProps} />;
};
AppPage.isThemeSupported = ({ router }) => {
AppPage.isBookingPage = ({ router }) => {
const route = getRoute(router.query.slug as string, router.query.pages as string[]);
if (route.notFound) {
return false;
}
const isThemeSupported = route.Component.isThemeSupported;
if (typeof isThemeSupported === "function") {
return isThemeSupported({ router });
const isBookingPage = route.Component.isBookingPage;
if (typeof isBookingPage === "function") {
return isBookingPage({ router });
}
return !!isThemeSupported;
return !!isBookingPage;
};
AppPage.getLayout = (page, router) => {
@@ -94,6 +97,8 @@ AppPage.getLayout = (page, router) => {
return route.Component.getLayout(page, router);
};
AppPage.PageWrapper = PageWrapper;
export default AppPage;
export async function getServerSideProps(
+3
View File
@@ -10,6 +10,7 @@ import prisma from "@calcom/prisma";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
import App from "@components/apps/App";
const md = new MarkdownIt("default", { html: true, breaks: true });
@@ -122,4 +123,6 @@ export const getStaticProps = async (ctx: GetStaticPropsContext) => {
};
};
SingleAppPage.PageWrapper = PageWrapper;
export default SingleAppPage;
+4
View File
@@ -5,6 +5,8 @@ import { useRouter } from "next/router";
import { AppSetupPage } from "@calcom/app-store/_pages/setup";
import { getStaticProps } from "@calcom/app-store/_pages/setup/_getStaticProps";
import PageWrapper from "@components/PageWrapper";
export default function SetupInformation(props: InferGetStaticPropsType<typeof getStaticProps>) {
const router = useRouter();
const slug = router.query.slug as string;
@@ -26,6 +28,8 @@ export default function SetupInformation(props: InferGetStaticPropsType<typeof g
return <AppSetupPage slug={slug} {...props} />;
}
SetupInformation.PageWrapper = PageWrapper;
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
@@ -9,6 +9,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import prisma from "@calcom/prisma";
import { AppCard, SkeletonText } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
export default function Apps({ apps }: InferGetStaticPropsType<typeof getStaticProps>) {
const { t, isLocaleReady } = useLocale();
const router = useRouter();
@@ -47,6 +49,8 @@ export default function Apps({ apps }: InferGetStaticPropsType<typeof getStaticP
);
}
Apps.PageWrapper = PageWrapper;
export const getStaticPaths = async () => {
const paths = Object.keys(AppCategories);
+4
View File
@@ -7,6 +7,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { SkeletonText } from "@calcom/ui";
import { ArrowLeft, ArrowRight } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
export default function Apps({ categories }: InferGetStaticPropsType<typeof getStaticProps>) {
const { t, isLocaleReady } = useLocale();
@@ -43,6 +45,8 @@ export default function Apps({ categories }: InferGetStaticPropsType<typeof getS
);
}
Apps.PageWrapper = PageWrapper;
export const getStaticProps = async () => {
const appStore = await getAppRegistry();
const categories = appStore.reduce((c, app) => {
+3
View File
@@ -12,6 +12,7 @@ import type { HorizontalTabItemProps } from "@calcom/ui";
import { AllApps, AppStoreCategories, HorizontalTabs, TextField, PopularAppsSlider } from "@calcom/ui";
import { Search } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
import AppsLayout from "@components/apps/layouts/AppsLayout";
import { ssrInit } from "@server/lib/ssr";
@@ -85,6 +86,8 @@ export default function Apps({ categories, appStore }: inferSSRProps<typeof getS
);
}
Apps.PageWrapper = PageWrapper;
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const { req, res } = context;
@@ -44,6 +44,7 @@ import {
import { QueryCell } from "@lib/QueryCell";
import AppListCard from "@components/AppListCard";
import PageWrapper from "@components/PageWrapper";
import { CalendarListContainer } from "@components/apps/CalendarListContainer";
import InstalledAppsLayout from "@components/apps/layouts/InstalledAppsLayout";
@@ -372,3 +373,5 @@ export async function getServerSideProps(ctx: AppGetServerSidePropsContext) {
},
};
}
InstalledApps.PageWrapper = PageWrapper;
+3
View File
@@ -7,6 +7,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, SkeletonText } from "@calcom/ui";
import { X } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
import AuthContainer from "@components/ui/AuthContainer";
import { ssgInit } from "@server/lib/ssg";
@@ -49,6 +50,8 @@ export default function Error() {
);
}
Error.PageWrapper = PageWrapper;
export const getStaticProps = async (context: GetStaticPropsContext) => {
const ssr = await ssgInit(context);
+2 -1
View File
@@ -12,6 +12,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import prisma from "@calcom/prisma";
import { Button, TextField } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import AuthContainer from "@components/ui/AuthContainer";
type Props = {
@@ -174,7 +175,7 @@ export default function Page({ resetPasswordRequest, csrfToken }: Props) {
}
Page.isThemeSupported = false;
Page.PageWrapper = PageWrapper;
export async function getServerSideProps(context: GetServerSidePropsContext) {
const id = context.params?.id as string;
@@ -11,6 +11,7 @@ import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, EmailField } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import AuthContainer from "@components/ui/AuthContainer";
export default function ForgotPassword({ csrfToken }: { csrfToken: string }) {
@@ -144,6 +145,7 @@ export default function ForgotPassword({ csrfToken }: { csrfToken: string }) {
}
ForgotPassword.isThemeSupported = false;
ForgotPassword.PageWrapper = PageWrapper;
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const { req, res } = context;
+2
View File
@@ -26,6 +26,7 @@ import type { WithNonceProps } from "@lib/withNonce";
import withNonce from "@lib/withNonce";
import AddToHomescreen from "@components/AddToHomescreen";
import PageWrapper from "@components/PageWrapper";
import TwoFactor from "@components/auth/TwoFactor";
import AuthContainer from "@components/ui/AuthContainer";
@@ -302,5 +303,6 @@ const _getServerSideProps = async function getServerSideProps(context: GetServer
};
Login.isThemeSupported = false;
Login.PageWrapper = PageWrapper;
export const getServerSideProps = withNonce(_getServerSideProps);
+2 -1
View File
@@ -10,6 +10,7 @@ import { Check } from "@calcom/ui/components/icon";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
import AuthContainer from "@components/ui/AuthContainer";
import { ssrInit } from "@server/lib/ssr";
@@ -51,7 +52,7 @@ export function Logout(props: Props) {
}
Logout.isThemeSupported = false;
Logout.PageWrapper = PageWrapper;
export default Logout;
export async function getServerSideProps(context: GetServerSidePropsContext) {
+3
View File
@@ -2,6 +2,8 @@ import { signIn } from "next-auth/react";
import { useRouter } from "next/router";
import { useEffect } from "react";
import PageWrapper from "@components/PageWrapper";
// To handle the IdP initiated login flow callback
export default function Page() {
const router = useRouter();
@@ -21,3 +23,4 @@ export default function Page() {
return null;
}
Page.PageWrapper = PageWrapper;
+2 -1
View File
@@ -11,6 +11,7 @@ import prisma from "@calcom/prisma";
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
import { Meta, WizardForm } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import { AdminUserContainer as AdminUser } from "@components/setup/AdminUser";
import ChooseLicense from "@components/setup/ChooseLicense";
import EnterpriseLicense from "@components/setup/EnterpriseLicense";
@@ -136,7 +137,7 @@ export function Setup(props: inferSSRProps<typeof getServerSideProps>) {
}
Setup.isThemeSupported = false;
Setup.PageWrapper = PageWrapper;
export default Setup;
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
+4
View File
@@ -4,6 +4,8 @@ import { getProviders, signIn, getCsrfToken } from "next-auth/react";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { Button } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
type Provider = {
name: string;
id: string;
@@ -23,6 +25,8 @@ function signin({ providers }: { providers: Provider[] }) {
);
}
signin.PageWrapper = PageWrapper;
export default signin;
export async function getServerSideProps(context: GetServerSidePropsContext) {
+4
View File
@@ -19,6 +19,8 @@ import prisma from "@calcom/prisma";
import { asStringOrNull } from "@lib/asStringOrNull";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
import { ssrInit } from "@server/lib/ssr";
export type SSOProviderPageProps = inferSSRProps<typeof getServerSideProps>;
@@ -49,6 +51,8 @@ export default function Provider(props: SSOProviderPageProps) {
return null;
}
Provider.PageWrapper = PageWrapper;
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
// get query params and typecast them to string
// (would be even better to assert them instead of typecasting)
+4
View File
@@ -6,6 +6,8 @@ import { HOSTED_CAL_FEATURES } from "@calcom/lib/constants";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
// This page is used to initiate the SAML authentication flow by redirecting to the SAML provider.
// Accessible only on self-hosted Cal.com instances.
export default function Page({ samlTenantID, samlProductID }: inferSSRProps<typeof getServerSideProps>) {
@@ -28,6 +30,8 @@ export default function Page({ samlTenantID, samlProductID }: inferSSRProps<type
return null;
}
Page.PageWrapper = PageWrapper;
export async function getServerSideProps() {
return {
props: {
+3
View File
@@ -11,6 +11,7 @@ import { trpc } from "@calcom/trpc/react";
import { Button, showToast } from "@calcom/ui";
import Loader from "@components/Loader";
import PageWrapper from "@components/PageWrapper";
async function sendVerificationLogin(email: string, username: string) {
await signIn("email", {
@@ -177,3 +178,5 @@ export default function Verify() {
</div>
);
}
Verify.PageWrapper = PageWrapper;
@@ -31,6 +31,7 @@ import { Info, Plus, Trash } from "@calcom/ui/components/icon";
import { HttpError } from "@lib/core/http/error";
import PageWrapper from "@components/PageWrapper";
import { SelectSkeletonLoader } from "@components/availability/SkeletonLoader";
import EditableHeading from "@components/ui/EditableHeading";
@@ -301,3 +302,5 @@ export default function Availability() {
</Shell>
);
}
Availability.PageWrapper = PageWrapper;
+3
View File
@@ -11,6 +11,7 @@ import { Clock } from "@calcom/ui/components/icon";
import { withQuery } from "@lib/QueryCell";
import { HttpError } from "@lib/core/http/error";
import PageWrapper from "@components/PageWrapper";
import SkeletonLoader from "@components/availability/SkeletonLoader";
export function AvailabilityList({ schedules }: RouterOutputs["viewer"]["availability"]["list"]) {
@@ -116,3 +117,5 @@ export default function AvailabilityPage() {
</div>
);
}
AvailabilityPage.PageWrapper = PageWrapper;
@@ -7,6 +7,8 @@ import { SkeletonText } from "@calcom/ui";
import useRouterQuery from "@lib/hooks/useRouterQuery";
import PageWrapper from "@components/PageWrapper";
type User = RouterOutputs["viewer"]["me"];
export interface IBusySlot {
@@ -126,6 +128,7 @@ export default function Troubleshoot() {
</div>
);
}
Troubleshoot.PageWrapper = PageWrapper;
function convertMinsToHrsMins(mins: number) {
const h = Math.floor(mins / 60);
+26 -10
View File
@@ -23,6 +23,7 @@ import {
useIsBackgroundTransparent,
useIsEmbed,
} from "@calcom/embed-core/embed-iframe";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import {
SystemField,
getBookingFieldsWithSystemFields,
@@ -41,7 +42,6 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import { getEveryFreqFor } from "@calcom/lib/recurringStrings";
import { maybeGetBookingUidFromSeat } from "@calcom/lib/server/maybeGetBookingUidFromSeat";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import { getIs24hClockFromLocalStorage, isBrowserLocale24h } from "@calcom/lib/timeFormat";
import { localStorage } from "@calcom/lib/webstorage";
import prisma from "@calcom/prisma";
@@ -54,6 +54,7 @@ import { X, ExternalLink, ChevronLeft, Check, Calendar } from "@calcom/ui/compon
import { timeZone } from "@lib/clock";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
import CancelBooking from "@components/booking/CancelBooking";
import EventReservationSchema from "@components/schemas/EventReservationSchema";
@@ -106,10 +107,10 @@ export default function Success(props: SuccessProps) {
seatReferenceUid,
} = querySchema.parse(router.query);
const tz =
(isSuccessBookingPage
? props.bookingInfo.attendees.find((attendee) => attendee.email === email)?.timeZone
: props.bookingInfo.eventType?.timeZone || props.bookingInfo.user?.timeZone) || timeZone();
const attendeeTimeZone = props?.bookingInfo?.attendees.find(
(attendee) => attendee.email === email
)?.timeZone;
const tz = isSuccessBookingPage && attendeeTimeZone ? attendeeTimeZone : props.tz ? props.tz : timeZone();
const location = props.bookingInfo.location as ReturnType<typeof getEventLocationValue>;
@@ -177,7 +178,7 @@ export default function Success(props: SuccessProps) {
// - Event Type has require confirmation option enabled always
// - EventType has conditionally enabled confirmation option based on how far the booking is scheduled.
// - It's a paid event and payment is pending.
const needsConfirmation = bookingInfo.status === BookingStatus.PENDING;
const needsConfirmation = bookingInfo.status === BookingStatus.PENDING && eventType.requiresConfirmation;
const userIsOwner = !!(session?.user?.id && eventType.owner?.id === session.user.id);
const isCancelled =
@@ -186,13 +187,13 @@ export default function Success(props: SuccessProps) {
(!!seatReferenceUid &&
!bookingInfo.seatsReferences.some((reference) => reference.referenceUid === seatReferenceUid));
const telemetry = useTelemetry();
useEffect(() => {
// const telemetry = useTelemetry();
/* useEffect(() => {
if (top !== window) {
//page_view will be collected automatically by _middleware.ts
telemetry.event(telemetryEventTypes.embedView, collectPageParameters("/booking"));
}
}, [telemetry]);
}, [telemetry]); */
useEffect(() => {
const users = eventType.users;
@@ -269,7 +270,9 @@ export default function Success(props: SuccessProps) {
return t("emailed_you_and_attendees" + titleSuffix);
}
useTheme(isSuccessBookingPage ? props.profile.theme : "light");
// This is a weird case where the same route can be opened in booking flow as a success page or as a booking detail page from the app
// As Booking Page it has to support configured theme, but as booking detail page it should not do any change. Let Shell.tsx handle it.
useTheme(isSuccessBookingPage ? props.profile.theme : undefined);
useBrandColors({
brandColor: props.profile.brandColor,
darkBrandColor: props.profile.darkBrandColor,
@@ -706,6 +709,9 @@ export default function Success(props: SuccessProps) {
);
}
Success.isBookingPage = true;
Success.PageWrapper = PageWrapper;
type RecurringBookingsProps = {
eventType: SuccessProps["eventType"];
recurringBookings: SuccessProps["recurringBookings"];
@@ -914,7 +920,16 @@ const handleSeatsEventTypeOnBooking = (
export async function getServerSideProps(context: GetServerSidePropsContext) {
const ssr = await ssrInit(context);
const session = await getServerSession(context);
let tz: string | null = null;
if (session) {
const user = await ssr.viewer.me.fetch();
tz = user.timeZone;
}
const parsedQuery = querySchema.safeParse(context.query);
if (!parsedQuery.success) return { notFound: true };
const { uid, email, eventTypeSlug, cancel, isSuccessBookingPage } = parsedQuery.data;
@@ -1046,6 +1061,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
dynamicEventName: bookingInfo?.eventType?.eventName || "",
bookingInfo,
paymentStatus: payment,
...(tz && { tz }),
},
};
}
+3
View File
@@ -16,6 +16,7 @@ import { Calendar } from "@calcom/ui/components/icon";
import { useInViewObserver } from "@lib/hooks/useInViewObserver";
import PageWrapper from "@components/PageWrapper";
import BookingListItem from "@components/booking/BookingListItem";
import SkeletonLoader from "@components/booking/SkeletonLoader";
@@ -194,6 +195,8 @@ export default function Bookings() {
);
}
Bookings.PageWrapper = PageWrapper;
export const getStaticProps: GetStaticProps = async (ctx) => {
const params = querySchema.safeParse(ctx.params);
const ssg = await ssgInit(ctx);
+4
View File
@@ -14,6 +14,7 @@ import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import type { EmbedProps } from "@lib/withEmbedSsr";
import PageWrapper from "@components/PageWrapper";
import AvailabilityPage from "@components/booking/pages/AvailabilityPage";
import { ssrInit } from "@server/lib/ssr";
@@ -24,6 +25,9 @@ export default function Type(props: DynamicAvailabilityPageProps) {
return <AvailabilityPage {...props} />;
}
Type.isBookingPage = true;
Type.PageWrapper = PageWrapper;
const querySchema = z.object({
link: z.string().optional().default(""),
slug: z.string().optional().default(""),
+4
View File
@@ -9,6 +9,7 @@ import { customInputSchema, eventTypeBookingFields, EventTypeMetaDataSchema } fr
import { asStringOrNull, asStringOrThrow } from "@lib/asStringOrNull";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
import BookingPage from "@components/booking/pages/BookingPage";
import { ssrInit } from "@server/lib/ssr";
@@ -19,6 +20,9 @@ export default function Book(props: HashLinkPageProps) {
return <BookingPage {...props} />;
}
Book.isBookingPage = true;
Book.PageWrapper = PageWrapper;
export async function getServerSideProps(context: GetServerSidePropsContext) {
const ssr = await ssrInit(context);
const link = asStringOrThrow(context.query.link as string);
+70 -11
View File
@@ -1,8 +1,7 @@
/* eslint-disable @typescript-eslint/no-empty-function */
import { useAutoAnimate } from "@formkit/auto-animate/react";
import { zodResolver } from "@hookform/resolvers/zod";
import type { PeriodType } from "@prisma/client";
import type { SchedulingType } from "@prisma/client";
import type { PeriodType, SchedulingType } from "@prisma/client";
import type { GetServerSidePropsContext } from "next";
import { Trans } from "next-i18next";
import { useEffect, useState } from "react";
@@ -18,10 +17,10 @@ import { CAL_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
import { HttpError } from "@calcom/lib/http-error";
import { useTelemetry, telemetryEventTypes } from "@calcom/lib/telemetry";
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import type { Prisma } from "@calcom/prisma/client";
import { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
import type { customInputSchema, EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import type { IntervalLimit, RecurringEvent } from "@calcom/types/Calendar";
@@ -30,9 +29,11 @@ import { ConfirmationDialogContent, Dialog, Form, showToast } from "@calcom/ui";
import { asStringOrThrow } from "@lib/asStringOrNull";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
// These can't really be moved into calcom/ui due to the fact they use infered getserverside props typings
import { EventAdvancedTab } from "@components/eventtype/EventAdvancedTab";
import { EventAppsTab } from "@components/eventtype/EventAppsTab";
import type { AvailabilityOption } from "@components/eventtype/EventAvailabilityTab";
import { EventAvailabilityTab } from "@components/eventtype/EventAvailabilityTab";
import { EventLimitsTab } from "@components/eventtype/EventLimitsTab";
import { EventRecurringTab } from "@components/eventtype/EventRecurringTab";
@@ -93,6 +94,7 @@ export type FormValues = {
children: ChildrenEventType[];
hosts: { userId: number; isFixed: boolean }[];
bookingFields: z.infer<typeof eventTypeBookingFields>;
availability?: AvailabilityOption;
};
export type CustomInputParsed = typeof customInputSchema._output;
@@ -261,6 +263,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
}, [defaultValues]);
const appsMetadata = formMethods.getValues("metadata")?.apps;
const availability = formMethods.watch("availability");
const numberOfInstalledApps = eventTypeApps?.filter((app) => app.isInstalled).length || 0;
let numberOfActiveApps = 0;
@@ -377,6 +380,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
enabledWorkflowsNumber={eventType.workflows.length}
eventType={eventType}
team={team}
availability={availability}
isUpdateMutationLoading={updateMutation.isLoading}
formMethods={formMethods}
disableBorder={tabName === "apps" || tabName === "workflows" || tabName === "webhooks"}
@@ -384,13 +388,66 @@ const EventTypePage = (props: EventTypeSetupProps) => {
<Form
form={formMethods}
id="event-type-form"
handleSubmit={async (values: FormValues) => {
if (!values.children.length) return handleSubmit(values);
const existingSlugEventTypes = values.children.filter((ch) =>
ch.owner.eventTypeSlugs.includes(slug)
);
if (!existingSlugEventTypes.length) return handleSubmit(values);
setSlugExistsChildrenDialogOpen(existingSlugEventTypes);
handleSubmit={async (values) => {
const {
periodDates,
periodCountCalendarDays,
beforeBufferTime,
afterBufferTime,
seatsPerTimeSlot,
seatsShowAttendees,
bookingLimits,
durationLimits,
recurringEvent,
locations,
metadata,
customInputs,
// We don't need to send send these values to the backend
// eslint-disable-next-line @typescript-eslint/no-unused-vars
seatsPerTimeSlotEnabled,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
minimumBookingNoticeInDurationType,
availability,
...input
} = values;
if (bookingLimits) {
const isValid = validateIntervalLimitOrder(bookingLimits);
if (!isValid) throw new Error(t("event_setup_booking_limits_error"));
}
if (durationLimits) {
const isValid = validateIntervalLimitOrder(durationLimits);
if (!isValid) throw new Error(t("event_setup_duration_limits_error"));
}
if (metadata?.multipleDuration !== undefined) {
if (metadata?.multipleDuration.length < 1) {
throw new Error(t("event_setup_multiple_duration_error"));
} else {
if (!input.length && !metadata?.multipleDuration?.includes(input.length)) {
throw new Error(t("event_setup_multiple_duration_default_error"));
}
}
}
updateMutation.mutate({
...input,
locations,
recurringEvent,
periodStartDate: periodDates.startDate,
periodEndDate: periodDates.endDate,
periodCountCalendarDays: periodCountCalendarDays === "1",
id: eventType.id,
beforeEventBuffer: beforeBufferTime,
afterEventBuffer: afterBufferTime,
bookingLimits,
durationLimits,
seatsPerTimeSlot,
seatsShowAttendees,
metadata,
customInputs,
});
}}>
<div ref={animationParentRef}>{tabMap[tabName]}</div>
</Form>
@@ -477,4 +534,6 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
};
};
EventTypePageWrapper.PageWrapper = PageWrapper;
export default EventTypePageWrapper;
+3
View File
@@ -61,6 +61,7 @@ import { withQuery } from "@lib/QueryCell";
import { HttpError } from "@lib/core/http/error";
import { EmbedButton, EmbedDialog } from "@components/Embed";
import PageWrapper from "@components/PageWrapper";
import SkeletonLoader from "@components/eventtype/SkeletonLoader";
type EventTypeGroups = RouterOutputs["viewer"]["eventTypes"]["getByViewer"]["eventTypeGroups"];
@@ -817,4 +818,6 @@ const EventTypesPage = () => {
);
};
EventTypesPage.PageWrapper = PageWrapper;
export default EventTypesPage;
@@ -13,6 +13,7 @@ import { Button, StepCard, Steps } from "@calcom/ui";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
import { ConnectedCalendars } from "@components/getting-started/steps-views/ConnectCalendars";
import { SetupAvailability } from "@components/getting-started/steps-views/SetupAvailability";
import UserProfile from "@components/getting-started/steps-views/UserProfile";
@@ -203,5 +204,6 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
};
OnboardingPage.isThemeSupported = false;
OnboardingPage.PageWrapper = PageWrapper;
export default OnboardingPage;
+4
View File
@@ -17,6 +17,8 @@ import { trpc } from "@calcom/trpc";
import { Button, ButtonGroup } from "@calcom/ui";
import { RefreshCcw, UserPlus, Users } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
const Heading = () => {
const { t } = useLocale();
@@ -111,6 +113,8 @@ export default function InsightsPage() {
);
}
InsightsPage.PageWrapper = PageWrapper;
// If feature flag is disabled, return not found on getServerSideProps
export const getServerSideProps = async () => {
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
+4
View File
@@ -4,6 +4,8 @@ import { APP_NAME, WEBSITE_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
export default function MaintenancePage() {
const { t, isLocaleReady } = useLocale();
if (!isLocaleReady) return null;
@@ -25,3 +27,5 @@ export default function MaintenancePage() {
</div>
);
}
MaintenancePage.PageWrapper = PageWrapper;
+3
View File
@@ -1,6 +1,8 @@
import Shell, { MobileNavigationMoreItems } from "@calcom/features/shell/Shell";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import PageWrapper from "@components/PageWrapper";
export default function MorePage() {
const { t } = useLocale();
return (
@@ -12,3 +14,4 @@ export default function MorePage() {
</Shell>
);
}
MorePage.PageWrapper = PageWrapper;
+3 -1
View File
@@ -2,8 +2,10 @@ import PaymentPage from "@calcom/features/ee/payments/components/PaymentPage";
import { getServerSideProps } from "@calcom/features/ee/payments/pages/payment";
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
export default function Payment(props: inferSSRProps<typeof getServerSideProps>) {
return <PaymentPage {...props} />;
}
Payment.PageWrapper = PageWrapper;
export { getServerSideProps };
@@ -2,6 +2,7 @@ import AdminAppsList from "@calcom/features/apps/AdminAppsList";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Meta } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import { getLayout } from "@components/auth/layouts/AdminLayout";
function AdminAppsView() {
@@ -15,5 +16,6 @@ function AdminAppsView() {
}
AdminAppsView.getLayout = getLayout;
AdminAppsView.PageWrapper = PageWrapper;
export default AdminAppsView;
+2
View File
@@ -1,9 +1,11 @@
import { FlagListingView } from "@calcom/features/flags/pages/flag-listing-view";
import PageWrapper from "@components/PageWrapper";
import { getLayout } from "@components/auth/layouts/AdminLayout";
const FlagsPage = () => <FlagListingView />;
FlagsPage.getLayout = getLayout;
FlagsPage.PageWrapper = PageWrapper;
export default FlagsPage;
@@ -4,6 +4,7 @@ import { useRef } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, Meta, TextField } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import { getLayout } from "@components/auth/layouts/AdminLayout";
function AdminView() {
@@ -37,5 +38,6 @@ function AdminView() {
}
AdminView.getLayout = getLayout;
AdminView.PageWrapper = PageWrapper;
export default AdminView;
+2
View File
@@ -1,5 +1,6 @@
import { Meta } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import { getLayout } from "@components/auth/layouts/AdminLayout";
function AdminAppsView() {
@@ -12,5 +13,6 @@ function AdminAppsView() {
}
AdminAppsView.getLayout = getLayout;
AdminAppsView.PageWrapper = PageWrapper;
export default AdminAppsView;
@@ -0,0 +1,9 @@
import UsersEditView from "@calcom/features/ee/users/pages/users-edit-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = UsersEditView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -0,0 +1,9 @@
import UsersAddView from "@calcom/features/ee/users/pages/users-add-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = UsersAddView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -0,0 +1,9 @@
import UsersListingView from "@calcom/features/ee/users/pages/users-listing-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = UsersListingView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -8,6 +8,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, Meta } from "@calcom/ui";
import { ExternalLink } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
interface CtaRowProps {
title: string;
description: string;
@@ -64,5 +66,6 @@ const BillingView = () => {
};
BillingView.getLayout = getLayout;
BillingView.PageWrapper = PageWrapper;
export default BillingView;
@@ -18,6 +18,8 @@ import {
} from "@calcom/ui";
import { Link as LinkIcon, Plus } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
const ApiKeysView = () => {
const { t } = useLocale();
@@ -92,5 +94,6 @@ const ApiKeysView = () => {
};
ApiKeysView.getLayout = getLayout;
ApiKeysView.PageWrapper = PageWrapper;
export default ApiKeysView;
@@ -1 +1,9 @@
export { default } from "@calcom/features/webhooks/pages/webhook-edit-view";
import WebhookEditView from "@calcom/features/webhooks/pages/webhook-edit-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = WebhookEditView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -1 +1,9 @@
export { default } from "@calcom/features/webhooks/pages/webhooks-view";
import WeebhooksView from "@calcom/features/webhooks/pages/webhooks-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = WeebhooksView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -1 +1,9 @@
export { default } from "@calcom/features/webhooks/pages/webhook-new-view";
import WeebhookNewView from "@calcom/features/webhooks/pages/webhook-new-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = WeebhookNewView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -22,6 +22,8 @@ import {
UpgradeTeamsBadge,
} from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
const SkeletonLoader = ({ title, description }: { title: string; description: string }) => {
return (
<SkeletonContainer>
@@ -230,5 +232,6 @@ const AppearanceView = () => {
};
AppearanceView.getLayout = getLayout;
AppearanceView.PageWrapper = PageWrapper;
export default AppearanceView;
@@ -28,6 +28,7 @@ import { Plus, Calendar } from "@calcom/ui/components/icon";
import { QueryCell } from "@lib/QueryCell";
import PageWrapper from "@components/PageWrapper";
import { CalendarSwitch } from "@components/settings/CalendarSwitch";
const SkeletonLoader = () => {
@@ -228,5 +229,6 @@ const CalendarsView = () => {
};
CalendarsView.getLayout = getLayout;
CalendarsView.PageWrapper = PageWrapper;
export default CalendarsView;
@@ -27,6 +27,7 @@ import {
import { AlertCircle, MoreHorizontal, Trash, Video } from "@calcom/ui/components/icon";
import AppListCard from "@components/AppListCard";
import PageWrapper from "@components/PageWrapper";
const SkeletonLoader = ({ title, description }: { title: string; description: string }) => {
return (
@@ -188,5 +189,6 @@ const ConferencingLayout = () => {
};
ConferencingLayout.getLayout = getLayout;
ConferencingLayout.PageWrapper = PageWrapper;
export default ConferencingLayout;
@@ -22,6 +22,8 @@ import {
import { withQuery } from "@lib/QueryCell";
import PageWrapper from "@components/PageWrapper";
const SkeletonLoader = ({ title, description }: { title: string; description: string }) => {
return (
<SkeletonContainer>
@@ -219,5 +221,6 @@ const GeneralView = ({ localeProp, user }: GeneralViewProps) => {
};
GeneralQueryView.getLayout = getLayout;
GeneralQueryView.PageWrapper = PageWrapper;
export default GeneralQueryView;
@@ -40,6 +40,7 @@ import {
} from "@calcom/ui";
import { AlertTriangle, Trash2 } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
import TwoFactor from "@components/auth/TwoFactor";
import { UsernameAvailabilityField } from "@components/ui/UsernameAvailability";
@@ -394,5 +395,6 @@ const ProfileForm = ({
};
ProfileView.getLayout = getLayout;
ProfileView.PageWrapper = PageWrapper;
export default ProfileView;
@@ -6,6 +6,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Button, Form, Label, Meta, showToast, Skeleton, Switch } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import { ssrInit } from "@server/lib/ssr";
const ProfileImpersonationView = () => {
@@ -85,6 +87,7 @@ const ProfileImpersonationView = () => {
};
ProfileImpersonationView.getLayout = getLayout;
ProfileImpersonationView.PageWrapper = PageWrapper;
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const ssr = await ssrInit(context);
@@ -9,6 +9,8 @@ import { userMetadata } from "@calcom/prisma/zod-utils";
import { trpc } from "@calcom/trpc/react";
import { Alert, Button, Form, Meta, PasswordField, Select, SettingsToggle, showToast } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
type ChangePasswordSessionFormValues = {
oldPassword: string;
newPassword: string;
@@ -207,5 +209,6 @@ const PasswordView = () => {
};
PasswordView.getLayout = getLayout;
PasswordView.PageWrapper = PageWrapper;
export default PasswordView;
+9 -1
View File
@@ -1 +1,9 @@
export { default } from "@calcom/features/ee/sso/page/user-sso-view";
import UserSSOView from "@calcom/features/ee/sso/page/user-sso-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = UserSSOView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -5,6 +5,7 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Badge, Meta, Switch, SkeletonButton, SkeletonContainer, SkeletonText, Alert } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import DisableTwoFactorModal from "@components/settings/DisableTwoFactorModal";
import EnableTwoFactorModal from "@components/settings/EnableTwoFactorModal";
@@ -84,5 +85,6 @@ const TwoFactorAuthView = () => {
};
TwoFactorAuthView.getLayout = getLayout;
TwoFactorAuthView.PageWrapper = PageWrapper;
export default TwoFactorAuthView;
@@ -1 +1,9 @@
export { default } from "@calcom/features/ee/teams/pages/team-appearance-view";
import TeamAppearenceView from "@calcom/features/ee/teams/pages/team-appearance-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = TeamAppearenceView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -1 +1,9 @@
export { default } from "@calcom/features/ee/teams/pages/team-billing-view";
import TeamBillingView from "@calcom/features/ee/teams/pages/team-billing-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = TeamBillingView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -1 +1,9 @@
export { default } from "@calcom/features/ee/teams/pages/team-members-view";
import TeamMembersView from "@calcom/features/ee/teams/pages/team-members-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = TeamMembersView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -3,6 +3,7 @@ import Head from "next/head";
import AddNewTeamMembers from "@calcom/features/ee/teams/components/AddNewTeamMembers";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import PageWrapper from "@components/PageWrapper";
import WizardLayout from "@components/layouts/WizardLayout";
const OnboardTeamMembersPage = () => {
@@ -24,4 +25,6 @@ OnboardTeamMembersPage.getLayout = (page: React.ReactElement) => (
</WizardLayout>
);
OnboardTeamMembersPage.PageWrapper = PageWrapper;
export default OnboardTeamMembersPage;
@@ -1 +1,9 @@
export { default } from "@calcom/features/ee/teams/pages/team-profile-view";
import TeamProfileView from "@calcom/features/ee/teams/pages/team-profile-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = TeamProfileView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
+9 -1
View File
@@ -1 +1,9 @@
export { default } from "@calcom/features/ee/sso/page/teams-sso-view";
import TeamSSOView from "@calcom/features/ee/sso/page/teams-sso-view";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = TeamSSOView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
+9 -1
View File
@@ -1 +1,9 @@
export { default } from "@calcom/features/ee/teams/pages/team-listing-view";
import TeamListView from "@calcom/features/ee/teams/pages/team-listing-view";
import PageWrapper from "@components/PageWrapper";
import type { CalPageWrapper } from "@components/PageWrapper";
const Page = TeamListView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -3,6 +3,7 @@ import Head from "next/head";
import { CreateANewTeamForm } from "@calcom/features/ee/teams/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import PageWrapper from "@components/PageWrapper";
import WizardLayout from "@components/layouts/WizardLayout";
const CreateNewTeamPage = () => {
@@ -26,5 +27,6 @@ const LayoutWrapper = (page: React.ReactElement) => {
};
CreateNewTeamPage.getLayout = LayoutWrapper;
CreateNewTeamPage.PageWrapper = PageWrapper;
export default CreateNewTeamPage;
+14 -1
View File
@@ -14,6 +14,8 @@ import prisma from "@calcom/prisma";
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
import { Alert, Button, EmailField, HeadSeo, PasswordField, TextField } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import { asStringOrNull } from "../lib/asStringOrNull";
import { IS_GOOGLE_LOGIN_ENABLED } from "../server/lib/constants";
import { ssrInit } from "../server/lib/ssr";
@@ -95,7 +97,17 @@ export default function Signup({ prepopulateFormValues }: inferSSRProps<typeof g
<div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div className="bg-default mx-2 px-4 py-8 shadow sm:rounded-lg sm:px-10">
<FormProvider {...methods}>
<form onSubmit={methods.handleSubmit(signUp)} className="bg-default space-y-6">
<form
onSubmit={(event) => {
event.preventDefault();
event.stopPropagation();
if (methods.formState?.errors?.apiError) {
methods.clearErrors("apiError");
}
methods.handleSubmit(signUp)(event);
}}
className="bg-default space-y-6">
{errors.apiError && <Alert severity="error" message={errors.apiError?.message} />}
<div className="space-y-2">
<TextField
@@ -220,3 +232,4 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
};
Signup.isThemeSupported = false;
Signup.PageWrapper = PageWrapper;
+4
View File
@@ -20,6 +20,7 @@ import { ArrowRight } from "@calcom/ui/components/icon";
import { useToggleQuery } from "@lib/hooks/useToggleQuery";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
import Team from "@components/team/screens/Team";
import { ssrInit } from "@server/lib/ssr";
@@ -203,4 +204,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
} as const;
};
TeamPage.isBookingPage = true;
TeamPage.PageWrapper = PageWrapper;
export default TeamPage;
+4
View File
@@ -14,6 +14,7 @@ import { asStringOrNull } from "@lib/asStringOrNull";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import type { EmbedProps } from "@lib/withEmbedSsr";
import PageWrapper from "@components/PageWrapper";
import AvailabilityPage from "@components/booking/pages/AvailabilityPage";
import { ssgInit } from "@server/lib/ssg";
@@ -24,6 +25,9 @@ export default function TeamType(props: AvailabilityTeamPageProps) {
return <AvailabilityPage {...props} />;
}
TeamType.isBookingPage = true;
TeamType.PageWrapper = PageWrapper;
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const slugParam = asStringOrNull(context.query.slug);
const typeParam = asStringOrNull(context.query.type);
+3
View File
@@ -14,6 +14,7 @@ import { customInputSchema, eventTypeBookingFields, EventTypeMetaDataSchema } fr
import { asStringOrNull, asStringOrThrow } from "@lib/asStringOrNull";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
import BookingPage from "@components/booking/pages/BookingPage";
import { ssrInit } from "@server/lib/ssr";
@@ -23,6 +24,8 @@ export type TeamBookingPageProps = inferSSRProps<typeof getServerSideProps>;
export default function TeamBookingPage(props: TeamBookingPageProps) {
return <BookingPage {...props} />;
}
TeamBookingPage.isBookingPage = true;
TeamBookingPage.PageWrapper = PageWrapper;
const querySchema = z.object({
rescheduleUid: z.string().optional(),
+3
View File
@@ -7,6 +7,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button } from "@calcom/ui";
import { Plus } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
function Teams() {
const { t } = useLocale();
return (
@@ -36,5 +38,6 @@ export const getStaticProps = async () => {
};
Teams.requiresLicense = false;
Teams.PageWrapper = PageWrapper;
export default Teams;
+4
View File
@@ -16,6 +16,8 @@ import prisma, { bookingMinimalSelect } from "@calcom/prisma";
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
import { ChevronRight } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
import { ssrInit } from "@server/lib/ssr";
const recordingStartedEventResponse = z
@@ -261,6 +263,8 @@ export function VideoMeetingInfo(props: VideoMeetingInfo) {
);
}
VideoMeetingInfo.PageWrapper = PageWrapper;
export async function getServerSideProps(context: GetServerSidePropsContext) {
const { req, res } = context;
@@ -9,6 +9,8 @@ import { ArrowRight, Calendar, X } from "@calcom/ui/components/icon";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import PageWrapper from "@components/PageWrapper";
export default function MeetingUnavailable(props: inferSSRProps<typeof getServerSideProps>) {
const { t } = useLocale();
@@ -62,6 +64,8 @@ export default function MeetingUnavailable(props: inferSSRProps<typeof getServer
);
}
MeetingUnavailable.PageWrapper = PageWrapper;
export async function getServerSideProps(context: NextPageContext) {
const booking = await prisma.booking.findUnique({
where: {
@@ -8,6 +8,8 @@ import type { inferSSRProps } from "@calcom/types/inferSSRProps";
import { Button, HeadSeo, EmptyScreen } from "@calcom/ui";
import { ArrowRight, Calendar, Clock } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
export default function MeetingNotStarted(props: inferSSRProps<typeof getServerSideProps>) {
const { t } = useLocale();
return (
@@ -37,6 +39,8 @@ export default function MeetingNotStarted(props: inferSSRProps<typeof getServerS
);
}
MeetingNotStarted.PageWrapper = PageWrapper;
export async function getServerSideProps(context: NextPageContext) {
const booking = await prisma.booking.findUnique({
where: {
@@ -2,6 +2,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, EmptyScreen, HeadSeo } from "@calcom/ui";
import { X, ArrowRight } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
export default function NoMeetingFound() {
const { t } = useLocale();
@@ -23,3 +25,5 @@ export default function NoMeetingFound() {
</>
);
}
NoMeetingFound.PageWrapper = PageWrapper;
+9 -1
View File
@@ -1,7 +1,10 @@
import type { GetStaticPaths, GetStaticProps } from "next";
import { z } from "zod";
export { default } from "@calcom/features/ee/workflows/pages/workflow";
import Workflow from "@calcom/features/ee/workflows/pages/workflow";
import PageWrapper from "@components/PageWrapper";
import type { CalPageWrapper } from "@components/PageWrapper";
const querySchema = z.object({
workflow: z.string(),
@@ -26,3 +29,8 @@ export const getStaticPaths: GetStaticPaths = () => {
fallback: "blocking",
};
};
const WorkflowsPage = Workflow as CalPageWrapper;
WorkflowsPage.PageWrapper = PageWrapper;
export default WorkflowsPage;

Some files were not shown because too many files have changed in this diff Show More