From f536d1040c2544fbfbdca3be0d27e499db81148a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Omar=20L=C3=B3pez?= Date: Wed, 23 Mar 2022 15:00:30 -0700 Subject: [PATCH] App Store (#1869) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * patch applied * patch applied * We shouldn't pollute global css * Build fixes * Updates typings * WIP extracting zoom to package * Revert "Upgrades next to 12.1 (#1895)" (#1903) This reverts commit ede0e98e1f7d462fe7196c6ce0de29490c00331e. * Tweak/gitignore prisma zod (#1905) * Extracts ignored createEventTypeBaseInput * Adds postinstall script * Revert "Tweak/gitignore prisma zod (#1905)" (#1906) This reverts commit 15bfeb30d7ce22a44f6dce9a74803a97ef43e2e6. * Eslint fixes (#1898) * Eslint fixes * Docs build fixes * Upgrade to next 12.1 (#1904) * Upgrades next to 12.1 * Fixes build * Updaters e2e test pipelines Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> * Fix URL by removing slash and backslash (#1733) * Fix URl by removing slash and backslash * Implement slugify * Add data type * Fixing folder structure * Solve zod-utils conflict * Build fixes (#1929) * Build fixes * Fixes type error * WIP * Conflict fixes * Removes unused file * TODO * WIP * Type fixes * Linting * WIP * Moved App definition to types * WIP * WIP * WIP * WIP WIP * Renamed zoomvideo app * Import fix * Daily.co app (#2022) * Daily.co app * Update packages/app-store/dailyvideo/lib/VideoApiAdapter.ts Co-authored-by: Omar López * Update packages/app-store/dailyvideo/lib/VideoApiAdapter.ts Co-authored-by: Omar López * Missing deps for newly added contants to lib Co-authored-by: Omar López * WIP * WIP * WIP * Daily fixes * Updated type info * Slack Oauth integration - api route ideas * Adds getLocationOptions * Type fixes * Adds location option for daily video * Revert "Slack Oauth integration - api route ideas" This reverts commit 35ffa78e929339c4badb98cdab4e4b953ecc7cca. * Slack Oauth + verify sig * Revert "Slack Oauth + verify sig" This reverts commit ee95795e0f0ae6d06be4e0a423afb8c315d9af7d. * Huddle01 migration to app store (#2038) * Jitsi Video App migration * Removing uneeded dependencies * Missed unused reference * Missing dependency `@calcom/lib` is needed in the `locationOption.ts` file * Huddle01 migration to app store * Jitsi Video App migration (#2027) * Jitsi Video App migration * Removing uneeded dependencies * Missed unused reference * Missing dependency `@calcom/lib` is needed in the `locationOption.ts` file Co-authored-by: Omar López * Monorepo/app store MS Teams Integration (#2080) * Create teamsvideo package * Remove zoom specific refrences * Add teams video files * Rename to office365_video * Add call back to add crednetial type office365_teams * Rename to office_video to match type * Add MS Teams as a location option * Rename files * Add teams reponse interface and create meeting * Comment out Daily imports * Add check for Teams integration * Add token checking functions * Change template to create event rather than meeting * Add comment to test between create link and event * Add teams URL to booking * Ask for just onlineMeeting permission * Add MS Teams logo * Add message to have an enterprise account * Remove comments * Comment back hasDailyIntegration * Comment back daily credentials * Update link to MS Graph section of README * Move API calls to package Co-authored-by: Omar López * Re-adds missing module for transpiling * Adds email as required field for app store metadata * WIP: migrates tandem to app store * Cleanup * Migrates tandem api routes to app store * Fixes tandem api handlers * Big WIP WIP * Build fixes * WIP * Fixes annoying circular dependency bug I've spent a whole day on this.... * Location option cleanup * Type fixes * Update EventManager.ts * Update CalendarManager.ts * Moves CalendarService back to lib * Moves apple calendar to App Store * Cleanup * More cleanup * Migrates apple calendar * Returns all connected calendars credentials * No tsx needed in calcom/lib * Update auth.ts * Reordering * Update i18n.utils.ts * WIP: Google Meet * Type fixes * Type fixes * Cleanup * Update LinkIconButton.tsx * Update TrialBanner.tsx * Cleanup * Cleanup * Type fixes * Update _appRegistry.ts * Update fonts.css * Update CalEventParser.ts * Delete yarn.lock.rej * Update eslint-preset.js * Delete zoom.tsx * Type fixes * Migrates caldav to app store * Cleanup * Type fixes * Adds caldav to app store * Test fixes * Updates integration tests * Moar test fixes * Redirection fixes * Redirection fixes * Update timeFormat.ts * Update booking-pages.test.ts * Connect button fixes * Fix empty item * Cal fixes andrea (#2234) * Fixes #2178 * Fixes #2178 * Update apps/web/components/availability/Schedule.tsx * Update apps/web/components/availability/Schedule.tsx Co-authored-by: Peer Richelsen Co-authored-by: Peer Richelsen * added meta viewport to disable zoom on input focus on mobile (#2238) * Update lint.yml (#2211) Co-authored-by: Peer Richelsen * Fix prisma client bundle makes app slow (#2237) Co-authored-by: Omar López * Slider fixes * Removed unused code * Full Shell when unauthed * App sidebar responsive fixes * Adds dynamic install button * Fix for duplicate connected calendars * Various fixes * Display notification on app delete * Reuse connect button * Adds CalDav button * Deprecates ConnectIntegration * Simplify install button * Adds Google Calendar connect button * Adds Office 365 Install button * Migrates Stripe to App Store * Zoom Install Button (#2244) * Fix minor css, app image load from static path * Fix app logos remote img src (#2252) * Adds missing exports * Cleanup * Disables install button for globally enabled apps * Update EventManager.ts * Stripe fixes * Disables example app Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: Juan Esteban Nieto Cifuentes <89233604+Jenietoc@users.noreply.github.com> Co-authored-by: Leo Giovanetti Co-authored-by: Sean Brydon Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com> Co-authored-by: Peer Richelsen Co-authored-by: Bailey Pumfleet Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com> Co-authored-by: andreaestefania12 Co-authored-by: Peer Richelsen Co-authored-by: Demian Caldelas Co-authored-by: Alan --- apps/web/components/App.tsx | 231 ++ apps/web/components/AppsShell.tsx | 30 + .../DestinationCalendarSelector.tsx | 2 +- apps/web/components/Shell.tsx | 286 ++- apps/web/components/apps/AllApps.tsx | 28 + apps/web/components/apps/AppCard.tsx | 41 + apps/web/components/apps/Categories.tsx | 28 + apps/web/components/apps/Slider.tsx | 88 + .../components/booking/pages/BookingPage.tsx | 2 + .../integrations/CalendarListContainer.tsx | 24 +- .../integrations/ConnectIntegrations.tsx | 64 - .../integrations/DisconnectIntegration.tsx | 5 +- .../integrations/IntegrationListItem.tsx | 5 +- apps/web/components/ui/form/DatePicker.tsx | 2 +- .../webhook/WebhookListContainer.tsx | 2 +- .../availability/TeamAvailabilityModal.tsx | 2 +- .../availability/TeamAvailabilityScreen.tsx | 4 +- apps/web/ee/components/web3/CryptoSection.tsx | 6 +- apps/web/ee/lib/stripe/server.ts | 2 +- .../api/integrations/stripepayment/webhook.ts | 11 +- apps/web/lib/config/constants.ts | 8 +- apps/web/lib/emails/email-manager.ts | 3 +- .../templates/attendee-rescheduled-email.ts | 2 +- .../templates/attendee-scheduled-email.ts | 8 +- .../templates/organizer-rescheduled-email.ts | 2 +- .../templates/organizer-scheduled-email.ts | 8 +- apps/web/lib/hooks/useMediaQuery.ts | 19 + apps/web/lib/integrations.ts | 34 - .../calendar/constants/formats.ts | 1 - .../calendar/constants/generals.ts | 10 - .../integrations/calendar/constants/types.ts | 57 - .../calendar/interfaces/GoogleCalendar.ts | 5 - .../calendar/services/AppleCalendarService.ts | 10 - .../services/CalDavCalendarService.ts | 10 - .../calendar/utils/CalendarUtils.ts | 16 - apps/web/lib/integrations/getIntegrations.ts | 164 -- apps/web/lib/queries/availability/index.ts | 6 +- apps/web/lib/random.ts | 11 +- apps/web/lib/timeFormat.ts | 2 +- apps/web/lib/webhooks/sendPayload.tsx | 2 +- apps/web/next.config.js | 2 + apps/web/package.json | 7 +- apps/web/pages/_error.tsx | 2 +- apps/web/pages/api/auth/[...nextauth].tsx | 3 +- .../pages/api/auth/two-factor/totp/enable.ts | 3 +- .../pages/api/auth/two-factor/totp/setup.ts | 3 +- apps/web/pages/api/availability/[user].ts | 5 +- apps/web/pages/api/availability/calendar.ts | 5 +- apps/web/pages/api/book/confirm.ts | 7 +- apps/web/pages/api/book/event.ts | 22 +- apps/web/pages/api/cancel.ts | 13 +- apps/web/pages/api/cron/bookingReminder.ts | 3 +- apps/web/pages/api/integrations/[...args].ts | 46 + .../api/integrations/stripepayment/add.ts | 1 - .../integrations/stripepayment/callback.ts | 1 - .../api/integrations/stripepayment/portal.ts | 1 - apps/web/pages/api/integrations/types.d.ts | 3 - apps/web/pages/api/integrations/utils.ts | 21 - apps/web/pages/apps/[slug].tsx | 68 + apps/web/pages/apps/categories/[category].tsx | 70 + apps/web/pages/apps/index.tsx | 40 + .../index.tsx => apps/installed.tsx} | 50 +- apps/web/pages/apps/nuke-my-cal.tsx | 118 + apps/web/pages/event-types/[type].tsx | 118 +- apps/web/pages/getting-started.tsx | 7 +- apps/web/pages/integrations/[integration].tsx | 9 - apps/web/playwright/booking-pages.test.ts | 25 +- .../playwright/integrations-stripe.test.ts | 13 +- apps/web/playwright/integrations.test.ts | 2 +- .../{integrations => apps}/apple-calendar.svg | 0 .../public/{integrations => apps}/caldav.svg | 0 .../public/{integrations => apps}/daily.svg | 0 .../public/{integrations => apps}/embed.svg | 0 .../google-calendar.svg | 0 .../public/{integrations => apps}/huddle.svg | 0 .../public/{integrations => apps}/jitsi.svg | 0 .../{integrations => apps}/metamask.svg | 0 .../microsoft-teams.svg | 0 apps/web/public/apps/msteams.svg | 22 + apps/web/public/apps/nuke-my-cal.svg | 77 + .../public/{integrations => apps}/outlook.svg | 0 .../public/{integrations => apps}/stripe.svg | 0 .../public/{integrations => apps}/tandem.svg | 0 .../public/{integrations => apps}/web3.svg | 0 .../{integrations => apps}/webhooks.svg | 0 .../public/{integrations => apps}/zapier.svg | 0 .../public/{integrations => apps}/zoom.svg | 0 .../web/public/integrations/go-to-meeting.svg | 18 - apps/web/public/static/locales/en/common.json | 22 + apps/web/server/createContext.ts | 1 + apps/web/server/routers/viewer.tsx | 22 +- apps/web/tsconfig.json | 10 +- apps/web/yarn.lock | 1897 ++++++++--------- apps/website | 2 +- package.json | 3 +- packages/app-store/_appRegistry.ts | 12 + packages/app-store/_example/api/example.ts | 10 + packages/app-store/_example/api/index.ts | 1 + .../_example/components/InstallAppButton.tsx | 13 + .../app-store/_example/components/index.ts | 1 + packages/app-store/_example/index.ts | 28 + .../app-store/_example/lib/VideoApiAdapter.ts | 36 + packages/app-store/_example/lib/index.ts | 1 + packages/app-store/_example/package.json | 14 + packages/app-store/_example/static/icon.svg | 6 + packages/app-store/_utils/decodeOAuthState.ts | 12 + packages/app-store/_utils/encodeOAuthState.ts | 12 + packages/app-store/_utils/getCalendar.ts | 20 + .../app-store/_utils/useAddAppMutation.ts | 26 + .../app-store/applecalendar/api}/add.ts | 22 +- packages/app-store/applecalendar/api/index.ts | 1 + .../components/AddIntegration.tsx | 12 +- .../components/InstallAppButton.tsx | 20 + .../applecalendar/components/index.ts | 2 + packages/app-store/applecalendar/index.ts | 29 + .../applecalendar/lib/CalendarService.ts | 9 + packages/app-store/applecalendar/lib/index.ts | 1 + packages/app-store/applecalendar/package.json | 15 + .../app-store/caldavcalendar/api}/add.ts | 22 +- .../app-store/caldavcalendar/api/index.ts | 1 + .../components/AddIntegration.tsx | 84 +- .../components/InstallAppButton.tsx | 20 + .../caldavcalendar/components/index.ts | 2 + packages/app-store/caldavcalendar/index.ts | 28 + .../caldavcalendar/lib/CalendarService.ts | 9 + .../app-store/caldavcalendar/lib/index.ts | 1 + .../app-store/caldavcalendar/package.json | 18 + packages/app-store/components.tsx | 48 + packages/app-store/dailyvideo/index.ts | 29 + .../dailyvideo/lib/VideoApiAdapter.ts | 16 +- packages/app-store/dailyvideo/lib/index.ts | 1 + packages/app-store/dailyvideo/package.json | 14 + packages/app-store/dailyvideo/static/icon.svg | 6 + .../app-store/googlecalendar/api}/add.ts | 13 +- .../app-store/googlecalendar/api}/callback.ts | 18 +- .../app-store/googlecalendar/api/index.ts | 2 + .../components/InstallAppButton.tsx | 18 + .../googlecalendar/components/index.ts | 1 + packages/app-store/googlecalendar/index.ts | 28 + .../googlecalendar/lib/CalendarService.ts | 21 +- .../app-store/googlecalendar/lib/index.ts | 1 + .../app-store/googlecalendar/package.json | 15 + .../app-store/googlecalendar/static/icon.svg | 6 + packages/app-store/googlevideo/index.ts | 29 + packages/app-store/googlevideo/package.json | 15 + .../app-store/googlevideo/static/icon.svg | 6 + packages/app-store/huddle01video/index.ts | 30 + .../huddle01video/lib/VideoApiAdapter.ts | 16 +- packages/app-store/huddle01video/lib/index.ts | 1 + packages/app-store/huddle01video/package.json | 13 + packages/app-store/index.ts | 31 + packages/app-store/jitsivideo/index.ts | 28 + .../jitsivideo/lib/VideoApiAdapter.ts | 13 +- packages/app-store/jitsivideo/lib/index.ts | 1 + packages/app-store/jitsivideo/package.json | 13 + packages/app-store/jitsivideo/static/icon.svg | 38 + .../app-store}/next-auth.d.ts | 0 packages/app-store/next.d.ts | 10 + .../app-store/office365calendar/api}/add.ts | 13 +- .../office365calendar/api}/callback.ts | 19 +- .../app-store/office365calendar/api/index.ts | 2 + .../components/InstallAppButton.tsx | 18 + .../office365calendar/components/index.ts | 1 + packages/app-store/office365calendar/index.ts | 27 + .../office365calendar/lib/CalendarService.ts | 23 +- .../app-store/office365calendar/lib/index.ts | 1 + .../app-store/office365calendar/package.json | 15 + .../office365calendar/static/icon.svg | 6 + .../types}/Office365Calendar.ts | 5 - .../app-store/office365video/.env.example | 4 + packages/app-store/office365video/api/add.ts | 25 + .../app-store/office365video/api/callback.ts | 67 + .../app-store/office365video/api/index.ts | 2 + packages/app-store/office365video/index.ts | 28 + .../office365video/lib/VideoApiAdapter.ts | 142 ++ .../app-store/office365video/lib/index.ts | 1 + .../app-store/office365video/package.json | 14 + packages/app-store/package.json | 18 + packages/app-store/stripepayment/LICENSE | 42 + packages/app-store/stripepayment/README.md | 27 + .../app-store/stripepayment/api}/add.ts | 15 +- .../app-store/stripepayment/api}/callback.ts | 17 +- packages/app-store/stripepayment/api/index.ts | 5 + .../app-store/stripepayment/api}/portal.ts | 12 +- .../components/InstallAppButton.tsx | 18 + .../stripepayment/components/index.ts | 1 + packages/app-store/stripepayment/index.ts | 31 + packages/app-store/stripepayment/package.json | 15 + .../app-store/stripepayment/static/icon.svg | 6 + .../app-store/tandemvideo/api}/add.ts | 15 +- .../app-store/tandemvideo/api}/callback.ts | 15 +- packages/app-store/tandemvideo/api/index.ts | 2 + .../components/InstallAppButton.tsx | 18 + .../app-store/tandemvideo/components/index.ts | 1 + packages/app-store/tandemvideo/index.ts | 29 + .../tandemvideo/lib/VideoApiAdapter.ts | 10 +- packages/app-store/tandemvideo/lib/index.ts | 1 + packages/app-store/tandemvideo/package.json | 14 + .../app-store/tandemvideo/static/icon.svg | 6 + packages/app-store/tsconfig.json | 8 + packages/app-store/types.d.ts | 8 + packages/app-store/utils.ts | 122 ++ packages/app-store/zoomvideo/.env.example | 4 + .../app-store/zoomvideo/api}/add.ts | 15 +- .../app-store/zoomvideo/api}/callback.ts | 18 +- packages/app-store/zoomvideo/api/index.ts | 2 + .../zoomvideo/components/InstallAppButton.tsx | 18 + .../app-store/zoomvideo/components/index.ts | 1 + packages/app-store/zoomvideo/index.ts | 28 + .../zoomvideo/lib/VideoApiAdapter.ts | 10 +- packages/app-store/zoomvideo/lib/index.ts | 1 + packages/app-store/zoomvideo/package.json | 14 + packages/app-store/zoomvideo/static/icon.svg | 38 + packages/config/eslint-preset.js | 1 + .../core}/CalendarManager.ts | 63 +- .../events => packages/core}/EventManager.ts | 81 +- packages/core/index.ts | 3 + packages/core/package.json | 23 + packages/core/tsconfig.json | 8 + .../web/lib => packages/core}/videoClient.ts | 61 +- {apps/web => packages}/lib/CalEventParser.ts | 7 +- .../lib/CalendarService.ts | 45 +- {apps/web => packages}/lib/crypto.ts | 0 {apps/web => packages}/lib/jsonUtils.ts | 0 packages/lib/location.ts | 2 + {apps/web => packages}/lib/logger.ts | 2 +- {apps/web => packages}/lib/notEmpty.ts | 0 packages/lib/package.json | 7 +- packages/lib/random.ts | 9 + packages/lib/server/i18n.ts | 18 + packages/types/App.d.ts | 65 + packages/types/BufferedBusyTime.d.ts | 4 + .../types/Calendar.d.ts | 93 +- packages/types/Event.d.ts | 4 + packages/types/EventManager.d.ts | 30 + packages/types/VideoApiAdapter.d.ts | 22 + {apps/web/@types => packages/types}/ical.d.ts | 18 +- packages/types/next-auth.d.ts | 15 + packages/types/next.d.ts | 10 + packages/types/tsconfig.json | 5 + .../utils.ts => packages/types/utils.d.ts | 0 yarn.lock | 16 +- 242 files changed, 4322 insertions(+), 2260 deletions(-) create mode 100644 apps/web/components/App.tsx create mode 100644 apps/web/components/AppsShell.tsx create mode 100644 apps/web/components/apps/AllApps.tsx create mode 100644 apps/web/components/apps/AppCard.tsx create mode 100644 apps/web/components/apps/Categories.tsx create mode 100644 apps/web/components/apps/Slider.tsx delete mode 100644 apps/web/components/integrations/ConnectIntegrations.tsx create mode 100644 apps/web/lib/hooks/useMediaQuery.ts delete mode 100644 apps/web/lib/integrations.ts delete mode 100644 apps/web/lib/integrations/calendar/constants/formats.ts delete mode 100644 apps/web/lib/integrations/calendar/constants/generals.ts delete mode 100644 apps/web/lib/integrations/calendar/constants/types.ts delete mode 100644 apps/web/lib/integrations/calendar/interfaces/GoogleCalendar.ts delete mode 100644 apps/web/lib/integrations/calendar/services/AppleCalendarService.ts delete mode 100644 apps/web/lib/integrations/calendar/services/CalDavCalendarService.ts delete mode 100644 apps/web/lib/integrations/calendar/utils/CalendarUtils.ts delete mode 100644 apps/web/lib/integrations/getIntegrations.ts create mode 100644 apps/web/pages/api/integrations/[...args].ts delete mode 100644 apps/web/pages/api/integrations/stripepayment/add.ts delete mode 100644 apps/web/pages/api/integrations/stripepayment/callback.ts delete mode 100644 apps/web/pages/api/integrations/stripepayment/portal.ts delete mode 100644 apps/web/pages/api/integrations/types.d.ts delete mode 100644 apps/web/pages/api/integrations/utils.ts create mode 100644 apps/web/pages/apps/[slug].tsx create mode 100644 apps/web/pages/apps/categories/[category].tsx create mode 100644 apps/web/pages/apps/index.tsx rename apps/web/pages/{integrations/index.tsx => apps/installed.tsx} (86%) create mode 100644 apps/web/pages/apps/nuke-my-cal.tsx delete mode 100644 apps/web/pages/integrations/[integration].tsx rename apps/web/public/{integrations => apps}/apple-calendar.svg (100%) rename apps/web/public/{integrations => apps}/caldav.svg (100%) rename apps/web/public/{integrations => apps}/daily.svg (100%) rename apps/web/public/{integrations => apps}/embed.svg (100%) rename apps/web/public/{integrations => apps}/google-calendar.svg (100%) rename apps/web/public/{integrations => apps}/huddle.svg (100%) rename apps/web/public/{integrations => apps}/jitsi.svg (100%) rename apps/web/public/{integrations => apps}/metamask.svg (100%) rename apps/web/public/{integrations => apps}/microsoft-teams.svg (100%) create mode 100644 apps/web/public/apps/msteams.svg create mode 100644 apps/web/public/apps/nuke-my-cal.svg rename apps/web/public/{integrations => apps}/outlook.svg (100%) rename apps/web/public/{integrations => apps}/stripe.svg (100%) rename apps/web/public/{integrations => apps}/tandem.svg (100%) rename apps/web/public/{integrations => apps}/web3.svg (100%) rename apps/web/public/{integrations => apps}/webhooks.svg (100%) rename apps/web/public/{integrations => apps}/zapier.svg (100%) rename apps/web/public/{integrations => apps}/zoom.svg (100%) delete mode 100644 apps/web/public/integrations/go-to-meeting.svg create mode 100644 packages/app-store/_appRegistry.ts create mode 100644 packages/app-store/_example/api/example.ts create mode 100644 packages/app-store/_example/api/index.ts create mode 100644 packages/app-store/_example/components/InstallAppButton.tsx create mode 100644 packages/app-store/_example/components/index.ts create mode 100644 packages/app-store/_example/index.ts create mode 100644 packages/app-store/_example/lib/VideoApiAdapter.ts create mode 100644 packages/app-store/_example/lib/index.ts create mode 100644 packages/app-store/_example/package.json create mode 100644 packages/app-store/_example/static/icon.svg create mode 100644 packages/app-store/_utils/decodeOAuthState.ts create mode 100644 packages/app-store/_utils/encodeOAuthState.ts create mode 100644 packages/app-store/_utils/getCalendar.ts create mode 100644 packages/app-store/_utils/useAddAppMutation.ts rename {apps/web/pages/api/integrations/apple => packages/app-store/applecalendar/api}/add.ts (65%) create mode 100644 packages/app-store/applecalendar/api/index.ts rename apps/web/lib/integrations/calendar/components/AddAppleIntegration.tsx => packages/app-store/applecalendar/components/AddIntegration.tsx (89%) create mode 100644 packages/app-store/applecalendar/components/InstallAppButton.tsx create mode 100644 packages/app-store/applecalendar/components/index.ts create mode 100644 packages/app-store/applecalendar/index.ts create mode 100644 packages/app-store/applecalendar/lib/CalendarService.ts create mode 100644 packages/app-store/applecalendar/lib/index.ts create mode 100644 packages/app-store/applecalendar/package.json rename {apps/web/pages/api/integrations/caldav => packages/app-store/caldavcalendar/api}/add.ts (65%) create mode 100644 packages/app-store/caldavcalendar/api/index.ts rename apps/web/lib/integrations/calendar/components/AddCalDavIntegration.tsx => packages/app-store/caldavcalendar/components/AddIntegration.tsx (52%) create mode 100644 packages/app-store/caldavcalendar/components/InstallAppButton.tsx create mode 100644 packages/app-store/caldavcalendar/components/index.ts create mode 100644 packages/app-store/caldavcalendar/index.ts create mode 100644 packages/app-store/caldavcalendar/lib/CalendarService.ts create mode 100644 packages/app-store/caldavcalendar/lib/index.ts create mode 100644 packages/app-store/caldavcalendar/package.json create mode 100644 packages/app-store/components.tsx create mode 100644 packages/app-store/dailyvideo/index.ts rename apps/web/lib/integrations/Daily/DailyVideoApiAdapter.ts => packages/app-store/dailyvideo/lib/VideoApiAdapter.ts (88%) create mode 100644 packages/app-store/dailyvideo/lib/index.ts create mode 100644 packages/app-store/dailyvideo/package.json create mode 100644 packages/app-store/dailyvideo/static/icon.svg rename {apps/web/pages/api/integrations/googlecalendar => packages/app-store/googlecalendar/api}/add.ts (77%) rename {apps/web/pages/api/integrations/googlecalendar => packages/app-store/googlecalendar/api}/callback.ts (68%) create mode 100644 packages/app-store/googlecalendar/api/index.ts create mode 100644 packages/app-store/googlecalendar/components/InstallAppButton.tsx create mode 100644 packages/app-store/googlecalendar/components/index.ts create mode 100644 packages/app-store/googlecalendar/index.ts rename apps/web/lib/integrations/calendar/services/GoogleCalendarService.ts => packages/app-store/googlecalendar/lib/CalendarService.ts (95%) create mode 100644 packages/app-store/googlecalendar/lib/index.ts create mode 100644 packages/app-store/googlecalendar/package.json create mode 100644 packages/app-store/googlecalendar/static/icon.svg create mode 100644 packages/app-store/googlevideo/index.ts create mode 100644 packages/app-store/googlevideo/package.json create mode 100644 packages/app-store/googlevideo/static/icon.svg create mode 100644 packages/app-store/huddle01video/index.ts rename apps/web/lib/integrations/Huddle01/Huddle01VideoApiAdapter.ts => packages/app-store/huddle01video/lib/VideoApiAdapter.ts (72%) create mode 100644 packages/app-store/huddle01video/lib/index.ts create mode 100644 packages/app-store/huddle01video/package.json create mode 100644 packages/app-store/index.ts create mode 100644 packages/app-store/jitsivideo/index.ts rename apps/web/lib/integrations/Jitsi/JitsiVideoApiAdapter.ts => packages/app-store/jitsivideo/lib/VideoApiAdapter.ts (68%) create mode 100644 packages/app-store/jitsivideo/lib/index.ts create mode 100644 packages/app-store/jitsivideo/package.json create mode 100644 packages/app-store/jitsivideo/static/icon.svg rename {apps/web/types => packages/app-store}/next-auth.d.ts (100%) create mode 100644 packages/app-store/next.d.ts rename {apps/web/pages/api/integrations/office365calendar => packages/app-store/office365calendar/api}/add.ts (68%) rename {apps/web/pages/api/integrations/office365calendar => packages/app-store/office365calendar/api}/callback.ts (76%) create mode 100644 packages/app-store/office365calendar/api/index.ts create mode 100644 packages/app-store/office365calendar/components/InstallAppButton.tsx create mode 100644 packages/app-store/office365calendar/components/index.ts create mode 100644 packages/app-store/office365calendar/index.ts rename apps/web/lib/integrations/calendar/services/Office365CalendarService.ts => packages/app-store/office365calendar/lib/CalendarService.ts (93%) create mode 100644 packages/app-store/office365calendar/lib/index.ts create mode 100644 packages/app-store/office365calendar/package.json create mode 100644 packages/app-store/office365calendar/static/icon.svg rename {apps/web/lib/integrations/calendar/interfaces => packages/app-store/office365calendar/types}/Office365Calendar.ts (61%) create mode 100644 packages/app-store/office365video/.env.example create mode 100644 packages/app-store/office365video/api/add.ts create mode 100644 packages/app-store/office365video/api/callback.ts create mode 100644 packages/app-store/office365video/api/index.ts create mode 100644 packages/app-store/office365video/index.ts create mode 100644 packages/app-store/office365video/lib/VideoApiAdapter.ts create mode 100644 packages/app-store/office365video/lib/index.ts create mode 100644 packages/app-store/office365video/package.json create mode 100644 packages/app-store/package.json create mode 100644 packages/app-store/stripepayment/LICENSE create mode 100644 packages/app-store/stripepayment/README.md rename {apps/web/ee/pages/api/integrations/stripepayment => packages/app-store/stripepayment/api}/add.ts (75%) rename {apps/web/ee/pages/api/integrations/stripepayment => packages/app-store/stripepayment/api}/callback.ts (70%) create mode 100644 packages/app-store/stripepayment/api/index.ts rename {apps/web/ee/pages/api/integrations/stripepayment => packages/app-store/stripepayment/api}/portal.ts (66%) create mode 100644 packages/app-store/stripepayment/components/InstallAppButton.tsx create mode 100644 packages/app-store/stripepayment/components/index.ts create mode 100644 packages/app-store/stripepayment/index.ts create mode 100644 packages/app-store/stripepayment/package.json create mode 100644 packages/app-store/stripepayment/static/icon.svg rename {apps/web/pages/api/integrations/tandemvideo => packages/app-store/tandemvideo/api}/add.ts (67%) rename {apps/web/pages/api/integrations/tandemvideo => packages/app-store/tandemvideo/api}/callback.ts (77%) create mode 100644 packages/app-store/tandemvideo/api/index.ts create mode 100644 packages/app-store/tandemvideo/components/InstallAppButton.tsx create mode 100644 packages/app-store/tandemvideo/components/index.ts create mode 100644 packages/app-store/tandemvideo/index.ts rename apps/web/lib/integrations/Tandem/TandemVideoApiAdapter.ts => packages/app-store/tandemvideo/lib/VideoApiAdapter.ts (94%) create mode 100644 packages/app-store/tandemvideo/lib/index.ts create mode 100644 packages/app-store/tandemvideo/package.json create mode 100644 packages/app-store/tandemvideo/static/icon.svg create mode 100644 packages/app-store/tsconfig.json create mode 100644 packages/app-store/types.d.ts create mode 100644 packages/app-store/utils.ts create mode 100644 packages/app-store/zoomvideo/.env.example rename {apps/web/pages/api/integrations/zoomvideo => packages/app-store/zoomvideo/api}/add.ts (65%) rename {apps/web/pages/api/integrations/zoomvideo => packages/app-store/zoomvideo/api}/callback.ts (72%) create mode 100644 packages/app-store/zoomvideo/api/index.ts create mode 100644 packages/app-store/zoomvideo/components/InstallAppButton.tsx create mode 100644 packages/app-store/zoomvideo/components/index.ts create mode 100644 packages/app-store/zoomvideo/index.ts rename apps/web/lib/integrations/Zoom/ZoomVideoApiAdapter.ts => packages/app-store/zoomvideo/lib/VideoApiAdapter.ts (96%) create mode 100644 packages/app-store/zoomvideo/lib/index.ts create mode 100644 packages/app-store/zoomvideo/package.json create mode 100644 packages/app-store/zoomvideo/static/icon.svg rename {apps/web/lib/integrations/calendar => packages/core}/CalendarManager.ts (65%) rename {apps/web/lib/events => packages/core}/EventManager.ts (83%) create mode 100644 packages/core/index.ts create mode 100644 packages/core/package.json create mode 100644 packages/core/tsconfig.json rename {apps/web/lib => packages/core}/videoClient.ts (61%) rename {apps/web => packages}/lib/CalEventParser.ts (91%) rename apps/web/lib/integrations/calendar/services/BaseCalendarService.ts => packages/lib/CalendarService.ts (90%) rename {apps/web => packages}/lib/crypto.ts (100%) rename {apps/web => packages}/lib/jsonUtils.ts (100%) rename {apps/web => packages}/lib/logger.ts (90%) rename {apps/web => packages}/lib/notEmpty.ts (100%) create mode 100644 packages/lib/random.ts create mode 100644 packages/lib/server/i18n.ts create mode 100644 packages/types/App.d.ts create mode 100644 packages/types/BufferedBusyTime.d.ts rename apps/web/lib/integrations/calendar/interfaces/Calendar.ts => packages/types/Calendar.d.ts (51%) create mode 100644 packages/types/Event.d.ts create mode 100644 packages/types/EventManager.d.ts create mode 100644 packages/types/VideoApiAdapter.d.ts rename {apps/web/@types => packages/types}/ical.d.ts (93%) create mode 100644 packages/types/next-auth.d.ts create mode 100644 packages/types/next.d.ts create mode 100644 packages/types/tsconfig.json rename apps/web/lib/types/utils.ts => packages/types/utils.d.ts (100%) diff --git a/apps/web/components/App.tsx b/apps/web/components/App.tsx new file mode 100644 index 0000000000..fbf678d0e8 --- /dev/null +++ b/apps/web/components/App.tsx @@ -0,0 +1,231 @@ +import { + BookOpenIcon, + DocumentTextIcon, + ExternalLinkIcon, + FlagIcon, + MailIcon, + ShieldCheckIcon, +} from "@heroicons/react/outline"; +import { ChevronLeftIcon } from "@heroicons/react/solid"; +import Link from "next/link"; +import React from "react"; + +import { InstallAppButton } from "@calcom/app-store/components"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; +import { App as AppType } from "@calcom/types/App"; +import { Button } from "@calcom/ui"; + +//import NavTabs from "@components/NavTabs"; +import Shell from "@components/Shell"; +import Badge from "@components/ui/Badge"; + +export default function App({ + name, + type, + logo, + body, + categories, + author, + price = 0, + commission, + isGlobal = false, + feeType, + docs, + website, + email, + tos, + privacy, +}: { + name: string; + type: AppType["type"]; + isGlobal?: AppType["isGlobal"]; + logo: string; + body: React.ReactNode; + categories: string[]; + author: string; + pro?: boolean; + price?: number; + commission?: number; + feeType?: AppType["feeType"]; + docs?: string; + website?: string; + email: string; // required + tos?: string; + privacy?: string; +}) { + const { t } = useLocale(); + + /*const tabs = [ + { + name: t("description"), + href: "?description", + }, + { + name: t("features"), + href: "?features", + }, + { + name: t("permissions"), + href: "?permissions", + }, + ];*/ + + const priceInDollar = Intl.NumberFormat("en-US", { + style: "currency", + currency: "USD", + useGrouping: false, + }).format(price); + + return ( + <> + +
+
+ + + {t("browse_apps")} + + +
+
+ +
+

{name}

+

+ {categories[0]} • {t("published_by", { author })} +

+
+
+ +
+ {isGlobal ? ( + + ) : ( + } + /> + )} + {price !== 0 && ( + + {feeType === "usage-based" + ? commission + "% + " + priceInDollar + "/booking" + : priceInDollar} + {feeType === "monthly" && "/" + t("month")} + + )} +
+
+ {/* reintroduce once we show permissions and features + */} +
+ +
+
{body}
+
+

