+34

![kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>](/assets/img/avatar_default.png)
![kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>](/assets/img/avatar_default.png)

![kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>](/assets/img/avatar_default.png)




Omar López
GitHub
CarinaWolli
Peer Richelsen
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Alex van Andel
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
gitstart
Júlio Piubello da Silva Cabral
Alan
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Joe Au-Yeung
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Carina Wollendorfer
kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Hariom Balhara
Syed Ali Shahbaz
Leo Giovanetti
Bailey Pumfleet
GitStart
Arthur Cruz
Mitchell Moore
Agusti Fernandez Pardo
Agusti Fernandez Pardo
sean-brydon
andreaestefania12
Miguel Nieto A
Hashen
buschco
iamkun
github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Crowdin Bot
Ankit Gordhandas
depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Ken Miller
Arun Kumar
Shrey Gupta
01631e808f
* Turbo fixes * Make apps single pages public * fixed /booking skeleton (#2722) * fixed /booking skeleton * nit * Type fixes * Test fixes * Update playwright.config.ts * More test fixes * Update dynamic-booking-pages.test.ts * add invite link to Zapier setup page (#2696) * add invite link and toaster to zapier setup page * create env variable for invite link and save in database * fetch invite link form getStaticProps * add getStaticPath method * clean code * Moves app setup and index page * Moves Loader to ui * Trying new way to handle dynamic app store pages * Cleanup * Update tailwind.config.js * zapier invite link fixes * Tests fixes Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> * Add more embed events (#2719) * Add more embed events * Add more embed events Co-authored-by: Peer Richelsen <peeroke@gmail.com> * adds availability select loader (#2718) * Improve logs and Fix unwanted 500 to reduce noise in logs (#2674) * Improve logs * Fix unintentional 500 Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Change date format for RecurringBookings (#2707) * Change date format for RecurringBookings * Missing bookingId query param Co-authored-by: Leo Giovanetti <hello@leog.me> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * added giphy description (#2730) * fixes #2732 (#2732) * Hotfix : Fix Infinite loading of Bookings (#2729) * Add more embed events * Add more embed events * Fix nextCursor calculation logic Co-authored-by: Peer Richelsen <peeroke@gmail.com> * Hotfix: Success page for recurring event (#2725) * Merge pull request #2672 from calcom/main v1.5.4 * Turbo fixes * Make apps single pages public * Fix preview.html not built and thus served during depooy (#2713) * Hotfix: Success page layout broken due to duplicate "When" (#2716) * Update BookingPage.tsx * Reverting unchaged lines * Fixing recurrenceRule for ICS files Co-authored-by: Omar López <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> * Fix preview.html not built and thus served during depooy (#2727) Co-authored-by: Omar López <zomars@me.com> * Allow deletion of a disabled event (#2737) * allows deletion of disabled event * some visual fixes Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Multiple E2E improvements * Parallelizes some tests * Update booking-pages.test.ts * E2E and paid bookings fixes * Add 'free' and 'workingElsewhere' as a non-blocking event (#2652) * Add 'free' and 'workingElsewhere' to non-blocking event - this will allow bookings at these times * Update CalendarService.ts Co-authored-by: zomars <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * TODO marks blocking test to be fixed * Update testUtils.ts * Update testUtils.ts * getBusyTimes consolidation * Fixes delete-me test * E2E fixing attemps * Adjusting Zapier endpoints for publishing integration (#2728) * add /me endpoint for zapier API testing * remove cacellationReason from listBookings response Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Omar López <zomars@me.com> * Fix reschedule not happening in calendar if two calendards are there (#2733) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> * Increases timeout temporarily * Merge pull request #2745 from calcom/apps/multiple-categories Allow apps to belong to multiple categories * Build fixes * Populate msteams key in db (#2743) * Populate msteams key in db * Fix calendar credentials to teams * Clarify account dialog Co-authored-by: Omar López <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Bailey Pumfleet <pumfleet@hey.com> * Improving Email DRYness (#2486) * Email DRY * WIP * Improve email DRYness Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * E2E fixtures (#2747) * Sign in button should be changed or disabled after click #2654 (#2749) Co-authored-by: gitstart <gitstart@users.noreply.github.com> * Fixing ESLint warnings (#2723) * Fixing warnings * Reverting and disabling ESLint in some cases * Reverting Next Images * Reverting file, bad merge * Targeting ESLint to line * Additional warnings * New warning squished * More tweaks and major fixes * Uneeded conf Co-authored-by: Omar López <zomars@me.com> * Fix/avoid multiple schedule deletions (#2602) * Prevents users from deleting the same schedule multiple times due to delay before the schedule disappears. It also applies the same fix to team disband. Schedule deletion:  Team disband:  Fixes issue [#2569](https://github.com/calcom/cal.com/issues/2569) Bug fix (non-breaking change which fixes an issue) **apps/web/components/LightLoader.tsx** → this file was created in order to make a light color loading spinner available. It's necessary when we need to display a loading spinner above dark backgrounds. **apps/web/components/availability/ScheduleListItem.tsx** → this component was created in order to give a schedule list item its own state. * Removing a "setTimeout" that was only used for testing purposes * Adding a code review suggestion to my modifications * Changing loading style * Cleanup * Avoids using unnecessary state * Revert "Adding a code review suggestion to my modifications" This reverts commit b5e40062d71157ca1d9384fb1f5c30d50625809d. * Reverts some changes * Renames isLoading Co-authored-by: Alex van Andel <me@alexvanandel.com> Co-authored-by: Omar López <zomars@me.com> * Added check on create eventtype to see is user has slug that already exists (#2757) * Added check on create eventtype to see is user has slug that already exists, added error check on onError * revert yarn.lock back * Catches prisma known error instead of making an additional query Co-authored-by: zomars <zomars@me.com> * Fix white border (#2761) * fix: remove hardcoded redirect in signin url email verification (#2764) Co-authored-by: Agusti Fernandez Pardo <git@agusti.me> * Bad UX when user wants to set the default Event Type Title #2245 (#2760) Co-authored-by: gitstart <gitstart@users.noreply.github.com> * Skip sending emails in E2E * Users Phone Number Option (#2669) * Users Phone Number Option * Implemented improvments * Add validation to form Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> * Fix/unpaid unconfirmed (#2553) * Fix merge errors * Errors prettier/prettier * Update apps/web/pages/api/book/event.ts Co-authored-by: Miguel Nieto A <39246879+miguelnietoa@users.noreply.github.com> * Update apps/web/pages/api/book/event.ts Co-authored-by: Miguel Nieto A <39246879+miguelnietoa@users.noreply.github.com> * Update apps/web/pages/api/integrations.ts Co-authored-by: Miguel Nieto A <39246879+miguelnietoa@users.noreply.github.com> * Fix merge errors * Errors prettier/prettier * Update apps/web/pages/api/book/confirm.ts Co-authored-by: alannnc <alannnc@gmail.com> * Modal window before delete stripe integration * ESLint Report * Test fixes Co-authored-by: Miguel Nieto A <39246879+miguelnietoa@users.noreply.github.com> Co-authored-by: alannnc <alannnc@gmail.com> Co-authored-by: zomars <zomars@me.com> * Mutually exclusive options (#2755) Co-authored-by: Omar López <zomars@me.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Readd steps to create a new user #2665 (#2759) Co-authored-by: gitstart <gitstart@users.noreply.github.com> * remove redundant conditional expressions (#2756) * remove redundant conditional expressions * remove redundant conditional expression Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com> * Fix adds redirect callback that support app.cal.com (#2768) * Fix adds redirect callback that support app.cal.com * Update apps/web/pages/api/auth/[...nextauth].tsx Check origin of website and baseurl Co-authored-by: Omar López <zomars@me.com> * fix: lint issue extra space removed Co-authored-by: Agusti Fernandez Pardo <git@agusti.me> Co-authored-by: Omar López <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * respect local set timezone and update url on mismatch (#2506) * ensure `timeZone()` will make its way to the URL fixes https://github.com/calcom/cal.com/issues/2482 * keep `timeZone()` and the offset from URL in sync Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Squashed commit of the following: commit27540b09ceAuthor: Agusti Fernandez Pardo <me@agusti.me> Date: Mon May 16 17:34:13 2022 +0200 fix: remove hardcoded redirect in signin url email verification (#2764) Co-authored-by: Agusti Fernandez Pardo <git@agusti.me> commitae15a7d739Author: Hariom Balhara <hariombalhara@gmail.com> Date: Tue May 10 14:30:43 2022 +0530 Fix time issue commit2a5a89fe50Author: Leo Giovanetti <hello@leog.me> Date: Wed May 11 10:21:46 2022 -0300 Missing fix for success page commit2ce1e78053Author: Leo Giovanetti <hello@leog.me> Date: Wed May 11 10:12:59 2022 -0300 Hotfix: Success page for recurring event (#2725) * Merge pull request #2672 from calcom/main v1.5.4 * Turbo fixes * Make apps single pages public * Fix preview.html not built and thus served during depooy (#2713) * Hotfix: Success page layout broken due to duplicate "When" (#2716) * Update BookingPage.tsx * Reverting unchaged lines * Fixing recurrenceRule for ICS files Co-authored-by: Omar López <zomars@me.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> commit2d6d1cb444Author: Hariom Balhara <hariombalhara@gmail.com> Date: Tue May 10 14:49:46 2022 +0530 Hotfix: Success page layout broken due to duplicate "When" (#2716) commitef68f4f4f8Author: Hariom Balhara <hariombalhara@gmail.com> Date: Tue May 10 10:54:20 2022 +0530 Fix preview.html not built and thus served during depooy (#2713) commit18c28cc3fdAuthor: zomars <zomars@me.com> Date: Mon May 9 16:17:07 2022 -0600 Make apps single pages public commitd40e8caff9Author: zomars <zomars@me.com> Date: Mon May 9 16:08:03 2022 -0600 Turbo fixes commit3161cc4d45Merge:ed808c3be4099a477dAuthor: zomars <zomars@me.com> Date: Mon May 9 14:58:33 2022 -0600 Merge branch 'main' into production commited808c3be6Author: Omar López <zomars@me.com> Date: Mon May 9 14:56:23 2022 -0600 Merge pull request #2672 from calcom/main v1.5.4 * Typo * Typo * Update apps/web/pages/apps/categories/[category].tsx * Apply suggestions from code review * Alert to describe exclusion of options (#2770) * Alert to describe exclusion of options * Update apps/web/pages/event-types/[type].tsx Co-authored-by: Omar López <zomars@me.com> * Update apps/web/components/eventtype/RecurringEventController.tsx Co-authored-by: Omar López <zomars@me.com> * Formatting Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Omar López <zomars@me.com> * fix: split time correctly if the local working hours are just across mid night (#2766) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Update crowdin.yml * New Crowdin translations by Github Action (#2773) * New Crowdin translations by Github Action * Update vital.json * Update vital.json Co-authored-by: Crowdin Bot <support+bot@crowdin.com> Co-authored-by: Omar López <zomars@me.com> * Add Google cal extneral calendar id to booking reference (#2671) * Set google cal event id to use our uid * Save calendar external id to bookingRef * Pass external calendar ids to update and delete * Create migration * Fix type errors * Fix prisma url Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Omar López <zomars@me.com> * v1.6 * v1.6 * 2FA submit disabled (#2790) * fixing the hyperlink for open startup (#2777) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Add login event (#2784) Co-authored-by: Bailey Pumfleet <pumfleet@hey.com> * Fixes infinite loop * Fixes infinite loop * Fixes infinite loop * Update all Yarn dependencies (2022-05-16) (#2769) * Update all Yarn dependencies (2022-05-16) * Upgrade dependencies * Removes deprecated packages * Upgrades deps * Updates submodules * Update yarn.lock * Linting * Linting * Update website * Build fixes * TODO: fix this * Module resolving * Type fixes * Intercom fixes on SSG * Fixes infinite loop * Upgrades to React 18 * Type fixes * Locks node version to 14 * Upgrades daily-js * Readds missing types * Upgrades playwright * Noop when intercom is not installed * Update website * Removed yarn.lock in favor of monorepo Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> * Create ci.yml * Update ci.yml * Reintroduces typescript-eslint Buckle up! * Type fixes * Update ci.yml * Update api * Update admin * Reusable inferSSRProps * Linting * Linting * Prisma fixes * Update ci.yml * Cache testing * Update e2e.yml * Update DatePicker.tsx * Update e2e.yml * Revert "Linting" This reverts commitadf817766e. * Revert "Linting" This reverts commit1b59dacd64. * Linting * Update e2e.yml * Ci updates * Add team Id to hash url (#2803) * Fix missing tabs - Embed (#2804) * Fix missing tabs * Fix Eslint error * Fix Eslint errors * Add import statement (#2812) * Add import statement * Update apps/docs/next.config.js Co-authored-by: Omar López <zomars@me.com> * Show success page if booking was deleted on calendar (#2808) * Add exception to 410 * Fix type error * Add GoogelCalError type * only show invite link for app.cal.dev (#2807) Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: Omar López <zomars@me.com> * fix: update eslint config to test .ts and .js separately (#2805) * fix: update eslint config * fix: update ts ignore * fix: update eslint config * Update TeamAvailabilityScreen.tsx * Type fixes * Update useIntercom.ts Co-authored-by: Omar López <zomars@me.com> * fix: sync api to latest commit (#2810) Co-authored-by: Agusti Fernandez Pardo <git@agusti.me> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Embed React improvements (#2782) * Add off support. Add getApi export. * Add publish command * Add embed-snippet in prod deps * Update README * Update package.json Co-authored-by: Bailey Pumfleet <pumfleet@hey.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Consolidates test-results * Add vscode tasks.json (#2801) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * save additional inputs as json + view details of booking (#2796) * move custom inputs from description to own json object * show custom inputs on success page * fix type error * add custom inputs to email and webhook * add custom inputs to all emails * add values for custom inputs when rescheduling * add custom input everywhere description is shown * fix bug with boolean value * fix issues with null values * disable custom inputs and add notes for organizer * don't show custom input with empty string * don't show custom inputs with empty string in calender event and email * add link to booking details page * redirect to success page to see booking details * add functionality to cancel and reschedule booking * fix bookings that require confirmation * clean code * fix infinite lopp in useEffect of success page * show web conference details message when integration as location * improve design of cancelling event * clean code * disable darkmode for organizer on booking details page * fix dark mode for cancelling booking * fix build error * Fixes infinite loop * Fixes infinite loop * Fixes infinite loop * Update all Yarn dependencies (2022-05-16) (#2769) * Update all Yarn dependencies (2022-05-16) * Upgrade dependencies * Removes deprecated packages * Upgrades deps * Updates submodules * Update yarn.lock * Linting * Linting * Update website * Build fixes * TODO: fix this * Module resolving * Type fixes * Intercom fixes on SSG * Fixes infinite loop * Upgrades to React 18 * Type fixes * Locks node version to 14 * Upgrades daily-js * Readds missing types * Upgrades playwright * Noop when intercom is not installed * Update website * Removed yarn.lock in favor of monorepo Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> * Create ci.yml * Update ci.yml * Reintroduces typescript-eslint Buckle up! * Type fixes * Update ci.yml * Update api * Update admin * Reusable inferSSRProps * Linting * Linting * Prisma fixes * Update ci.yml * Cache testing * Update e2e.yml * Update DatePicker.tsx * Update e2e.yml * Revert "Linting" This reverts commitadf817766e. * Revert "Linting" This reverts commit1b59dacd64. * Linting * Update e2e.yml * Ci updates * Add team Id to hash url (#2803) * Fix missing tabs - Embed (#2804) * Fix missing tabs * Fix Eslint error * Fix Eslint errors * Add import statement (#2812) * Add import statement * Update apps/docs/next.config.js Co-authored-by: Omar López <zomars@me.com> * Show success page if booking was deleted on calendar (#2808) * Add exception to 410 * Fix type error * Add GoogelCalError type * only show invite link for app.cal.dev (#2807) Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: Omar López <zomars@me.com> * fix: update eslint config to test .ts and .js separately (#2805) * fix: update eslint config * fix: update ts ignore * fix: update eslint config * Update TeamAvailabilityScreen.tsx * Type fixes * Update useIntercom.ts Co-authored-by: Omar López <zomars@me.com> * fix: sync api to latest commit (#2810) Co-authored-by: Agusti Fernandez Pardo <git@agusti.me> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Embed React improvements (#2782) * Add off support. Add getApi export. * Add publish command * Add embed-snippet in prod deps * Update README * Update package.json Co-authored-by: Bailey Pumfleet <pumfleet@hey.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Consolidates test-results * Type fixes * Abstracts minimal booking select * Type fixes * Update listBookings.ts * Update common.json * Update bookingReminder.ts * Consolidates isOutOfBounds * Update webhookResponse-chromium.txt * Update TableActions.tsx * Type fixes * Update BookingPage.tsx * Update webhookResponse-chromium.txt Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: Alex van Andel <me@alexvanandel.com> Co-authored-by: Bailey Pumfleet <pumfleet@hey.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Co-authored-by: iamkun <kunhello@outlook.com> Co-authored-by: Agusti Fernandez Pardo <me@agusti.me> Co-authored-by: Agusti Fernandez Pardo <git@agusti.me> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Update check-types.yml * adding organizer as attendee to google calendar events (#2779) * Fix auto-select and close of dropdown (#2819) * fixes dynamic color and typefix for tfunction after react upgrade (#2821) * New Crowdin translations by Github Action (#2791) Co-authored-by: Crowdin Bot <support+bot@crowdin.com> * Relocates admin to console # Conflicts: # apps/admin * Relocates admin to console * Fix login submit (#2849) * fix: long string overflowing calendar div (#2842) Co-authored-by: gitstart <gitstart@users.noreply.github.com> Co-authored-by: Júlio Piubello da Silva Cabral <julio.piubello@gitstart.dev> * Adding labels (#2783) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Wrong username is identified if query params are present and user doesn't exist (#2838) Co-authored-by: gitstart <gitstart@users.noreply.github.com> Co-authored-by: Júlio Piubello da Silva Cabral <julio.piubello@gitstart.dev> * Meet/Zoom Email Clarification (#2828) * Add clarificaiton to email * Update apps/web/lib/emails/templates/organizer-scheduled-email.ts * Add to attendee scheduled email Co-authored-by: Omar López <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Request the inclusion Assuncion Time Zone (#2840) Co-authored-by: gitstart <gitstart@users.noreply.github.com> Co-authored-by: Júlio Piubello da Silva Cabral <julio.piubello@gitstart.dev> * Fix UI of dialog (#2788) * removed large mandatory height and scroll * added z index using css * cleanup * fixed TS errors * extract dialog out of dropdown * Adds custom loading text to confirmation dialog * rename update * utilizing mutation loading state Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Hotfix: Fixing Security Issues (#2848) * Fixing Privilege Escalation * Fixing critical obj ref in availability * Fixing reschedule security issue Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> * Merge production to main * Update vital.json * Update vital.json * Fix login page CTA disabled state (#2832) * fix(ui/login): better disabled state for login CTA The fix involves tracking the form submission with a dedicated state `submitInProgress` with React. `formState` from `react-hook-form` does not take time taken for the network call into account. For example, if the api takes 5 seconds to complete, we would expect the `formState.isSubmitting` to be true for `5` seconds. But, surprisingly this is not the case and `formState` from `react-hook-form` resolves immediately after it makes a successful connection to the endpoint. A dedicated state (with `useState`) is introduced that is enabled when the user clicks on the login CTA, and disabled when the api call is resolved, either successfully or with an error. * Update login.tsx * Update login.tsx * Fixes isSubmitting state Co-authored-by: zomars <zomars@me.com> * Playwright binaries shouldn't be on deps * Playwright binaries shouldn't be on deps * Fix infinite renders on event-type edit page (#2820) * Updates submodules * Makes sure to hash post-install cache * Add seats to event types (#2485) * Add seatsPerTimeSlot to event type schema * Add seats per time slot to event type form * Book event and render seats * Pass booking uid for seats * Disable requires confirmation if seats are enabled * Fix type errors * Update submodules * Fix type errors * Fix type errors * Fix duplicate string * Fix duplicate string * Fix schema and migration file * Fix render seats * Fix bookinguid typos * Remove console.log * Fix type error * Fix mobile formatting * Update apps/web/lib/hooks/useSlots.ts Co-authored-by: Omar López <zomars@me.com> * Update apps/web/lib/hooks/useSlots.ts Co-authored-by: Omar López <zomars@me.com> * Added translation for seats available text Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: alannnc <alannnc@gmail.com> * Redesign help menu item (#2710) * Seperate help menu item and contact menu item * Add menu items * Install react-popover * Render contact only if support keys are present * Adjust contact support links * Add translations * Add embed changes * Adjust menu if helped is pressed * Add items to help menu * Change button color on selection * Create endpoint * Create feedback table * Create migration file * Write feedback to db * Remove logs * Add response message * Send feedback email * Disable submit if no rating and after submit * Add translations * Fix padding * Clean up * Clean up * Add user feedback email to .env example * Lint fixes and styles * Changed onClick function to a named function and fix style * Fix ids order * Removed commented code and changed textarea id and name * Fix id orders * Change to AND operator Co-authored-by: Omar López <zomars@me.com> * Add user relation to feedback Co-authored-by: Omar López <zomars@me.com> * Add migration files * Change rating to strings * Change rating to strings * Fix type errors * WIP success & error messages * Change success and error to boolans * Style messages * Add await Co-authored-by: Omar López <zomars@me.com> * Remove duplicate string * Refactor import statement Co-authored-by: Omar López <zomars@me.com> * Change opacity of emojis * added support@cal.com email for feedback * Add success toast * Update .env.example Co-authored-by: Omar López <zomars@me.com> * Add tCRP route * tCRP send email * tCRP send email Co-authored-by: Alan <alannnc@gmail.com> Co-authored-by: Omar López <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> * fixed labels for seats, removes shadow from event-type inputs (#2862) * fixed labels for seats * minor fixes, removed shadow from all event-type inputs * Render input field on pro accounts (#2859) Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> * Submodule sync * sec-001 fixes (#2866) (#2867) * sec-001 fixes (#2866) * sec-001 fixes * Typo * Fixes paid bookings # Conflicts: # apps/web/ee/components/stripe/Payment.tsx * Hotfix: Fixing Security Issues (#2848) (#2850) * sec-001 fixes (#2866) * sec-001 fixes * Typo * Fixes paid bookings * fixes issues with date of recurring events on booking detail page (#2872) * fixes date not showing for confirmed recurring event * only show all events on upcoming bookings Co-authored-by: CarinaWolli <wollencarina@gmail.com> * Resolve if can't find event on google cal (#2860) * Resolve if can't find event on google cal * Change order of console.error Co-authored-by: Omar López <zomars@me.com> Co-authored-by: Omar López <zomars@me.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> * Disable Impersonation Option (#2880) * Disable Impersonation * Update Description Copy Co-authored-by: Peer Richelsen <peeroke@gmail.com> * Fix deleted event when on different cal (404) (#2882) * Fix/email shows false (#2879) * Webhook sec fixes (#2883) * Webhook sec fixes * Revert changes * Feat/Display location information publicly (#2752) * Updating checkbox field to reflect new designs * Include Infobadge option checkbox * Checkbox Field + i18n * Default checked - true * Sync with router * Extracting Types * Update filtering logic * Add UI to booking page * Default address/link * Update hashedlink page * Tidy up * Video icon * Add nullish check * Update to use RHF controller Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Fix 500 errors if data is invalid (#2886) * Check in middleware to ensure authorization for all endpoints (#2885) Co-authored-by: Alex van Andel <me@alexvanandel.com> * Fix bug to check opt in bookings (#2889) * Fix bug to check opt in bookings * Implemented value, onChange instead of form access Co-authored-by: Alex van Andel <me@alexvanandel.com> * remove unused imports (#2892) * Cascades impersonations on user delete (#2891) Co-authored-by: Alex van Andel <me@alexvanandel.com> * Ensures json fields on each call (#2893) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Redundant conditional expression (#2894) * remove redundant conditional expressions * remove redundant conditional expressions * License server (#2379) * WIP License server * WIP * Moves locations to App Store and Core * LocationType fixes * Runs db migrations post-deploy * WIP * WIP * Cleanup * WIP * WIP * Decouples translations from NavTabs * Adds admin submodule * Adds admin submodule * Sync dependencies * WIP * WIP * Updates submodules * Renames package * Updates submodules * Adds scripts for console * Updates license checker URL * Updates admin * Adds staging/prod admin console links * Update yarn.lock * Update NavTabs.tsx * WIP * Update admin * WIP * Adds hint to InputField * Update admin * Adds turbo admin dependecies * Update admin * Prevents redirection on form submit * Form warning fixes * Update admin * Form fixes * Update yarn.lock * Update admin * Update admin * Update admin * Adds withLicenseRequired HOC * Adds LicenseRequired to EE components * Admin deploy fix? * Updates submodules * Use relative inside lib * type fixes * Fixes turbo race condition * Relocates admin to console * Relocates admin to console * Update console * Update api * Update turbo.json * Update ErrorBoundary.tsx * Update defaultEvents.ts * Update checkLicense.ts * Update yarn.lock * Skip on E2E Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Update turbo.json * Reverts license check on payment Since it's a public page * Submodule sync * fix: overflowing text on teams page - using tailwind line-clamp (#2843) Co-authored-by: gitstart <gitstart@users.noreply.github.com> Co-authored-by: Júlio Piubello da Silva Cabral <julio.piubello@gitstart.dev> * Fix @calcom/embed-react installation with TS project (#2870) * Fix failing builds (#2908) * Update turbo.json * Change location of booking (#2658) * add functionality to change location in booking and send out mail * add i18n * change location with dropdown like in event-types * small fixes and code clean up * clean code * improve format of current Location string * clean code * clear selection when dialog closed * added mutation and changed props (first working verison) * clean code * clean code * clean code * clean code * fix typo * change maxHeight of select * use useWatch for selectedLocation * pass default values with props * set current location directly in useState * clear selected values when updating location * fix trpc query for credentialst * change icons for editing booking * improve naming of variables * remove unnecessary orderBy * use locationOptionsToString method * fix current location naming for Cal Video * add phone input * save phone number as location of booking * remove input field for phone number for event-types * fix redirection issue * show previous selected location in event-type * remove attendee number from selection for booking * make first letter of location lowercase * remove input field for attendee phone number * clear Errors when changing location type * set location details to optional * clean code * fixing issue that dropdown doesn't close when dialog opens * clean code * make overflow visibile in dialog * fix existing bug with address not showing in event-type settings * fix issue with losing focus after validation * close rejection dialog * small spelling fixes * fix issue with LocationChangeEmail * fix failing E2E test * fix failing E2E test * fix E2E test * bug fix for saving user phone, and other minor changes * merge main * improve text * fix UI of booking list * Delete admin * remove selection after update and submit * add translation for error message * add default values for checkbox * add "your phone number" to locations on booking page * remove duplicate attributes from viewer.bookings Co-authored-by: Omar López <zomars@me.com> * check if user is authorized to make changes to booking * remove location string * clan code for displayLocaitonPublicly checkbox * fetch locationOptions on server side * remove trpc query for credentials * fix phone number input * fix labels of host and attendee phone number for booking page * Migrates edit location to tRPC * Link elemnt should only be used in `a` tags * Adds missin router * Migrates locationOptions to tRPC query * Type fixes Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: Alan <alannnc@gmail.com> Co-authored-by: Omar López <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * added checkly and twitch badges * Update README.md * areas of expertise test * Update CONTRIBUTING.md * Update README.md (#2912) * Update CONTRIBUTING.md * Update CONTRIBUTING.md * Update CONTRIBUTING.md * Update CONTRIBUTING.md * Update CONTRIBUTING.md * Update CONTRIBUTING.md * remove unsed imports (#2895) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Fix event-type preview links on Vercel Previews (#2919) * Fix website url * Fix avatar paths everywhere * Fix linting errors Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Cleanup & removed usages of sparingly used Text/ files (#2904) * Update CONTRIBUTING.md * Update CONTRIBUTING.md * Fixed typo in CheckboxField and wrapped description in <label> (#2924) * Fixed typo in CheckboxField and wrapped description in <label> * Make functionality identical to before * Fixed use of infomationIconText * Fix lint error (needs refactor, out of scope) * Payment amount input leading 0 (#2836) Co-authored-by: gitstart <gitstart@users.noreply.github.com> Co-authored-by: Júlio Piubello da Silva Cabral <julio.piubello@gitstart.dev> * Allow less than 6 bookings and add proper min validation of 2+ (#2921) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * fix(app-store): Giphy Ux fixes (#2746) * fix(app-store): Giphy Ux fixes * Add search placeholder * Min height image on event type page * Use regex in zod validation and fix design issues for figma row 1 * Add paddings as per discussion with Ciarán * Fix getGiphyApiKey nomenclature * Update apps/web/public/static/locales/en/common.json * Update regex to be more readable and allow enter to search Co-authored-by: Omar López <zomars@me.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> * Add embed tests in CI (#2887) * Add embed tests in CI * Update e2e-embed.yml * Run quick tests only * Ignore certain folders * Add embed-react tests as well * Fix commands * Dont run unit tests * Update playwright.config.ts * Update playwright.config.ts * Update playwright.config.ts * Create correct artifcats * Create correct artifcats * Fi ignore path * Update package.json * Add back embed-react typecheck Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * remove subtitle (#2925) Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Fix booking detail page for cancelled events (#2905) * fix booking detail page for cancelled events * Fix typo * fix bug when now attendees exist in booking Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: Alan <alannnc@gmail.com> * v1.6.2 * Add reschedule reason to DB and emails (#2909) * Write reschedule reason to db * Add reschedule reason to emails * Add reschedule reason to request reschedule email * Add reschedule reason to request reschedule email * Add reschedule reason to request reschedule email * Add reschedule reason to request reschedule email * Write reschedule reason to db * Add reschedule reason to emails * No longer using rescheduleReason in favor of cancellationReason * Update apps emails accordingly with reschedule reason * Update reschedule.test.ts Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Alan <alannnc@gmail.com> Co-authored-by: zomars <zomars@me.com> * Update website * Update HelpMenuItem.tsx * Update event.ts Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com> Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com> Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com> Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Co-authored-by: Leo Giovanetti <hello@leog.me> Co-authored-by: Alex van Andel <me@alexvanandel.com> Co-authored-by: Bailey Pumfleet <pumfleet@hey.com> Co-authored-by: GitStart <1501599+gitstart@users.noreply.github.com> Co-authored-by: gitstart <gitstart@users.noreply.github.com> Co-authored-by: Arthur Cruz <42497300+arthur1041@users.noreply.github.com> Co-authored-by: Mitchell Moore <47459168+Mitchell-Moore@users.noreply.github.com> Co-authored-by: Agusti Fernandez Pardo <me@agusti.me> Co-authored-by: Agusti Fernandez Pardo <git@agusti.me> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> Co-authored-by: andreaestefania12 <19562383+andreaestefania12@users.noreply.github.com> Co-authored-by: Miguel Nieto A <39246879+miguelnietoa@users.noreply.github.com> Co-authored-by: alannnc <alannnc@gmail.com> Co-authored-by: Hashen <37979557+Hashen110@users.noreply.github.com> Co-authored-by: buschco <colin@busch.dev> Co-authored-by: iamkun <kunhello@outlook.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Crowdin Bot <support+bot@crowdin.com> Co-authored-by: Ankit Gordhandas <agordhandas@gmail.com> Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com> Co-authored-by: Ken Miller <kemiller@users.noreply.github.com> Co-authored-by: Júlio Piubello da Silva Cabral <julio.piubello@gitstart.dev> Co-authored-by: Arun Kumar <palerdot@users.noreply.github.com> Co-authored-by: Shrey Gupta <connectwithshrey@gmail.com>
624 lines
24 KiB
TypeScript
624 lines
24 KiB
TypeScript
import { SelectorIcon } from "@heroicons/react/outline";
|
|
import {
|
|
ArrowLeftIcon,
|
|
CalendarIcon,
|
|
ClockIcon,
|
|
CogIcon,
|
|
ExternalLinkIcon,
|
|
LinkIcon,
|
|
LogoutIcon,
|
|
MapIcon,
|
|
MoonIcon,
|
|
ViewGridIcon,
|
|
QuestionMarkCircleIcon,
|
|
} from "@heroicons/react/solid";
|
|
import { UserPlan } from "@prisma/client";
|
|
import { SessionContextValue, signOut, useSession } from "next-auth/react";
|
|
import Link from "next/link";
|
|
import { useRouter } from "next/router";
|
|
import React, { Fragment, ReactNode, useEffect, useState } from "react";
|
|
import { Toaster } from "react-hot-toast";
|
|
|
|
import { useIsEmbed } from "@calcom/embed-core/embed-iframe";
|
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
|
import Button from "@calcom/ui/Button";
|
|
import Dropdown, {
|
|
DropdownMenuContent,
|
|
DropdownMenuItem,
|
|
DropdownMenuSeparator,
|
|
DropdownMenuTrigger,
|
|
} from "@calcom/ui/Dropdown";
|
|
import LicenseBanner from "@ee/components/LicenseBanner";
|
|
import TrialBanner from "@ee/components/TrialBanner";
|
|
import HelpMenuItem from "@ee/components/support/HelpMenuItem";
|
|
|
|
import ErrorBoundary from "@lib/ErrorBoundary";
|
|
import classNames from "@lib/classNames";
|
|
import { WEBAPP_URL } from "@lib/config/constants";
|
|
import { shouldShowOnboarding } from "@lib/getting-started";
|
|
import useMeQuery from "@lib/hooks/useMeQuery";
|
|
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@lib/telemetry";
|
|
import { trpc } from "@lib/trpc";
|
|
|
|
import CustomBranding from "@components/CustomBranding";
|
|
import Loader from "@components/Loader";
|
|
import { HeadSeo } from "@components/seo/head-seo";
|
|
import ImpersonatingBanner from "@components/ui/ImpersonatingBanner";
|
|
|
|
import pkg from "../package.json";
|
|
import { useViewerI18n } from "./I18nLanguageHandler";
|
|
import Logo from "./Logo";
|
|
|
|
function useRedirectToLoginIfUnauthenticated(isPublic = false) {
|
|
const { data: session, status } = useSession();
|
|
const loading = status === "loading";
|
|
const router = useRouter();
|
|
|
|
useEffect(() => {
|
|
if (isPublic) {
|
|
return;
|
|
}
|
|
|
|
if (!loading && !session) {
|
|
router.replace({
|
|
pathname: "/auth/login",
|
|
query: {
|
|
callbackUrl: `${WEBAPP_URL}${location.pathname}${location.search}`,
|
|
},
|
|
});
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [loading, session, isPublic]);
|
|
|
|
return {
|
|
loading: loading && !session,
|
|
session,
|
|
};
|
|
}
|
|
|
|
function useRedirectToOnboardingIfNeeded() {
|
|
const router = useRouter();
|
|
const query = useMeQuery();
|
|
const user = query.data;
|
|
|
|
const isRedirectingToOnboarding = user && shouldShowOnboarding(user);
|
|
|
|
useEffect(() => {
|
|
if (isRedirectingToOnboarding) {
|
|
router.replace({
|
|
pathname: "/getting-started",
|
|
});
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [isRedirectingToOnboarding]);
|
|
return {
|
|
isRedirectingToOnboarding,
|
|
};
|
|
}
|
|
|
|
export function ShellSubHeading(props: {
|
|
title: ReactNode;
|
|
subtitle?: ReactNode;
|
|
actions?: ReactNode;
|
|
className?: string;
|
|
}) {
|
|
return (
|
|
<div className={classNames("mb-3 block justify-between sm:flex", props.className)}>
|
|
<div>
|
|
<h2 className="flex content-center items-center space-x-2 text-base font-bold leading-6 text-gray-900 rtl:space-x-reverse">
|
|
{props.title}
|
|
</h2>
|
|
{props.subtitle && <p className="text-sm text-neutral-500 ltr:mr-4">{props.subtitle}</p>}
|
|
</div>
|
|
{props.actions && <div className="flex-shrink-0">{props.actions}</div>}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const Layout = ({
|
|
status,
|
|
plan,
|
|
...props
|
|
}: LayoutProps & { status: SessionContextValue["status"]; plan?: UserPlan; isLoading: boolean }) => {
|
|
const isEmbed = useIsEmbed();
|
|
const router = useRouter();
|
|
|
|
const { t } = useLocale();
|
|
const navigation = [
|
|
{
|
|
name: t("event_types_page_title"),
|
|
href: "/event-types",
|
|
icon: LinkIcon,
|
|
current: router.asPath.startsWith("/event-types"),
|
|
},
|
|
{
|
|
name: t("bookings"),
|
|
href: "/bookings/upcoming",
|
|
icon: CalendarIcon,
|
|
current: router.asPath.startsWith("/bookings"),
|
|
},
|
|
{
|
|
name: t("availability"),
|
|
href: "/availability",
|
|
icon: ClockIcon,
|
|
current: router.asPath.startsWith("/availability"),
|
|
},
|
|
{
|
|
name: t("apps"),
|
|
href: "/apps",
|
|
icon: ViewGridIcon,
|
|
current: router.asPath.startsWith("/apps"),
|
|
child: [
|
|
{
|
|
name: t("app_store"),
|
|
href: "/apps",
|
|
current: router.asPath === "/apps",
|
|
},
|
|
{
|
|
name: t("installed_apps"),
|
|
href: "/apps/installed",
|
|
current: router.asPath === "/apps/installed",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
name: t("settings"),
|
|
href: "/settings/profile",
|
|
icon: CogIcon,
|
|
current: router.asPath.startsWith("/settings"),
|
|
},
|
|
];
|
|
const pageTitle = typeof props.heading === "string" ? props.heading : props.title;
|
|
|
|
return (
|
|
<>
|
|
<HeadSeo
|
|
title={pageTitle ?? "Cal.com"}
|
|
description={props.subtitle ? props.subtitle?.toString() : ""}
|
|
nextSeoProps={{
|
|
nofollow: true,
|
|
noindex: true,
|
|
}}
|
|
/>
|
|
<div>
|
|
<Toaster position="bottom-right" />
|
|
</div>
|
|
|
|
<div
|
|
className={classNames("flex h-screen overflow-hidden", props.large ? "bg-white" : "bg-gray-100")}
|
|
data-testid="dashboard-shell">
|
|
{status === "authenticated" && (
|
|
<div style={isEmbed ? { display: "none" } : {}} className="hidden md:flex lg:flex-shrink-0">
|
|
<div className="flex w-14 flex-col lg:w-56">
|
|
<div className="flex h-0 flex-1 flex-col border-r border-gray-200 bg-white">
|
|
<div className="flex flex-1 flex-col overflow-y-auto pt-3 pb-4 lg:pt-5">
|
|
<Link href="/event-types">
|
|
<a className="px-4 md:hidden lg:inline">
|
|
<Logo small />
|
|
</a>
|
|
</Link>
|
|
{/* logo icon for tablet */}
|
|
<Link href="/event-types">
|
|
<a className="text-center md:inline lg:hidden">
|
|
<Logo small icon />
|
|
</a>
|
|
</Link>
|
|
<nav className="mt-2 flex-1 space-y-1 bg-white px-2 lg:mt-5">
|
|
{navigation.map((item) => (
|
|
<Fragment key={item.name}>
|
|
<Link href={item.href}>
|
|
<a
|
|
aria-label={item.name}
|
|
className={classNames(
|
|
item.current
|
|
? "bg-neutral-100 text-neutral-900"
|
|
: "text-neutral-500 hover:bg-gray-50 hover:text-neutral-900",
|
|
"group flex items-center rounded-sm px-2 py-2 text-sm font-medium"
|
|
)}>
|
|
<item.icon
|
|
className={classNames(
|
|
item.current
|
|
? "text-neutral-500"
|
|
: "text-neutral-400 group-hover:text-neutral-500",
|
|
"h-5 w-5 flex-shrink-0 ltr:mr-3 rtl:ml-3"
|
|
)}
|
|
aria-hidden="true"
|
|
/>
|
|
<span className="hidden lg:inline">{item.name}</span>
|
|
</a>
|
|
</Link>
|
|
{item.child &&
|
|
router.asPath.startsWith(item.href) &&
|
|
item.child.map((item) => {
|
|
return (
|
|
<Link key={item.name} href={item.href}>
|
|
<a
|
|
className={classNames(
|
|
item.current
|
|
? "text-neutral-900"
|
|
: "text-neutral-500 hover:text-neutral-900",
|
|
"group hidden items-center rounded-sm px-2 py-2 pl-10 text-sm font-medium lg:flex"
|
|
)}>
|
|
<span className="hidden lg:inline">{item.name}</span>
|
|
</a>
|
|
</Link>
|
|
);
|
|
})}
|
|
</Fragment>
|
|
))}
|
|
</nav>
|
|
</div>
|
|
<TrialBanner />
|
|
<div
|
|
className="rounded-sm pb-2 pl-3 pt-2 pr-2 hover:bg-gray-100 lg:mx-2 lg:pl-2"
|
|
data-testid="user-dropdown-trigger">
|
|
<span className="hidden lg:inline">
|
|
<UserDropdown />
|
|
</span>
|
|
<span className="hidden md:inline lg:hidden">
|
|
<UserDropdown small />
|
|
</span>
|
|
</div>
|
|
<small style={{ fontSize: "0.5rem" }} className="mx-3 mt-1 mb-2 hidden opacity-50 lg:block">
|
|
© {new Date().getFullYear()} Cal.com, Inc. v.{pkg.version + "-"}
|
|
{process.env.NEXT_PUBLIC_WEBSITE_URL === "https://cal.com" ? "h" : "sh"}
|
|
<span className="lowercase" data-testid={`plan-${plan?.toLowerCase()}`}>
|
|
-{plan}
|
|
</span>
|
|
</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<div className="flex w-0 flex-1 flex-col overflow-hidden">
|
|
<main
|
|
className={classNames(
|
|
"relative z-0 flex-1 overflow-y-auto focus:outline-none",
|
|
status === "authenticated" && "max-w-[1700px]",
|
|
props.flexChildrenContainer && "flex flex-col"
|
|
)}>
|
|
{/* show top navigation for md and smaller (tablet and phones) */}
|
|
{status === "authenticated" && (
|
|
<nav
|
|
style={isEmbed ? { display: "none" } : {}}
|
|
className="flex items-center justify-between border-b border-gray-200 bg-white p-4 md:hidden">
|
|
<Link href="/event-types">
|
|
<a>
|
|
<Logo />
|
|
</a>
|
|
</Link>
|
|
<div className="flex items-center gap-3 self-center">
|
|
<button className="rounded-full bg-white p-2 text-gray-400 hover:bg-gray-50 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2">
|
|
<span className="sr-only">{t("view_notifications")}</span>
|
|
<Link href="/settings/profile">
|
|
<a>
|
|
<CogIcon className="h-6 w-6" aria-hidden="true" />
|
|
</a>
|
|
</Link>
|
|
</button>
|
|
<UserDropdown small />
|
|
</div>
|
|
</nav>
|
|
)}
|
|
<div
|
|
className={classNames(
|
|
props.centered && "mx-auto md:max-w-5xl",
|
|
props.flexChildrenContainer && "flex flex-1 flex-col",
|
|
!props.large && "py-8"
|
|
)}>
|
|
<ImpersonatingBanner />
|
|
{!!props.backPath && (
|
|
<div className="mx-3 mb-8 sm:mx-8">
|
|
<Button
|
|
onClick={() => router.push(props.backPath as string)}
|
|
StartIcon={ArrowLeftIcon}
|
|
color="secondary">
|
|
Back
|
|
</Button>
|
|
</div>
|
|
)}
|
|
{props.heading && (
|
|
<div
|
|
className={classNames(
|
|
props.large && "bg-gray-100 py-8 lg:mb-8 lg:pt-16 lg:pb-7",
|
|
"block min-h-[80px] justify-between px-4 sm:flex sm:px-6 md:px-8"
|
|
)}>
|
|
{props.HeadingLeftIcon && <div className="ltr:mr-4">{props.HeadingLeftIcon}</div>}
|
|
<div className="mb-8 w-full">
|
|
{props.isLoading ? (
|
|
<>
|
|
<div className="mb-1 h-6 w-24 animate-pulse rounded-md bg-gray-200"></div>
|
|
<div className="mb-1 h-6 w-32 animate-pulse rounded-md bg-gray-200"></div>
|
|
</>
|
|
) : (
|
|
<>
|
|
<h1 className="font-cal mb-1 text-xl font-bold capitalize tracking-wide text-gray-900">
|
|
{props.heading}
|
|
</h1>
|
|
<p className="min-h-10 text-sm text-neutral-500 ltr:mr-4 rtl:ml-4">
|
|
{props.subtitle}
|
|
</p>
|
|
</>
|
|
)}
|
|
</div>
|
|
{props.CTA && <div className="mb-4 flex-shrink-0">{props.CTA}</div>}
|
|
</div>
|
|
)}
|
|
<div
|
|
className={classNames(
|
|
"px-4 sm:px-6 md:px-8",
|
|
props.flexChildrenContainer && "flex flex-1 flex-col"
|
|
)}>
|
|
<ErrorBoundary>{!props.isLoading ? props.children : props.customLoader}</ErrorBoundary>
|
|
</div>
|
|
{/* show bottom navigation for md and smaller (tablet and phones) */}
|
|
{status === "authenticated" && (
|
|
<nav
|
|
style={isEmbed ? { display: "none" } : {}}
|
|
className="bottom-nav fixed bottom-0 z-30 flex w-full bg-white shadow md:hidden">
|
|
{/* note(PeerRich): using flatMap instead of map to remove settings from bottom nav */}
|
|
{navigation.flatMap((item, itemIdx) =>
|
|
item.href === "/settings/profile" ? (
|
|
[]
|
|
) : (
|
|
<Link key={item.name} href={item.href}>
|
|
<a
|
|
className={classNames(
|
|
item.current ? "text-gray-900" : "text-neutral-400 hover:text-gray-700",
|
|
itemIdx === 0 ? "rounded-l-lg" : "",
|
|
itemIdx === navigation.length - 1 ? "rounded-r-lg" : "",
|
|
"group relative min-w-0 flex-1 overflow-hidden bg-white py-2 px-2 text-center text-xs font-medium hover:bg-gray-50 focus:z-10 sm:text-sm"
|
|
)}
|
|
aria-current={item.current ? "page" : undefined}>
|
|
<item.icon
|
|
className={classNames(
|
|
item.current ? "text-gray-900" : "text-gray-400 group-hover:text-gray-500",
|
|
"mx-auto mb-1 block h-5 w-5 flex-shrink-0 text-center"
|
|
)}
|
|
aria-hidden="true"
|
|
/>
|
|
<span className="truncate">{item.name}</span>
|
|
</a>
|
|
</Link>
|
|
)
|
|
)}
|
|
</nav>
|
|
)}
|
|
{/* add padding to content for mobile navigation*/}
|
|
<div className="block pt-12 md:hidden" />
|
|
</div>
|
|
<LicenseBanner />
|
|
</main>
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
const MemoizedLayout = React.memo(Layout);
|
|
|
|
type LayoutProps = {
|
|
centered?: boolean;
|
|
title?: string;
|
|
heading?: ReactNode;
|
|
subtitle?: ReactNode;
|
|
children: ReactNode;
|
|
CTA?: ReactNode;
|
|
large?: boolean;
|
|
HeadingLeftIcon?: ReactNode;
|
|
backPath?: string; // renders back button to specified path
|
|
// use when content needs to expand with flex
|
|
flexChildrenContainer?: boolean;
|
|
isPublic?: boolean;
|
|
customLoader?: ReactNode;
|
|
};
|
|
|
|
export default function Shell(props: LayoutProps) {
|
|
const router = useRouter();
|
|
const { loading, session } = useRedirectToLoginIfUnauthenticated(props.isPublic);
|
|
const { isRedirectingToOnboarding } = useRedirectToOnboardingIfNeeded();
|
|
const telemetry = useTelemetry();
|
|
|
|
useEffect(() => {
|
|
telemetry.withJitsu((jitsu) => {
|
|
return jitsu.track(telemetryEventTypes.pageView, collectPageParameters(router.asPath));
|
|
});
|
|
}, [telemetry, router.asPath]);
|
|
|
|
const query = useMeQuery();
|
|
const user = query.data;
|
|
|
|
const i18n = useViewerI18n();
|
|
const { status } = useSession();
|
|
|
|
const isLoading =
|
|
i18n.status === "loading" || query.status === "loading" || isRedirectingToOnboarding || loading;
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="absolute z-50 flex h-screen w-full items-center bg-gray-50">
|
|
<Loader />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (!session && !props.isPublic) return null;
|
|
|
|
return (
|
|
<>
|
|
<CustomBranding lightVal={user?.brandColor} darkVal={user?.darkBrandColor} />
|
|
<MemoizedLayout plan={user?.plan} status={status} {...props} isLoading={isLoading} />
|
|
</>
|
|
);
|
|
}
|
|
|
|
function UserDropdown({ small }: { small?: boolean }) {
|
|
const { t } = useLocale();
|
|
const query = useMeQuery();
|
|
const user = query.data;
|
|
const mutation = trpc.useMutation("viewer.away", {
|
|
onSettled() {
|
|
utils.invalidateQueries("viewer.me");
|
|
},
|
|
});
|
|
const utils = trpc.useContext();
|
|
const [helpOpen, setHelpOpen] = useState(false);
|
|
|
|
return (
|
|
<Dropdown onOpenChange={() => setHelpOpen(false)}>
|
|
<DropdownMenuTrigger asChild>
|
|
<button className="group flex w-full cursor-pointer appearance-none items-center text-left">
|
|
<span
|
|
className={classNames(
|
|
small ? "h-8 w-8" : "h-10 w-10",
|
|
"relative flex-shrink-0 rounded-full bg-gray-300 ltr:mr-3 rtl:ml-3"
|
|
)}>
|
|
{
|
|
// eslint-disable-next-line @next/next/no-img-element
|
|
<img
|
|
className="rounded-full"
|
|
src={WEBAPP_URL + "/" + user?.username + "/avatar.png"}
|
|
alt={user?.username || "Nameless User"}
|
|
/>
|
|
}
|
|
{!user?.away && (
|
|
<div className="absolute bottom-0 right-0 h-3 w-3 rounded-full border-2 border-white bg-green-500"></div>
|
|
)}
|
|
{user?.away && (
|
|
<div className="absolute bottom-0 right-0 h-3 w-3 rounded-full border-2 border-white bg-yellow-500"></div>
|
|
)}
|
|
</span>
|
|
{!small && (
|
|
<span className="flex flex-grow items-center truncate">
|
|
<span className="flex-grow truncate text-sm">
|
|
<span className="block truncate font-medium text-gray-900">
|
|
{user?.username || "Nameless User"}
|
|
</span>
|
|
<span className="block truncate font-normal text-neutral-500">
|
|
{user?.username ? `cal.com/${user.username}` : "No public page"}
|
|
</span>
|
|
</span>
|
|
<SelectorIcon
|
|
className="h-5 w-5 flex-shrink-0 text-gray-400 group-hover:text-gray-500"
|
|
aria-hidden="true"
|
|
/>
|
|
</span>
|
|
)}
|
|
</button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent portalled={true}>
|
|
{helpOpen ? (
|
|
<HelpMenuItem />
|
|
) : (
|
|
<>
|
|
<DropdownMenuItem>
|
|
<a
|
|
onClick={() => {
|
|
mutation.mutate({ away: !user?.away });
|
|
utils.invalidateQueries("viewer.me");
|
|
}}
|
|
className="flex min-w-max cursor-pointer px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900">
|
|
<MoonIcon
|
|
className={classNames(
|
|
user?.away
|
|
? "text-purple-500 group-hover:text-purple-700"
|
|
: "text-gray-500 group-hover:text-gray-700",
|
|
"h-5 w-5 flex-shrink-0 ltr:mr-3 rtl:ml-3"
|
|
)}
|
|
aria-hidden="true"
|
|
/>
|
|
{user?.away ? t("set_as_free") : t("set_as_away")}
|
|
</a>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuSeparator className="h-px bg-gray-200" />
|
|
{user?.username && (
|
|
<DropdownMenuItem>
|
|
<a
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
href={`${process.env.NEXT_PUBLIC_WEBSITE_URL}/${user.username}`}
|
|
className="flex items-center px-4 py-2 text-sm text-gray-700">
|
|
<ExternalLinkIcon className="h-5 w-5 text-gray-500 ltr:mr-3 rtl:ml-3" />{" "}
|
|
{t("view_public_page")}
|
|
</a>
|
|
</DropdownMenuItem>
|
|
)}
|
|
<DropdownMenuSeparator className="h-px bg-gray-200" />
|
|
<DropdownMenuItem>
|
|
<a
|
|
href="https://cal.com/slack"
|
|
target="_blank"
|
|
rel="noreferrer"
|
|
className="flex px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900">
|
|
<svg
|
|
viewBox="0 0 2447.6 2452.5"
|
|
className={classNames(
|
|
"text-gray-500 group-hover:text-gray-700",
|
|
"mt-0.5 h-4 w-4 flex-shrink-0 ltr:mr-4 rtl:ml-4"
|
|
)}
|
|
xmlns="http://www.w3.org/2000/svg">
|
|
<g clipRule="evenodd" fillRule="evenodd">
|
|
<path
|
|
d="m897.4 0c-135.3.1-244.8 109.9-244.7 245.2-.1 135.3 109.5 245.1 244.8 245.2h244.8v-245.1c.1-135.3-109.5-245.1-244.9-245.3.1 0 .1 0 0 0m0 654h-652.6c-135.3.1-244.9 109.9-244.8 245.2-.2 135.3 109.4 245.1 244.7 245.3h652.7c135.3-.1 244.9-109.9 244.8-245.2.1-135.4-109.5-245.2-244.8-245.3z"
|
|
fill="currentColor"></path>
|
|
<path
|
|
d="m2447.6 899.2c.1-135.3-109.5-245.1-244.8-245.2-135.3.1-244.9 109.9-244.8 245.2v245.3h244.8c135.3-.1 244.9-109.9 244.8-245.3zm-652.7 0v-654c.1-135.2-109.4-245-244.7-245.2-135.3.1-244.9 109.9-244.8 245.2v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.3z"
|
|
fill="currentColor"></path>
|
|
<path
|
|
d="m1550.1 2452.5c135.3-.1 244.9-109.9 244.8-245.2.1-135.3-109.5-245.1-244.8-245.2h-244.8v245.2c-.1 135.2 109.5 245 244.8 245.2zm0-654.1h652.7c135.3-.1 244.9-109.9 244.8-245.2.2-135.3-109.4-245.1-244.7-245.3h-652.7c-135.3.1-244.9 109.9-244.8 245.2-.1 135.4 109.4 245.2 244.7 245.3z"
|
|
fill="currentColor"></path>
|
|
<path
|
|
d="m0 1553.2c-.1 135.3 109.5 245.1 244.8 245.2 135.3-.1 244.9-109.9 244.8-245.2v-245.2h-244.8c-135.3.1-244.9 109.9-244.8 245.2zm652.7 0v654c-.2 135.3 109.4 245.1 244.7 245.3 135.3-.1 244.9-109.9 244.8-245.2v-653.9c.2-135.3-109.4-245.1-244.7-245.3-135.4 0-244.9 109.8-244.8 245.1 0 0 0 .1 0 0"
|
|
fill="currentColor"></path>
|
|
</g>
|
|
</svg>
|
|
{t("join_our_slack")}
|
|
</a>
|
|
</DropdownMenuItem>
|
|
<DropdownMenuItem>
|
|
<a
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
href="https://cal.com/roadmap"
|
|
className="flex items-center px-4 py-2 text-sm text-gray-700">
|
|
<MapIcon className="h-5 w-5 text-gray-500 ltr:mr-3 rtl:ml-3" /> {t("visit_roadmap")}
|
|
</a>
|
|
</DropdownMenuItem>
|
|
|
|
<button
|
|
className="flex w-full px-4 py-2 text-sm font-medium text-neutral-700 hover:bg-gray-100 hover:text-gray-900"
|
|
onClick={() => setHelpOpen(true)}>
|
|
<QuestionMarkCircleIcon
|
|
className={classNames(
|
|
"text-gray-500 group-hover:text-neutral-500",
|
|
"h-5 w-5 flex-shrink-0 ltr:mr-3"
|
|
)}
|
|
aria-hidden="true"
|
|
/>
|
|
|
|
{t("help")}
|
|
</button>
|
|
|
|
<DropdownMenuSeparator className="h-px bg-gray-200" />
|
|
<DropdownMenuItem>
|
|
<a
|
|
onClick={() => signOut({ callbackUrl: "/auth/logout" })}
|
|
className="flex cursor-pointer px-4 py-2 text-sm hover:bg-gray-100 hover:text-gray-900">
|
|
<LogoutIcon
|
|
className={classNames(
|
|
"text-gray-500 group-hover:text-gray-700",
|
|
"h-5 w-5 flex-shrink-0 ltr:mr-3 rtl:ml-3"
|
|
)}
|
|
aria-hidden="true"
|
|
/>
|
|
{t("sign_out")}
|
|
</a>
|
|
</DropdownMenuItem>
|
|
</>
|
|
)}
|
|
</DropdownMenuContent>
|
|
</Dropdown>
|
|
);
|
|
}
|