{t("categories")}

+
+ {categories.map((category) => ( + + + {category} + + + ))} +
+

{t("pricing")}

+ + {price === 0 ? ( + "Free" + ) : ( + <> + {Intl.NumberFormat("en-US", { + style: "currency", + currency: "USD", + useGrouping: false, + }).format(price)} + {feeType === "monthly" && "/" + t("month")} + + )} + +

{t("learn_more")}

+ +
+ + Every app published on the Cal.com App Store is open source and thoroughly tested via peer + reviews. Nevertheless, Cal.com, Inc. does not endorse or certify these apps unless they are + published by Cal.com. If you encounter inappropriate content or behaviour please report it. + + + Report App + +
+
+
+
+ + ); +} diff --git a/apps/web/components/AppsShell.tsx b/apps/web/components/AppsShell.tsx new file mode 100644 index 0000000000..16817268e4 --- /dev/null +++ b/apps/web/components/AppsShell.tsx @@ -0,0 +1,30 @@ +import { useSession } from "next-auth/react"; +import React from "react"; + +import { useLocale } from "@lib/hooks/useLocale"; + +import NavTabs from "./NavTabs"; + +export default function AppsShell({ children }: { children: React.ReactNode }) { + const { t } = useLocale(); + const { status } = useSession(); + const tabs = [ + { + name: t("app_store"), + href: "/apps", + }, + { + name: t("installed_apps"), + href: "/apps/installed", + }, + ]; + + return ( + <> +
+ {status === "authenticated" && } +
+
{children}
+ + ); +} diff --git a/apps/web/components/DestinationCalendarSelector.tsx b/apps/web/components/DestinationCalendarSelector.tsx index f2462dd9d0..7d829bdbbb 100644 --- a/apps/web/components/DestinationCalendarSelector.tsx +++ b/apps/web/components/DestinationCalendarSelector.tsx @@ -67,7 +67,7 @@ const DestinationCalendarSelector = ({ placeholder={!hidePlaceholder ? `${t("select_destination_calendar")}:` : undefined} options={options} isSearchable={false} - className="focus:border-primary-500 focus:ring-primary-500 mt-1 mb-2 block w-full min-w-0 flex-1 rounded-none rounded-r-md border-gray-300 sm:text-sm" + className="focus:ring-primary-500 focus:border-primary-500 mt-1 mb-2 block w-full min-w-0 flex-1 rounded-none rounded-r-md border-gray-300 sm:text-sm" onChange={(option) => { setSelectedOption(option); if (!option) { diff --git a/apps/web/components/Shell.tsx b/apps/web/components/Shell.tsx index 130ebbd814..4b67070f5e 100644 --- a/apps/web/components/Shell.tsx +++ b/apps/web/components/Shell.tsx @@ -1,20 +1,20 @@ import { SelectorIcon } from "@heroicons/react/outline"; import { CalendarIcon, - ArrowLeftIcon, ClockIcon, CogIcon, ExternalLinkIcon, LinkIcon, LogoutIcon, - PuzzleIcon, + ViewGridIcon, MoonIcon, MapIcon, + ArrowLeftIcon, } from "@heroicons/react/solid"; import { signOut, useSession } from "next-auth/react"; import Link from "next/link"; import { useRouter } from "next/router"; -import React, { ReactNode, useEffect, useState } from "react"; +import React, { Fragment, ReactNode, useEffect, useState } from "react"; import { Toaster } from "react-hot-toast"; import Button from "@calcom/ui/Button"; @@ -59,6 +59,10 @@ function useRedirectToLoginIfUnauthenticated() { const router = useRouter(); useEffect(() => { + if (router.pathname.startsWith("/apps")) { + return; + } + if (!loading && !session) { router.replace({ pathname: "/auth/login", @@ -121,10 +125,11 @@ export function ShellSubHeading(props: { export default function Shell(props: { centered?: boolean; title?: string; - heading: ReactNode; + 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 @@ -157,10 +162,22 @@ export default function Shell(props: { current: router.asPath.startsWith("/availability"), }, { - name: t("integrations"), - href: "/integrations", - icon: PuzzleIcon, - current: router.asPath.startsWith("/integrations"), + 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"), @@ -182,6 +199,7 @@ export default function Shell(props: { const user = query.data; const i18n = useViewerI18n(); + const { status } = useSession(); if (i18n.status === "loading" || isRedirectingToOnboarding || loading) { // show spinner whilst i18n is loading to avoid language flicker @@ -206,95 +224,121 @@ export default function Shell(props: { -
-
-
-
-
- - - - - - {/* logo icon for tablet */} - - - - - - +
+ {status === "authenticated" && ( +
+
+
+
+ + + + + + {/* logo icon for tablet */} + + + + + + +
+ +
+ + + + + + +
+ + © {new Date().getFullYear()} Cal.com, Inc. v.{pkg.version + "-"} + {process.env.NEXT_PUBLIC_APP_URL === "https://cal.com" ? "h" : "sh"} + -{user && user.plan} +
- -
- - - - - - -
- - © {new Date().getFullYear()} Cal.com, Inc. v.{pkg.version + "-"} - {process.env.NEXT_PUBLIC_APP_URL === "https://cal.com" ? "h" : "sh"} - -{user && user.plan} -
-
+ )}
{/* show top navigation for md and smaller (tablet and phones) */} - + {status === "authenticated" && ( + + )}
{!!props.backPath && (
@@ -306,14 +350,22 @@ export default function Shell(props: {
)} -
- {props.HeadingLeftIcon &&
{props.HeadingLeftIcon}
} -
-

{props.heading}

-

{props.subtitle}

+ {props.heading && props.subtitle && ( +
+ {props.HeadingLeftIcon &&
{props.HeadingLeftIcon}
} +
+

+ {props.heading} +

+

{props.subtitle}

+
+ {props.CTA &&
{props.CTA}
}
-
{props.CTA}
-
+ )}
{/* show bottom navigation for md and smaller (tablet and phones) */} - + aria-current={item.current ? "page" : undefined}> +