Compare commits

...
328 Commits
Author SHA1 Message Date
Alex van Andel abce20824f v2.6.5
release.yml / release (push) Canceled after 0s
2023-02-24 14:24:12 +00:00
Peer Richelsen 76a8c89d33 session with ciaran (#7366) 2023-02-24 15:21:31 +01:00
github-actions[bot]andCrowdin Bot fc9360d99a New Crowdin translations by Github Action (#7356)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2023-02-24 12:56:50 +01:00
Nafees Nazik a5c21d5e3e fix: primary button loading indicator color (#7364) 2023-02-24 12:55:46 +01:00
github-actions[bot]andCrowdin Bot 3960c8a954 New Crowdin translations by Github Action (#7355)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2023-02-24 11:51:21 +01:00
github-actions[bot]andCrowdin Bot 0cbcda7430 New Crowdin translations by Github Action (#7352)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2023-02-24 11:46:10 +01:00
Peer Richelsen ff12e35748 Update SettingsLayout.tsx 2023-02-24 11:43:45 +01:00
Nafees Nazik 15d967b1d2 fix: mobile drawer z-index issue (#7353) 2023-02-24 11:41:25 +01:00
github-actions[bot]andCrowdin Bot b309be1d94 New Crowdin translations by Github Action (#7316)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2023-02-24 11:20:02 +01:00
alannncandAlex van Andel 94dc2643f2 fix/payment-status-message-on-booking-cancelled (#7260)
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-02-24 10:28:14 +05:30
Miguel Nieto 6440d3da6a Fix command to create new app for the app store (#7322) 2023-02-24 09:55:00 +05:30
9e08cf88f4 removed SSR trpc calls instead SPA for logged in pages (#6936)
* removed SSR trpc

* Re added debug endpoint

* Update me.ts

* Fixes unused imports

* Rollback unrelated changes

---------

Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Efraín Rochín <roae.85@gmail.com>
2023-02-23 18:41:57 -07:00
zomars 8b3eb986df Fix shared DB cache 2023-02-23 18:24:07 -07:00
Alex van Andel 8a6a7524cc Prioritise organizer to be the fixed, not lucky (round robin) user (#7317) 2023-02-23 18:22:18 -07:00
Hariom Balhara 1dbdb8a4d4 Remove _metadata.ts files for apps that have config.json (#7188) 2023-02-23 18:21:48 -07:00
Levent DenizandLevent Deniz 4fb0852505 [CAL-1125] Fix app detail page heading size (#7257)
* [CAL-1125] Fix app detail page heading size

* [CAL-1125] Fix margin on back button in shell

* [CAL-1125] Fix shell-margin for mobile

---------

Co-authored-by: Levent Deniz <levent.deniz@check24.de>
2023-02-23 17:19:52 -07:00
Nafees Nazik 0815ab715b fix: slot picker scroll position not consistent (#7282)
* fix: remove old scroll to method

* feat: add scroll into view
2023-02-23 17:19:23 -07:00
Joe Au-Yeung 944ff68463 Fix Outlook & Zoom creating events in UTC (#7283)
* Apply utc offset to time strings

* Zoom, create events in proper time zone
2023-02-23 17:18:49 -07:00
GitStart-Cal.comandgitstart-calcom 676254e96b [CAL-1103] mobile /event-type edit - Move the "Hide from profile" toggle into the dropdown (#7297)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-02-23 15:09:10 -07:00
Ben Hybert 207bcb9a97 fix non-admin team preview button (#7301) 2023-02-23 15:03:33 -07:00
github-actions[bot]andCrowdin Bot 4d825672db New Crowdin translations by Github Action (#7303)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2023-02-23 15:02:12 -07:00
Carina WollendorferandCarinaWolli ba86e7f540 Fixes SMS actions and cal.com branding for premium plan (#7306)
* enable sms actions with premium user name

* allow hide branding when user has premium user name

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-23 15:01:51 -07:00
Udit Takkar 3206e4ea12 fix: remove scroll (#7312)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-02-23 15:01:09 -07:00
zomars dbcebec31b Update lint.yml 2023-02-23 14:27:43 -07:00
zomars f427c09e88 Update pr.yml 2023-02-23 14:21:15 -07:00
zomars ded838881f Update pr.yml 2023-02-23 14:13:24 -07:00
zomars 08da9d805a Create cache-clean.yml 2023-02-23 14:06:34 -07:00
zomars 7cd0d5c3c3 Squashed commit of the following:
commit db31f2fdf442a7e68b8cdee4990318d30a5a3210
Author: zomars <zomars@me.com>
Date:   Thu Feb 23 11:41:46 2023 -0700

    Update pr.yml

commit 7afa9839e3a3842f2277f54bff703b1eb5740905
Author: zomars <zomars@me.com>
Date:   Thu Feb 23 11:36:49 2023 -0700

    Update nextjs-bundle-analysis.yml

commit 3b68ed19d774ce9540b0729e0b109cccbde65ea4
Author: zomars <zomars@me.com>
Date:   Thu Feb 23 11:28:30 2023 -0700

    Update pr.yml

commit 7c7e5ab65b03f97760481610a71c796611080719
Author: zomars <zomars@me.com>
Date:   Thu Feb 23 10:56:14 2023 -0700

    Update pr.yml

commit d1854cedd2aa19a7c260426ce3b309a40a16315a
Merge: 26568ba69 b018ee34a
Author: zomars <zomars@me.com>
Date:   Thu Feb 23 10:50:32 2023 -0700

    Merge remote-tracking branch 'upstream/main'

commit 26568ba693a2dd456bcd962598b4dddb8d117d1f
Merge: 2c72ac6f0 f5318c6be
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 17:10:10 2023 -0700

    Merge remote-tracking branch 'upstream/main'

commit 2c72ac6f0c0edbedc305eb7366742d31534ea1c2
Author: Peer Richelsen <peeroke@gmail.com>
Date:   Tue Feb 21 23:25:43 2023 +0100

    improved brand colors on booking page (#7269)

commit 65c0d3ffe8a7bd197c99bac3715356ab08669fbd
Author: Alex van Andel <me@alexvanandel.com>
Date:   Tue Feb 21 20:03:52 2023 +0000

    Define CODEOWNERS file (#7245)

    * Start defining CODEOWNERS file

    * Update CODEOWNERS

    ---------

    Co-authored-by: Omar López <zomars@me.com>

commit 29fb81434864634af584228e3bf3ddea1d630ecd
Author: Omar López <zomars@me.com>
Date:   Tue Feb 21 17:06:44 2023 -0700

    Update .github/actions/cache-db/action.yml

commit 92672fe3aa5539a083cbb10f82f87441b9e899d3
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 16:09:20 2023 -0700

    Revert "Revert "Re-enables buildjet""

    This reverts commit a1d78e7c12618d14b23bd50540ee005c6a550e7b.

commit 530e9748d7f2d4826ccffaa40dea2f137f8f17a9
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 15:13:22 2023 -0700

    Fixes build env

commit a1d78e7c12618d14b23bd50540ee005c6a550e7b
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 14:39:09 2023 -0700

    Revert "Re-enables buildjet"

    This reverts commit badd655e1edf8c2942582439f9fd48c00f892c38.

commit 8f67711e5d387ae0cd97d495766ccd06c4a61b0c
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 14:38:41 2023 -0700

    Adds missing build cache to e2e

commit badd655e1edf8c2942582439f9fd48c00f892c38
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 14:27:11 2023 -0700

    Re-enables buildjet

commit c7bdb52e0abfde27dd42494477ffff39cc3e4e19
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 14:10:34 2023 -0700

    Inherit secrets

commit 86b9b48e86e1c3d6e89b931ae8c8ce515c07b866
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 13:58:35 2023 -0700

    Fixes?

commit ebc304b39e815a0ff5c9e760550e4fee8283a567
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 13:42:33 2023 -0700

    Update nextjs-bundle-analysis.yml

commit 7da00d9566d4a56d77e7feb0d1504efa86148cbe
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 13:32:08 2023 -0700

    Update nextjs-bundle-analysis.yml

commit 224cc38fac42434e3a621c81a993798bb4abc773
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 13:21:38 2023 -0700

    Update nextjs-bundle-analysis.yml

commit 8fdd71ae36362290f80b55e8a2996d413d988c05
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 12:50:45 2023 -0700

    Build fixes

commit 6790be6f8fbba98658730266fb3927001066671f
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 12:46:17 2023 -0700

    Upgrades actions/checkout@v3

commit cc85218e0bdbf1f857296836c0026e09c8466ce9
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 12:29:33 2023 -0700

    Update action.yml

commit 380b1c2be4da15bc40113c7651e1595b5613b8b8
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 12:09:00 2023 -0700

    Update action.yml

commit 39b05a4e9bcba2e00b7efe342f7d456b5fba059a
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 11:55:50 2023 -0700

    Update action.yml

commit f4260393da8716c5246a6148d125d12b51993902
Merge: a82e9925f 4adfcb4b6
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 11:48:32 2023 -0700

    Merge remote-tracking branch 'upstream/main'

commit a82e9925f55c4967bad3dbb47566979734608bbc
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 11:46:07 2023 -0700

    Update lint.yml

commit 747ad8513f20767d6f66021cc548a308e18b6326
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 11:27:22 2023 -0700

    Caches DB

commit f5e96ba3f116eeb62f8ac47ca0d08e17f1fb2fdc
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 10:49:05 2023 -0700

    Comments out buildjet

commit aad26223b16c5444b947191c780416f4c8e61a94
Author: zomars <zomars@me.com>
Date:   Tue Feb 21 10:36:59 2023 -0700

    Update pr.yml

commit 7ce463f38cd1296f47cc5bb5cf8f863a6dfef9a7
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 22:07:31 2023 -0700

    Update action.yml

commit f5f57d963280d743cae0d04b6d80a7f49971f9e0
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 22:06:23 2023 -0700

    Adjustments

commit 2f048acbe6374ff6e8d9d750808c8b3e7bf7b333
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 21:47:01 2023 -0700

    WIP

commit dd1d86beb2bae0bd12b14a636398a2e2ce80555d
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 21:44:14 2023 -0700

    Removed required checks

commit 0db2b50ca8d125e1f7b115ae24cd2346fde92ab9
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 21:11:27 2023 -0700

    Fixes

commit bdc46bd5eef5dbb3c3b8dc2e68468bbff6c20aec
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 21:05:01 2023 -0700

    Update pr.yml

commit f6c58252a8e1b8971e70d3cb644b492d2fbad40d
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 21:02:39 2023 -0700

    Fixes

commit 04369405f38f200fece773ab7f9717fd62145fcf
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 20:35:39 2023 -0700

    Fixes

commit 4a60555b2bd2012c18fae8e338b7ef4bb39dc725
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 20:32:37 2023 -0700

    Update yarn-install.yml

commit 3d7749cef00cbbc843316e75d29e60ee68fe818d
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 20:31:53 2023 -0700

    Update yarn-install.yml

commit 374dc68848ee8be331e703fb0ef0cd08483694e5
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 20:28:14 2023 -0700

    Update yarn-install.yml

commit ae13d06ec2ffc759b1f8d9aea29b419e081e7693
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 20:27:31 2023 -0700

    Update check-types.yml

commit 93ad2cc92319bff6783f8633fc5bc1b8347376c4
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 20:26:38 2023 -0700

    Cleanup

commit 26730f7bbcaa07c323692ed76a17fa471f8e4f2e
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 20:05:54 2023 -0700

    Test

commit 76373a91c19fb1e67b050b0f36bb9b562d9024cd
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 19:51:28 2023 -0700

    Update yarn-e2e.yml

commit 0b3d98a4bc0cc3718b8fdb6f0537e824a6ef4204
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 19:51:14 2023 -0700

    Update package.json

commit 978d848b3989755e728353542714915782fc12c0
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 19:37:19 2023 -0700

    Cleanup

commit f2ccee16a73751f9e0bb26619da0ddfddc094907
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 19:18:42 2023 -0700

    Update action.yml

commit cf9cbbc5f08f29c2ba5a4c390129ff46bf8a3cf5
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 18:59:35 2023 -0700

    Update pr.yml

commit e8d39a91a5909674bfe9d4775ca09d814372529d
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 18:57:53 2023 -0700

    Update action.yml

commit eaa1210d1386b2eadd0bb1990ded444f7c307e60
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 18:43:59 2023 -0700

    Anotha one

commit 2958c17ebb28b3a231982a60fc3f3255a0d013e9
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 16:36:39 2023 -0700

    Tests

commit 922c9077b66b061e9f644eedf0022907ac6df161
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 16:02:05 2023 -0700

    Update pr.yml

commit 663b3bf48aa83a19f735badeb126e2968ee73733
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 16:00:49 2023 -0700

    Adds type check

commit 99746ee6e8662e39862ce25b5d9804372adf9fa4
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 15:53:57 2023 -0700

    Update yarn-e2e.yml

commit f82833cfdb17fa4a3da588a92925d3ebd8579357
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 15:53:04 2023 -0700

    Abstract playwright cache

commit e92ad12b54563219708b1e4423e502e1ac1f2197
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 15:41:07 2023 -0700

    Update action.yml

commit 271fe44bf087b19a7d0b1484261eff1cae8cb8b9
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 15:34:38 2023 -0700

    Update action.yml

commit 9a690de1ffd43270973c969c816e7b76a1d50a38
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 15:26:51 2023 -0700

    WIP

commit 5322fc7134bfa9c1061c45033573503023ba05db
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 15:04:03 2023 -0700

    Fixes

commit 3721dae0b45e4bd309f6a7c92db393956e543880
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 14:59:12 2023 -0700

    Update action.yml

commit 1027f058fd1bcbaa680b4297b081dd838f6ea886
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 14:56:51 2023 -0700

    Update action.yml

commit 9d74f9ed7bddf3e5563420c88476b73230c619df
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 14:53:43 2023 -0700

    Fixes

commit 4bfd63afef3b4139bb797ca6e5a9895138092417
Author: zomars <zomars@me.com>
Date:   Mon Feb 20 14:51:46 2023 -0700

    DRY

commit ea6114835dda65b5d6b31a96ad2781938cc8c121
Author: Omar López <zomars@me.com>
Date:   Sat Feb 18 16:38:00 2023 -0700

    Update production-build.yml

commit 8ec2b2c2c505c74b40a8e50a43e41f3d444730dc
Author: Omar López <zomars@me.com>
Date:   Sat Feb 18 16:36:44 2023 -0700

    Update production-build.yml

commit b0a7ccaa753f2fcf1ec571f3af1df9eea228f8b3
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 15:59:25 2023 -0700

    TEST

commit 0d639fdeb95deaa588fd29e63c275ea8b10a25d8
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 15:36:00 2023 -0700

    Revert

commit 5a597644a0a90cd212ff826aa3dda3214ab05334
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 15:32:16 2023 -0700

    Test

commit 7aafa78f1463f5a22576f814fa70db73db1ff89e
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 12:09:58 2023 -0700

    test

commit 81287f963bfcecbb1fd45670043b4e14690f8a6e
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 11:12:56 2023 -0700

    Update pr.yml

commit ef596f53d4614335ce36e084eae4b79efeed057c
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 10:59:08 2023 -0700

    Update pr.yml

commit 7dbaf1d08deec73c6f4bb53659d4af56282a2c68
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 10:58:22 2023 -0700

    Update pr.yml

commit 25489edac712e5b343c8f31123415a3cc804d254
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 10:39:55 2023 -0700

    Update pr.yml

commit 29ae0845b5b179c1493a35c18925f3f3e619d997
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 10:32:17 2023 -0700

    Update production-build.yml

commit 791492ac9e98046acd9fd5c100d0a3afa54fbbe3
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 10:28:37 2023 -0700

    Update pr.yml

commit 92597d8d7e4139b8129cd499545c37d1a518c0d0
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 10:24:15 2023 -0700

    Update pr.yml

commit 9bc85570c758f86079712270a1cc96e5983368a4
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 10:23:25 2023 -0700

    Update pr.yml

commit ba20dbbb96c95272118ecf5b6eead4ee0e816782
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 10:15:53 2023 -0700

    Update nextjs-bundle-analysis.yml

commit 35b7cd52d819409516f76d2b0e5849a136f55dc2
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 10:11:02 2023 -0700

    Update pr.yml

commit 8fe421e8d5c227d1cb5e31fe73398776d3b05dbf
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 09:55:49 2023 -0700

    Update pr.yml

commit f96af3f70810555d75ae9f3ba6f16e7e464e1926
Author: zomars <zomars@me.com>
Date:   Sat Feb 18 09:33:34 2023 -0700

    Update production-build.yml

commit 29134a3245e00b94a4b0edc2889ea6e81adf3e9b
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 20:53:06 2023 -0700

    Tests

commit 4aa8917687ccb28c1c9abfc30441c96db1bc1663
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 20:38:17 2023 -0700

    Update production-build.yml

commit 7c0884d0b7a45f9e8722547288d3879ee3e82add
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 20:16:59 2023 -0700

    Update pr.yml

commit b68ccd5ee1502de4f9afed2841cf2ab61309cf0e
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 20:16:27 2023 -0700

    Update pr.yml

commit 0c15086a7c02513e73821828a9392cdf45af6227
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 20:13:29 2023 -0700

    Update pr.yml

commit da277ce83bcebd62afc7e2074e82b9e4c64f4c27
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 20:12:50 2023 -0700

    Update pr.yml

commit fdb170086b70ded1f7109e35e85cce60a2ef7eaf
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 20:12:19 2023 -0700

    Update pr.yml

commit 1676d9070b2a07bbbf03297aa6c331dd68b7df4f
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 20:12:06 2023 -0700

    Update pr.yml

commit e834b42e87cad2401219b6fae765871f4b5eb7e8
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 19:59:53 2023 -0700

    Update pr.yml

commit e414378d243f3f43f3639127dee2f4bc4ac75633
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 19:57:07 2023 -0700

    Update pr.yml

commit 6904553b627a4896dab6adb8ac909f6e8604e893
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 19:55:47 2023 -0700

    Update pr.yml

commit 4722f0b44ac33f62ac019a4e707005bc7ff22b07
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 19:54:50 2023 -0700

    Update pr.yml

commit 2a9afdc4ac7a90c76f0aa7edbb2f3af0fbd0e7f1
Author: zomars <zomars@me.com>
Date:   Fri Feb 17 19:13:25 2023 -0700

    Testing
2023-02-23 13:44:38 -07:00
Nafees Nazik b018ee34a7 fix: placeholder in custom event name (#7247)
* fix: replace placeholder

* refactor: replace placeholder into a separate function
2023-02-23 15:46:36 +00:00
Peer Richelsen 17345f9326 added danish (#7302) 2023-02-23 16:40:17 +01:00
a1d7b30d51 New Crowdin translations by Github Action (#7273)Co-authored-by: Crowdin Bot <support+bot@crowdin.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com>
* New Crowdin translations by Github Action

* Update apps/web/public/static/locales/es/common.json

* Update apps/web/public/static/locales/ro/common.json

---------

Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-02-23 16:38:37 +01:00
Hariom Balhara 87dbfba5df Hotfix/ Fix failing build due to terser missing (#7294)
* No need to use terser

* v1.1.3

* v1.0.5

* v1.0.10
2023-02-23 13:55:02 +01:00
Esaú Morais e5d44d029a Allow user to add as many locations as they want (#7279) 2023-02-23 16:49:28 +05:30
Peer Richelsen 4803817055 2.6.4
release.yml / release (push) Canceled after 0s
2023-02-23 11:43:24 +01:00
Nafees Nazik dac6bff5b1 feat: add line clamp class (#7291) 2023-02-23 09:25:31 +01:00
Alex van Andel a3c10d0beb Amend logic to figure out the months between dates (#7289) 2023-02-22 14:36:30 -07:00
zomars d2b45e52ff Update nextjs-bundle-analysis.yml 2023-02-22 14:36:14 -07:00
zomars 0da6878188 Update pr.yml 2023-02-22 14:34:05 -07:00
zomars 572b54b7f0 Update forgot-password.e2e.ts 2023-02-22 14:34:05 -07:00
Carina WollendorferandCarinaWolli d9bf89beab fix variable for name (#7288)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-22 14:06:05 -07:00
Nafees NazikandHariom Balhara 0d1f484c92 test: multiple organizer address test (#7179)
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-22 10:52:49 +05:30
github-actions[bot]andCrowdin Bot 51d02c9873 New Crowdin translations by Github Action (#7271)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2023-02-21 17:49:47 -07:00
Peer Richelsen 6226baa244 added cal video to Tips.tsx (#7268)
* Update Tips.tsx

* Update packages/features/tips/Tips.tsx
2023-02-21 17:48:52 -07:00
zomars 81d842ade7 Update nextjs-bundle-analysis.yml 2023-02-21 17:22:46 -07:00
d26732c9dc Refactors Github Workflows (#7267)
* Testing

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update production-build.yml

* Tests

* Update production-build.yml

* Update pr.yml

* Update pr.yml

* Update nextjs-bundle-analysis.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update production-build.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* Update pr.yml

* test

* Test

* Revert

* TEST

* Update production-build.yml

* Update production-build.yml

* DRY

* Fixes

* Update action.yml

* Update action.yml

* Fixes

* WIP

* Update action.yml

* Update action.yml

* Abstract playwright cache

* Update yarn-e2e.yml

* Adds type check

* Update pr.yml

* Tests

* Anotha one

* Update action.yml

* Update pr.yml

* Update action.yml

* Cleanup

* Update package.json

* Update yarn-e2e.yml

* Test

* Cleanup

* Update check-types.yml

* Update yarn-install.yml

* Update yarn-install.yml

* Update yarn-install.yml

* Fixes

* Fixes

* Update pr.yml

* Fixes

* Removed required checks

* WIP

* Adjustments

* Update action.yml

* Update pr.yml

* Comments out buildjet

* Caches DB

* Update lint.yml

* Update action.yml

* Update action.yml

* Update action.yml

* Upgrades actions/checkout@v3

* Build fixes

* Update nextjs-bundle-analysis.yml

* Update nextjs-bundle-analysis.yml

* Update nextjs-bundle-analysis.yml

* Fixes?

* Inherit secrets

* Re-enables buildjet

* Adds missing build cache to e2e

* Revert "Re-enables buildjet"

This reverts commit badd655e1edf8c2942582439f9fd48c00f892c38.

* Fixes build env

* Revert "Revert "Re-enables buildjet""

This reverts commit a1d78e7c12618d14b23bd50540ee005c6a550e7b.

* Update .github/actions/cache-db/action.yml

* Define CODEOWNERS file (#7245)

* Start defining CODEOWNERS file

* Update CODEOWNERS

---------

Co-authored-by: Omar López <zomars@me.com>

* improved brand colors on booking page (#7269)

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-02-21 17:10:39 -07:00
Peer Richelsen f5318c6be3 improved brand colors on booking page (#7269) 2023-02-21 15:25:43 -07:00
Alex van AndelandOmar López dafbebe6f3 Define CODEOWNERS file (#7245)
* Start defining CODEOWNERS file

* Update CODEOWNERS

---------

Co-authored-by: Omar López <zomars@me.com>
2023-02-21 13:03:52 -07:00
Peer Richelsen 4adfcb4b6b Update README.md 2023-02-21 18:31:31 +01:00
Nafees Nazik 3ac6a8aa39 fix: allow admin role to degrade as a member (#7258) 2023-02-21 18:19:52 +01:00
sean-brydon c8019edb57 User email as impersonation if username is null (#7250) 2023-02-21 17:12:26 +00:00
Alex van Andel bfc81b770a Change API error handling - download works on local (#7256) 2023-02-21 17:03:10 +00:00
Hariom Balhara 4a5404bf21 Simplify turbo pipelone (#7252) 2023-02-21 16:48:01 +00:00
Hariom Balhara 7a9b40f218 Add sentry and WEBAPP_URL to whitelist (#7248) 2023-02-21 16:46:27 +00:00
Alex van Andel dca1d35cb4 v2.6.3
release.yml / release (push) Canceled after 0s
2023-02-21 13:26:11 +00:00
Esaú Morais af970c049a Do not show location when booking has been cancelled (#7244)
* fix(schedule): close on click #7143

* fix(booking): do not show location when booking has been cancelled
2023-02-21 09:25:57 +00:00
Esaú Morais 6fc3840ca3 Remove duplicated border in Calendar category (#7235)
* fix(schedule): close on click #7143

* fix(CalendarListContainer): remove duplicated border #7222

* fix: set right border to all installed apps
2023-02-21 09:19:29 +00:00
Udit TakkarandHariom Balhara c51150350a chore: check IS_SELF_HOSTED in download (#7214)
* chore: check IS_SELF_HOSTED in download

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

* Update apps/web/pages/api/download-cal-video-recording.ts

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Update apps/web/pages/api/download-cal-video-recording.ts

* Linting fix

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-21 09:00:08 +00:00
Alex van Andel 51664bf733 Fixed invalid busy times query logic (#7243)
* Fixed invalid busy times query logic

* Adjusted collective test
2023-02-21 02:45:10 +00:00
Alex van Andel 831506447a Assign userIds to all schedules, including common eventType schedules (#7241) 2023-02-20 23:48:15 +00:00
zomars ee54e670cb FIXME 2023-02-20 14:32:56 -07:00
Carina WollendorferandCarinaWolli 99cd6fe7da add all location links to metadata (#7236)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-20 18:52:07 +00:00
Hariom Balhara 75c7e03efe Upgrade vite (#7197) 2023-02-20 17:50:40 +00:00
Carina WollendorferandCarinaWolli 2ebfcf448c Fixes that workflow reminders of cancelled and rescheduled bookings are still sent (#7232)
* small UI fix

* fix cancelling scheduled emails

* improve comments

* delete reminders for rescheduled bookings

* add migration file

* cancel rescheduled bookings immediately

* remove immediate delete for request reschedule

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-20 12:40:08 -05:00
Oscar DominguezandHariom Balhara 235ec0e906 improve typing by removing as html element (#7212)
* refactor(embeds): use generic HTMLIFrameElement instead of 'as HTMLIFrameElement'

* refactor(embeds): improve types for floatingButton logic

* Fix floating button popup not working

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-20 17:37:03 +00:00
Nafees Nazik ea73870ce9 fix: overflow issue in Custom event name modal (#7224) 2023-02-20 21:46:31 +05:30
Peer Richelsen d1440bb5d2 added pwa: extension for standalone, lots of mobile improvements (#7218) 2023-02-20 15:11:51 +01:00
Hariom Balhara a000030040 Check embed in a better way (#7221) 2023-02-20 11:31:56 +00:00
Joe Au-Yeung 44864a801d Admin apps console - revert back to swtiches (#7219) 2023-02-20 15:38:16 +05:30
Sai Deepesh b9fd0b4c78 chore: add i18n in routing form pages (#7193)
* chore: add i18n in routing form pages

* use existing string

* add strings to en/common.json file

* address comments
2023-02-20 10:07:58 +00:00
Harsh SinghandGuest 0e7276370f Fix: mounting state use theme (#7203)
Co-authored-by: Guest <guest@pop-os.localdomain>
2023-02-20 15:17:33 +05:30
Hariom Balhara 4d2cf28c7e Fix metadata not being retrieved (#7208) 2023-02-20 07:30:23 +05:30
sean-brydon 55ee939cf9 Dont default empty state (#7217) 2023-02-19 20:16:19 +00:00
Udit Takkar 2fe54ded15 fix: use getVideoData function (#7205) 2023-02-19 13:13:36 +05:30
Udit Takkar 8e3fa4be29 Fix/email responsive bug (#6901)
* fix: prevent overflow of url

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

* fix: manage link responsive in emails

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

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-02-18 22:26:55 +00:00
Hariom Balhara d7b4d5932d Avoid theme not ready causing the select to not render (#7194)
release.yml / release (push) Canceled after 0s
2023-02-18 15:53:14 +00:00
3c7fc85b34 feat(app-store): add facetime app to app-store (#7174)
* feat(app-store): add facetime app to app-store

Add the facetime app to the app-store allowing for facetime web links and facetime app link schemes.

fixes #6965

* Update packages/app-store/facetime/config.json

* Remove unneeded files and make app follow the new app rules

* fix(app-store): update facetime app config

Update the regex and placeholder for the facetime app to reflect the decisions to only accept https://facetime.apple.com links. This was decided as it means that all participants can join a meeting even in the event that they don't have an Apple device.

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-18 06:40:07 +00:00
Omar López af018f0e8b Adds CalDav Edge case (#7187)
* Adds CalDav Edge case

* Update packages/lib/CalendarService.ts
2023-02-17 18:34:37 -07:00
Alex van Andel 6573f75a83 Bugfix/customer being prompted to upgrade to teams after purchasing (#6955)
* Move subscriptionId creation to earlier in the flow

* Fail silently when slug is missing

* Set team to created team
2023-02-17 23:45:50 +00:00
Carina WollendorferandCarinaWolli a3b26cd1e7 Removes team paywall for self-hosted (#7185)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-17 23:00:19 +00:00
Nafees NazikandPeer Richelsen 4f99746f68 fix: color picker a11y fixes (#7084)
* refactor: remove swatch component

* feat: use radix ui popover component

* refactor: remove duplicate component

* fix: import color picker from `@calcom/ui`

* fix: type error

* fix: update color picker to match the design

* fix: type

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
2023-02-17 20:27:29 +00:00
Efraín Rochínandzomars fd76bc9cab Reduce booking page bundle size (#7131)
* AvailabilityPage Component loaded dynamically

* update next/bundle-analyzer dependency

* Load dynamically SlotPicker and TimezoneDropDown and make some imports refactoring

* Gates functionality Returned

* Replace crypto with md5 dependency to generate gravatar url

* Refactor: AvailableTimes and SlotPicker

* Update next.config.js

* Update SlotPicker.tsx

* Update getEventTypeAppData.ts

---------

Co-authored-by: zomars <zomars@me.com>
2023-02-17 12:53:31 -07:00
Nafees Nazik 602c813928 fix: remove styled jsx (#7133) 2023-02-17 19:32:29 +00:00
Jeremiah Ajayi 2c54ea90f9 CAL-1053: Invalidate password to avoid once Google auth is used to merge accounts (#7152)
* CAL-1053: Invalidate password to avoid once Google auth is used to merge accounts

* remove log
2023-02-17 18:59:34 +00:00
+17 2698cde311 Gradually increase the getSchedule refetch interval until it reaches 30 seconds (#7104)
* Generate SSG Page used as cache for user's third-party calendars

* remove next-build-id dependency

* yarn.lock from main

* add support to get cached data from multiple months

* Update apps/web/pages/[user]/calendar-cache/[month].tsx

Co-authored-by: Omar López <zomars@me.com>

* Update apps/web/pages/[user]/calendar-cache/[month].tsx

Co-authored-by: Omar López <zomars@me.com>

* Update packages/core/CalendarManager.ts

Co-authored-by: Omar López <zomars@me.com>

* Add api endpoint that revalidates the current month and 3 more ahead

* Revalidate calendar cache when user connect new calendar.

* Revalidate calendar cache when user remove a calendar.

* Revalidate calendar cache when user change de selected calendars-

* Change revalidateCalendarCache function to @calcom/lib/server

* Remove the memory cache from getCachedResults

* refetch availability slots in a 3 seconds interval

* Hotfix: Event Name (#6863) (#6864)

* feat: make key unique (#6861)

* version 2.5.9 (#6868)

* Use Calendar component view=day for drop-in replacement troubleshooter (#6869)

* Use Calendar component view=day for drop-in replacement troubleshooter

* Setting the id to undefined makes the busy time selected

* Updated event title to include title+source

* lots of small changes by me and ciaran (#6871)

* Hotfix: For old Plausible installs enabled in an EventType, give a default value (#6860)

* Add default for trackingId for old plausible installs in event-types

* Fix types

* fix: filter booking in upcoming (#6406)

* fix: filter booking in upcoming

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

* fix: test

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

* fix: wipe-my-cal failing test

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

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Peer Richelsen <peer@cal.com>

* fix workflows when duplicating event types (#6873)

* fix: get location url from metadata (#6774)

* fix: get location url from metadata

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

* fix: replace location

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

* fix: type error

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

* fix: use zod

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

---------

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

* Updates heroku deployment template (#6879)

* Hide button (#6895)

* Fixed some inconsistencies within single event type page (#6887)

* Fixed some inconsistencies within single event type page

* Fix layout shift on AvailabilityTab

* fix(date-overrides): alignment of edit & delete btns (#6892)

* When unchecking the common schedule, schedule should be nulled (#6898)

* theme for storybook

* nit border change (#6899)

* fix: metadata not saved while creating a booking. (#6866)

* feat: add metadata to booking creation

* fix: bug

* Beginning of Strict CSP Compliance (#6841)

* Add CSP Support and enable it initially for Login page

* Update README

* Make sure that CSP is not enabled if CSP_POLICY isnt set

* Add a new value for x-csp header that tells if instance has opted-in to CSP or not

* Add more src to CSP

* Fix typo in header name

* Remove duplicate headers fn

* Add https://eu.ui-avatars.com/api/

* Add CSP_POLICY to env.example

* v2.5.10

* fix: add req.headers (#6921)

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

* add-console-vars (#6929)

* Admin Wizard Choose License (#6574)

* Implementation

* i18n

* More i18n

* extracted i18n, needs api to get most recent price, added hint: update later

* Fixing i18n var

* Fix booking filters not working for admin (#6576)

* fix: react-select overflow issue in some modals. (#6587)

* feat: add a disable overflow prop

* feat: use the disable overflow prop

* Tailwind Merge (#6596)

* Tailwind Merge

* Fix merge classNames

* [CAL-808] /availability/single - UI issue on buttons beside time inputs (#6561)

* [CAL-808] /availability/single - UI issue on buttons beside time inputs

* Update apps/web/public/static/locales/en/common.json

* Update packages/features/schedules/components/Schedule.tsx

* create new translation for tooltip

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Bye bye submodules (#6585)

* WIP

* Uses ssh instead

* Update .gitignore

* Update .gitignore

* Update Makefile

* Update git-setup.sh

* Update git-setup.sh

* Replaced Makefile with bash script

* Update package.json

* fix: show button on empty string (#6601)

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

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

* fix: add delete in dropdown (#6599)

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

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

* Update README.md

* Update README.md

* Changed a neutral- classes to gray (#6603)

* Changed a neutral- classes to gray

* Changed all border-1 to border

* Update package.json

* Test fixes

* Yarn lock fixes

* Fix string equality check in git-setup.sh

* [CAL-811] Avatar icon not redirecting user back to the main page (#6586)

* Remove cursor-pointer, remove old Avatar* files

* Fixed styling for checkedSelect + some cleanup

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Harsh/add member invite (#6598)

Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>

* Regenerated lockfile without upgrade (#6610)

* fix: remove annoying outline when <Button /> clicked (#6537)

* fix: remove annoying outline when <Button /> clicked

* Delete yarn.lock

* remove 1 on 1 icon (#6609)

* removed 1-on-1 badge

* changed user to users for group events

* fix: case-sensitivity in apps path (#6552)

* fix: lowercase slug

* fix: make fallback blocking

* Fix FAB (#6611)

* feat: add LocationSelect component (#6571)

* feat: add LocationSelect component

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

* fix: type error

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

* chore: type error

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

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

* Update booking filters design  (#6543)

* Update booking filters

* Add filter on YOUR bookings

* Fix pending members showing up in list

* Reduce the avatar size to 'sm' for now

* Bugfix/dropdown menu trigger as child remove class names (#6614)

* Fix UsernameTextfield to take right height

* Remove className side-effect

* Incorrect resolution version fixed

* Converted mobile DropdownMenuTrigger styles into Button

* v2.5.3

* fix: use items-center (#6618)

* fix tooltip and modal stacking issues (#6491)

* fix tooltip and modal stacking issues

* use z-index in larger screens and less

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Temporary fix (#6626)

* Fix Ga4 tracking (#6630)

* generic <UpgradeScreen> component (#6594)

* first attempt of <UpgradeScreen>

* changes to icons

* reverted changes back to initial state, needs fix: teams not showing

* WIP

* Fix weird reactnode error

* Fix loading text

* added upgradeTip to routing forms

* icon colors

* create and use hook to check if user has team plan

* use useTeamPlan for upgradeTeamsBadge

* replace huge svg with compressed jpeg

* responsive fixes

* Update packages/ui/components/badge/UpgradeTeamsBadge.tsx

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>

* Give team plan features to E2E tests

* Allow option to make a user part of team int ests

* Remove flash of paywall for team user

* Add team user for typeform tests as well

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Removing env var to rely on db

* Restoring i18n keys, set loading moved

* Fixing tailwind-preset glob

* Wizard width fix for md+ screens

* Converting licenses options to radix radio

* Applying feedback + other tweaks

* Reverting this, not this PR related

* Unneeded code removal

* Reverting unneeded style change

* Applying feedback

* Removing licenseType

* Upgrades typescript

* Update yarn lock

* Typings

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712)

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713)

* Adds deployment settings to DB (#6706)

* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup

* Delete migration.sql

* Relying on both, env var and new model

* Restoring env example doc for backward compat

* Maximum call stack size exceeded fix?

* Revert upgrade

* Update index.ts

* Delete index.ts

* Not exposing license key, fixed radio behavior

* Covering undefined env var

* Self contained checkLicense

* Feedback

* Moar feedback

* Feedback

* Feedback

* Feedback

* Cleanup

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Nafees Nazik <84864519+G3root@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Harsh Singh <51085015+harshsinghatz@users.noreply.github.com>
Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>
Co-authored-by: Luis Cadillo <luiscaf3r@gmail.com>
Co-authored-by: Mohammed Cherfaoui <hi@cherfaoui.dev>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>

* added two new tips (#6915)

* [CAL-488] Timezone selection has a weird double dropdown (#6851)

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>

* fix: color and line height of icon (#6913)

* fix: use destination calendar email (#6886)

* fix: use destination calendar email
to display correct primary email

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

* fix: simplify logic

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

---------

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

* fix: dropdown title in bookings page (#6924)

* fixes the broken max size of members on teams page (#6926)

* fix: display provider name instead of url (#6914)

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

* fix: add sortByLabel (#6797)

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

* Email Variables Bug (#6943)

* Remove _subject translations for zh-CN, needs retranslation

* minor timezone-select improvements (#6944)

* fixed timezone select positioning and hover

* fixed timezone select positioning and hover

* Give trackingId a default value because if user doesnt interact with trackingId input it is not set (#6945)

* Block /auth/:path, nothing else. (#6949)

* Block /auth/:path, nothing else.

* Also add /signup

* fix start icon in button (#6950)

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Fixes localisation of {EVENT_DATE} in workflows (#6907)

* translate {EVENT_DATE} variable to correct language

* fix locale for cron schedule reminder emails/sms

* fix type error

* add missing locale to attendees

* fix type error

* code clean up

* revert last commit

* using Intl for date translations

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Allow account linking for Google and SAML providers (#6874)

* allow account linking for self-hosted instances, both Google and SAML are verified emails

* allow account linking for Google and SSO if emails match with existing username/password account

* Tweaked find user by email since we now have multiple providers (other than credentials provider)

* feat/payment-service-6438-cal-767 (#6677)

* WIP paymentService

* Changes for payment Service

* Fix for stripe payment flow

* Remove logs/comments

* Refactored refund for stripe app

* Move stripe handlePayment to own lib

* Move stripe delete payments to paymentService

* lint fix

* Change handleRefundError as generic function

* remove log

* remove logs

* remove logs

* Return stripe default export to lib/server

* Fixing types

* Fix types

* Upgrades typescript

* Update yarn lock

* Typings

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712)

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713)

* Adds deployment settings to DB (#6706)

* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup

* Revert "lint fix"

This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6.

* Add validation

* Revert changes removed in force push

* Removing abstract class and just leaving interface implementation

* Fix types for handlePayments

* Fix payment test appStore import

* Fix stripe metadata in event type

* Move migration to separate PR

* Revert "Move migration to separate PR"

This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6.

* Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql

Co-authored-by: Omar López <zomars@me.com>

---------

Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Small UI fixes for seats & destination calendars (#6859)

* Do not add former time for events on seats

* Default display destination calendar

* Add seats badge to event type item

* Add string

* Actively watch seats enabled option for requires confirmation

* Only show former time when there is a rescheduleUid

* fix: use typedquery hook in duplicate dialog (#6730)

* fix: use typedquery hook in duplicate dialog

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

* Update packages/features/eventtypes/components/DuplicateDialog.tsx

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Omar López <zomars@me.com>

* Fixing admin wizard step done (#6954)

* Feature/maintenance mode (#6930)

* Implement maintenance mode with Vercel Edge Config

* Error log is spam during development/ added \n in .env.example

* Exclude _next, /api for /maintenance page

* Re-instate previous config

* rtl: begone

* Added note to explain why /auth/login covers the maintenance page.

---------

Co-authored-by: Omar López <zomars@me.com>

* Update package.json

* I18N Caching (#6823)

* Caching Logic Changes

Enabled this function to change its cache value based on incoming paths value

* Invalidate I18N Cache

Invalidating the I18N cache when a user saves changes to their General settings

* Removes deprecated useLocale location

* Overriding the default getSchedule cache to have a revalidation time of 1 second

* Update apps/web/pages/api/trpc/[trpc].ts

* Updated cache values to match the comment

---------

Co-authored-by: zomars <zomars@me.com>

* feat: return `x-vercel-ip-timezone` in headers (#6849)

* feat: add trpc to matcher and pass vercel timezone header

* feat: pass request to context

* feat: return timezone in header

* refactor: split context

* fix: remove tsignore comment

* Update [trpc].ts

---------

Co-authored-by: zomars <zomars@me.com>

* log the json url for testing

* use WEBAPP_URL constant instead env.NEXT_PUBLIC_WEBAPP_URL

* remove the commented selectedCalendars var, it is not necessary

* Caching fixes

* Separate selectedDate slots from month slots

* Update [trpc].ts

* Log headers

* Update [trpc].ts

* Update package.json

* Fixes/trpc headers (#7045)

* Cache fixes

* Testing

* SWR breaks embed tests

* Prevent refetching day on month switch

* Skeleton fixes

* gradually increase the refetch interval

* Update AvailabilityPage.tsx

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Nafees Nazik <84864519+G3root@users.noreply.github.com>
Co-authored-by: Ben Hybert <53020786+Hybes@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Sai Deepesh <saideepesh000@gmail.com>
Co-authored-by: alannnc <alannnc@gmail.com>
Co-authored-by: Leo Giovanetti <hello@leog.me>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Harsh Singh <51085015+harshsinghatz@users.noreply.github.com>
Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>
Co-authored-by: Luis Cadillo <luiscaf3r@gmail.com>
Co-authored-by: Mohammed Cherfaoui <hi@cherfaoui.dev>
Co-authored-by: Joe Shajan <joeshajan1551@gmail.com>
Co-authored-by: Deepak Prabhakara <deepak@boxyhq.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Aaron Presley <155617+AaronPresley@users.noreply.github.com>
2023-02-17 11:50:02 -07:00
1433ec6946 feat: use @next/font for font loading (#6346)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-02-17 18:53:17 +01:00
Peer RichelsenandCarinaWolli 48e5d18ea1 show upgrade badge and hide /team/null when team unpublished (#7059)
* untested but i think this works

* fix upgrade badge

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-17 10:48:13 -07:00
Peer Richelsen 5da76c698e use support email (.env) in password reset mail (#7181)
release.yml / release (push) Canceled after 0s
2023-02-17 16:44:42 +00:00
Christian Emmert 578308a8cb Display timezones in availabilities (#7081) 2023-02-17 16:07:59 +00:00
Lucas Smith 6b3862f96d fix(app): disable edit availability link while fetching (#7144) 2023-02-17 13:27:56 +00:00
Matt Pocock 94f239bc42 Improved typings of window.Cal (#7178) 2023-02-17 13:23:30 +00:00
Matt Pocock 2f2f6006e6 Improved types in ModalBox.ts (#7177) 2023-02-17 13:23:19 +00:00
Matt Pocock f8558e16e8 Removed 'as any' in jackson.ts (#7175) 2023-02-17 13:21:29 +00:00
Carina WollendorferandCarinaWolli 38be2bef9a fix custom workflow template (#7154)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-17 13:21:11 +00:00
Nafees Nazik 485619602f refactor: usetheme hook (#7112)
* refactor: useTheme hook

* feat: add mounted state hook

* feat: add mounted hook

* fix: add comments
2023-02-17 11:18:54 +00:00
sean-brydon ce01537fe6 Fix errors (#7134) 2023-02-17 11:15:42 +00:00
sean-brydon f77e7476d2 Fix tab focus state in New select (#7139)
* Fix tab focus state

* Update packages/ui/components/form/selectimproved/components/Select.tsx

* Remove flex import
2023-02-17 11:15:02 +00:00
Carina WollendorferandCarinaWolli b6016c8f20 fix zapier app settings (#7161)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-17 11:12:20 +00:00
Hariom Balhara a5e5d103a0 Embed: Remove ugly windows scrollbar even on unscrollable content (#7171) 2023-02-17 10:35:39 +00:00
Peer Richelsen fec02979ba hide team member availability button (#7147) 2023-02-17 10:09:49 +00:00
sean-brydon dc200b95cb Add max h to booking filters (#7170) 2023-02-17 11:02:10 +01:00
Peer Richelsen 78a54e5f54 Update CONTRIBUTING.md 2023-02-17 10:59:46 +01:00
sean-brydon 00ebda2fc6 Fix default app in main appstore list (#7141) 2023-02-17 09:11:03 +00:00
Omar López 7c749299bb Enforces explicit type imports (#7158)
* Enforces explicit type imports

* Upgrades typescript-eslint

* Upgrades eslint related dependencies

* Update config

* Sync packages mismatches

* Syncs prettier version

* Linting

* Relocks node version

* Fixes

* Locks @vitejs/plugin-react to 1.3.2

* Linting
2023-02-16 15:39:57 -07:00
Esaú Morais 3df289b557 fix(schedule): close on click #7143 (#7148) 2023-02-16 13:42:41 -07:00
Carina Wollendorfer f4c849b75c fix deleting webhook (#7159) 2023-02-16 21:22:14 +01:00
Aaron Presley 09cc6f07e4 Booking page now displays localized dates, times, and timezones (#7130) 2023-02-16 18:16:22 +01:00
sean-brydon 78656f2116 Layout Story (#7116)
* Flex component + spacing story

* Add Flex Story

* Remove flex component
2023-02-15 19:12:10 +00:00
Nafees Nazikandzomars 1fa5e296af refactor: use dynamic import in booking page (#7101)
Co-authored-by: zomars <zomars@me.com>
2023-02-15 20:08:17 +01:00
alannnc 0f76530c11 fix/premium-username-user-state-overriden (#7099) 2023-02-15 19:40:29 +01:00
Omar López ab6758194b v2.6.0
release.yml / release (push) Canceled after 0s
2023-02-15 11:28:32 -07:00
zomars 5528d60897 Set bundle threshold to 500 bytes 2023-02-15 11:05:12 -07:00
Nafees Nazik bb1c55e07f fix: booking confirmation email missing variables (#7109)
* fix: make the method public

* fix: missing variables
2023-02-15 10:49:44 -07:00
Nafees Nazik c899921591 fix: label (#7119) 2023-02-15 17:19:39 +00:00
sean-brydonandzomars ea34545d72 Handle booking flow for dynamic default events (#7094)
* Handle booking flow for default events

* Cleanup

* Update packages/lib/defaultEvents.ts

* Fix naming conventions

* Fix prettier error

---------

Co-authored-by: zomars <zomars@me.com>
2023-02-15 15:42:49 +00:00
Omar López 9d3540511b Add/eslint plugin unused imports (#7102)
* Re added debug endpoint

* Update me.ts

* Adds eslint-plugin-unused-imports

* Linting
2023-02-14 23:26:29 +00:00
zomars e8cf92361a Fingers crossed 🤞 2023-02-14 15:36:02 -07:00
zomars e8525b963b Update .gitignore 2023-02-14 14:47:58 -07:00
zomars 24dabd0ddc Update nextjs-bundle-analysis.yml 2023-02-14 14:21:12 -07:00
zomars 5203168b2e Re added debug endpoint
Update me.ts
2023-02-14 14:11:09 -07:00
Omar López c3e40f84a9 v2.5.15
release.yml / release (push) Canceled after 0s
2023-02-14 10:08:30 -07:00
Omar López 8e2ece7526 Prevent timeouts when cache fails (#7095)
Return empty cache instead of failing

Keeping console errors
2023-02-14 10:07:58 -07:00
Omar López b6eca6e083 v2.5.14
release.yml / release (push) Canceled after 0s
2023-02-14 09:02:24 -07:00
zomars 4cb264f1f7 Revert "Revert "I18N Caching (#6823)""
This reverts commit e248fda36b.

Re-fixed cache rules
2023-02-14 09:00:28 -07:00
Alex van Andel e248fda36b Revert "I18N Caching (#6823)"
This reverts commit 05c33bd94b.
2023-02-14 13:55:19 +00:00
sean-brydon 1c97e549eb Implement URL validation on default videos links (#7087) 2023-02-14 13:19:45 +00:00
77600f8168 Feat/custom default video (#6971)
* Add queries to fetch metadata and update default

* Add to zod schema

* Change default rules on settings page

* Update query

* Initall override on create event type

* Working default

* Change schema to save locationLink too

* Update default conferncing to include link

* Rename tsx to ts. Fix metadata keys

* WIP on refactoring appstore installed

* Add this to appstore installed apps too

* Display only on conferencing apps

* Add i18n strings

* Change order in dropdown menu so delete is bottom

* Refactor query to not expose all of metadata

* Fix mr type checker

* Possible e2e fix

* Refactor metadata to use ctx

* Refactor back to query cell

* Alias schema

* Adding comment for more info

* Remove constant for clarity

* Update nextjs-bundle-analysis.yml

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: zomars <zomars@me.com>
2023-02-13 22:55:32 +00:00
Omar López 6cad606ba1 v2.5.13
release.yml / release (push) Canceled after 0s
2023-02-13 15:54:14 -07:00
zomars 7cae7a7bd4 Bundle analyzer fixes 2023-02-13 15:38:44 -07:00
zomars 93f65807e7 Bundle output fixes 2023-02-13 15:13:57 -07:00
Peer Richelsen 0a63820699 fixed border on dark mode (#7079) 2023-02-13 23:02:57 +01:00
zomars 05ad437b27 Update nextjs-bundle-analysis.yml 2023-02-13 15:01:23 -07:00
zomars 26a57a71ae Update nextjs-bundle-analysis.yml 2023-02-13 14:46:04 -07:00
zomars 34a10205a3 Update nextjs-bundle-analysis.yml 2023-02-13 14:44:55 -07:00
Joe Shajan fbf8ff6db7 Public booking page hover fix (#6952)
* fix: hover bg on dark mode

* fix: badge bg color

* fix: bg darkgray 200 on dark mode
2023-02-13 22:02:12 +01:00
Amir FakhrullahandUdit Takkar bef6d18fdf [CAL-1030] fix flickering border issue in menu layout for mobile (#7036)
* fix flickering border issue in menu layout for mobile

* transfer styles changes to the DropdownMenuItem

* remove button border for Remove button

* fix: use dropdownItem

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

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-02-13 21:57:33 +01:00
zomars 2e96e2ef3f Update nextjs-bundle-analysis.yml 2023-02-13 13:54:27 -07:00
zomars 2ca6769a70 Update nextjs_bundle_analysis.yml 2023-02-13 12:44:37 -07:00
zomars 1eb514dfcf Testing bundle analyzer action 2023-02-13 12:38:54 -07:00
Nafees Nazik d6c004ba22 feat: add stale issues action (#7028) 2023-02-13 12:21:07 -07:00
+17 afb9605f0a Generate SSG Page used as cache for user's third-party calendar (#6775)
* Generate SSG Page used as cache for user's third-party calendars

* remove next-build-id dependency

* yarn.lock from main

* add support to get cached data from multiple months

* Update apps/web/pages/[user]/calendar-cache/[month].tsx

Co-authored-by: Omar López <zomars@me.com>

* Update apps/web/pages/[user]/calendar-cache/[month].tsx

Co-authored-by: Omar López <zomars@me.com>

* Update packages/core/CalendarManager.ts

Co-authored-by: Omar López <zomars@me.com>

* Add api endpoint that revalidates the current month and 3 more ahead

* Revalidate calendar cache when user connect new calendar.

* Revalidate calendar cache when user remove a calendar.

* Revalidate calendar cache when user change de selected calendars-

* Change revalidateCalendarCache function to @calcom/lib/server

* Remove the memory cache from getCachedResults

* refetch availability slots in a 3 seconds interval

* Hotfix: Event Name (#6863) (#6864)

* feat: make key unique (#6861)

* version 2.5.9 (#6868)

* Use Calendar component view=day for drop-in replacement troubleshooter (#6869)

* Use Calendar component view=day for drop-in replacement troubleshooter

* Setting the id to undefined makes the busy time selected

* Updated event title to include title+source

* lots of small changes by me and ciaran (#6871)

* Hotfix: For old Plausible installs enabled in an EventType, give a default value (#6860)

* Add default for trackingId for old plausible installs in event-types

* Fix types

* fix: filter booking in upcoming (#6406)

* fix: filter booking in upcoming

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

* fix: test

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

* fix: wipe-my-cal failing test

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

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Peer Richelsen <peer@cal.com>

* fix workflows when duplicating event types (#6873)

* fix: get location url from metadata (#6774)

* fix: get location url from metadata

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

* fix: replace location

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

* fix: type error

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

* fix: use zod

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

---------

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

* Updates heroku deployment template (#6879)

* Hide button (#6895)

* Fixed some inconsistencies within single event type page (#6887)

* Fixed some inconsistencies within single event type page

* Fix layout shift on AvailabilityTab

* fix(date-overrides): alignment of edit & delete btns (#6892)

* When unchecking the common schedule, schedule should be nulled (#6898)

* theme for storybook

* nit border change (#6899)

* fix: metadata not saved while creating a booking. (#6866)

* feat: add metadata to booking creation

* fix: bug

* Beginning of Strict CSP Compliance (#6841)

* Add CSP Support and enable it initially for Login page

* Update README

* Make sure that CSP is not enabled if CSP_POLICY isnt set

* Add a new value for x-csp header that tells if instance has opted-in to CSP or not

* Add more src to CSP

* Fix typo in header name

* Remove duplicate headers fn

* Add https://eu.ui-avatars.com/api/

* Add CSP_POLICY to env.example

* v2.5.10

* fix: add req.headers (#6921)

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

* add-console-vars (#6929)

* Admin Wizard Choose License (#6574)

* Implementation

* i18n

* More i18n

* extracted i18n, needs api to get most recent price, added hint: update later

* Fixing i18n var

* Fix booking filters not working for admin (#6576)

* fix: react-select overflow issue in some modals. (#6587)

* feat: add a disable overflow prop

* feat: use the disable overflow prop

* Tailwind Merge (#6596)

* Tailwind Merge

* Fix merge classNames

* [CAL-808] /availability/single - UI issue on buttons beside time inputs (#6561)

* [CAL-808] /availability/single - UI issue on buttons beside time inputs

* Update apps/web/public/static/locales/en/common.json

* Update packages/features/schedules/components/Schedule.tsx

* create new translation for tooltip

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Bye bye submodules (#6585)

* WIP

* Uses ssh instead

* Update .gitignore

* Update .gitignore

* Update Makefile

* Update git-setup.sh

* Update git-setup.sh

* Replaced Makefile with bash script

* Update package.json

* fix: show button on empty string (#6601)

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

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

* fix: add delete in dropdown (#6599)

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

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

* Update README.md

* Update README.md

* Changed a neutral- classes to gray (#6603)

* Changed a neutral- classes to gray

* Changed all border-1 to border

* Update package.json

* Test fixes

* Yarn lock fixes

* Fix string equality check in git-setup.sh

* [CAL-811] Avatar icon not redirecting user back to the main page (#6586)

* Remove cursor-pointer, remove old Avatar* files

* Fixed styling for checkedSelect + some cleanup

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Harsh/add member invite (#6598)

Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>

* Regenerated lockfile without upgrade (#6610)

* fix: remove annoying outline when <Button /> clicked (#6537)

* fix: remove annoying outline when <Button /> clicked

* Delete yarn.lock

* remove 1 on 1 icon (#6609)

* removed 1-on-1 badge

* changed user to users for group events

* fix: case-sensitivity in apps path (#6552)

* fix: lowercase slug

* fix: make fallback blocking

* Fix FAB (#6611)

* feat: add LocationSelect component (#6571)

* feat: add LocationSelect component

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

* fix: type error

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

* chore: type error

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

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

* Update booking filters design  (#6543)

* Update booking filters

* Add filter on YOUR bookings

* Fix pending members showing up in list

* Reduce the avatar size to 'sm' for now

* Bugfix/dropdown menu trigger as child remove class names (#6614)

* Fix UsernameTextfield to take right height

* Remove className side-effect

* Incorrect resolution version fixed

* Converted mobile DropdownMenuTrigger styles into Button

* v2.5.3

* fix: use items-center (#6618)

* fix tooltip and modal stacking issues (#6491)

* fix tooltip and modal stacking issues

* use z-index in larger screens and less

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Temporary fix (#6626)

* Fix Ga4 tracking (#6630)

* generic <UpgradeScreen> component (#6594)

* first attempt of <UpgradeScreen>

* changes to icons

* reverted changes back to initial state, needs fix: teams not showing

* WIP

* Fix weird reactnode error

* Fix loading text

* added upgradeTip to routing forms

* icon colors

* create and use hook to check if user has team plan

* use useTeamPlan for upgradeTeamsBadge

* replace huge svg with compressed jpeg

* responsive fixes

* Update packages/ui/components/badge/UpgradeTeamsBadge.tsx

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>

* Give team plan features to E2E tests

* Allow option to make a user part of team int ests

* Remove flash of paywall for team user

* Add team user for typeform tests as well

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Removing env var to rely on db

* Restoring i18n keys, set loading moved

* Fixing tailwind-preset glob

* Wizard width fix for md+ screens

* Converting licenses options to radix radio

* Applying feedback + other tweaks

* Reverting this, not this PR related

* Unneeded code removal

* Reverting unneeded style change

* Applying feedback

* Removing licenseType

* Upgrades typescript

* Update yarn lock

* Typings

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712)

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713)

* Adds deployment settings to DB (#6706)

* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup

* Delete migration.sql

* Relying on both, env var and new model

* Restoring env example doc for backward compat

* Maximum call stack size exceeded fix?

* Revert upgrade

* Update index.ts

* Delete index.ts

* Not exposing license key, fixed radio behavior

* Covering undefined env var

* Self contained checkLicense

* Feedback

* Moar feedback

* Feedback

* Feedback

* Feedback

* Cleanup

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Nafees Nazik <84864519+G3root@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Harsh Singh <51085015+harshsinghatz@users.noreply.github.com>
Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>
Co-authored-by: Luis Cadillo <luiscaf3r@gmail.com>
Co-authored-by: Mohammed Cherfaoui <hi@cherfaoui.dev>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>

* added two new tips (#6915)

* [CAL-488] Timezone selection has a weird double dropdown (#6851)

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>

* fix: color and line height of icon (#6913)

* fix: use destination calendar email (#6886)

* fix: use destination calendar email
to display correct primary email

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

* fix: simplify logic

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

---------

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

* fix: dropdown title in bookings page (#6924)

* fixes the broken max size of members on teams page (#6926)

* fix: display provider name instead of url (#6914)

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

* fix: add sortByLabel (#6797)

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

* Email Variables Bug (#6943)

* Remove _subject translations for zh-CN, needs retranslation

* minor timezone-select improvements (#6944)

* fixed timezone select positioning and hover

* fixed timezone select positioning and hover

* Give trackingId a default value because if user doesnt interact with trackingId input it is not set (#6945)

* Block /auth/:path, nothing else. (#6949)

* Block /auth/:path, nothing else.

* Also add /signup

* fix start icon in button (#6950)

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Fixes localisation of {EVENT_DATE} in workflows (#6907)

* translate {EVENT_DATE} variable to correct language

* fix locale for cron schedule reminder emails/sms

* fix type error

* add missing locale to attendees

* fix type error

* code clean up

* revert last commit

* using Intl for date translations

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Allow account linking for Google and SAML providers (#6874)

* allow account linking for self-hosted instances, both Google and SAML are verified emails

* allow account linking for Google and SSO if emails match with existing username/password account

* Tweaked find user by email since we now have multiple providers (other than credentials provider)

* feat/payment-service-6438-cal-767 (#6677)

* WIP paymentService

* Changes for payment Service

* Fix for stripe payment flow

* Remove logs/comments

* Refactored refund for stripe app

* Move stripe handlePayment to own lib

* Move stripe delete payments to paymentService

* lint fix

* Change handleRefundError as generic function

* remove log

* remove logs

* remove logs

* Return stripe default export to lib/server

* Fixing types

* Fix types

* Upgrades typescript

* Update yarn lock

* Typings

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712)

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713)

* Adds deployment settings to DB (#6706)

* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup

* Revert "lint fix"

This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6.

* Add validation

* Revert changes removed in force push

* Removing abstract class and just leaving interface implementation

* Fix types for handlePayments

* Fix payment test appStore import

* Fix stripe metadata in event type

* Move migration to separate PR

* Revert "Move migration to separate PR"

This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6.

* Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql

Co-authored-by: Omar López <zomars@me.com>

---------

Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Small UI fixes for seats & destination calendars (#6859)

* Do not add former time for events on seats

* Default display destination calendar

* Add seats badge to event type item

* Add string

* Actively watch seats enabled option for requires confirmation

* Only show former time when there is a rescheduleUid

* fix: use typedquery hook in duplicate dialog (#6730)

* fix: use typedquery hook in duplicate dialog

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

* Update packages/features/eventtypes/components/DuplicateDialog.tsx

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Omar López <zomars@me.com>

* Fixing admin wizard step done (#6954)

* Feature/maintenance mode (#6930)

* Implement maintenance mode with Vercel Edge Config

* Error log is spam during development/ added \n in .env.example

* Exclude _next, /api for /maintenance page

* Re-instate previous config

* rtl: begone

* Added note to explain why /auth/login covers the maintenance page.

---------

Co-authored-by: Omar López <zomars@me.com>

* Update package.json

* I18N Caching (#6823)

* Caching Logic Changes

Enabled this function to change its cache value based on incoming paths value

* Invalidate I18N Cache

Invalidating the I18N cache when a user saves changes to their General settings

* Removes deprecated useLocale location

* Overriding the default getSchedule cache to have a revalidation time of 1 second

* Update apps/web/pages/api/trpc/[trpc].ts

* Updated cache values to match the comment

---------

Co-authored-by: zomars <zomars@me.com>

* feat: return `x-vercel-ip-timezone` in headers (#6849)

* feat: add trpc to matcher and pass vercel timezone header

* feat: pass request to context

* feat: return timezone in header

* refactor: split context

* fix: remove tsignore comment

* Update [trpc].ts

---------

Co-authored-by: zomars <zomars@me.com>

* log the json url for testing

* use WEBAPP_URL constant instead env.NEXT_PUBLIC_WEBAPP_URL

* remove the commented selectedCalendars var, it is not necessary

* Caching fixes

* Separate selectedDate slots from month slots

* Update [trpc].ts

* Log headers

* Update [trpc].ts

* Update package.json

* Fixes/trpc headers (#7045)

* Cache fixes

* Testing

* SWR breaks embed tests

* Prevent refetching day on month switch

* Skeleton fixes

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Nafees Nazik <84864519+G3root@users.noreply.github.com>
Co-authored-by: Ben Hybert <53020786+Hybes@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Sai Deepesh <saideepesh000@gmail.com>
Co-authored-by: alannnc <alannnc@gmail.com>
Co-authored-by: Leo Giovanetti <hello@leog.me>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Harsh Singh <51085015+harshsinghatz@users.noreply.github.com>
Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>
Co-authored-by: Luis Cadillo <luiscaf3r@gmail.com>
Co-authored-by: Mohammed Cherfaoui <hi@cherfaoui.dev>
Co-authored-by: Joe Shajan <joeshajan1551@gmail.com>
Co-authored-by: Deepak Prabhakara <deepak@boxyhq.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Aaron Presley <155617+AaronPresley@users.noreply.github.com>
2023-02-13 11:42:53 -07:00
Nafees Nazik a2549bd7b6 feat: use week start from owner (#7072) 2023-02-13 16:21:55 +00:00
Joe Shajan c2a8f799ff fix: availability header margin bottom (#7037) 2023-02-13 15:06:27 +00:00
sean-brydon c68ff54e77 Feat/full custom select (#6865)
* Inital Setup - refactors/optimise

* Escape clears focus

* A11y and optimisations

* A11y enter fix

* Sort out flatternt list indexing

* Fix spacing - fix single selected state

* Solves group highlights breaking things

* Fix selecting while filtering list

* Remove styles and rename story

* Hide labels while searching for now

* Remove group item

* move onclick hook to hooks

* Fix typo

* Use check icon on single select

* scroll into view when keyboard navigating

* add comment explaining dropdown close

* Remove tenery and make disabled easier to read

* Typo

* remove log

* Remove destructing of classNames props

* Refactor callbacks + hooks

* Style updates with ciaran

* Final style changes

* center icon

* Add darkmode
2023-02-13 15:14:23 +01:00
darshan 74fe20802d Ability to write placeholder in routing forms (#7054) 2023-02-13 18:43:24 +05:30
Aaron Presley d59cda3286 Collective events are now considered from getBusyTimes booking query (#6911)
* Updated the busyTimes query to include bookings owned OR hosted by the given user

* Updated getSchedule tests to account for the new where condition

* Ignoring typing within a mocked function

* Further type checks, figured out how to run the command locally
2023-02-13 12:46:37 +00:00
Carina WollendorferandCarinaWolli 1cae2b6f3d Fixing issues around workflows (#6991)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-13 12:39:06 +00:00
Richard Poelderl 9d9fa8e575 turn inline logo & shell headers into h3 (#7060) 2023-02-13 12:29:48 +00:00
Nafees Nazik f04c634c48 fix: fixme line in todo action (#6982)
* fix: remove line marked with the comment fixme

* fix: remove push
2023-02-13 12:27:48 +00:00
alannnc c3e7981917 Fix/bookings unintended confirmations on rejection 6975 (#7047)
* Fixed translation message and added paymentStatus to booking page

* Fix booking confirmation with payment

* Remove previous code unnecesary
2023-02-13 12:26:28 +00:00
Shane Maglangit d6594dab0f fix: add null check for userSchedule.availability (#7053) 2023-02-13 11:23:24 +00:00
Carina WollendorferandCarinaWolli 5fcfbb2d90 fix text color (#7056)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-13 11:10:52 +00:00
Peer Richelsen 8a99c3d2a5 Update Tips.tsx 2023-02-12 22:34:07 +01:00
Peer Richelsen 336c2d3643 Update README.md 2023-02-12 22:06:03 +01:00
Peer Richelsen cfe3ef4ab0 Update README.md 2023-02-12 20:43:16 +01:00
Peer Richelsen 4ec8241a86 Update README.md 2023-02-12 20:33:16 +01:00
Peer Richelsen e6313aafac Update README.md 2023-02-12 20:31:32 +01:00
Peer Richelsen f87f030bb5 Update README.md 2023-02-12 20:31:20 +01:00
Amir FakhrullahandPeer Richelsen f87254cdc3 Fix: avatar group buggy with +0 (#7044)
* fix AvatarGroup, refactor a bit

* handle cases where truncated avatars are 2 digits

* use slice, and add comment

* update comment

* Update packages/ui/components/avatar/AvatarGroup.tsx

* fix classname order issue

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
2023-02-11 16:25:36 +00:00
Omar López 1f74837189 Fixes/trpc headers (#7045)
* Cache fixes

* Testing

* SWR breaks embed tests
2023-02-10 14:06:52 -07:00
Omar López c7064906c9 Update package.json (#7043) 2023-02-10 13:50:01 -07:00
Omar López 86c94a3cd5 Upgrades tRPC to 10.10.0 (#6995)
* Upgrades tRPC to 10.10.0

* Type fixes
2023-02-10 13:05:02 -07:00
Joe Au-Yeung 2056ebe186 Only show seats badge if it is greater than 1 (#7041) 2023-02-10 16:38:20 +00:00
Leo Giovanetti 53424ca9ae Fixing using given username (#7033) 2023-02-10 10:23:24 -03:00
Nafees NazikandPeer Richelsen 8197ba18d4 feat: add new Jitsu events (#6980)
Co-authored-by: Peer Richelsen <peer@cal.com>
2023-02-10 09:53:03 +00:00
GitStart-Cal.comandgitstart-calcom d341ea5111 [CAL-812] Button group focus/hover state (#6854)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-02-09 21:54:09 +00:00
Omar López 42dcd4a2a9 Revert "Use Calendar component view=day for drop-in replacement troubleshooter (#6869)" (#6985)
This reverts commit f18e80cfcf.
2023-02-09 12:01:43 -07:00
Leo Giovanetti c63225fdbf Fixing finish button not working (#6977) 2023-02-09 18:15:28 +00:00
zomars 41774e4932 Fix flaky test 2023-02-09 10:51:48 -07:00
Omar López af7849f951 v2.5.12
release.yml / release (push) Canceled after 0s
2023-02-09 09:34:51 -07:00
Alex van Andel 5353610d9a Only handle refunds when there are payments, otherwise skip (#6974) 2023-02-09 15:43:28 +00:00
+14 156f3e5de2 fix: admin password hint text (#6906)
* feat: use the trans hook

* fix: hide AdminPasswordBanner

* fix: translation

* fix: style and use validation

* fix: layout

* fix: use trans keys

* fix: replace number with placeholder

* feat: add alert banner

* fix: use the correct password length

* fix: metadata not saved while creating a booking. (#6866)

* feat: add metadata to booking creation

* fix: bug

* Beginning of Strict CSP Compliance (#6841)

* Add CSP Support and enable it initially for Login page

* Update README

* Make sure that CSP is not enabled if CSP_POLICY isnt set

* Add a new value for x-csp header that tells if instance has opted-in to CSP or not

* Add more src to CSP

* Fix typo in header name

* Remove duplicate headers fn

* Add https://eu.ui-avatars.com/api/

* Add CSP_POLICY to env.example

* v2.5.10

* fix: add req.headers (#6921)

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

* add-console-vars (#6929)

* Admin Wizard Choose License (#6574)

* Implementation

* i18n

* More i18n

* extracted i18n, needs api to get most recent price, added hint: update later

* Fixing i18n var

* Fix booking filters not working for admin (#6576)

* fix: react-select overflow issue in some modals. (#6587)

* feat: add a disable overflow prop

* feat: use the disable overflow prop

* Tailwind Merge (#6596)

* Tailwind Merge

* Fix merge classNames

* [CAL-808] /availability/single - UI issue on buttons beside time inputs (#6561)

* [CAL-808] /availability/single - UI issue on buttons beside time inputs

* Update apps/web/public/static/locales/en/common.json

* Update packages/features/schedules/components/Schedule.tsx

* create new translation for tooltip

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Bye bye submodules (#6585)

* WIP

* Uses ssh instead

* Update .gitignore

* Update .gitignore

* Update Makefile

* Update git-setup.sh

* Update git-setup.sh

* Replaced Makefile with bash script

* Update package.json

* fix: show button on empty string (#6601)

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

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

* fix: add delete in dropdown (#6599)

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

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

* Update README.md

* Update README.md

* Changed a neutral- classes to gray (#6603)

* Changed a neutral- classes to gray

* Changed all border-1 to border

* Update package.json

* Test fixes

* Yarn lock fixes

* Fix string equality check in git-setup.sh

* [CAL-811] Avatar icon not redirecting user back to the main page (#6586)

* Remove cursor-pointer, remove old Avatar* files

* Fixed styling for checkedSelect + some cleanup

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Harsh/add member invite (#6598)

Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>

* Regenerated lockfile without upgrade (#6610)

* fix: remove annoying outline when <Button /> clicked (#6537)

* fix: remove annoying outline when <Button /> clicked

* Delete yarn.lock

* remove 1 on 1 icon (#6609)

* removed 1-on-1 badge

* changed user to users for group events

* fix: case-sensitivity in apps path (#6552)

* fix: lowercase slug

* fix: make fallback blocking

* Fix FAB (#6611)

* feat: add LocationSelect component (#6571)

* feat: add LocationSelect component

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

* fix: type error

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

* chore: type error

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

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

* Update booking filters design  (#6543)

* Update booking filters

* Add filter on YOUR bookings

* Fix pending members showing up in list

* Reduce the avatar size to 'sm' for now

* Bugfix/dropdown menu trigger as child remove class names (#6614)

* Fix UsernameTextfield to take right height

* Remove className side-effect

* Incorrect resolution version fixed

* Converted mobile DropdownMenuTrigger styles into Button

* v2.5.3

* fix: use items-center (#6618)

* fix tooltip and modal stacking issues (#6491)

* fix tooltip and modal stacking issues

* use z-index in larger screens and less

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Temporary fix (#6626)

* Fix Ga4 tracking (#6630)

* generic <UpgradeScreen> component (#6594)

* first attempt of <UpgradeScreen>

* changes to icons

* reverted changes back to initial state, needs fix: teams not showing

* WIP

* Fix weird reactnode error

* Fix loading text

* added upgradeTip to routing forms

* icon colors

* create and use hook to check if user has team plan

* use useTeamPlan for upgradeTeamsBadge

* replace huge svg with compressed jpeg

* responsive fixes

* Update packages/ui/components/badge/UpgradeTeamsBadge.tsx

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>

* Give team plan features to E2E tests

* Allow option to make a user part of team int ests

* Remove flash of paywall for team user

* Add team user for typeform tests as well

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Removing env var to rely on db

* Restoring i18n keys, set loading moved

* Fixing tailwind-preset glob

* Wizard width fix for md+ screens

* Converting licenses options to radix radio

* Applying feedback + other tweaks

* Reverting this, not this PR related

* Unneeded code removal

* Reverting unneeded style change

* Applying feedback

* Removing licenseType

* Upgrades typescript

* Update yarn lock

* Typings

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712)

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713)

* Adds deployment settings to DB (#6706)

* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup

* Delete migration.sql

* Relying on both, env var and new model

* Restoring env example doc for backward compat

* Maximum call stack size exceeded fix?

* Revert upgrade

* Update index.ts

* Delete index.ts

* Not exposing license key, fixed radio behavior

* Covering undefined env var

* Self contained checkLicense

* Feedback

* Moar feedback

* Feedback

* Feedback

* Feedback

* Cleanup

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Nafees Nazik <84864519+G3root@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Harsh Singh <51085015+harshsinghatz@users.noreply.github.com>
Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>
Co-authored-by: Luis Cadillo <luiscaf3r@gmail.com>
Co-authored-by: Mohammed Cherfaoui <hi@cherfaoui.dev>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>

* added two new tips (#6915)

* [CAL-488] Timezone selection has a weird double dropdown (#6851)

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>

* fix: color and line height of icon (#6913)

* fix: use destination calendar email (#6886)

* fix: use destination calendar email
to display correct primary email

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

* fix: simplify logic

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

---------

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

* fix: dropdown title in bookings page (#6924)

* fixes the broken max size of members on teams page (#6926)

* fix: display provider name instead of url (#6914)

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

* fix: add sortByLabel (#6797)

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

* Email Variables Bug (#6943)

* Remove _subject translations for zh-CN, needs retranslation

* minor timezone-select improvements (#6944)

* fixed timezone select positioning and hover

* fixed timezone select positioning and hover

* Give trackingId a default value because if user doesnt interact with trackingId input it is not set (#6945)

* Block /auth/:path, nothing else. (#6949)

* Block /auth/:path, nothing else.

* Also add /signup

* fix start icon in button (#6950)

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Fixes localisation of {EVENT_DATE} in workflows (#6907)

* translate {EVENT_DATE} variable to correct language

* fix locale for cron schedule reminder emails/sms

* fix type error

* add missing locale to attendees

* fix type error

* code clean up

* revert last commit

* using Intl for date translations

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Allow account linking for Google and SAML providers (#6874)

* allow account linking for self-hosted instances, both Google and SAML are verified emails

* allow account linking for Google and SSO if emails match with existing username/password account

* Tweaked find user by email since we now have multiple providers (other than credentials provider)

* feat/payment-service-6438-cal-767 (#6677)

* WIP paymentService

* Changes for payment Service

* Fix for stripe payment flow

* Remove logs/comments

* Refactored refund for stripe app

* Move stripe handlePayment to own lib

* Move stripe delete payments to paymentService

* lint fix

* Change handleRefundError as generic function

* remove log

* remove logs

* remove logs

* Return stripe default export to lib/server

* Fixing types

* Fix types

* Upgrades typescript

* Update yarn lock

* Typings

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712)

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713)

* Adds deployment settings to DB (#6706)

* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup

* Revert "lint fix"

This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6.

* Add validation

* Revert changes removed in force push

* Removing abstract class and just leaving interface implementation

* Fix types for handlePayments

* Fix payment test appStore import

* Fix stripe metadata in event type

* Move migration to separate PR

* Revert "Move migration to separate PR"

This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6.

* Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql

Co-authored-by: Omar López <zomars@me.com>

---------

Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Small UI fixes for seats & destination calendars (#6859)

* Do not add former time for events on seats

* Default display destination calendar

* Add seats badge to event type item

* Add string

* Actively watch seats enabled option for requires confirmation

* Only show former time when there is a rescheduleUid

* fix: use typedquery hook in duplicate dialog (#6730)

* fix: use typedquery hook in duplicate dialog

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

* Update packages/features/eventtypes/components/DuplicateDialog.tsx

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Omar López <zomars@me.com>

* Fixing admin wizard step done (#6954)

* Feature/maintenance mode (#6930)

* Implement maintenance mode with Vercel Edge Config

* Error log is spam during development/ added \n in .env.example

* Exclude _next, /api for /maintenance page

* Re-instate previous config

* rtl: begone

* Added note to explain why /auth/login covers the maintenance page.

---------

Co-authored-by: Omar López <zomars@me.com>

* Update package.json

* I18N Caching (#6823)

* Caching Logic Changes

Enabled this function to change its cache value based on incoming paths value

* Invalidate I18N Cache

Invalidating the I18N cache when a user saves changes to their General settings

* Removes deprecated useLocale location

* Overriding the default getSchedule cache to have a revalidation time of 1 second

* Update apps/web/pages/api/trpc/[trpc].ts

* Updated cache values to match the comment

---------

Co-authored-by: zomars <zomars@me.com>

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: alannnc <alannnc@gmail.com>
Co-authored-by: Leo Giovanetti <hello@leog.me>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Harsh Singh <51085015+harshsinghatz@users.noreply.github.com>
Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>
Co-authored-by: Luis Cadillo <luiscaf3r@gmail.com>
Co-authored-by: Mohammed Cherfaoui <hi@cherfaoui.dev>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Joe Shajan <joeshajan1551@gmail.com>
Co-authored-by: Ben Hybert <53020786+Hybes@users.noreply.github.com>
Co-authored-by: Deepak Prabhakara <deepak@boxyhq.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Aaron Presley <155617+AaronPresley@users.noreply.github.com>
2023-02-09 02:02:17 +00:00
Omar López 05f51459a6 Add todo to issue action (#6749)
* Create todo-to-issue.yml

* Update todo-to-issue.yml

* Update todo-to-issue.yml

* Update todo-to-issue.yml

* Update todo-to-issue.yml

* test

* Update todo-to-issue.yml
2023-02-08 18:24:01 -07:00
Nafees Nazikandzomars f0db97bbb1 feat: return x-vercel-ip-timezone in headers (#6849)
* feat: add trpc to matcher and pass vercel timezone header

* feat: pass request to context

* feat: return timezone in header

* refactor: split context

* fix: remove tsignore comment

* Update [trpc].ts

---------

Co-authored-by: zomars <zomars@me.com>
2023-02-09 01:12:45 +00:00
Aaron Presleyandzomars 05c33bd94b I18N Caching (#6823)
* Caching Logic Changes

Enabled this function to change its cache value based on incoming paths value

* Invalidate I18N Cache

Invalidating the I18N cache when a user saves changes to their General settings

* Removes deprecated useLocale location

* Overriding the default getSchedule cache to have a revalidation time of 1 second

* Update apps/web/pages/api/trpc/[trpc].ts

* Updated cache values to match the comment

---------

Co-authored-by: zomars <zomars@me.com>
2023-02-08 17:35:43 -07:00
Omar López 7d4cc59cd2 Update package.json
release.yml / release (push) Canceled after 0s
2023-02-08 16:07:19 -07:00
Alex van AndelandOmar López a94465ff04 Feature/maintenance mode (#6930)
* Implement maintenance mode with Vercel Edge Config

* Error log is spam during development/ added \n in .env.example

* Exclude _next, /api for /maintenance page

* Re-instate previous config

* rtl: begone

* Added note to explain why /auth/login covers the maintenance page.

---------

Co-authored-by: Omar López <zomars@me.com>
2023-02-08 21:51:58 +00:00
Leo Giovanetti 4d54ac3ca2 Fixing admin wizard step done (#6954) 2023-02-08 14:36:46 -07:00
15da690270 fix: use typedquery hook in duplicate dialog (#6730)
* fix: use typedquery hook in duplicate dialog

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

* Update packages/features/eventtypes/components/DuplicateDialog.tsx

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Omar López <zomars@me.com>
2023-02-08 21:29:16 +00:00
Joe Au-Yeung 2462e8e597 Small UI fixes for seats & destination calendars (#6859)
* Do not add former time for events on seats

* Default display destination calendar

* Add seats badge to event type item

* Add string

* Actively watch seats enabled option for requires confirmation

* Only show former time when there is a rescheduleUid
2023-02-08 21:13:10 +00:00
2f628a17df feat/payment-service-6438-cal-767 (#6677)
* WIP paymentService

* Changes for payment Service

* Fix for stripe payment flow

* Remove logs/comments

* Refactored refund for stripe app

* Move stripe handlePayment to own lib

* Move stripe delete payments to paymentService

* lint fix

* Change handleRefundError as generic function

* remove log

* remove logs

* remove logs

* Return stripe default export to lib/server

* Fixing types

* Fix types

* Upgrades typescript

* Update yarn lock

* Typings

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712)

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713)

* Adds deployment settings to DB (#6706)

* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup

* Revert "lint fix"

This reverts commit e1a2e4a357e58e6673c47399888ae2e00d1351a6.

* Add validation

* Revert changes removed in force push

* Removing abstract class and just leaving interface implementation

* Fix types for handlePayments

* Fix payment test appStore import

* Fix stripe metadata in event type

* Move migration to separate PR

* Revert "Move migration to separate PR"

This reverts commit 48aa64e0724a522d3cc2fefaaaee5792ee9cd9e6.

* Update packages/prisma/migrations/20230125175109_remove_type_from_payment_and_add_app_relationship/migration.sql

Co-authored-by: Omar López <zomars@me.com>

---------

Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-08 13:36:22 -07:00
Deepak Prabhakara 1ee3783db3 Allow account linking for Google and SAML providers (#6874)
* allow account linking for self-hosted instances, both Google and SAML are verified emails

* allow account linking for Google and SSO if emails match with existing username/password account

* Tweaked find user by email since we now have multiple providers (other than credentials provider)
2023-02-08 11:39:56 -07:00
Carina WollendorferandCarinaWolli b3d8d7e944 Fixes localisation of {EVENT_DATE} in workflows (#6907)
* translate {EVENT_DATE} variable to correct language

* fix locale for cron schedule reminder emails/sms

* fix type error

* add missing locale to attendees

* fix type error

* code clean up

* revert last commit

* using Intl for date translations

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-08 17:06:25 +00:00
Carina WollendorferandCarinaWolli a4b7f1af65 fix start icon in button (#6950)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-02-08 17:02:08 +00:00
Alex van Andel f7445bf8a1 Block /auth/:path, nothing else. (#6949)
* Block /auth/:path, nothing else.

* Also add /signup
2023-02-08 16:27:18 +00:00
Hariom Balhara 9cad7086d7 Give trackingId a default value because if user doesnt interact with trackingId input it is not set (#6945) 2023-02-08 16:20:13 +00:00
Peer Richelsen 3345ec61ee minor timezone-select improvements (#6944)
* fixed timezone select positioning and hover

* fixed timezone select positioning and hover
2023-02-08 14:34:17 +00:00
Alex van Andel 7797421ce9 Remove _subject translations for zh-CN, needs retranslation 2023-02-08 14:31:29 +00:00
Udit Takkar 075a274207 Email Variables Bug (#6943) 2023-02-08 15:17:45 +01:00
Udit Takkar a46a31040a fix: add sortByLabel (#6797)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-02-08 12:48:47 +00:00
Udit Takkar 7a28e1d6f4 fix: display provider name instead of url (#6914)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-02-08 12:45:09 +00:00
Ben Hybert 51fd7fdb3e fixes the broken max size of members on teams page (#6926) 2023-02-08 12:44:28 +00:00
Joe Shajan d01963303a fix: dropdown title in bookings page (#6924) 2023-02-08 12:43:45 +00:00
Udit Takkar 6877d0f693 fix: use destination calendar email (#6886)
* fix: use destination calendar email
to display correct primary email

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

* fix: simplify logic

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

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-02-08 12:19:02 +00:00
Udit Takkar 39040fca9a fix: color and line height of icon (#6913) 2023-02-08 13:14:52 +01:00
GitStart-Cal.comandgitstart-calcom 6fa4befc9b [CAL-488] Timezone selection has a weird double dropdown (#6851)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-02-08 12:08:00 +00:00
Peer Richelsen 8c9871c6ce added two new tips (#6915) 2023-02-08 11:21:07 +00:00
+8 a9af2fb255 Admin Wizard Choose License (#6574)
* Implementation

* i18n

* More i18n

* extracted i18n, needs api to get most recent price, added hint: update later

* Fixing i18n var

* Fix booking filters not working for admin (#6576)

* fix: react-select overflow issue in some modals. (#6587)

* feat: add a disable overflow prop

* feat: use the disable overflow prop

* Tailwind Merge (#6596)

* Tailwind Merge

* Fix merge classNames

* [CAL-808] /availability/single - UI issue on buttons beside time inputs (#6561)

* [CAL-808] /availability/single - UI issue on buttons beside time inputs

* Update apps/web/public/static/locales/en/common.json

* Update packages/features/schedules/components/Schedule.tsx

* create new translation for tooltip

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* Bye bye submodules (#6585)

* WIP

* Uses ssh instead

* Update .gitignore

* Update .gitignore

* Update Makefile

* Update git-setup.sh

* Update git-setup.sh

* Replaced Makefile with bash script

* Update package.json

* fix: show button on empty string (#6601)

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

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

* fix: add delete in dropdown (#6599)

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

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

* Update README.md

* Update README.md

* Changed a neutral- classes to gray (#6603)

* Changed a neutral- classes to gray

* Changed all border-1 to border

* Update package.json

* Test fixes

* Yarn lock fixes

* Fix string equality check in git-setup.sh

* [CAL-811] Avatar icon not redirecting user back to the main page (#6586)

* Remove cursor-pointer, remove old Avatar* files

* Fixed styling for checkedSelect + some cleanup

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Harsh/add member invite (#6598)

Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>

* Regenerated lockfile without upgrade (#6610)

* fix: remove annoying outline when <Button /> clicked (#6537)

* fix: remove annoying outline when <Button /> clicked

* Delete yarn.lock

* remove 1 on 1 icon (#6609)

* removed 1-on-1 badge

* changed user to users for group events

* fix: case-sensitivity in apps path (#6552)

* fix: lowercase slug

* fix: make fallback blocking

* Fix FAB (#6611)

* feat: add LocationSelect component (#6571)

* feat: add LocationSelect component

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

* fix: type error

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

* chore: type error

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

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

* Update booking filters design  (#6543)

* Update booking filters

* Add filter on YOUR bookings

* Fix pending members showing up in list

* Reduce the avatar size to 'sm' for now

* Bugfix/dropdown menu trigger as child remove class names (#6614)

* Fix UsernameTextfield to take right height

* Remove className side-effect

* Incorrect resolution version fixed

* Converted mobile DropdownMenuTrigger styles into Button

* v2.5.3

* fix: use items-center (#6618)

* fix tooltip and modal stacking issues (#6491)

* fix tooltip and modal stacking issues

* use z-index in larger screens and less

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* Temporary fix (#6626)

* Fix Ga4 tracking (#6630)

* generic <UpgradeScreen> component (#6594)

* first attempt of <UpgradeScreen>

* changes to icons

* reverted changes back to initial state, needs fix: teams not showing

* WIP

* Fix weird reactnode error

* Fix loading text

* added upgradeTip to routing forms

* icon colors

* create and use hook to check if user has team plan

* use useTeamPlan for upgradeTeamsBadge

* replace huge svg with compressed jpeg

* responsive fixes

* Update packages/ui/components/badge/UpgradeTeamsBadge.tsx

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>

* Give team plan features to E2E tests

* Allow option to make a user part of team int ests

* Remove flash of paywall for team user

* Add team user for typeform tests as well

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>

* Removing env var to rely on db

* Restoring i18n keys, set loading moved

* Fixing tailwind-preset glob

* Wizard width fix for md+ screens

* Converting licenses options to radix radio

* Applying feedback + other tweaks

* Reverting this, not this PR related

* Unneeded code removal

* Reverting unneeded style change

* Applying feedback

* Removing licenseType

* Upgrades typescript

* Update yarn lock

* Typings

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712)

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713)

* Adds deployment settings to DB (#6706)

* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup

* Delete migration.sql

* Relying on both, env var and new model

* Restoring env example doc for backward compat

* Maximum call stack size exceeded fix?

* Revert upgrade

* Update index.ts

* Delete index.ts

* Not exposing license key, fixed radio behavior

* Covering undefined env var

* Self contained checkLicense

* Feedback

* Moar feedback

* Feedback

* Feedback

* Feedback

* Cleanup

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Nafees Nazik <84864519+G3root@users.noreply.github.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Harsh Singh <51085015+harshsinghatz@users.noreply.github.com>
Co-authored-by: Guest <guest@pop-os.localdomain>
Co-authored-by: root <harsh.singh@gocomet.com>
Co-authored-by: Luis Cadillo <luiscaf3r@gmail.com>
Co-authored-by: Mohammed Cherfaoui <hi@cherfaoui.dev>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2023-02-07 17:23:42 -07:00
alannnc 8c150264f4 add-console-vars (#6929) 2023-02-07 15:40:38 -07:00
Udit Takkar cfc3644d51 fix: add req.headers (#6921)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-02-07 12:42:47 +00:00
Omar López bdb4a7353b v2.5.10
release.yml / release (push) Canceled after 0s
2023-02-06 16:12:11 -07:00
Hariom Balhara 30c0e6d1d7 Beginning of Strict CSP Compliance (#6841)
* Add CSP Support and enable it initially for Login page

* Update README

* Make sure that CSP is not enabled if CSP_POLICY isnt set

* Add a new value for x-csp header that tells if instance has opted-in to CSP or not

* Add more src to CSP

* Fix typo in header name

* Remove duplicate headers fn

* Add https://eu.ui-avatars.com/api/

* Add CSP_POLICY to env.example
2023-02-06 22:50:08 +00:00
Nafees Nazik 390967990a fix: metadata not saved while creating a booking. (#6866)
* feat: add metadata to booking creation

* fix: bug
2023-02-06 18:05:30 +00:00
Peer Richelsen cc56602474 nit border change (#6899) 2023-02-06 15:59:20 +01:00
Peer Richelsen 43a044d59e theme for storybook 2023-02-06 15:15:26 +01:00
Alex van Andel 5b8ed9c3ef When unchecking the common schedule, schedule should be nulled (#6898) 2023-02-06 15:01:54 +01:00
Sai Deepesh c3d6df2dcf fix(date-overrides): alignment of edit & delete btns (#6892) 2023-02-06 01:31:05 +00:00
Alex van Andel 9d02cb493c Fixed some inconsistencies within single event type page (#6887)
* Fixed some inconsistencies within single event type page

* Fix layout shift on AvailabilityTab
2023-02-06 00:09:27 +01:00
sean-brydon 26ed478e50 Hide button (#6895) 2023-02-05 20:30:51 +00:00
Syed Ali Shahbaz 09e338970d Updates heroku deployment template (#6879) 2023-02-05 14:50:04 +00:00
Udit Takkar f60399ca8b fix: get location url from metadata (#6774)
* fix: get location url from metadata

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

* fix: replace location

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

* fix: type error

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

* fix: use zod

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

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-02-05 14:43:37 +00:00
Carina Wollendorfer 5cf7e32852 fix workflows when duplicating event types (#6873) 2023-02-04 13:06:37 +01:00
24be8a63f2 fix: filter booking in upcoming (#6406)
* fix: filter booking in upcoming

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

* fix: test

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

* fix: wipe-my-cal failing test

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

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Peer Richelsen <peer@cal.com>
2023-02-03 22:03:35 +00:00
Hariom Balhara 75509c97fd Hotfix: For old Plausible installs enabled in an EventType, give a default value (#6860)
* Add default for trackingId for old plausible installs in event-types

* Fix types
2023-02-03 21:38:06 +00:00
Peer Richelsen 9b26c7aee6 lots of small changes by me and ciaran (#6871) 2023-02-03 16:49:33 +00:00
Alex van Andel f18e80cfcf Use Calendar component view=day for drop-in replacement troubleshooter (#6869)
* Use Calendar component view=day for drop-in replacement troubleshooter

* Setting the id to undefined makes the busy time selected

* Updated event title to include title+source
2023-02-03 16:43:52 +00:00
Ben Hybert 0a4b1ca014 version 2.5.9 (#6868) 2023-02-03 15:36:31 +00:00
Nafees Nazik 9fa6aced33 feat: make key unique (#6861)
release.yml / release (push) Canceled after 0s
2023-02-03 11:20:45 +01:00
Hariom Balhara 9093909075 Hotfix: Event Name (#6863) (#6864) 2023-02-03 11:20:10 +01:00
Aaron Presley 832fce91e0 Left / Right buttons now bottom-aligned and slightly shorter (#6857)
Fixes https://github.com/calcom/cal.com/issues/6589
2023-02-02 20:49:20 +01:00
Peer Richelsen 6da41fce63 fixed availabilty layout 2023-02-02 19:28:46 +01:00
Alex van Andel 3b51cc9aef v2.5.8
release.yml / release (push) Canceled after 0s
2023-02-02 15:54:38 +00:00
Hariom Balhara 50c8959cfa Use trackingId only for trackingDomain as thats the only variable supported (#6856) 2023-02-02 15:13:42 +00:00
Hariom Balhara c96d258f5e Give highest possible value to z-index (#6853) 2023-02-02 15:04:38 +00:00
Alex van Andel 6e45b1c383 Don't override but decorate the built-in encode function (#6850)
* Don't override but decorate the built-in encode function

* Removed jose + synced lockfile
2023-02-02 14:26:00 +00:00
GitStart-Cal.comandgitstart-calcom 551ebe863b [CAL-90] Event Types Single / Allow multiple physical locations (#6692)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-02-02 12:42:56 +00:00
Peer Richelsen fa7b94bfe9 Merge branch 'main' of https://github.com/calcom/cal.com 2023-02-02 13:33:49 +01:00
Peer Richelsen 56c5d39cd3 i18n fix 2023-02-02 12:50:28 +01:00
Peer Richelsen 7574fb6f44 i18n fix 2023-02-02 12:49:11 +01:00
Nafees Nazik 901d1f0e01 fix: make cal video default value (#6716) 2023-02-02 12:24:34 +01:00
GitStart-Cal.comandgitstart-calcom 828fcbe1d9 [CAL-713] /availability single - layout issues. Check spacing, margin, alignment with spec'd design (#6724)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-02-02 12:21:05 +01:00
Joe Au-Yeung 34db46869e Move e2e to buildjet (#6840) 2023-02-02 08:42:28 +00:00
Nafees Nazik 1f1cab2be1 fix: padding in shell for mobile (#6825)
* fix: padding

* fix: breakpoints in fab

* fix: padding
2023-02-02 09:24:31 +01:00
Alex van Andel 6cf53feaf8 v2.5.7
release.yml / release (push) Canceled after 0s
2023-02-02 01:06:20 +00:00
Leo Giovanetti 376b693d91 Not allowing random duration (#6743) 2023-02-01 22:19:37 +00:00
Alex van Andel 831aa72d23 Invalidate hasTeamPlan when the last team is removed (#6837) 2023-02-01 21:23:34 +00:00
Peer RichelsenandAlex van Andel ef78db7856 /teams improvements (#6831)
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-02-01 20:41:47 +00:00
Nafees Nazik 7ee5967075 feat: add theming options to teams (#6807) 2023-02-01 19:27:26 +01:00
Alex van Andel 5b165e6ebf Fixed broken path to fix SB build failure 2023-02-01 16:09:45 +00:00
Joe Shajan 624f52c305 webhook from ui design change (#6803)
* webhook from ui change

* fix: webhook test border & test webhook font style
2023-02-01 14:51:42 +00:00
GitStart-Cal.comandgitstart-calcom df25ae6a3d [CAL-845] Improve the custom event name modal UI/UX (#6660)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-02-01 13:10:16 +01:00
Josh Avant 7f65d7f3c3 Removes pay_later_instructions (#6824) 2023-02-01 09:17:11 +01:00
Alex van AndelandHariom Balhara c42674595c Add X-Frame-Options to page headers (#6784)
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-02-01 11:28:47 +05:30
Nafees Nazikandalannnc 17eb45b0b6 fix: input component style in routing forms (#6731)
* fix: remove custom className

* removed extra type text

removed extra type text from input

---------

Co-authored-by: alannnc <alannnc@gmail.com>
2023-02-01 01:39:29 +00:00
Peer Richelsen 48d0edeaf4 fixed event-type description 2023-01-31 23:35:05 +01:00
Peer Richelsen ed4b31767f lint 2023-01-31 23:33:20 +01:00
Peer Richelsen cebb10bfe4 re-adding subtitle to Shell 2023-01-31 23:31:04 +01:00
Ben Lam 7a6e7c2f1d Removed unused variables (#6704) (#6750) 2023-01-31 22:29:24 +00:00
Peer Richelsen 0ffed24359 user management moved to console.cal.com (#6799) 2023-01-31 21:59:11 +00:00
Nafees NazikandAlan e121615d36 fix: installed apps and admin apps layout spacing issues. (#6753)
* feat: add highlight props

* feat: add isTemplate prop

* feat: add invalid credintial prop

* feat: add children prop

* feat: render app list card

* fix: add horizontal gap

* fix: installed app layout style

* fix: admin layout

* feat: add isGlobal to returned data

* feat: fix admin tab.

* use common components list and AppListCard

* show isDefault Badge

* hide switch for global apps

* fix: show switch

* fix: remove isglobal

* fix: layout

* refactor: remove unused component and import

* feat: use app list card component

* fix: query param

* fix: prevent unnecessary props passed to the component

* feat: add disabled style

* feat: add disconnect integration modal

* feat: new changes.

* render disconnect integration model only once.

* add dropdown for actions

* feat: changes in admin apps.

* use dropdown for selecting action buttons.

* use modal for editing keys.

* Remove boolean comparison

---------

Co-authored-by: Alan <alannnc@gmail.com>
2023-01-31 22:45:38 +01:00
4f9aa8bd96 Hide attendees from calendar description (#6800)
* Show the organizer timezone when booking on seats

* Only show organizer in event description

* Type fixes

* Update snapshot with new response

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Alan <alannnc@gmail.com>
2023-01-31 14:14:19 -07:00
alannncandsean-brydon 64ede37ad6 Fix embed modal leading inputs (#6822)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-01-31 13:58:15 -07:00
36b6c351ec Session Timeout (#6439)
* Implementation

* Unifying UI to password screen

* Tweaks for session in password section

* Update apps/web/pages/settings/security/password.tsx

Co-authored-by: Omar López <zomars@me.com>

* Update packages/features/kbar/Kbar.tsx

Co-authored-by: Omar López <zomars@me.com>

* Update packages/features/settings/layouts/SettingsLayout.tsx

Co-authored-by: Omar López <zomars@me.com>

* Relying on extra db query

* Upgrades typescript

* Update yarn lock

* Typings

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712)

* Hotfix: ping,riverside,whereby and around not showing up in list (#6712) (#6713)

* Adds deployment settings to DB (#6706)

* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup

* Using same version as other deps

* Reverting prisma changes and fixing things

* Uneeded tx-expect-error

* Fixing default value

* Update apps/web/public/static/locales/en/common.json

Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>

---------

Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2023-01-31 17:44:14 -03:00
GitStart-Cal.comandgitstart-calcom 9ab5a3149c [CAL-807] /event-types/single - Fix the header (#6738)
release.yml / release (push) Canceled after 0s
* [CAL-807] /event-types/single - Fix the header

* [CAL-807] /event-types/single - Fix the header

* [CAL-807] /event-types/single - Fix the header

---------

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-01-31 20:19:02 +00:00
Nafees NazikandAlan 3b8f436bdf feat: tabs for teams in mobile (#6685)
* fix: padding

* feat: add teams tab component

* fix: add image to type

* fix: current path check

* fix: add avatar prop

* feat: add teams tab for mobile

* fix: padding

* fix: background and padding x

* fix: empty logic

* fix: conditions

* fix: bg

---------

Co-authored-by: Alan <alannnc@gmail.com>
2023-01-31 12:54:40 -07:00
Nafees Nazik 77d45a6ec2 fix: use guest email in create booking link banner (#6694) 2023-01-31 19:47:32 +00:00
Carina WollendorferandCarinaWolli 50c74cf286 change useHasTeamPlan hook to useHasPaidPlan (#6699)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-01-31 19:10:21 +00:00
Richard Poelderl dcbafced8b update isCalcom for canonicals to handle https://cal.com (#6802)
* update isCalcom for canonicals to handle https://cal.com

* avoid env var

* prettier

* handle window undefined

* handle window undefined during pre-render

* add some logs

* add some logs

* Revert "add some logs"

This reverts commit 9d27de029024e526417bc79e9cee42d7333ac592.
2023-01-31 19:07:50 +00:00
GitStart-Cal.comandgitstart-calcom 4679c80ea0 [CAL-727] [500] on /api/trpc/[trpc] (#6795)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-01-31 18:50:06 +00:00
Bram Verstraten 291316ee01 Fix Dutch custom event names (#6806)
Continued from #6375
2023-01-31 18:46:07 +00:00
sean-brydon 208fc2f0e4 Feat - invite user to team flow improvements (#6725) 2023-01-31 18:16:43 +00:00
Joe Au-Yeung 99e71054ff Change lint action to run on BuildJet (#6819) 2023-01-31 19:08:08 +01:00
Nafees Nazik 9d118d4e34 fix: flash of i18n in teams page (#6818) 2023-01-31 19:05:18 +01:00
+6 d1a877e70d Add additional guests (#6419)
* Add additional guests

* WIP

* WIP

* Type fix

* WIP

* Add validation for already invited attendees

* Revert type to email

* remove controlled fields

* disables signups via env variable (#6212)

* disables signups via env variable

* Apply suggestions from code review

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Omar López <zomars@me.com>

* Reusable Upgrade component for teams only features (#6473)

Co-authored-by: CarinaWolli <wollencarina@gmail.com>

* i18n udpate

* fix: darkmode in booking/[id] page (#6458)

* fix: text-area style

* fix: border styles

* fix: german translation for reschedule booking email  subject (#6483)

* fix: german translation for reschedule subject

* fix: add a full stop

* fix: app store spacing issues (#6481)

* feat: add equal spacing with gap

* fix: title style

* fix: title style

* fix: remove margin

* fix: remove margin

* fix: sub header spacing and slider button

* fix: category card text

* fix: app store spacing issues

* fix: tab in tablet

* fix: shell

* fix: styling of dropdown component (#6440)

* fix: styling of dropdown component

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

* Apply suggestions from code review

* fix: use dropdown item in all pages

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

* chore: undo

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

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* readding sidebar tips for everyone, added 3 more features to teams empty screen (#6475)

* readding sidebar tips for everyone

* added 3 more features to teams plan

* responsive fixes

* responsive fixes

* small responsive fix

* CTA alignment fixed

* Minor alignment fixes to Shell for event-types/[type]

Co-authored-by: Alex van Andel <me@alexvanandel.com>

* fix: wrong i18n  placeholder in many locales (#6496)

* fix: czech translation

* fix: spanish translation

* fix: italian translation

* fix: japanese translation

* fix: korean translation

* fix: dutch translation

* fix: norwegian translation

* fix: polish translation

* fix: portuguese translation

* fix: portuguese translation

* fix: romanian translation

* fix: russian translation

* fix: serbian translation

* fix: swedish translation

* fix: turkish translation

* fix: ukrainian translation

* fix: vietnamese translation

* fix: chinese simplified translation

* fix: chinese traditional translation

* Disable redirect for cancellation page (#6498)

* [CAL-677] /event-type : Event Setup sidebar item doesn't reflect multiple durations (#6390)

Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>

* Added fallback to hostsFixed too which is used in COLLECTIVE (#6500)

* Don't update the field when changing the select (#6486)

* Don't update the field when changing the select

* Fixing missing label

* Applied the correct y-8 vertical margin

* Changed the description vertical offset from title a bit more

* Add Trash icon on Availability list dropdown

* fix: tablet sidebar profile being too wide and not centered  (#6490)

* feat: updated app list items styling issues inside settings/conferencing

* feat: fixed tablet sidebar width and not centered issue

* fix: removed un-related changes from this pr

* deleted .env

* fix: added the accidentaly deleted .env file

* fix: removed unwanted .env file from the pr

Co-authored-by: Peer Richelsen <peeroke@gmail.com>

* Bring back PublicShell (#6505)

* Add red text to error message

* WIP

* Rearrange guest input

* Fix validate unique guests logic

* Allow guests on reschedule

* Lint fix

* More lint fixes

* Lint fixes

* More lint fixes

* Fix remove guest button margin

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
Co-authored-by: Jeff Loiselle <jeff@loiselles.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Nafees Nazik <84864519+G3root@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com>
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
Co-authored-by: Ronit Panda <72537293+rtpa25@users.noreply.github.com>
Co-authored-by: Alan <alannnc@gmail.com>
2023-01-31 17:36:38 +00:00
Nafees Nazik 238b509be6 fix: border color in dark teams page (#6817) 2023-01-31 18:21:51 +01:00
Richard Poelderl c7471b404c fix(web): remove noindex & nofollow tags from the App and Shell components (#6816)
Fixes https://github.com/calcom/cal.com/issues/6815
2023-01-31 17:08:59 +00:00
Alex van Andel 4db4df8ace Correct invalid ukraine language code ua -> uk 2023-01-30 21:09:09 +00:00
Udit Takkar a15b8fb92e fix: booking limits saved as undefined (#6720)
* fix: booking limits saved as undefined

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

* fix: add event limit

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

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-01-30 19:38:22 +01:00
Syed Ali Shahbaz a4bed48eaf Standardize response codes in Login (#6787)
* standardizing login response codes

* playwright fix

* added translation
2023-01-30 18:37:03 +00:00
Peer Richelsen 1be6f192d4 added impersonation tip (#6794) 2023-01-30 16:19:11 +01:00
Richard Poelderl f1c5838aef fix(web): set canonical as https://cal.com in the <HeadSeo/> (#6693)
* fix(web): set canonical as https://cal.com in the <HeadSeo/>

* use `window.document.location?.href` if self hosted

* clean up

* use `isCalcom` from library

* handle trailing slash on homepage again
2023-01-30 13:54:07 +01:00
Peer Richelsen 8e994dcc33 adding ukrainian (#6791) 2023-01-30 13:49:08 +01:00
Peer Richelsen 506bbe3d31 Update README.md 2023-01-30 13:48:02 +01:00
Nafees Nazik 419a84c5a2 fix: location select menu overflowing the container (#6719) 2023-01-30 12:58:37 +01:00
Hariom Balhara 8cf0050d1f Fix: EventType Duplication (#6778) 2023-01-30 12:55:08 +01:00
Sai Deepesh 6c23813192 fix padding of lenght input on add event modal (#6771) 2023-01-30 11:12:53 +00:00
Joe Au-Yeung 875f922597 Disable autocomplete on password field (#6705) 2023-01-30 09:42:52 +00:00
Udit Takkar c8e3f6494a fix: back button and heading size (#6768)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-01-29 10:38:31 +01:00
Carina WollendorferandCarinaWolli 333801d2ae Fix shift-enter in bio editor (#6769)
* fix wrong enabled update button at first load

* fix shift-enter error

* small fixes + code clean up

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-01-27 23:14:58 +00:00
Joe Au-Yeung 60f7528cbc On seats, hide attendees if option is selected (#6767)
* On seats, hide attendees if option is selected

* Remove unused line
2023-01-27 12:10:49 -07:00
Peer Richelsen 0faf294367 removed credits from auth container (#6766) 2023-01-27 19:20:39 +01:00
Peer Richelsen 87c178e53b added blue color for links in bio (#6760) 2023-01-27 17:03:04 +01:00
Peer Richelsen 7710b1b718 Update README.md 2023-01-27 15:14:16 +01:00
Peer Richelsen d71c6ccb31 Update README.md 2023-01-27 12:07:12 +01:00
GitStart-Cal.comandgitstart-calcom 33a4117fb5 On duplicating an event type, spacing between arrows and label is wide (Length field) (#6717)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-01-27 11:06:29 +01:00
Omar López a90419c40b Adds booking data to SDK success event (#6737) 2023-01-27 11:02:33 +05:30
Omar López 16adf86c8c Upgrades typescript to 4.9.4 (#6747)
* Upgrades typescript to 4.9.4

* Type fixes
2023-01-26 18:50:56 -07:00
Peer Richelsen 3b838c475a replaced edit location dialog subtitle with link to app store (#6746) 2023-01-27 00:33:56 +01:00
Omar López cf33106d8b WIP: SIU: Maximum call stack size exceeded fix? (#6740)
* Maximum call stack size exceeded fix?

# Conflicts:
#	packages/prisma/index.ts

* Prisma client extensions is too much for our TS

* Removed unused Icons

* Type fixes
2023-01-26 17:51:03 -05:00
zomars a63f9ddf61 Adds deployment settings to DB (#6706) 2023-01-26 13:36:15 -07:00
zomars 1cf83068b2 Update yarn.lock 2023-01-26 13:33:59 -07:00
Hariom Balhara 23de92f818 Hotfix: ping,riverside,whereby and around not showing up in list (#6712) 2023-01-26 13:31:13 -07:00
zomars c6fc1f756b Update yarn.lock 2023-01-25 16:56:44 -07:00
zomars 88b7c506f1 Include submodule dependencies in lockfile 2023-01-25 16:56:25 -07:00
zomars 755aae969c Removed pre-install script
devs should opt-in to submodules
2023-01-25 13:39:12 -07:00
Peer Richelsen 2d50d09ce6 added hacker news badge to readme 2023-01-25 13:52:08 +01:00
Peer Richelsen a22397dbb4 Update README.md 2023-01-25 13:44:28 +01:00
Mohammed Cherfaoui d1076982a7 fix: event location link modal (#6387) 2023-01-25 09:49:05 +00:00
Nafees Nazik d77e4f3c4a fix: decode characters if encoded (#6447) 2023-01-25 09:44:48 +00:00
Joe Cohen b1c0ea4c38 Fix duplicate event modal page slug (#6657) 2023-01-25 09:16:50 +00:00
Carina WollendorferandCarinaWolli 425e18f53c enable scroll (#6676)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-01-25 09:14:20 +00:00
Peer Richelsen 3611807838 Update README.md (#6682) 2023-01-25 09:13:33 +00:00
Udit Takkar 5b1cd9e5ce fix: send email if username is being passed (#6674)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-01-25 08:56:20 +00:00
Joe Au-Yeung 00bff598ef Add videoCallData to evt on new attendee (#6673)
* Add videoCallData to evt on new attendee

* Remove console.log
2023-01-25 08:52:58 +00:00
Nafees Nazik 3a8aa26c78 fix: duplicate iframes in cal video (#6662)
* chore: upgrade daily-co

* feat: return only needed data and preload i18n

* fix: useEffect
2023-01-25 08:51:09 +00:00
Carina WollendorferandCarinaWolli 3c761f4451 Fixes issues with workflows that have more than one action (#6670)
* fix untitled workflow name when no action exists

* fix wrong data loaded one first laod when step was added

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-01-25 08:42:57 +00:00
8640eb9f52 Ability to format user and team bio (#6572)
* use texteditor for bio

* remove block types from about editor

* add props to make editor height adjustable

* set isDirty to true when about input is edited

* add editor to getting-started

* fix editor height

* remove required error for onboarding

* add helper function to check if parsed bio has text

* add back commented code

* fix onboarding tests for optional about field

* rename function

* parse team bio for read only members

* code clean up

* fix failing e2e because of missing test id

* fix onboarding e2e test

* add missing parse of user bio

* Update apps/web/components/getting-started/steps-views/UserProfile.tsx

* Update apps/web/pages/settings/my-account/profile.tsx

Co-authored-by: Omar López <zomars@me.com>

* use css inline style for height instead of tailwind class

* fix height of editor-input

* save bio as markdown in db

* fix empty line when bio is empty

* fix hydration failed error

* Update packages/ui/components/editor/Editor.tsx

Co-authored-by: Omar López <zomars@me.com>

* remove unused import

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-01-24 18:08:10 -07:00
Kiran K abb5fd36f3 Support OIDC (#6661)
* Support OIDC

* tweak to the Configure button

* fix the type import
2023-01-24 13:02:43 -07:00
Alex van Andel 865663646a v2.5.5
release.yml / release (push) Canceled after 0s
2023-01-24 16:54:35 +00:00
Alex van Andel b7c92063c2 Revert "v2.5.4"
This reverts commit 4f293edb6b.
2023-01-24 16:54:05 +00:00
Alex van Andel 4f293edb6b v2.5.4 2023-01-24 16:52:33 +00:00
Ben HybertandAlex van Andel 0c88cf75e0 corrected avatars inside users block (#6667)
* corrected avatars inside users block

* ensured the team avatar didnt shrink too

* Update packages/ui/components/avatar/Avatar.tsx

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-01-24 16:10:43 +00:00
Nafees NazikandUdit Takkar 0b93647209 fix: double border issue in Location Select (#6646)
* fix: border issue

* fix: remove border from dropdown

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

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-01-24 17:05:35 +01:00
Alex van Andel b931b00714 Add env variables to turbo.json relevant to the website build (#6654) 2023-01-24 15:47:46 +00:00
Nafees Nazik 796a5f8d51 feat: use cal video as the default location (#6643)
* feat: use cal video as default while creating new events

* feat: use cal video as default value

* chore: remove default value

* fix: default value logic

* chore: remove console.log
2023-01-24 15:28:40 +00:00
sean-brydon 905a110377 Invites (#6665) 2023-01-24 15:27:05 +00:00
Alex van Andel 6ccc19985f Add sizePropsBySize to avatarPrimitive root (#6666) 2023-01-24 14:01:27 +00:00
Udit Takkar 8f71474303 fix: add allowOverflow property (#6636)
* fix: add allowOverlfow property

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

* fix: date override input dialog

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

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-01-24 14:00:45 +00:00
zomars 5f351230ff Ignores auth submodule 2023-01-23 16:50:17 -07:00
Alex van Andel 3e005919c1 Only return enabled apps in getEnabledApps (#6653) 2023-01-23 16:27:20 -07:00
cfa8fd8b67 Reduce bundle size by importing single icons at a time (#6644)
* Removed barrel import for icons to reduce bundle size.

* Fixed replacement mistakes

* Reverted unneccesary yarn.lock updates

* Added some missed Icon. import conversions

* Remove merge artifact import in @calcom/ui

* Don't import Icon in pages/[user]

* Update packages/ui/package.json

Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Omar López <zomars@me.com>
2023-01-23 23:08:01 +00:00
Alex van Andel a888be6e04 Support both https/git by detection of origin root (#6651)
* Support both https/git by detection of origin root

* Remove unnecessary .

* Minor comment fixup
2023-01-23 23:05:53 +00:00
Joe Au-Yeung 6aa2cba3ce Msteams access token refresh (#6607)
* Add is valid call

* WIP

* Change logic for Microsoft refresh token

* remove async
2023-01-23 15:36:24 -07:00
sean-brydon 12ab615684 Fix weird avatar issue (#6645) 2023-01-23 15:48:40 +00:00
1d792a2c6c generic <UpgradeScreen> component (#6594)
* first attempt of <UpgradeScreen>

* changes to icons

* reverted changes back to initial state, needs fix: teams not showing

* WIP

* Fix weird reactnode error

* Fix loading text

* added upgradeTip to routing forms

* icon colors

* create and use hook to check if user has team plan

* use useTeamPlan for upgradeTeamsBadge

* replace huge svg with compressed jpeg

* responsive fixes

* Update packages/ui/components/badge/UpgradeTeamsBadge.tsx

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>

* Give team plan features to E2E tests

* Allow option to make a user part of team int ests

* Remove flash of paywall for team user

* Add team user for typeform tests as well

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-01-23 10:58:41 +01:00
Hariom Balhara 9602ac29fb Fix Ga4 tracking (#6630) 2023-01-23 09:09:16 +00:00
Leo Giovanetti 5714471b9a Temporary fix (#6626)
release.yml / release (push) Canceled after 0s
2023-01-22 17:27:27 +00:00
Mohammed CherfaouiandAlex van Andel a99e93a4bd fix tooltip and modal stacking issues (#6491)
* fix tooltip and modal stacking issues

* use z-index in larger screens and less

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-01-22 20:31:25 +05:30
Udit Takkar 7f044ff92f fix: use items-center (#6618) 2023-01-22 13:36:07 +01:00
848 changed files with 18139 additions and 7871 deletions
+11 -4
View File
@@ -1,20 +1,21 @@
# ********** INDEX **********
#
# - LICENSE
# - LICENSE (DEPRECATED)
# - DATABASE
# - SHARED
# - NEXTAUTH
# - E-MAIL SETTINGS
# - LICENSE *************************************************************************************************
# https://github.com/calendso/calendso/blob/main/LICENSE
# - LICENSE (DEPRECATED) ************************************************************************************
# https://github.com/calcom/cal.com/blob/main/LICENSE
#
# Summary of terms:
# - The codebase has to stay open source, whether it was modified or not
# - You can not repackage or sell the codebase
# - Acquire a commercial license to remove these terms by visiting: cal.com/sales
#
# To enable enterprise-only features, fill your license key in here.
# To enable enterprise-only features, as an admin, go to /auth/setup to select your license and follow
# instructions. This environment variable is deprecated although still supported for backward compatibility.
# @see https://console.cal.com
CALCOM_LICENSE_KEY=
# ***********************************************************************************************************
@@ -157,3 +158,9 @@ NEXT_PUBLIC_COMPANY_NAME="Cal.com, Inc."
# Set this to true in to disable new signups
# NEXT_PUBLIC_DISABLE_SIGNUP=true
NEXT_PUBLIC_DISABLE_SIGNUP=
# Content Security Policy
CSP_POLICY=
# Vercel Edge Config
EDGE_CONFIG=
+32
View File
@@ -0,0 +1,32 @@
# This is a comment.
# Each line is a file pattern followed by one or more owners.
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
* @calcom/reviewers
.github/ @calcom/core
.husky/ @calcom/core
.vcode/ @calcom/core
.snaplet/ @calcom/core
deploy/ @calcom/core
scripts/ @calcom/core
apps/docs @calcom/docs
apps/swagger @calcom/docs
packages/app-store-cli @hariombalhara
packages/dayjs @zomars
packages/emails @zomars
packages/embeds @hariombalhara
packages/eslint-plugin @zomars
packages/features @zomars
packages/features/kbar @alishaz-polymath
packages/features/ee/impersonation @sean-brydon
packages/features/ee/payments @alannnc
packages/features/ee/workflows @CarinaWolli
packages/features/tips @PeerRich
packages/ui @calcom/ui
packages/config @calcom/core
+23
View File
@@ -0,0 +1,23 @@
name: Cache production build binaries
description: "Cache or restore if necessary"
env:
node_version: v16.x
runs:
using: "composite"
steps:
- name: Cache production build
uses: actions/cache@v3
env:
cache-name: prod-build
key-1: ${{ env.node_version }}-${{ hashFiles('yarn.lock') }}
key-2: ${{ hashFiles('apps/web/next.config.js') }}
with:
path: |
apps/web/.next
node_modules/.cache/turbo
**/.turbo/**
**/dist/**
key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-${{ env.key-2 }}-
${{ runner.os }}-${{ env.cache-name }}-${{ env.key-1 }}-
+34
View File
@@ -0,0 +1,34 @@
name: Cache database between jobs
description: "Cache or restore if necessary"
inputs:
DATABASE_URL:
required: true
path:
required: false
default: "backups/backup.sql"
runs:
using: "composite"
steps:
- name: Cache database
id: cache-db
uses: actions/cache@v3
env:
cache-name: cache-db
with:
path: ${{ inputs.path }}
key: ${{ runner.os }}-${{ env.cache-name }}-${{ inputs.path }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-${{ env.cache-name }}-${{ inputs.path }}-${{ github.sha }}
- name: Postgres Dump Backup
if: steps.cache-db.outputs.cache-hit != 'true'
uses: tj-actions/pg-dump@v2.3
with:
database_url: ${{ inputs.DATABASE_URL }}
path: ${{ inputs.path }}
options: "-O"
- name: Postgres Backup Restore
if: steps.cache-db.outputs.cache-hit == 'true'
uses: tj-actions/pg-restore@v4.5
with:
database_url: ${{ inputs.DATABASE_URL }}
backup_file: ${{ inputs.path }}
@@ -0,0 +1,10 @@
name: Dangerous git Checkout
description: "Git Checkout from PR code so we can run checks from forks"
runs:
using: "composite"
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2
+104
View File
@@ -0,0 +1,104 @@
name: Production Build
description: "Creates a production build, caches it and restores if necessary"
inputs:
DATABASE_URL:
required: true
NEXT_PUBLIC_WEBAPP_URL:
required: true
NEXT_PUBLIC_WEBSITE_URL:
required: true
NEXTAUTH_SECRET:
required: true
GOOGLE_API_CREDENTIALS:
required: true
GOOGLE_LOGIN_ENABLED:
required: true
CRON_API_KEY:
required: false
CALENDSO_ENCRYPTION_KEY:
required: true
DAILY_API_KEY:
required: true
NEXT_PUBLIC_STRIPE_PUBLIC_KEY:
required: true
NEXT_PUBLIC_STRIPE_FREE_PLAN_PRICE:
required: true
NEXT_PUBLIC_STRIPE_PRO_PLAN_PRICE:
required: true
NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE:
required: true
NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE:
required: true
NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN:
required: true
STRIPE_PRIVATE_KEY:
required: true
STRIPE_CLIENT_ID:
required: true
STRIPE_WEBHOOK_SECRET:
required: true
STRIPE_PRO_PLAN_PRODUCT_ID:
required: true
STRIPE_PREMIUM_PLAN_PRODUCT_ID:
required: true
STRIPE_FREE_PLAN_PRODUCT_ID:
required: true
PAYMENT_FEE_PERCENTAGE:
required: true
PAYMENT_FEE_FIXED:
required: true
SAML_DATABASE_URL:
required: true
SAML_ADMINS:
required: true
NEXTAUTH_URL:
required: true
NEXT_PUBLIC_IS_E2E:
required: true
TURBO_TOKEN:
required: true
TURBO_TEAM:
required: true
runs:
using: "composite"
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/cache-build
id: prod-build-cache
- name: Next.js production build
if: steps.prod-build-cache.outputs.cache-hit != 'true'
shell: bash
env:
DATABASE_URL: ${{ inputs.DATABASE_URL }}
NEXT_PUBLIC_WEBAPP_URL: ${{ inputs.NEXT_PUBLIC_WEBAPP_URL }}
NEXT_PUBLIC_WEBSITE_URL: ${{ inputs.NEXT_PUBLIC_WEBSITE_URL }}
NEXTAUTH_SECRET: ${{ inputs.NEXTAUTH_SECRET }}
GOOGLE_API_CREDENTIALS: ${{ inputs.GOOGLE_API_CREDENTIALS }}
GOOGLE_LOGIN_ENABLED: ${{ inputs.GOOGLE_LOGIN_ENABLED }}
CALENDSO_ENCRYPTION_KEY: ${{ inputs.CALENDSO_ENCRYPTION_KEY }}
DAILY_API_KEY: ${{ inputs.DAILY_API_KEY }}
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: ${{ inputs.NEXT_PUBLIC_STRIPE_PUBLIC_KEY }}
NEXT_PUBLIC_STRIPE_FREE_PLAN_PRICE: ${{ inputs.NEXT_PUBLIC_STRIPE_FREE_PLAN_PRICE }}
NEXT_PUBLIC_STRIPE_PRO_PLAN_PRICE: ${{ inputs.NEXT_PUBLIC_STRIPE_PRO_PLAN_PRICE }}
NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE: ${{ inputs.NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE }}
NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE: ${{ inputs.NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE }}
NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN: ${{ inputs.NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN }}
STRIPE_PRIVATE_KEY: ${{ inputs.STRIPE_PRIVATE_KEY }}
STRIPE_CLIENT_ID: ${{ inputs.STRIPE_CLIENT_ID }}
STRIPE_WEBHOOK_SECRET: ${{ inputs.STRIPE_WEBHOOK_SECRET }}
STRIPE_PRO_PLAN_PRODUCT_ID: ${{ inputs.STRIPE_PRO_PLAN_PRODUCT_ID }}
STRIPE_PREMIUM_PLAN_PRODUCT_ID: ${{ inputs.STRIPE_PREMIUM_PLAN_PRODUCT_ID }}
STRIPE_FREE_PLAN_PRODUCT_ID: ${{ inputs.STRIPE_FREE_PLAN_PRODUCT_ID }}
PAYMENT_FEE_PERCENTAGE: ${{ inputs.PAYMENT_FEE_PERCENTAGE }}
PAYMENT_FEE_FIXED: ${{ inputs.PAYMENT_FEE_FIXED }}
SAML_DATABASE_URL: ${{ inputs.SAML_DATABASE_URL }}
SAML_ADMINS: ${{ inputs.SAML_ADMINS }}
NEXTAUTH_URL: ${{ inputs.NEXTAUTH_URL }}
NEXT_PUBLIC_IS_E2E: ${{ inputs.NEXT_PUBLIC_IS_E2E }}
TURBO_TOKEN: ${{ inputs.TURBO_TOKEN }}
TURBO_TEAM: ${{ inputs.TURBO_TEAM }}
run: |
yarn db-seed
yarn build
+30
View File
@@ -0,0 +1,30 @@
name: Yarn install
description: "Install all NPM dependencies, caches them and restores if necessary"
env:
node_version: v16.x
runs:
using: "composite"
steps:
- name: Use Node ${{ env.node_version }}
uses: actions/setup-node@v3
with:
node-version: ${{ env.node_version }}
cache: "yarn"
- name: node_modules cache
id: node-modules-cache
uses: actions/cache@v3
env:
cache-name: node-modules-yarn
cache-key: ${{ env.node_version }}-${{ hashFiles('yarn.lock', 'packages/prisma/schema.prisma') }}
with:
path: |
**/node_modules/**
packages/prisma/zod
key: ${{ runner.os }}-${{ env.cache-name }}-${{ env.cache-key }}
restore-keys: ${{ runner.os }}-${{ env.cache-name }}-
- name: Yarn install
shell: bash
if: steps.node-modules-cache.outputs.cache-hit != 'true'
run: |
yarn install --prefer-offline --frozen-lockfile
yarn prisma generate
@@ -0,0 +1,19 @@
name: Install playwright binaries
description: "Install playwright, cache and restore if necessary"
runs:
using: "composite"
steps:
- name: Cache playwright binaries
id: playwright-cache
uses: actions/cache@v2
with:
path: |
~/Library/Caches/ms-playwright
~/.cache/ms-playwright
${{ github.workspace }}/node_modules/playwright
key: cache-playwright-${{ hashFiles('**/yarn.lock') }}
restore-keys: cache-playwright-
- name: Yarn playwright install
shell: bash
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: yarn playwright install
+33
View File
@@ -0,0 +1,33 @@
name: cleanup caches by a branch
on:
pull_request:
types:
- closed
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Cleanup
run: |
gh extension install actions/gh-actions-cache
REPO=${{ github.repository }}
BRANCH="refs/pull/${{ github.event.pull_request.number }}/merge"
echo "Fetching list of cache key"
cacheKeysForPR=$(gh actions-cache list -R $REPO -B $BRANCH | cut -f 1 )
## Setting this to not fail the workflow while deleting cache keys.
set +e
echo "Deleting caches..."
for cacheKey in $cacheKeysForPR
do
gh actions-cache delete $cacheKey -R $REPO -B $BRANCH --confirm
done
echo "Done"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }} # So we can test on forks
fetch-depth: 0
+5 -22
View File
@@ -1,34 +1,17 @@
name: Check types
on:
pull_request_target:
branches:
- main
paths:
- "**.tsx?"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
workflow_call:
env:
NODE_OPTIONS: "--max-old-space-size=8192"
jobs:
check-types:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- uses: ./.github/actions/yarn-install
- name: Use Node 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: "yarn"
- name: Show info
run: node -e "console.log(require('v8').getHeapStatistics())"
- run: yarn --frozen-lockfile
- run: yarn type-check
+22
View File
@@ -0,0 +1,22 @@
name: Cron - mark stale for inactive issues
permissions:
issues: write
on:
# "Scheduled workflows run on the latest commit on the default or base branch."
# — https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#schedule
schedule:
# Runs every day (see https://crontab.guru)
- cron: "0 0 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v7
with:
days-before-stale: 60
include-only-assigned: true
days-before-close: -1
+1 -3
View File
@@ -9,14 +9,12 @@ concurrency:
cancel-in-progress: true
jobs:
required-checks:
uses: calcom/cal.com/.github/workflows/required-checks.yml@main
synchronize-with-crowdin:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: crowdin action
uses: crowdin/github-action@1.4.9
+1 -1
View File
@@ -7,7 +7,7 @@ jobs:
db-staging-snapshot:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install Snaplet CLI
run: curl -sL https://app.snaplet.dev/get-cli/ | bash
- name: Restore Snapshot
+11 -45
View File
@@ -1,29 +1,12 @@
name: E2E App-Store Apps
on:
push:
branches: [fixes/e2e-consolidation] # TODO: Remove this after merged in main
pull_request_target: # So we can test on forks
branches:
- main
paths-ignore:
- apps/api/**
- apps/console/**
- apps/docs/**
- apps/swagger/**
- apps/website/**
- apps/web/public/**
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
workflow_call:
jobs:
test:
e2e-app-store:
timeout-minutes: 20
name: E2E App-Store Apps
strategy:
matrix:
node: ["16.x"]
os: [ubuntu-latest]
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
env:
DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
@@ -65,32 +48,15 @@ jobs:
- 5432:5432
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }} # So we can test on forks
fetch-depth: 2
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- run: echo 'NODE_OPTIONS="--max_old_space_size=4096"' >> $GITHUB_ENV
- name: Use Node ${{ matrix.node }}
uses: actions/setup-node@v3
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- uses: ./.github/actions/cache-db
with:
node-version: ${{ matrix.node }}
cache: "yarn"
- name: Cache playwright binaries
uses: actions/cache@v2
id: playwright-cache
with:
path: |
~/Library/Caches/ms-playwright
~/.cache/ms-playwright
${{ github.workspace }}/node_modules/playwright
key: cache-playwright-${{ hashFiles('**/yarn.lock') }}
restore-keys: cache-playwright-
- run: yarn --frozen-lockfile
- name: Install playwright deps
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: yarn playwright install --with-deps
DATABASE_URL: ${{ env.DATABASE_URL }}
- uses: ./.github/actions/cache-build
- name: Run Tests
run: yarn test-e2e:app-store
+8 -36
View File
@@ -1,21 +1,11 @@
name: E2E Embed tests and booking flow(for non-embed as well)
on:
pull_request_target: # So we can test on forks
branches:
- main
# Embed e2e - tests verify booking flow which is applicable to non-embed case also. So, don't ignore apps/web changes.
paths:
- apps/web/**
- packages/embeds/**
workflow_call:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
e2e-embed:
timeout-minutes: 20
runs-on: ubuntu-latest
env:
DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
NEXT_PUBLIC_WEBAPP_URL: http://localhost:3000
@@ -61,35 +51,17 @@ jobs:
- 5432:5432
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }} # So we can test on forks
fetch-depth: 2
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- run: echo 'NODE_OPTIONS="--max_old_space_size=4096"' >> $GITHUB_ENV
- name: Use Node 16.x
uses: actions/setup-node@v3
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- uses: ./.github/actions/cache-db
with:
node-version: 16.x
cache: "yarn"
- name: Cache playwright binaries
uses: actions/cache@v2
id: playwright-cache
with:
path: |
~/Library/Caches/ms-playwright
~/.cache/ms-playwright
${{ github.workspace }}/node_modules/playwright
key: cache-playwright-${{ hashFiles('**/yarn.lock') }}
restore-keys: cache-playwright-
- run: yarn --frozen-lockfile
- name: Install playwright deps
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: yarn playwright install --with-deps
DATABASE_URL: ${{ env.DATABASE_URL }}
- uses: ./.github/actions/cache-build
- name: Run Tests
run: yarn turbo run embed-tests-update-snapshots:ci --scope=@calcom/embed-react --concurrency=1
- name: Upload embed-core results
if: ${{ always() }}
uses: actions/upload-artifact@v2
+8 -36
View File
@@ -1,20 +1,10 @@
name: E2E test
on:
pull_request_target: # So we can test on forks
branches:
- main
paths:
- apps/web/**
- packages/**
workflow_call:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
e2e:
timeout-minutes: 20
runs-on: ubuntu-latest
runs-on: buildjet-4vcpu-ubuntu-2204
env:
DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
NEXT_PUBLIC_WEBAPP_URL: http://localhost:3000
@@ -64,34 +54,16 @@ jobs:
- 5432:5432
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }} # So we can test on forks
fetch-depth: 2
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- run: echo 'NODE_OPTIONS="--max_old_space_size=4096"' >> $GITHUB_ENV
- name: Use Node 16.x
uses: actions/setup-node@v3
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-playwright-install
- uses: ./.github/actions/cache-db
with:
node-version: 16.x
cache: "yarn"
- name: Cache playwright binaries
uses: actions/cache@v2
id: playwright-cache
with:
path: |
~/Library/Caches/ms-playwright
~/.cache/ms-playwright
${{ github.workspace }}/node_modules/playwright
key: cache-playwright-${{ hashFiles('**/yarn.lock') }}
restore-keys: cache-playwright-
- run: yarn --frozen-lockfile
- name: Install playwright deps
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: yarn playwright install --with-deps
DATABASE_URL: ${{ env.DATABASE_URL }}
- uses: ./.github/actions/cache-build
- run: yarn test-e2e
- name: Upload test results
if: ${{ always() }}
uses: actions/upload-artifact@v2
+4 -28
View File
@@ -1,38 +1,14 @@
name: Lint
on:
pull_request_target:
branches:
- main
paths:
- "**.tsx?"
- "**.jsx?"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
workflow_call:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2
- name: Use Node 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: "yarn"
- name: Install deps
if: steps.yarn-cache.outputs.cache-hit != 'true'
run: yarn --frozen-lockfile
- name: Test Code Linting
run: yarn lint
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- uses: ./.github/actions/yarn-install
- name: Save Code Linting Reports
run: yarn lint:report
continue-on-error: true
@@ -0,0 +1,95 @@
name: "Next.js Bundle Analysis"
on:
workflow_call:
push:
branches:
- main
jobs:
build:
name: Production build
if: ${{ github.event_name == 'push' }}
uses: ./.github/workflows/production-build.yml
secrets: inherit
analyze:
needs: build
if: always()
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/cache-build
- name: Analyze bundle
run: |
cd apps/web
npx -p nextjs-bundle-analysis report
- name: Upload bundle
uses: actions/upload-artifact@v2
with:
name: bundle
path: apps/web/.next/analyze/__bundle_analysis.json
- name: Download base branch bundle stats
uses: dawidd6/action-download-artifact@v2
if: success() && github.event.number
with:
workflow: nextjs-bundle-analysis.yml
branch: ${{ github.event.pull_request.base.ref }}
path: apps/web/.next/analyze/base
# And here's the second place - this runs after we have both the current and
# base branch bundle stats, and will compare them to determine what changed.
# There are two configurable arguments that come from package.json:
#
# - budget: optional, set a budget (bytes) against which size changes are measured
# it's set to 350kb here by default, as informed by the following piece:
# https://infrequently.org/2021/03/the-performance-inequality-gap/
#
# - red-status-percentage: sets the percent size increase where you get a red
# status indicator, defaults to 20%
#
# Either of these arguments can be changed or removed by editing the `nextBundleAnalysis`
# entry in your package.json file.
- name: Compare with base branch bundle
if: success() && github.event.number
run: |
cd apps/web
ls -laR .next/analyze/base && npx -p nextjs-bundle-analysis compare
- name: Get comment body
id: get-comment-body
if: success() && github.event.number
run: |
cd apps/web
body=$(cat .next/analyze/__bundle_analysis_comment.txt)
body="${body//'%'/'%25'}"
body="${body//$'\n'/'%0A'}"
body="${body//$'\r'/'%0D'}"
echo ::set-output name=body::$body
- name: Find Comment
uses: peter-evans/find-comment@v1
if: success() && github.event.number
id: fc
with:
issue-number: ${{ github.event.number }}
body-includes: "<!-- __NEXTJS_BUNDLE -->"
- name: Create Comment
uses: peter-evans/create-or-update-comment@v1.4.4
if: success() && github.event.number && steps.fc.outputs.comment-id == 0
with:
issue-number: ${{ github.event.number }}
body: ${{ steps.get-comment-body.outputs.body }}
- name: Update Comment
uses: peter-evans/create-or-update-comment@v1.4.4
if: success() && github.event.number && steps.fc.outputs.comment-id != 0
with:
issue-number: ${{ github.event.number }}
body: ${{ steps.get-comment-body.outputs.body }}
comment-id: ${{ steps.fc.outputs.comment-id }}
edit-mode: replace
+96
View File
@@ -0,0 +1,96 @@
name: PR Update
on:
pull_request_target:
branches:
- main
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
changes:
runs-on: ubuntu-latest
permissions:
pull-requests: read
outputs:
app-store: ${{ steps.filter.outputs.app-store }}
embed: ${{ steps.filter.outputs.embed }}
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
app-store:
- 'apps/web/**'
- 'packages/app-store/**'
embed:
- 'apps/web/**'
- 'packages/embeds/**'
setup:
name: Yarn install & cache
uses: ./.github/workflows/yarn-install.yml
secrets: inherit
type-check:
name: Type check
needs: setup
uses: ./.github/workflows/check-types.yml
secrets: inherit
test:
name: Unit tests
needs: setup
uses: ./.github/workflows/test.yml
secrets: inherit
lint:
name: Linters
needs: setup
uses: ./.github/workflows/lint.yml
secrets: inherit
build:
name: Production build
needs: setup
uses: ./.github/workflows/production-build.yml
secrets: inherit
e2e:
name: E2E tests
needs: [lint, build]
uses: ./.github/workflows/e2e.yml
secrets: inherit
e2e-app-store:
name: E2E App Store tests
if: ${{ needs.changes.outputs.app-store == 'true' }}
needs: [changes, lint, build]
uses: ./.github/workflows/e2e-app-store.yml
secrets: inherit
e2e-embed:
name: E2E embeds tests
if: ${{ needs.changes.outputs.embed == 'true' }}
needs: [changes, lint, build]
uses: ./.github/workflows/e2e.yml
secrets: inherit
analyze:
needs: build
uses: ./.github/workflows/nextjs-bundle-analysis.yml
secrets: inherit
required:
needs: [lint, type-check, test, build, e2e]
if: always()
runs-on: ubuntu-latest
steps:
- name: fail if conditional jobs failed
if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'skipped') || contains(needs.*.result, 'cancelled')
run: exit 1
+85
View File
@@ -0,0 +1,85 @@
name: Production Build
on:
workflow_call:
env:
DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
NEXT_PUBLIC_WEBAPP_URL: http://localhost:3000
NEXT_PUBLIC_WEBSITE_URL: http://localhost:3000
NEXTAUTH_SECRET: secret
GOOGLE_API_CREDENTIALS: ${{ secrets.CI_GOOGLE_API_CREDENTIALS }}
GOOGLE_LOGIN_ENABLED: true
# CRON_API_KEY: xxx
CALENDSO_ENCRYPTION_KEY: ${{ secrets.CI_CALENDSO_ENCRYPTION_KEY }}
DAILY_API_KEY: ${{ secrets.CI_DAILY_API_KEY }}
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: ${{ secrets.CI_NEXT_PUBLIC_STRIPE_PUBLIC_KEY }}
NEXT_PUBLIC_STRIPE_FREE_PLAN_PRICE: ${{ secrets.CI_NEXT_PUBLIC_STRIPE_FREE_PLAN_PRICE }}
NEXT_PUBLIC_STRIPE_PRO_PLAN_PRICE: ${{ secrets.CI_NEXT_PUBLIC_STRIPE_PRO_PLAN_PRICE }}
NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE: ${{ secrets.CI_NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE }}
NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE: ${{ secrets.NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE }}
NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN: 1
STRIPE_PRIVATE_KEY: ${{ secrets.CI_STRIPE_PRIVATE_KEY }}
STRIPE_CLIENT_ID: ${{ secrets.CI_STRIPE_CLIENT_ID }}
STRIPE_WEBHOOK_SECRET: ${{ secrets.CI_STRIPE_WEBHOOK_SECRET }}
STRIPE_PRO_PLAN_PRODUCT_ID: ${{ secrets.CI_STRIPE_PRO_PLAN_PRODUCT_ID }}
STRIPE_PREMIUM_PLAN_PRODUCT_ID: ${{ secrets.CI_STRIPE_PREMIUM_PLAN_PRODUCT_ID }}
STRIPE_FREE_PLAN_PRODUCT_ID: ${{ secrets.CI_STRIPE_FREE_PLAN_PRODUCT_ID }}
PAYMENT_FEE_PERCENTAGE: 0.005
PAYMENT_FEE_FIXED: 10
SAML_DATABASE_URL: postgresql://postgres:@localhost:5432/calendso
SAML_ADMINS: pro@example.com
NEXTAUTH_URL: http://localhost:3000/api/auth
NEXT_PUBLIC_IS_E2E: 1
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
jobs:
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 30
services:
postgres:
image: postgres:12.1
env:
POSTGRES_USER: postgres
POSTGRES_DB: calendso
ports:
- 5432:5432
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/yarn-install
- uses: ./.github/actions/yarn-build
with:
# GitHub Composite actions cannot read secrets, we have to pass them in here
DATABASE_URL: ${{ env.DATABASE_URL }}
NEXT_PUBLIC_WEBAPP_URL: ${{ env.NEXT_PUBLIC_WEBAPP_URL }}
NEXT_PUBLIC_WEBSITE_URL: ${{ env.NEXT_PUBLIC_WEBSITE_URL }}
NEXTAUTH_SECRET: ${{ env.NEXTAUTH_SECRET }}
GOOGLE_API_CREDENTIALS: ${{ env.GOOGLE_API_CREDENTIALS }}
GOOGLE_LOGIN_ENABLED: ${{ env.GOOGLE_LOGIN_ENABLED }}
CALENDSO_ENCRYPTION_KEY: ${{ env.CALENDSO_ENCRYPTION_KEY }}
DAILY_API_KEY: ${{ env.DAILY_API_KEY }}
NEXT_PUBLIC_STRIPE_PUBLIC_KEY: ${{ env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY }}
NEXT_PUBLIC_STRIPE_FREE_PLAN_PRICE: ${{ env.NEXT_PUBLIC_STRIPE_FREE_PLAN_PRICE }}
NEXT_PUBLIC_STRIPE_PRO_PLAN_PRICE: ${{ env.NEXT_PUBLIC_STRIPE_PRO_PLAN_PRICE }}
NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE: ${{ env.NEXT_PUBLIC_STRIPE_PREMIUM_PLAN_PRICE }}
NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE: ${{ env.NEXT_PUBLIC_STRIPE_PREMIUM_NEW_PLAN_PRICE }}
NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN: ${{ env.NEXT_PUBLIC_IS_PREMIUM_NEW_PLAN }}
STRIPE_PRIVATE_KEY: ${{ env.STRIPE_PRIVATE_KEY }}
STRIPE_CLIENT_ID: ${{ env.STRIPE_CLIENT_ID }}
STRIPE_WEBHOOK_SECRET: ${{ env.STRIPE_WEBHOOK_SECRET }}
STRIPE_PRO_PLAN_PRODUCT_ID: ${{ env.STRIPE_PRO_PLAN_PRODUCT_ID }}
STRIPE_PREMIUM_PLAN_PRODUCT_ID: ${{ env.STRIPE_PREMIUM_PLAN_PRODUCT_ID }}
STRIPE_FREE_PLAN_PRODUCT_ID: ${{ env.STRIPE_FREE_PLAN_PRODUCT_ID }}
PAYMENT_FEE_PERCENTAGE: ${{ env.PAYMENT_FEE_PERCENTAGE }}
PAYMENT_FEE_FIXED: ${{ env.PAYMENT_FEE_FIXED }}
SAML_DATABASE_URL: ${{ env.SAML_DATABASE_URL }}
SAML_ADMINS: ${{ env.SAML_ADMINS }}
NEXTAUTH_URL: ${{ env.NEXTAUTH_URL }}
NEXT_PUBLIC_IS_E2E: ${{ env.NEXT_PUBLIC_IS_E2E }}
TURBO_TOKEN: ${{ env.TURBO_TOKEN }}
TURBO_TEAM: ${{ env.TURBO_TEAM }}
- uses: ./.github/actions/cache-db
with:
DATABASE_URL: ${{ env.DATABASE_URL }}
-44
View File
@@ -1,44 +0,0 @@
name: "Meta Workflow: Require Conditional Status Checks"
on:
pull_request:
branches:
- main
workflow_call:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
required-checks:
runs-on: ubuntu-latest
steps:
- name: Ensure All Conditional Checks Have Passed
uses: blend/require-conditional-status-checks@2022.02.04
with:
timeout: 15m
github-token: ${{ github.token }}
interval: 20s
# Question marks aren't working
# @see https://github.com/blend/require-conditional-status-checks/pull/11
checks-yaml: |
- job: lint
paths:
- /**/*.jsx
- /**/*.js
- /**/*.tsx
- /**/*.ts
- job: check-types
paths:
- /**/*.tsx
- /**/*.ts
- job: e2e
paths:
- /apps/web/**
- /packages/**
- job: e2e-embed
paths:
- /apps/web/**
- /packages/embeds/**
- job: test
paths:
- /apps/web/**
- /packages/**
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
submodules: recursive
token: ${{ secrets.GH_ACCESS_TOKEN }}
+5 -21
View File
@@ -1,33 +1,17 @@
name: Unit tests
on:
pull_request_target: # So we can test on forks
branches:
- main
paths:
- apps/web/**
- packages/**
workflow_call:
workflow_run:
workflows: [Crowdin Action]
types: [completed]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
test:
timeout-minutes: 20
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v2
with:
ref: ${{ github.event.pull_request.head.sha }} # So we can test on forks
fetch-depth: 2
# Should be an 8GB machine as per https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- run: echo 'NODE_OPTIONS="--max_old_space_size=6144"' >> $GITHUB_ENV
- name: Use Node 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: "yarn"
- run: yarn --frozen-lockfile
- uses: ./.github/actions/yarn-install
# Should be an 8GB machine as per https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners
- run: yarn test
+32
View File
@@ -0,0 +1,32 @@
name: TODO to Issue
on:
pull_request_target: # So we can test on forks
branches:
- main
workflow_dispatch:
inputs:
MANUAL_COMMIT_REF:
description: "The SHA of the commit to get the diff for"
required: true
MANUAL_BASE_REF:
description: "By default, the commit entered above is compared to the one directly before it; to go back further, enter an earlier SHA here"
required: false
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
todos:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 2
- name: "Add TODOs to issues"
uses: "alstr/todo-to-issue-action@v4"
env:
MANUAL_COMMIT_REF: ${{ inputs.MANUAL_COMMIT_REF }}
MANUAL_BASE_REF: ${{ inputs.MANUAL_BASE_REF }}
with:
IDENTIFIERS: '[{"name": "TODO", "labels": ["🙋🏻‍♂️help wanted"]}, {"name": "FIXME", "labels": ["🐛 bug"]}]'
+14
View File
@@ -0,0 +1,14 @@
name: Yarn install
on:
workflow_call:
jobs:
setup:
name: Yarn install & cache
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- uses: ./.github/actions/yarn-install
+4
View File
@@ -77,6 +77,9 @@ lint-results
#Storybook
apps/storybook/build-storybook.log
# Infisical
.infisical.json
# Snaplet
.snaplet/snapshots
.snaplet/structure.d.ts
@@ -86,3 +89,4 @@ apps/storybook/build-storybook.log
apps/api
apps/website
apps/console
apps/auth
+54
View File
@@ -4,6 +4,60 @@ Contributions are what make the open source community such an amazing place to l
- Before jumping into a PR be sure to search [existing PRs](https://github.com/calcom/cal.com/pulls) or [issues](https://github.com/calcom/cal.com/issues) for an open or closed item that relates to your submission.
## Priorities
<table>
<tr>
<td>
Type of Issue
</td>
<td>
Priority
</td>
</tr>
<tr>
<td>
Minor improvements, non-core feature requests
</td>
<td>
<a href="https://github.com/calcom/cal.com/issues?q=is:issue+is:open+sort:updated-desc+label:%22Low+priority%22">
<img src="https://img.shields.io/badge/-Low%20Priority-green">
</a>
</td>
</tr>
<tr>
<td>
Confusing UX (... but working)
</td>
<td>
<a href="https://github.com/calcom/cal.com/issues?q=is:issue+is:open+sort:updated-desc+label:%22Medium+priority%22">
<img src="https://img.shields.io/badge/-Medium%20Priority-yellow">
</a>
</td>
</tr>
<tr>
<td>
Core Features (Booking page, availabilty, timezone calculation)
</td>
<td>
<a href="https://github.com/calcom/cal.com/issues?q=is:issue+is:open+sort:updated-desc+label:%22High+priority%22">
<img src="https://img.shields.io/badge/-High%20Priority-orange">
</a>
</td>
</tr>
<tr>
<td>
Core Bugs (Login, Booking page, Emails are not working)
</td>
<td>
<a href="https://github.com/calcom/cal.com/issues?q=is:issue+is:open+sort:updated-desc+label:Urgent">
<img src="https://img.shields.io/badge/-Urgent-red">
</a>
</td>
</tr>
</table>
## Developing
The development branch is `main`. This is the branch that all pull
+41 -9
View File
File diff suppressed because one or more lines are too long
+7 -4
View File
@@ -6,7 +6,7 @@
"keywords": ["react", "typescript", "node", "nextjs", "prisma", "postgres", "trpc"],
"addons": [
{
"plan": "heroku-postgresql:hobby-dev"
"plan": "heroku-postgresql:mini"
}
],
"env": {
@@ -43,15 +43,18 @@
},
"SENDGRID_API_KEY": {
"description": "Sendgrid api key. Used for email reminders in workflows",
"value": ""
"value": "",
"required": false
},
"SENDGRID_SYNC_API_KEY": {
"description": "Sendgrid internal sync service",
"value": ""
"value": "",
"required": false
},
"SENDGRID_EMAIL": {
"description": "Sendgrid email. Used for email reminders in workflows",
"value": ""
"value": "",
"required": false
},
"EMAIL_FROM": {
"description": "Configures the global From: header whilst sending emails",
-81
View File
@@ -1,81 +0,0 @@
<!-- PROJECT LOGO -->
<div align="right">
<a href="https://github.com/calcom/cal.com">
<img src="https://user-images.githubusercontent.com/8019099/133430653-24422d2a-3c8d-4052-9ad6-0580597151ee.png" alt="Logo">
</a>
<a href="https://cal.com">Website</a>
·
<a href="https://github.com/calcom/cal.com/issues">Community Support</a>
</div>
# Cal.com Documentation
The official product, support and developer documentation, containing information and guides about using the product as well as support for self-hosted installations. This documentation site runs on [Nextra](https://nextra.vercel.app), so you may refer to their documentation should you need information on anything that isn't covered here.
## Prerequisites
- Git
- Node.js & npm
- Yarn
## Installation
Firstly, clone the repository using Git:
```console
git clone https://github.com/calcom/docs.git
```
Now, you can install the dependencies with yarn:
```console
yarn install
```
## Editing
To create, edit and delete documentation pages, you can simply create markdown (.mdx) files in the `pages/` folder. You can edit Markdown with any text editor, but VS Code and WebStorm have side-by-side previews so you can see your formatted content whilst writing markdown.
You will also need to add it as an entry to the `meta.json` file found in whichever directory that the .mdx file is in.
## Local Development
```console
yarn dev
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
## Build
```console
yarn build
```
This command generates static content into the `build` directory and can be served using any static content hosting service.
## How to easily contribute
## Existing Page
1. From the documentation's GitHub repository, head to the folder called 'pages' and open it.
2. From here you can view all current pages on the documentation site. Select the page you would like to contribute to.
3. You should now be able to view the page you have selected. Located at the top right of the page will be a pencil icon. Pressing this will bring you up an editor to edit and make changes. You can add formatting using the buttons at the top, which will automatically insert the relevant markdown content needed to style the text.
4. From here make the changes you wish to make.
5. At the bottom of the screen will be a 'Propose Changes' box, fill in all the relevant details such as title and description then press the green 'Propose Changes' button.
6. Your changes have been saved, to submit them for review, located on your screen, press the green 'Create Pull Request' button.
7. Fill in all the relevant details such as title and description and after finalize the submission.
You have now successfully edited and submitted changes to our documentation site.
## Creating a New Page
1. From the documentation's GitHub repository, head to the folder called 'pages' and open it.
2. From here you can view all current pages on the documentation site. At the top of your screen press the 'New file' button.
3. You should now be able to view the page you have created. Remember when renaming the document to put .mdx at the end of the file name.
4. From here make the changes you wish to make. Such as creating a title, sub-title and body text.
5. At the bottom of the screen will be a 'Propose Changes' box, fill in all the relevant details such as title and description then press the green 'Propose Changes' button.
6. Your changes have been saved, to submit them for review, located on your screen, press the greem 'Create Pull Request' button.
7. Fill in all the relevant details such as title and description and after finalize the submission.
You have now successfully created and submitted changes to our documentation site.
+1 -1
View File
@@ -25,6 +25,6 @@
},
"devDependencies": {
"@calcom/config": "*",
"eslint": "^8.22.0"
"eslint": "^8.34.0"
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { AppProps } from "next/app";
import type { AppProps } from "next/app";
import "nextra-theme-docs/style.css";
import "./style.css";
+12
View File
@@ -0,0 +1,12 @@
import { create } from "@storybook/theming";
export default create({
base: "light",
colorPrimary: "#111827",
colorSecondary: "#111827",
appContentBg: "#F9FAFC",
brandTitle: "Cal.com UI",
brandUrl: "https://cal.com",
brandImage: "https://cal.com/logo.svg",
brandTarget: "_self",
});
+7
View File
@@ -0,0 +1,7 @@
import { addons } from "@storybook/addons";
import yourTheme from "./YourTheme";
addons.setConfig({
theme: yourTheme,
});
+4 -4
View File
@@ -15,7 +15,7 @@
"@radix-ui/react-dialog": "^1.0.0",
"@radix-ui/react-dropdown-menu": "^1.0.0",
"@radix-ui/react-id": "^1.0.0",
"@radix-ui/react-popover": "^1.0.0",
"@radix-ui/react-popover": "^1.0.2",
"@radix-ui/react-radio-group": "^1.0.0",
"@radix-ui/react-slider": "^1.0.0",
"@radix-ui/react-switch": "^1.0.0",
@@ -36,8 +36,8 @@
"@storybook/manager-webpack5": "^6.5.13",
"@storybook/react": "^6.5.13",
"@storybook/testing-library": "^0.0.13",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.9",
"@vitejs/plugin-react": "^2.1.0",
"autoprefixer": "^10.4.12",
"babel-loader": "^8.2.5",
@@ -49,7 +49,7 @@
"storybook-addon-next": "^1.6.9",
"storybook-react-i18next": "^1.1.2",
"tailwindcss": "^3.2.1",
"typescript": "^4.7.4",
"typescript": "^4.9.4",
"vite": "^2.9.15"
}
}
+6 -1
View File
@@ -2,4 +2,9 @@
@tailwind components;
@tailwind utilities;
@import "../../../packages/ui/styles/shared-globals.css"
@import "../../../packages/ui/styles/shared-globals.css";
:root {
--font-inter: "Inter var";
--font-cal: "Cal Sans";
}
+3 -3
View File
@@ -22,8 +22,8 @@
},
"devDependencies": {
"@types/node": "16.9.1",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
"typescript": "^4.7.4"
"@types/react": "18.0.26",
"@types/react-dom": "18.0.9",
"typescript": "^4.9.4"
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
import dynamic from "next/dynamic";
import { SwaggerUI } from "swagger-ui-react";
import type { SwaggerUI } from "swagger-ui-react";
import { SnippedGenerator, requestSnippets } from "@lib/snippets";
+2 -2
View File
@@ -1,7 +1,7 @@
import { useState } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Icon } from "@calcom/ui";
import { FiX } from "@calcom/ui/components/icon";
export default function AddToHomescreen() {
const { t } = useLocale();
@@ -40,7 +40,7 @@ export default function AddToHomescreen() {
type="button"
className="-mr-1 flex rounded-md p-2 hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-white">
<span className="sr-only">{t("dismiss")}</span>
<Icon.FiX className="h-6 w-6 text-white" aria-hidden="true" />
<FiX className="h-6 w-6 text-white" aria-hidden="true" />
</button>
</div>
</div>
@@ -1,6 +1,6 @@
import React from "react";
import Select from "react-select";
import { OptionProps } from "react-select";
import type { OptionProps } from "react-select";
import { InstallAppButton } from "@calcom/app-store/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
+66 -8
View File
@@ -1,35 +1,93 @@
import { ReactNode } from "react";
import { useRouter } from "next/router";
import type { ReactNode } from "react";
import { useEffect, useRef, useState } from "react";
import { z } from "zod";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
import { Badge, ListItemText } from "@calcom/ui";
import { FiAlertCircle } from "@calcom/ui/components/icon";
interface AppListCardProps {
type ShouldHighlight = { slug: string; shouldHighlight: true } | { shouldHighlight?: never; slug?: never };
type AppListCardProps = {
logo?: string;
title: string;
description: string;
actions?: ReactNode;
isDefault?: boolean;
}
isTemplate?: boolean;
invalidCredential?: boolean;
children?: ReactNode;
} & ShouldHighlight;
const schema = z.object({ hl: z.string().optional() });
export default function AppListCard(props: AppListCardProps) {
const { t } = useLocale();
const { logo, title, description, actions, isDefault } = props;
const {
logo,
title,
description,
actions,
isDefault,
slug,
shouldHighlight,
isTemplate,
invalidCredential,
children,
} = props;
const {
data: { hl },
} = useTypedQuery(schema);
const router = useRouter();
const [highlight, setHighlight] = useState(shouldHighlight && hl === slug);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
useEffect(() => {
if (shouldHighlight && highlight) {
const timer = setTimeout(() => {
setHighlight(false);
const url = new URL(window.location.href);
url.searchParams.delete("hl");
router.replace(url.pathname, undefined, { shallow: true });
}, 3000);
timeoutRef.current = timer;
}
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current);
timeoutRef.current = null;
}
};
}, []);
return (
<div className="p-4">
<div className="flex items-center gap-x-3">
<div className={`${highlight ? "bg-yellow-100" : ""}`}>
<div className="flex gap-x-3 p-4">
{logo ? <img className="h-10 w-10" src={logo} alt={`${title} logo`} /> : null}
<div className="flex grow flex-col gap-y-1 truncate">
<div className="flex items-center gap-x-2">
<h3 className="truncate text-sm font-semibold text-gray-900">{title}</h3>
{isDefault ? <Badge variant="green">{t("default")}</Badge> : null}
<div className="flex items-center gap-x-2">
{isDefault && <Badge variant="green">{t("default")}</Badge>}
{isTemplate && <Badge variant="red">Template</Badge>}
</div>
</div>
<ListItemText component="p">{description}</ListItemText>
{invalidCredential && (
<div className="flex gap-x-2 pt-2">
<FiAlertCircle className="h-8 w-8 text-red-500 sm:h-4 sm:w-4" />
<ListItemText component="p" className="whitespace-pre-wrap text-red-500">
{t("invalid_credential")}
</ListItemText>
</div>
)}
</div>
{actions}
</div>
{children && <div className="w-full">{children}</div>}
</div>
);
}
@@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react";
import Select from "react-select";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { DestinationCalendar } from "@calcom/prisma/client";
import type { DestinationCalendar } from "@calcom/prisma/client";
import { trpc } from "@calcom/trpc/react";
interface Props {
+20 -18
View File
@@ -1,8 +1,11 @@
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@radix-ui/react-collapsible";
import classNames from "classnames";
import { NextRouter, useRouter } from "next/router";
import { createRef, forwardRef, MutableRefObject, RefObject, useRef, useState } from "react";
import { components, ControlProps } from "react-select";
import type { NextRouter } from "next/router";
import { useRouter } from "next/router";
import type { MutableRefObject, RefObject } from "react";
import { createRef, forwardRef, useRef, useState } from "react";
import type { ControlProps } from "react-select";
import { components } from "react-select";
import { APP_NAME, EMBED_LIB_URL, WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -12,16 +15,15 @@ import {
DialogClose,
DialogContent,
HorizontalTabs,
Icon,
InputLeading,
Label,
showToast,
Switch,
TextArea,
TextField,
ColorPicker,
} from "@calcom/ui";
import { FiCode, FiTrello, FiSun, FiArrowLeft, FiChevronRight } from "@calcom/ui/components/icon";
import ColorPicker from "@components/ui/colorpicker";
import Select from "@components/ui/form/Select";
type EmbedType = "inline" | "floating-popup" | "element-click";
@@ -488,7 +490,7 @@ const tabs = [
{
name: "HTML",
href: "embedTabName=embed-code",
icon: Icon.FiCode,
icon: FiCode,
type: "code",
Component: forwardRef<
HTMLTextAreaElement | HTMLIFrameElement | null,
@@ -541,7 +543,7 @@ ${getEmbedTypeSpecificString({ embedFramework: "HTML", embedType, calLink, previ
{
name: "React",
href: "embedTabName=embed-react",
icon: Icon.FiCode,
icon: FiCode,
type: "code",
Component: forwardRef<
HTMLTextAreaElement | HTMLIFrameElement | null,
@@ -581,7 +583,7 @@ ${getEmbedTypeSpecificString({ embedFramework: "react", embedType, calLink, prev
{
name: "Preview",
href: "embedTabName=embed-preview",
icon: Icon.FiTrello,
icon: FiTrello,
type: "iframe",
Component: forwardRef<
HTMLIFrameElement | HTMLTextAreaElement | null,
@@ -617,7 +619,7 @@ Cal("init", {origin:"${WEBAPP_URL}"});
const ThemeSelectControl = ({ children, ...props }: ControlProps<{ value: Theme; label: string }, false>) => {
return (
<components.Control {...props}>
<Icon.FiSun className="ml-2 h-4 w-4 text-gray-500" />
<FiSun className="ml-2 h-4 w-4 text-gray-500" />
{children}
</components.Control>
);
@@ -676,7 +678,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
return `${router.asPath.split("?")[0]}?${searchParams.toString()}`;
};
const parsedTabs = tabs.map((t) => ({ ...t, href: s(t.href) }));
const embedCodeRefs: Record<typeof tabs[0]["name"], RefObject<HTMLTextAreaElement>> = {};
const embedCodeRefs: Record<(typeof tabs)[0]["name"], RefObject<HTMLTextAreaElement>> = {};
tabs
.filter((tab) => tab.type === "code")
.forEach((codeTab) => {
@@ -720,7 +722,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
const calLink = decodeURIComponent(embedUrl);
const addToPalette = (update: typeof previewState["palette"]) => {
const addToPalette = (update: (typeof previewState)["palette"]) => {
setPreviewState((previewState) => {
return {
...previewState,
@@ -815,7 +817,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
onClick={() => {
removeQueryParams(router, ["embedType", "embedTabName"]);
}}>
<Icon.FiArrowLeft className="mr-4 w-4" />
<FiArrowLeft className="mr-4 w-4" />
</button>
{embed.title}
</h3>
@@ -835,7 +837,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
? "Floating Popup Customization"
: "Element Click Customization"}
</div>
<Icon.FiChevronRight
<FiChevronRight
className={`${
isEmbedCustomizationOpen ? "rotate-90 transform" : ""
} ml-auto h-5 w-5 text-gray-500`}
@@ -863,7 +865,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
};
});
}}
addOnLeading={<InputLeading>W</InputLeading>}
addOnLeading={<>W</>}
/>
<span className="p-2">×</span>
<TextField
@@ -883,7 +885,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
};
});
}}
addOnLeading={<InputLeading>H</InputLeading>}
addOnLeading={<>H</>}
/>
</div>
</div>
@@ -1002,7 +1004,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
onOpenChange={() => setIsBookingCustomizationOpen((val) => !val)}>
<CollapsibleTrigger className="flex w-full" type="button">
<div className="text-base font-medium text-gray-900">Cal Booking Customization</div>
<Icon.FiChevronRight
<FiChevronRight
className={`${
isBookingCustomizationOpen ? "rotate-90 transform" : ""
} ml-auto h-5 w-5 text-gray-500`}
@@ -1061,7 +1063,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
defaultValue="#000000"
onChange={(color) => {
addToPalette({
[palette.name as keyof typeof previewState["palette"]]: color,
[palette.name as keyof (typeof previewState)["palette"]]: color,
});
}}
/>
+3 -2
View File
@@ -1,6 +1,7 @@
import dynamic from "next/dynamic";
import { Dispatch, useState, useEffect } from "react";
import { JSONObject } from "superjson/dist/types";
import type { Dispatch } from "react";
import { useState, useEffect } from "react";
import type { JSONObject } from "superjson/dist/types";
export type Gate = undefined | "rainbow"; // Add more like ` | "geolocation" | "payment"`
+5 -3
View File
@@ -1,11 +1,13 @@
import { FormEvent, useCallback, useEffect, useState } from "react";
import type { FormEvent } from "react";
import { useCallback, useEffect, useState } from "react";
import Cropper from "react-easy-crop";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, Dialog, DialogClose, DialogContent, DialogTrigger } from "@calcom/ui";
import { Area, getCroppedImg } from "@lib/cropImage";
import type { Area } from "@lib/cropImage";
import { getCroppedImg } from "@lib/cropImage";
import { useFileReader } from "@lib/hooks/useFileReader";
import { useLocale } from "@lib/hooks/useLocale";
import Slider from "@components/Slider";
+5 -3
View File
@@ -1,13 +1,15 @@
import { AdminRequired } from "components/ui/AdminRequired";
import noop from "lodash/noop";
import Link, { LinkProps } from "next/link";
import type { LinkProps } from "next/link";
import Link from "next/link";
import { useRouter } from "next/router";
import { FC, Fragment, MouseEventHandler } from "react";
import type { FC, MouseEventHandler } from "react";
import { Fragment } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import classNames from "@lib/classNames";
import { SVGComponent } from "@lib/types/SVGComponent";
import type { SVGComponent } from "@lib/types/SVGComponent";
export interface NavTabProps {
tabs: {
+10 -8
View File
@@ -1,7 +1,9 @@
import React, { ComponentProps } from "react";
import type { ComponentProps } from "react";
import React from "react";
import Shell from "@calcom/features/shell/Shell";
import { ErrorBoundary, Icon } from "@calcom/ui";
import { ErrorBoundary } from "@calcom/ui";
import { FiCreditCard, FiKey, FiLock, FiTerminal, FiUser, FiUsers } from "@calcom/ui/components/icon";
import NavTabs from "./NavTabs";
@@ -9,32 +11,32 @@ const tabs = [
{
name: "profile",
href: "/settings/profile",
icon: Icon.FiUser,
icon: FiUser,
},
{
name: "teams",
href: "/settings/teams",
icon: Icon.FiUsers,
icon: FiUsers,
},
{
name: "security",
href: "/settings/security",
icon: Icon.FiKey,
icon: FiKey,
},
{
name: "developer",
href: "/settings/developer",
icon: Icon.FiTerminal,
icon: FiTerminal,
},
{
name: "billing",
href: "/settings/billing",
icon: Icon.FiCreditCard,
icon: FiCreditCard,
},
{
name: "admin",
href: "/settings/admin",
icon: Icon.FiLock,
icon: FiLock,
adminRequired: true,
},
];
@@ -1,10 +1,11 @@
import { OptionProps } from "react-select";
import type { OptionProps } from "react-select";
import { InstallAppButton } from "@calcom/app-store/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import type { App } from "@calcom/types/App";
import { Button, Icon, Select } from "@calcom/ui";
import { Button, Select } from "@calcom/ui";
import { FiPlus } from "@calcom/ui/components/icon";
import { QueryCell } from "@lib/QueryCell";
@@ -31,7 +32,7 @@ const ImageOption = (optionProps: OptionProps<{ [key: string]: string; type: App
/>
) : (
<Button className="w-full" color="minimal" href="/apps/categories/calendar">
<Icon.FiPlus className="text-color mr-3 ml-1 h-4 w-4" />
<FiPlus className="text-color mr-3 ml-1 h-4 w-4" />
<p>{t("install_new_calendar_app")}</p>
</Button>
);
@@ -61,7 +62,7 @@ const AdditionalCalendarSelector = ({ isLoading }: AdditionalCalendarSelectorPro
<Select
name="additionalCalendar"
placeholder={
<Button StartIcon={Icon.FiPlus} color="secondary">
<Button StartIcon={FiPlus} color="secondary">
{t("add")}
</Button>
}
+27 -18
View File
@@ -11,8 +11,18 @@ import classNames from "@calcom/lib/classNames";
import { APP_NAME, COMPANY_NAME, SUPPORT_MAIL_ADDRESS } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { App as AppType } from "@calcom/types/App";
import { Button, Icon, showToast, SkeletonButton, SkeletonText, HeadSeo, Badge } from "@calcom/ui";
import type { App as AppType } from "@calcom/types/App";
import { Button, showToast, SkeletonButton, SkeletonText, HeadSeo, Badge } from "@calcom/ui";
import {
FiBookOpen,
FiCheck,
FiExternalLink,
FiFile,
FiFlag,
FiMail,
FiPlus,
FiShield,
} from "@calcom/ui/components/icon";
const Component = ({
name,
@@ -118,7 +128,7 @@ const Component = ({
isGlobal ||
(existingCredentials.length > 0 && allowedMultipleInstalls ? (
<div className="flex space-x-3">
<Button StartIcon={Icon.FiCheck} color="secondary" disabled>
<Button StartIcon={FiCheck} color="secondary" disabled>
{existingCredentials.length > 0
? t("active_install", { count: existingCredentials.length })
: t("default")}
@@ -139,7 +149,7 @@ const Component = ({
}
return (
<Button
StartIcon={Icon.FiPlus}
StartIcon={FiPlus}
{...props}
// @TODO: Overriding color and size prevent us from
// having to duplicate InstallAppButton for now.
@@ -200,7 +210,7 @@ const Component = ({
</span>
)}
<div className="prose prose-sm mt-8">{body}</div>
<div className="prose-sm prose mt-8">{body}</div>
<h4 className="mt-8 font-semibold text-gray-900 ">{t("pricing")}</h4>
<span>
{price === 0 ? (
@@ -226,7 +236,7 @@ const Component = ({
rel="noreferrer"
className="text-sm font-normal text-black no-underline hover:underline"
href={docs}>
<Icon.FiBookOpen className="mr-1 -mt-1 inline h-4 w-4 text-gray-500" />
<FiBookOpen className="mr-1 -mt-1 inline h-4 w-4 text-gray-500" />
{t("documentation")}
</a>
</li>
@@ -238,7 +248,7 @@ const Component = ({
rel="noreferrer"
className="font-normal text-black no-underline hover:underline"
href={website}>
<Icon.FiExternalLink className="mr-1 -mt-px inline h-4 w-4 text-gray-500" />
<FiExternalLink className="mr-1 -mt-px inline h-4 w-4 text-gray-500" />
{website.replace("https://", "")}
</a>
</li>
@@ -250,7 +260,7 @@ const Component = ({
rel="noreferrer"
className="font-normal text-black no-underline hover:underline"
href={"mailto:" + email}>
<Icon.FiMail className="mr-1 -mt-px inline h-4 w-4 text-gray-500" />
<FiMail className="mr-1 -mt-px inline h-4 w-4 text-gray-500" />
{email}
</a>
@@ -263,7 +273,7 @@ const Component = ({
rel="noreferrer"
className="font-normal text-black no-underline hover:underline"
href={tos}>
<Icon.FiFile className="mr-1 -mt-px inline h-4 w-4 text-gray-500" />
<FiFile className="mr-1 -mt-px inline h-4 w-4 text-gray-500" />
{t("terms_of_service")}
</a>
</li>
@@ -275,7 +285,7 @@ const Component = ({
rel="noreferrer"
className="font-normal text-black no-underline hover:underline"
href={privacy}>
<Icon.FiShield className="mr-1 -mt-px inline h-4 w-4 text-gray-500" />
<FiShield className="mr-1 -mt-px inline h-4 w-4 text-gray-500" />
{t("privacy_policy")}
</a>
</li>
@@ -286,13 +296,18 @@ const Component = ({
{t("every_app_published", { appName: APP_NAME, companyName: COMPANY_NAME })}
</span>
<a className="mt-2 block text-xs text-red-500" href={`mailto:${SUPPORT_MAIL_ADDRESS}`}>
<Icon.FiFlag className="inline h-3 w-3" /> {t("report_app")}
<FiFlag className="inline h-3 w-3" /> {t("report_app")}
</a>
</div>
</div>
);
};
const ShellHeading = () => {
const { t } = useLocale();
return <span className="block py-2">{t("app_store")}</span>;
};
export default function App(props: {
name: string;
description: AppType["description"];
@@ -318,18 +333,12 @@ export default function App(props: {
images?: string[];
isTemplate?: boolean;
}) {
const { t } = useLocale();
return (
<Shell large isPublic heading={t("app_store")} backPath="/apps" withoutSeo>
<Shell smallHeading isPublic heading={<ShellHeading />} backPath="/apps" withoutSeo>
<HeadSeo
title={props.name}
description={props.description}
app={{ slug: props.logo, name: props.name, description: props.description }}
nextSeoProps={{
nofollow: true,
noindex: true,
}}
/>
{props.licenseRequired ? (
<LicenseRequired>
@@ -11,18 +11,18 @@ import {
Alert,
Button,
EmptyScreen,
Icon,
List,
showToast,
AppSkeletonLoader as SkeletonLoader,
Switch,
ShellSubHeading,
} from "@calcom/ui";
import { FiArrowLeft, FiCalendar, FiPlus } from "@calcom/ui/components/icon";
import { QueryCell } from "@lib/QueryCell";
import AppListCard from "@components/AppListCard";
import AdditionalCalendarSelector from "@components/apps/AdditionalCalendarSelector";
import IntegrationListItem from "@components/apps/IntegrationListItem";
import SubHeadingTitleWithConnections from "@components/integrations/SubHeadingTitleWithConnections";
type Props = {
@@ -100,7 +100,7 @@ function CalendarSwitch(props: {
/>
{!!props.destination && (
<span className="ml-4 inline-flex items-center gap-1 rounded-md bg-gray-100 px-2 py-1 text-sm font-normal text-gray-800">
<Icon.FiArrowLeft className="h-4 w-4" />
<FiArrowLeft className="h-4 w-4" />
{t("adding_events_to")}
</span>
)}
@@ -118,13 +118,13 @@ function CalendarList(props: Props) {
success={({ data }) => (
<List>
{data.items.map((item) => (
<IntegrationListItem
name={item.name}
slug={item.slug}
key={item.title}
title={item.title}
<AppListCard
title={item.name}
key={item.name}
logo={item.logo}
description={item.description}
shouldHighlight
slug={item.slug}
actions={
<InstallAppButton
type={item.type}
@@ -161,16 +161,16 @@ function ConnectedCalendarsList(props: Props) {
}
return (
<List className="flex flex-col gap-6" noBorderTreatment>
<List>
{data.connectedCalendars.map((item) => (
<Fragment key={item.credentialId}>
{item.calendars ? (
<IntegrationListItem
<AppListCard
shouldHighlight
slug={item.integration.slug}
title={item.integration.title}
title={item.integration.name}
logo={item.integration.logo}
description={item.primary?.email ?? item.integration.description}
separate={true}
actions={
<div className="flex w-32 justify-end">
<DisconnectIntegration
@@ -200,7 +200,7 @@ function ConnectedCalendarsList(props: Props) {
</>
)}
</div>
</IntegrationListItem>
</AppListCard>
) : (
<Alert
severity="warning"
@@ -282,8 +282,8 @@ export function CalendarListContainer(props: { heading?: boolean; fromOnboarding
<div className="flex justify-between rounded-md border border-gray-200 bg-gray-50 p-4">
<div className="flex w-full flex-col items-start gap-4 md:flex-row md:items-center">
<div className="relative rounded-md border border-gray-200 bg-white p-1.5">
<Icon.FiCalendar className="h-8 w-8" strokeWidth="1" />
<Icon.FiPlus
<FiCalendar className="h-8 w-8" strokeWidth="1" />
<FiPlus
className="absolute left-4 top-1/2 ml-0.5 mt-[1px] h-2 w-2 text-black"
strokeWidth="4"
/>
@@ -322,7 +322,7 @@ export function CalendarListContainer(props: { heading?: boolean; fromOnboarding
</>
) : (
<EmptyScreen
Icon={Icon.FiCalendar}
Icon={FiCalendar}
headline={t("no_category_apps", {
category: t("calendar").toLowerCase(),
})}
@@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react";
import Select from "react-select";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { DestinationCalendar } from "@calcom/prisma/client";
import type { DestinationCalendar } from "@calcom/prisma/client";
import { trpc } from "@calcom/trpc/react";
interface Props {
@@ -1,80 +0,0 @@
import Link from "next/link";
import { useRouter } from "next/router";
import { ReactNode, useEffect, useState } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Badge, Icon, ListItem, ListItemText, ListItemTitle, showToast } from "@calcom/ui";
import classNames from "@lib/classNames";
function IntegrationListItem(props: {
imageSrc?: string;
slug: string;
name?: string;
title?: string;
description: string;
actions?: ReactNode;
children?: ReactNode;
logo: string;
destination?: boolean;
separate?: boolean;
invalidCredential?: boolean;
isTemplate?: boolean;
}): JSX.Element {
const { t } = useLocale();
const router = useRouter();
const { hl } = router.query;
const [highlight, setHighlight] = useState(hl === props.slug);
const title = props.name || props.title;
// The highlight is to show a newly installed app, coming from the app's
// redirection after installation, so we proceed to show the corresponding
// message
if (highlight) {
showToast(t("app_successfully_installed"), "success");
}
useEffect(() => {
const timer = setTimeout(() => setHighlight(false), 3000);
return () => {
clearTimeout(timer);
};
}, []);
return (
<ListItem
expanded={!!props.children}
className={classNames(
props.separate ? "rounded-md" : "first:rounded-t-md last:rounded-b-md",
"my-0 flex-col border transition-colors duration-500",
highlight ? "bg-yellow-100" : ""
)}>
<div className={classNames("flex w-full flex-1 items-center space-x-2 p-4 rtl:space-x-reverse")}>
{props.logo && <img className="h-11 w-11" src={props.logo} alt={title} />}
<div className="flex-grow truncate pl-2">
<ListItemTitle component="h3" className="flex ">
<Link href={"/apps/" + props.slug}>{props.name || title}</Link>
{props.isTemplate && (
<Badge variant="red" className="ml-4">
Template
</Badge>
)}
</ListItemTitle>
<ListItemText component="p">{props.description}</ListItemText>
{/* Alert error that key stopped working. */}
{props.invalidCredential && (
<div className="flex items-center space-x-2 rtl:space-x-reverse">
<Icon.FiAlertCircle className="w-8 text-red-500 sm:w-4" />
<ListItemText component="p" className="whitespace-pre-wrap text-red-500">
{t("invalid_credential")}
</ListItemText>
</div>
)}
</div>
<div>{props.actions}</div>
</div>
{props.children && <div className="w-full">{props.children}</div>}
</ListItem>
);
}
export default IntegrationListItem;
@@ -1,10 +1,12 @@
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import React, { ComponentProps } from "react";
import type { ComponentProps } from "react";
import React from "react";
import Shell from "@calcom/features/shell/Shell";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { EmptyScreen, Icon } from "@calcom/ui";
import { EmptyScreen } from "@calcom/ui";
import { FiAlertCircle } from "@calcom/ui/components/icon";
type AppsLayoutProps = {
children: React.ReactNode;
@@ -25,7 +27,7 @@ export default function AppsLayout({ children, actions, emptyStore, ...rest }: A
<main className="w-full">
{emptyStore ? (
<EmptyScreen
Icon={Icon.FiAlertCircle}
Icon={FiAlertCircle}
headline={t("no_apps")}
description={session.data?.user.role === "ADMIN" ? "You can enable apps in the settings" : ""}
buttonText={session.data?.user.role === "ADMIN" ? t("apps_settings") : ""}
@@ -1,42 +1,43 @@
import React, { ComponentProps } from "react";
import type { ComponentProps } from "react";
import React from "react";
import AppCategoryNavigation from "@calcom/app-store/_components/AppCategoryNavigation";
import { InstalledAppVariants } from "@calcom/app-store/utils";
import type { InstalledAppVariants } from "@calcom/app-store/utils";
import Shell from "@calcom/features/shell/Shell";
import { trpc } from "@calcom/trpc/react";
import { Icon } from "@calcom/ui";
import type { HorizontalTabItemProps, VerticalTabItemProps } from "@calcom/ui";
import { FiBarChart, FiCalendar, FiCreditCard, FiGrid, FiShare2, FiVideo } from "@calcom/ui/components/icon";
const tabs: (VerticalTabItemProps | HorizontalTabItemProps)[] = [
{
name: "calendar",
href: "/apps/installed/calendar",
icon: Icon.FiCalendar,
icon: FiCalendar,
},
{
name: "conferencing",
href: "/apps/installed/conferencing",
icon: Icon.FiVideo,
icon: FiVideo,
},
{
name: "payment",
href: "/apps/installed/payment",
icon: Icon.FiCreditCard,
icon: FiCreditCard,
},
{
name: "automation",
href: "/apps/installed/automation",
icon: Icon.FiShare2,
icon: FiShare2,
},
{
name: "analytics",
href: "/apps/installed/analytics",
icon: Icon.FiBarChart,
icon: FiBarChart,
},
{
name: "other",
href: "/apps/installed/other",
icon: Icon.FiGrid,
icon: FiGrid,
},
];
@@ -44,7 +45,7 @@ export default function InstalledAppsLayout({
children,
...rest
}: { children: React.ReactNode } & ComponentProps<typeof Shell>) {
const variant: typeof InstalledAppVariants[number] = "payment";
const variant: (typeof InstalledAppVariants)[number] = "payment";
const query = trpc.viewer.integrations.useQuery({
variant,
@@ -57,9 +58,7 @@ export default function InstalledAppsLayout({
return (
<Shell {...rest}>
<AppCategoryNavigation
baseURL="/apps/installed"
containerClassname="w-full xl:mx-5 xl:w-4/5 xl:max-w-2xl xl:pr-5">
<AppCategoryNavigation baseURL="/apps/installed" containerClassname="min-w-0 w-full">
{children}
</AppCategoryNavigation>
</Shell>
@@ -1,15 +1,16 @@
import { UserPermissionRole } from "@prisma/client";
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import React, { ComponentProps, useEffect } from "react";
import type { ComponentProps } from "react";
import React, { useEffect } from "react";
import SettingsLayout from "@calcom/features/settings/layouts/SettingsLayout";
import Shell from "@calcom/features/shell/Shell";
import type Shell from "@calcom/features/shell/Shell";
import { ErrorBoundary } from "@calcom/ui";
import { UserPermissionRole } from ".prisma/client";
export default function AdminLayout({
children,
...rest
}: { children: React.ReactNode } & ComponentProps<typeof Shell>) {
const session = useSession();
@@ -22,10 +23,11 @@ export default function AdminLayout({
}
}, [session, router]);
const isAppsPage = router.asPath.startsWith("/settings/admin/apps");
return (
<SettingsLayout {...rest}>
<div className="mx-auto flex max-w-4xl flex-row divide-y divide-gray-200">
<div className="flex flex-1 [&>*]:flex-1">
<div className={isAppsPage ? "min-w-0" : "flex flex-1 [&>*]:flex-1"}>
<ErrorBoundary>{children}</ErrorBoundary>
</div>
</div>
@@ -1,37 +1,38 @@
import { getEventLocationType, locationKeyToString } from "@calcom/app-store/locations";
import { classNames } from "@calcom/lib";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Icon, Tooltip } from "@calcom/ui";
import { Tooltip } from "@calcom/ui";
import { FiLink } from "@calcom/ui/components/icon";
import { Props } from "./pages/AvailabilityPage";
import type { Props } from "./pages/AvailabilityPage";
export function AvailableEventLocations({ locations }: { locations: Props["eventType"]["locations"] }) {
const { t } = useLocale();
return locations.length ? (
<div className="dark:text-darkgray-600 mr-6 flex w-full flex-col space-y-2 break-words text-sm text-gray-600">
{locations.map((location) => {
<div className="dark:text-darkgray-600 mr-6 flex w-full flex-col space-y-4 break-words text-sm text-gray-600">
{locations.map((location, index) => {
const eventLocationType = getEventLocationType(location.type);
if (!eventLocationType) {
// It's possible that the location app got uninstalled
return null;
}
return (
<div key={location.type} className="flex flex-row items-center text-sm font-medium">
<div key={`${location.type}-${index}`} className="flex flex-row items-center text-sm font-medium">
{eventLocationType.iconUrl === "/link.svg" ? (
<Icon.FiLink className="dark:text-darkgray-600 ml-[2px] h-4 w-4 opacity-70 ltr:mr-[10px] rtl:ml-[10px] dark:opacity-100 " />
<FiLink className="dark:text-darkgray-600 ml-[2px] h-4 w-4 opacity-70 ltr:mr-[10px] rtl:ml-[10px] dark:opacity-100 " />
) : (
<img
src={eventLocationType.iconUrl}
className={classNames(
"ml-[2px] h-4 w-4 opacity-70 ltr:mr-[10px] rtl:ml-[10px] dark:opacity-100 ",
!eventLocationType.iconUrl?.includes("api") ? "dark:invert" : ""
!eventLocationType.iconUrl?.includes("api") ? "dark:invert-[.65]" : ""
)}
alt={`${eventLocationType.label} icon`}
/>
)}
<Tooltip content={t(locationKeyToString(location) ?? "")}>
<p className="truncate">{t(locationKeyToString(location) ?? "")}</p>
<p className="line-clamp-1">{t(locationKeyToString(location) ?? "")}</p>
</Tooltip>
</div>
);
+131 -115
View File
@@ -1,9 +1,13 @@
import { useAutoAnimate } from "@formkit/auto-animate/react";
import Link from "next/link";
import { useRouter } from "next/router";
import { FC, useEffect, useState } from "react";
import type { FC } from "react";
import { useEffect, useState, useCallback } from "react";
import dayjs, { Dayjs } from "@calcom/dayjs";
import type { Dayjs } from "@calcom/dayjs";
import dayjs from "@calcom/dayjs";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useMediaQuery from "@calcom/lib/hooks/useMediaQuery";
import { TimeFormat } from "@calcom/lib/timeFormat";
import { nameOfDay } from "@calcom/lib/weekday";
import type { Slot } from "@calcom/trpc/server/routers/viewer/slots";
@@ -37,6 +41,7 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
seatsPerTimeSlot,
ethSignature,
}) => {
const [slotPickerRef] = useAutoAnimate<HTMLDivElement>();
const { t, i18n } = useLocale();
const router = useRouter();
const { rescheduleUid } = router.query;
@@ -46,123 +51,134 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
useEffect(() => {
setBrand(getComputedStyle(document.documentElement).getPropertyValue("--brand-color").trim());
}, []);
if (!date) return null;
const isMobile = useMediaQuery("(max-width: 768px)");
const ref = useCallback(
(node: HTMLDivElement) => {
if (isMobile) {
node?.scrollIntoView({ behavior: "smooth" });
}
},
[isMobile]
);
return (
<div className="dark:bg-darkgray-100 mt-8 flex h-full w-full flex-col px-4 text-center sm:mt-0 sm:p-5 md:-mb-5 md:min-w-[200px] lg:min-w-[300px]">
<div className="mb-6 flex items-center text-left text-base">
<div className="mr-4">
<span className="text-bookingdarker dark:text-darkgray-800 font-semibold text-gray-900">
{nameOfDay(i18n.language, Number(date.format("d")), "short")}
</span>
<span className="text-bookinglight font-medium">
, {date.toDate().toLocaleString(i18n.language, { month: "short" })} {date.format(" D ")}
</span>
</div>
<div className="ml-auto">
<ToggleGroup
onValueChange={(timeFormat) => onTimeFormatChange(timeFormat === "24")}
defaultValue={timeFormat === TimeFormat.TWELVE_HOUR ? "12" : "24"}
options={[
{ value: "12", label: t("12_hour_short") },
{ value: "24", label: t("24_hour_short") },
]}
/>
</div>
</div>
<div className="flex-grow overflow-y-auto sm:block md:h-[364px]">
{slots.length > 0 &&
slots.map((slot) => {
type BookingURL = {
pathname: string;
query: Record<string, string | number | string[] | undefined>;
};
const bookingUrl: BookingURL = {
pathname: router.pathname.endsWith("/embed") ? "../book" : "book",
query: {
...router.query,
date: dayjs.utc(slot.time).tz(timeZone()).format(),
type: eventTypeId,
slug: eventTypeSlug,
/** Treat as recurring only when a count exist and it's not a rescheduling workflow */
count: recurringCount && !rescheduleUid ? recurringCount : undefined,
...(ethSignature ? { ethSignature } : {}),
},
};
if (rescheduleUid) {
bookingUrl.query.rescheduleUid = rescheduleUid as string;
}
// If event already has an attendee add booking id
if (slot.bookingUid) {
bookingUrl.query.bookingUid = slot.bookingUid;
}
return (
<div data-slot-owner={(slot.userIds || []).join(",")} key={`${dayjs(slot.time).format()}`}>
{/* ^ data-slot-owner is helpful in debugging and used to identify the owners of the slot. Owners are the users which have the timeslot in their schedule. It doesn't consider if a user has that timeslot booked */}
{/* Current there is no way to disable Next.js Links */}
{seatsPerTimeSlot && slot.attendees && slot.attendees >= seatsPerTimeSlot ? (
<div
className={classNames(
"text-primary-500 dark:bg-darkgray-200 dark:text-darkgray-900 mb-2 block rounded-sm border bg-white py-2 font-medium opacity-25 dark:border-transparent ",
brand === "#fff" || brand === "#ffffff" ? "" : ""
)}>
{dayjs(slot.time).tz(timeZone()).format(timeFormat)}
{!!seatsPerTimeSlot && <p className="text-sm">{t("booking_full")}</p>}
</div>
) : (
<Link
href={bookingUrl}
prefetch={false}
className={classNames(
"text-primary-500 hover:border-gray-900 hover:bg-gray-50",
"dark:bg-darkgray-200 dark:hover:bg-darkgray-300 dark:hover:border-darkmodebrand dark:text-darkgray-800 mb-2 block rounded-md border bg-white py-2 text-sm font-medium dark:border-transparent",
brand === "#fff" || brand === "#ffffff" ? "" : ""
)}
data-testid="time">
{dayjs(slot.time).tz(timeZone()).format(timeFormat)}
{!!seatsPerTimeSlot && (
<p
className={`${
slot.attendees && slot.attendees / seatsPerTimeSlot >= 0.8
? "text-rose-600"
: slot.attendees && slot.attendees / seatsPerTimeSlot >= 0.33
? "text-yellow-500"
: "text-emerald-400"
} text-sm`}>
{slot.attendees ? seatsPerTimeSlot - slot.attendees : seatsPerTimeSlot} /{" "}
{seatsPerTimeSlot} {t("seats_available")}
</p>
)}
</Link>
)}
</div>
);
})}
{!isLoading && !slots.length && (
<div className="-mt-4 flex h-full w-full flex-col content-center items-center justify-center">
<h1 className="my-6 text-xl text-black dark:text-white">{t("all_booked_today")}</h1>
<div ref={slotPickerRef}>
{!!date ? (
<div className="dark:bg-darkgray-100 mt-8 flex h-full w-full flex-col px-4 text-center sm:mt-0 sm:p-5 md:-mb-5 md:min-w-[200px] lg:min-w-[300px]">
<div className="mb-6 flex items-center text-left text-base">
<div className="mr-4">
<span className="text-bookingdarker dark:text-darkgray-800 font-semibold text-gray-900">
{nameOfDay(i18n.language, Number(date.format("d")), "short")}
</span>
<span className="text-bookinglight font-medium">
, {date.toDate().toLocaleString(i18n.language, { month: "short" })} {date.format(" D ")}
</span>
</div>
<div className="ml-auto">
<ToggleGroup
onValueChange={(timeFormat) => onTimeFormatChange(timeFormat === "24")}
defaultValue={timeFormat === TimeFormat.TWELVE_HOUR ? "12" : "24"}
options={[
{ value: "12", label: t("12_hour_short") },
{ value: "24", label: t("24_hour_short") },
]}
/>
</div>
</div>
)}
<div ref={ref} className="flex-grow overflow-y-auto sm:block md:h-[364px]">
{slots.length > 0 &&
slots.map((slot) => {
type BookingURL = {
pathname: string;
query: Record<string, string | number | string[] | undefined>;
};
const bookingUrl: BookingURL = {
pathname: router.pathname.endsWith("/embed") ? "../book" : "book",
query: {
...router.query,
date: dayjs.utc(slot.time).tz(timeZone()).format(),
type: eventTypeId,
slug: eventTypeSlug,
/** Treat as recurring only when a count exist and it's not a rescheduling workflow */
count: recurringCount && !rescheduleUid ? recurringCount : undefined,
...(ethSignature ? { ethSignature } : {}),
},
};
{isLoading && !slots.length && (
<>
<SkeletonContainer className="mb-2">
<SkeletonText className="h-5 w-full" />
</SkeletonContainer>
<SkeletonContainer className="mb-2">
<SkeletonText className="h-5 w-full" />
</SkeletonContainer>
<SkeletonContainer className="mb-2">
<SkeletonText className="h-5 w-full" />
</SkeletonContainer>
</>
)}
</div>
if (rescheduleUid) {
bookingUrl.query.rescheduleUid = rescheduleUid as string;
}
// If event already has an attendee add booking id
if (slot.bookingUid) {
bookingUrl.query.bookingUid = slot.bookingUid;
}
return (
<div data-slot-owner={(slot.userIds || []).join(",")} key={`${dayjs(slot.time).format()}`}>
{/* ^ data-slot-owner is helpful in debugging and used to identify the owners of the slot. Owners are the users which have the timeslot in their schedule. It doesn't consider if a user has that timeslot booked */}
{/* Current there is no way to disable Next.js Links */}
{seatsPerTimeSlot && slot.attendees && slot.attendees >= seatsPerTimeSlot ? (
<div
className={classNames(
"text-primary-500 dark:bg-darkgray-200 dark:text-darkgray-900 mb-2 block rounded-sm border bg-white py-2 font-medium opacity-25 dark:border-transparent ",
brand === "#fff" || brand === "#ffffff" ? "" : ""
)}>
{dayjs(slot.time).tz(timeZone()).format(timeFormat)}
{!!seatsPerTimeSlot && <p className="text-sm">{t("booking_full")}</p>}
</div>
) : (
<Link
href={bookingUrl}
prefetch={false}
className={classNames(
"hover:bg-brand hover:border-brand hover:text-brandcontrast dark:hover:text-darkmodebrandcontrast",
"dark:bg-darkgray-200 dark:hover:bg-darkmodebrand dark:hover:border-darkmodebrand dark:text-darkgray-800 mb-2 block rounded-md border bg-white py-2 text-sm font-medium dark:border-transparent",
brand === "#fff" || brand === "#ffffff" ? "" : ""
)}
data-testid="time">
{dayjs(slot.time).tz(timeZone()).format(timeFormat)}
{!!seatsPerTimeSlot && (
<p
className={`${
slot.attendees && slot.attendees / seatsPerTimeSlot >= 0.8
? "text-rose-600"
: slot.attendees && slot.attendees / seatsPerTimeSlot >= 0.33
? "text-yellow-500"
: "text-emerald-400"
} text-sm`}>
{slot.attendees ? seatsPerTimeSlot - slot.attendees : seatsPerTimeSlot} /{" "}
{seatsPerTimeSlot} {t("seats_available")}
</p>
)}
</Link>
)}
</div>
);
})}
{!isLoading && !slots.length && (
<div className="-mt-4 flex h-full w-full flex-col content-center items-center justify-center">
<h1 className="my-6 text-xl text-black dark:text-white">{t("all_booked_today")}</h1>
</div>
)}
{isLoading && !slots.length && (
<>
<SkeletonContainer className="mb-2">
<SkeletonText className="h-5 w-full" />
</SkeletonContainer>
<SkeletonContainer className="mb-2">
<SkeletonText className="h-5 w-full" />
</SkeletonContainer>
<SkeletonContainer className="mb-2">
<SkeletonText className="h-5 w-full" />
</SkeletonContainer>
</>
)}
</div>
</div>
) : null}
</div>
);
};
@@ -1,10 +1,12 @@
import { SchedulingType } from "@prisma/client";
import { FC, ReactNode, useEffect } from "react";
import type { FC, ReactNode } from "react";
import { useEffect } from "react";
import dayjs from "@calcom/dayjs";
import { classNames } from "@calcom/lib";
import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Icon, Badge } from "@calcom/ui";
import { Badge } from "@calcom/ui";
import { FiCheckSquare, FiClock, FiInfo } from "@calcom/ui/components/icon";
import useRouterQuery from "@lib/hooks/useRouterQuery";
@@ -93,7 +95,7 @@ const BookingDescription: FC<Props> = (props) => {
isBookingPage && "dark:text-darkgray-600 text-sm font-medium text-gray-600"
)}>
<div>
<Icon.FiInfo
<FiInfo
className={classNames(
"ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]",
isBookingPage && "dark:text-darkgray-600 -mt-1 text-gray-500"
@@ -112,7 +114,7 @@ const BookingDescription: FC<Props> = (props) => {
isBookingPage && "dark:text-darkgray-600 text-sm font-medium text-gray-600"
)}>
<div>
<Icon.FiCheckSquare className="ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px] " />
<FiCheckSquare className="ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px] " />
</div>
{requiresConfirmationText}
</div>
@@ -123,9 +125,10 @@ const BookingDescription: FC<Props> = (props) => {
<div
className={classNames(
"flex flex-nowrap text-sm font-medium",
isBookingPage && "dark:text-darkgray-600 text-gray-600"
isBookingPage && "dark:text-darkgray-600 text-gray-600",
!eventType.metadata?.multipleDuration && "items-center"
)}>
<Icon.FiClock
<FiClock
className={classNames(
"min-h-4 min-w-4 ml-[2px] inline-block ltr:mr-[10px] rtl:ml-[10px]",
isBookingPage && "mt-[2px]"
+30 -30
View File
@@ -2,14 +2,17 @@ import { BookingStatus } from "@prisma/client";
import { useRouter } from "next/router";
import { useState } from "react";
import { EventLocationType, getEventLocationType } from "@calcom/app-store/locations";
import type { EventLocationType } from "@calcom/app-store/locations";
import { getEventLocationType } from "@calcom/app-store/locations";
import dayjs from "@calcom/dayjs";
import ViewRecordingsDialog from "@calcom/features/ee/video/ViewRecordingsDialog";
import classNames from "@calcom/lib/classNames";
import { formatTime } from "@calcom/lib/date-fns";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { getEveryFreqFor } from "@calcom/lib/recurringStrings";
import { RouterInputs, RouterOutputs, trpc } from "@calcom/trpc/react";
import type { RouterInputs, RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import type { ActionType } from "@calcom/ui";
import {
Badge,
Button,
@@ -17,15 +20,13 @@ import {
DialogClose,
DialogContent,
DialogFooter,
DialogHeader,
Icon,
MeetingTimeInTimezones,
showToast,
TextArea,
Tooltip,
ActionType,
TableActions,
TextAreaField,
} from "@calcom/ui";
import { FiCheck, FiClock, FiMapPin, FiRefreshCcw, FiSend, FiSlash, FiX } from "@calcom/ui/components/icon";
import useMeQuery from "@lib/hooks/useMeQuery";
@@ -53,7 +54,7 @@ function BookingListItem(booking: BookingItemProps) {
const [viewRecordingsDialogIsOpen, setViewRecordingsDialogIsOpen] = useState<boolean>(false);
const mutation = trpc.viewer.bookings.confirm.useMutation({
onSuccess: (data) => {
if (data.status === BookingStatus.REJECTED) {
if (data?.status === BookingStatus.REJECTED) {
setRejectionDialogIsOpen(false);
showToast(t("booking_rejection_success"), "success");
} else {
@@ -100,7 +101,7 @@ function BookingListItem(booking: BookingItemProps) {
onClick: () => {
setRejectionDialogIsOpen(true);
},
icon: Icon.FiSlash,
icon: FiSlash,
disabled: mutation.isLoading,
},
{
@@ -109,7 +110,7 @@ function BookingListItem(booking: BookingItemProps) {
onClick: () => {
bookingConfirm(true);
},
icon: Icon.FiCheck,
icon: FiCheck,
disabled: mutation.isLoading,
color: "primary",
},
@@ -135,7 +136,7 @@ function BookingListItem(booking: BookingItemProps) {
href: `/booking/${booking.uid}?cancel=true${
isTabRecurring && isRecurring ? "&allRemainingBookings=true" : ""
}`,
icon: Icon.FiX,
icon: FiX,
},
{
id: "edit_booking",
@@ -143,13 +144,13 @@ function BookingListItem(booking: BookingItemProps) {
actions: [
{
id: "reschedule",
icon: Icon.FiClock,
icon: FiClock,
label: t("reschedule_booking"),
href: `/reschedule/${booking.uid}`,
},
{
id: "reschedule_request",
icon: Icon.FiSend,
icon: FiSend,
iconClassName: "rotate-45 w-[16px] -translate-x-0.5 ",
label: t("send_reschedule_request"),
onClick: () => {
@@ -162,7 +163,7 @@ function BookingListItem(booking: BookingItemProps) {
onClick: () => {
setIsOpenLocationDialog(true);
},
icon: Icon.FiMapPin,
icon: FiMapPin,
},
],
},
@@ -179,7 +180,7 @@ function BookingListItem(booking: BookingItemProps) {
const RequestSentMessage = () => {
return (
<div className="ml-1 mr-8 flex text-gray-500" data-testid="request_reschedule_sent">
<Icon.FiSend className="-mt-[1px] w-4 rotate-45" />
<FiSend className="-mt-[1px] w-4 rotate-45" />
<p className="ml-2 ">{t("reschedule_request_sent")}</p>
</div>
);
@@ -245,24 +246,23 @@ function BookingListItem(booking: BookingItemProps) {
)}
{/* NOTE: Should refactor this dialog component as is being rendered multiple times */}
<Dialog open={rejectionDialogIsOpen} onOpenChange={setRejectionDialogIsOpen}>
<DialogContent>
<DialogHeader title={t("rejection_reason_title")} />
<p className="-mt-4 text-sm text-gray-500">{t("rejection_reason_description")}</p>
<p className="mt-6 mb-2 text-sm font-bold text-black">
{t("rejection_reason")}
<span className="font-normal text-gray-500"> (Optional)</span>
</p>
<TextArea
name={t("rejection_reason")}
value={rejectionReason}
onChange={(e) => setRejectionReason(e.target.value)}
className="mb-5 sm:mb-6"
/>
<DialogContent title={t("rejection_reason_title")} description={t("rejection_reason_description")}>
<div>
<TextAreaField
name="rejectionReason"
label={
<>
{t("rejection_reason")}
<span className="font-normal text-gray-500"> (Optional)</span>
</>
}
value={rejectionReason}
onChange={(e) => setRejectionReason(e.target.value)}
/>
</div>
<DialogFooter>
<DialogClose />
<Button
disabled={mutation.isLoading}
onClick={() => {
@@ -455,7 +455,7 @@ const RecurringBookingsTooltip = ({ booking, recurringDates }: RecurringBookings
);
})}>
<div className="text-gray-600 dark:text-white">
<Icon.FiRefreshCcw
<FiRefreshCcw
strokeWidth="3"
className="float-left mr-1 mt-1.5 inline-block h-3 w-3 text-gray-400"
/>
@@ -5,7 +5,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import type { RecurringEvent } from "@calcom/types/Calendar";
import { Button, Icon, TextArea } from "@calcom/ui";
import { Button, TextArea } from "@calcom/ui";
import { FiX } from "@calcom/ui/components/icon";
type Props = {
booking: {
@@ -28,7 +29,7 @@ export default function CancelBooking(props: Props) {
const [cancellationReason, setCancellationReason] = useState<string>("");
const { t } = useLocale();
const router = useRouter();
const { booking, profile, team, allRemainingBookings } = props;
const { booking, allRemainingBookings } = props;
const [loading, setLoading] = useState(false);
const telemetry = useTelemetry();
const [error, setError] = useState<string | null>(booking ? null : t("booking_already_cancelled"));
@@ -39,7 +40,7 @@ export default function CancelBooking(props: Props) {
{error && (
<div className="mt-8">
<div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-red-100">
<Icon.FiX className="h-6 w-6 text-red-600" />
<FiX className="h-6 w-6 text-red-600" />
</div>
<div className="mt-3 text-center sm:mt-5">
<h3 className="text-lg font-medium leading-6 text-gray-900" id="modal-title">
+200
View File
@@ -0,0 +1,200 @@
import type { EventType } from "@prisma/client";
import dynamic from "next/dynamic";
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import type { z } from "zod";
import type { Dayjs } from "@calcom/dayjs";
import dayjs from "@calcom/dayjs";
import DatePicker from "@calcom/features/calendars/DatePicker";
import classNames from "@calcom/lib/classNames";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { TimeFormat } from "@calcom/lib/timeFormat";
import type { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { trpc } from "@calcom/trpc/react";
import useRouterQuery from "@lib/hooks/useRouterQuery";
const AvailableTimes = dynamic(() => import("@components/booking/AvailableTimes"));
const getRefetchInterval = (refetchCount: number): number => {
const intervals = [3000, 3000, 5000, 10000, 20000, 30000] as const;
return intervals[refetchCount] || intervals[intervals.length - 1];
};
const useSlots = ({
eventTypeId,
eventTypeSlug,
startTime,
endTime,
usernameList,
timeZone,
duration,
enabled = true,
}: {
eventTypeId: number;
eventTypeSlug: string;
startTime?: Dayjs;
endTime?: Dayjs;
usernameList: string[];
timeZone?: string;
duration?: string;
enabled?: boolean;
}) => {
const [refetchCount, setRefetchCount] = useState(0);
const refetchInterval = getRefetchInterval(refetchCount);
const { data, isLoading, isPaused, fetchStatus } = trpc.viewer.public.slots.getSchedule.useQuery(
{
eventTypeId,
eventTypeSlug,
usernameList,
startTime: startTime?.toISOString() || "",
endTime: endTime?.toISOString() || "",
timeZone,
duration,
},
{
enabled: !!startTime && !!endTime && enabled,
refetchInterval,
trpc: { context: { skipBatch: true } },
}
);
useEffect(() => {
if (!!data && fetchStatus === "idle") {
setRefetchCount(refetchCount + 1);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fetchStatus, data]);
// The very first time isPaused is set if auto-fetch is disabled, so isPaused should also be considered a loading state.
return { slots: data?.slots || {}, isLoading: isLoading || isPaused };
};
export const SlotPicker = ({
eventType,
timeFormat,
onTimeFormatChange,
timeZone,
recurringEventCount,
users,
seatsPerTimeSlot,
weekStart = 0,
ethSignature,
}: {
eventType: Pick<
EventType & { metadata: z.infer<typeof EventTypeMetaDataSchema> },
"id" | "schedulingType" | "slug" | "length" | "metadata"
>;
timeFormat: TimeFormat;
onTimeFormatChange: (is24Hour: boolean) => void;
timeZone?: string;
seatsPerTimeSlot?: number;
recurringEventCount?: number;
users: string[];
weekStart?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
ethSignature?: string;
}) => {
const [selectedDate, setSelectedDate] = useState<Dayjs>();
const [browsingDate, setBrowsingDate] = useState<Dayjs>();
let { duration = eventType.length.toString() } = useRouterQuery("duration");
const { date, setQuery: setDate } = useRouterQuery("date");
const { month, setQuery: setMonth } = useRouterQuery("month");
const router = useRouter();
if (!eventType.metadata?.multipleDuration) {
duration = eventType.length.toString();
}
useEffect(() => {
if (!router.isReady) return;
// Etc/GMT is not actually a timeZone, so handle this select option explicitly to prevent a hard crash.
if (timeZone === "Etc/GMT") {
setBrowsingDate(dayjs.utc(month).set("date", 1).set("hour", 0).set("minute", 0).set("second", 0));
if (date) {
setSelectedDate(dayjs.utc(date));
}
} else {
// Set the start of the month without shifting time like startOf() may do.
setBrowsingDate(
dayjs.tz(month, timeZone).set("date", 1).set("hour", 0).set("minute", 0).set("second", 0)
);
if (date) {
// It's important to set the date immediately to the timeZone, dayjs(date) will convert to browsertime.
setSelectedDate(dayjs.tz(date, timeZone));
}
}
}, [router.isReady, month, date, duration, timeZone]);
const { i18n, isLocaleReady } = useLocale();
const { slots: monthSlots, isLoading } = useSlots({
eventTypeId: eventType.id,
eventTypeSlug: eventType.slug,
usernameList: users,
startTime:
browsingDate === undefined || browsingDate.get("month") === dayjs.tz(undefined, timeZone).get("month")
? dayjs.tz(undefined, timeZone).subtract(2, "days").startOf("day")
: browsingDate?.startOf("month"),
endTime: browsingDate?.endOf("month"),
timeZone,
duration,
});
const { slots: selectedDateSlots, isLoading: _isLoadingSelectedDateSlots } = useSlots({
eventTypeId: eventType.id,
eventTypeSlug: eventType.slug,
usernameList: users,
startTime: selectedDate?.startOf("day"),
endTime: selectedDate?.endOf("day"),
timeZone,
duration,
/** Prevent refetching is we already have this data from month slots */
enabled: !!selectedDate,
});
/** Hide skeleton if we have the slot loaded in the month query */
const isLoadingSelectedDateSlots = (() => {
if (!selectedDate) return _isLoadingSelectedDateSlots;
if (!!selectedDateSlots[selectedDate.format("YYYY-MM-DD")]) return false;
if (!!monthSlots[selectedDate.format("YYYY-MM-DD")]) return false;
return false;
})();
return (
<>
<DatePicker
isLoading={isLoading}
className={classNames(
"mt-8 px-4 pb-4 sm:mt-0 md:min-w-[300px] md:px-5 lg:min-w-[455px]",
selectedDate ? "sm:dark:border-darkgray-200 border-gray-200 sm:border-r sm:p-4 sm:pr-6" : "sm:p-4"
)}
includedDates={Object.keys(monthSlots).filter((k) => monthSlots[k].length > 0)}
locale={isLocaleReady ? i18n.language : "en"}
selected={selectedDate}
onChange={(newDate) => {
setDate(newDate.format("YYYY-MM-DD"));
}}
onMonthChange={(newMonth) => {
setMonth(newMonth.format("YYYY-MM"));
}}
browsingDate={browsingDate}
weekStart={weekStart}
/>
<AvailableTimes
isLoading={isLoadingSelectedDateSlots}
slots={
selectedDate &&
(selectedDateSlots[selectedDate.format("YYYY-MM-DD")] ||
monthSlots[selectedDate.format("YYYY-MM-DD")])
}
date={selectedDate}
timeFormat={timeFormat}
onTimeFormatChange={onTimeFormatChange}
eventTypeId={eventType.id}
eventTypeSlug={eventType.slug}
seatsPerTimeSlot={seatsPerTimeSlot}
recurringCount={recurringEventCount}
ethSignature={ethSignature}
/>
</>
);
};
+63 -16
View File
@@ -1,7 +1,11 @@
import { FC, useEffect, useState } from "react";
import type { FC } from "react";
import { useEffect, useState } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { ITimezoneOption, TimezoneSelect } from "@calcom/ui";
import useTheme from "@calcom/lib/hooks/useTheme";
import type { ITimezoneOption } from "@calcom/ui";
import { TimezoneSelect } from "@calcom/ui";
import useMeQuery from "@lib/hooks/useMeQuery";
import { timeZone } from "../../lib/clock";
@@ -11,7 +15,8 @@ type Props = {
const TimeOptions: FC<Props> = ({ onSelectTimeZone }) => {
const [selectedTimeZone, setSelectedTimeZone] = useState("");
const { t } = useLocale();
const query = useMeQuery();
const userTheme = useTheme(query?.data?.theme).resolvedTheme;
useEffect(() => {
setSelectedTimeZone(timeZone());
@@ -23,18 +28,60 @@ const TimeOptions: FC<Props> = ({ onSelectTimeZone }) => {
}
}, [selectedTimeZone, onSelectTimeZone]);
return selectedTimeZone !== "" ? (
<div className="dark:border-darkgray-300 dark:bg-darkgray-200 rounded-sm border border-gray-200 bg-white px-4 pt-4 pb-3 shadow-sm">
<div className="mb-4 flex">
<div className="text-sm font-medium text-gray-600 dark:text-white">{t("time_options")}</div>
</div>
<TimezoneSelect
id="timeZone"
value={selectedTimeZone}
onChange={(tz: ITimezoneOption) => setSelectedTimeZone(tz.value)}
className="focus:border-brand mt-1 mb-2 block w-full rounded-md border-gray-300 text-sm focus:ring-black"
/>
</div>
const customStyles = {
option: (_provided: object, state: { isSelected: boolean; isFocused: boolean }) => ({
padding: "10px 12px !important",
color: state.isSelected || state.isFocused ? "#101010" : "#374151",
backgroundColor: state.isSelected ? "#E5E7EB !important" : "white",
...(userTheme === "dark" && {
color: state.isSelected || state.isFocused ? "white" : "#80868B",
}),
}),
control: () => ({
display: "flex",
cursor: "pointer",
backgroundColor: "transparent !important",
minWidth: "5rem",
height: "24px",
minHeight: "24px !important",
boxShadow: "none !important",
}),
singleValue: (provided: object, state: { selectProps: { menuIsOpen: boolean } }) => ({
...provided,
color: state.selectProps.menuIsOpen ? "#111827" : "#4B5563",
...(userTheme === "dark" && {
color: "#a5a5a5 !important",
}),
}),
menu: (provided: object) => ({
...provided,
minWidth: "20rem",
margin: "8px 0 0 -20px",
}),
valueContainer: (provided: object) => ({
...provided,
padding: "0 0 0 6px",
}),
dropdownIndicator: (provided: object, state: { selectProps: { menuIsOpen: boolean } }) => ({
...provided,
transform: state.selectProps.menuIsOpen ? "rotate(180deg)" : "",
color: state.selectProps.menuIsOpen ? "#111827" : "#4B5563",
marginLeft: 4,
padding: 0,
...(userTheme === "dark" && {
color: "#80868B",
}),
}),
};
return !!selectedTimeZone ? (
<TimezoneSelect
id="timeZone"
value={selectedTimeZone}
onChange={(tz: ITimezoneOption) => setSelectedTimeZone(tz.value)}
className="flex h-6 text-sm font-medium"
styles={customStyles}
/>
) : null;
};
@@ -0,0 +1,26 @@
import { FiGlobe } from "@calcom/ui/components/icon";
import { timeZone as localStorageTimeZone } from "@lib/clock";
import TimeOptions from "@components/booking/TimeOptions";
export function TimezoneDropdown({
onChangeTimeZone,
}: {
onChangeTimeZone: (newTimeZone: string) => void;
timeZone?: string;
}) {
const handleSelectTimeZone = (newTimeZone: string) => {
onChangeTimeZone(newTimeZone);
localStorageTimeZone(newTimeZone);
};
return (
<>
<div className="dark:focus-within:bg-darkgray-200 dark:bg-darkgray-100 dark:hover:bg-darkgray-200 -mx-[2px] !mt-3 flex w-fit items-center rounded-[4px] px-1 py-[2px] text-sm font-medium focus-within:bg-gray-200 hover:bg-gray-100 [&_svg]:focus-within:text-gray-900 dark:[&_svg]:focus-within:text-white [&_p]:focus-within:text-gray-900 dark:[&_p]:focus-within:text-white">
<FiGlobe className="dark:text-darkgray-600 flex h-4 w-4 text-gray-600 ltr:mr-[2px] rtl:ml-[2px]" />
<TimeOptions onSelectTimeZone={handleSelectTimeZone} />
</div>
</>
);
}
+2 -1
View File
@@ -1,5 +1,6 @@
import { CAL_URL } from "@calcom/lib/constants";
import { AvatarGroup, AvatarGroupProps } from "@calcom/ui";
import type { AvatarGroupProps } from "@calcom/ui";
import { AvatarGroup } from "@calcom/ui";
export const UserAvatars = ({
profile,
@@ -1,15 +1,12 @@
import { useAutoAnimate } from "@formkit/auto-animate/react";
import { EventType } from "@prisma/client";
import * as Popover from "@radix-ui/react-popover";
import dynamic from "next/dynamic";
import { useRouter } from "next/router";
import { useReducer, useEffect, useMemo, useState } from "react";
import { Toaster } from "react-hot-toast";
import { useEffect, useMemo, useReducer, useState } from "react";
import { FormattedNumber, IntlProvider } from "react-intl";
import { z } from "zod";
import BookingPageTagManager from "@calcom/app-store/BookingPageTagManager";
import { getEventTypeAppData } from "@calcom/app-store/utils";
import dayjs, { Dayjs } from "@calcom/dayjs";
import dayjs from "@calcom/dayjs";
import {
useEmbedNonStylesConfig,
useEmbedStyles,
@@ -17,229 +14,39 @@ import {
useIsBackgroundTransparent,
useIsEmbed,
} from "@calcom/embed-core/embed-iframe";
import DatePicker from "@calcom/features/calendars/DatePicker";
import CustomBranding from "@calcom/lib/CustomBranding";
import classNames from "@calcom/lib/classNames";
import getStripeAppData from "@calcom/lib/getStripeAppData";
import getPaymentAppData from "@calcom/lib/getPaymentAppData";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import notEmpty from "@calcom/lib/notEmpty";
import { getRecurringFreq } from "@calcom/lib/recurringStrings";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import { detectBrowserTimeFormat, setIs24hClockInLocalStorage, TimeFormat } from "@calcom/lib/timeFormat";
import { trpc } from "@calcom/trpc/react";
import { Icon, HeadSeo } from "@calcom/ui";
import { HeadSeo } from "@calcom/ui";
import { FiCreditCard, FiRefreshCcw } from "@calcom/ui/components/icon";
import { timeZone as localStorageTimeZone } from "@lib/clock";
import useRouterQuery from "@lib/hooks/useRouterQuery";
import Gates, { Gate, GateState } from "@components/Gates";
import AvailableTimes from "@components/booking/AvailableTimes";
import type { Gate, GateState } from "@components/Gates";
import Gates from "@components/Gates";
import BookingDescription from "@components/booking/BookingDescription";
import TimeOptions from "@components/booking/TimeOptions";
import PoweredByCal from "@components/ui/PoweredByCal";
import { SlotPicker } from "@components/booking/SlotPicker";
import type { AvailabilityPageProps } from "../../../pages/[user]/[type]";
import type { DynamicAvailabilityPageProps } from "../../../pages/d/[link]/[slug]";
import type { AvailabilityTeamPageProps } from "../../../pages/team/[slug]/[type]";
const useSlots = ({
eventTypeId,
eventTypeSlug,
startTime,
endTime,
usernameList,
timeZone,
duration,
}: {
eventTypeId: number;
eventTypeSlug: string;
startTime?: Dayjs;
endTime?: Dayjs;
usernameList: string[];
timeZone?: string;
duration?: string;
}) => {
const { data, isLoading, isPaused } = trpc.viewer.public.slots.getSchedule.useQuery(
{
eventTypeId,
eventTypeSlug,
usernameList,
startTime: startTime?.toISOString() || "",
endTime: endTime?.toISOString() || "",
timeZone,
duration,
},
{
enabled: !!startTime && !!endTime,
}
);
const [cachedSlots, setCachedSlots] = useState<NonNullable<typeof data>["slots"]>({});
const PoweredByCal = dynamic(() => import("@components/ui/PoweredByCal"));
useEffect(() => {
if (data?.slots) {
setCachedSlots((c) => ({ ...c, ...data?.slots }));
}
}, [data]);
// The very first time isPaused is set if auto-fetch is disabled, so isPaused should also be considered a loading state.
return { slots: cachedSlots, isLoading: isLoading || isPaused };
};
const SlotPicker = ({
eventType,
timeFormat,
onTimeFormatChange,
timeZone,
recurringEventCount,
users,
seatsPerTimeSlot,
weekStart = 0,
ethSignature,
}: {
eventType: Pick<EventType, "id" | "schedulingType" | "slug">;
timeFormat: TimeFormat;
onTimeFormatChange: (is24Hour: boolean) => void;
timeZone?: string;
seatsPerTimeSlot?: number;
recurringEventCount?: number;
users: string[];
weekStart?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
ethSignature?: string;
}) => {
const [selectedDate, setSelectedDate] = useState<Dayjs>();
const [browsingDate, setBrowsingDate] = useState<Dayjs>();
const { duration } = useRouterQuery("duration");
const { date, setQuery: setDate } = useRouterQuery("date");
const { month, setQuery: setMonth } = useRouterQuery("month");
const router = useRouter();
const [slotPickerRef] = useAutoAnimate<HTMLDivElement>();
useEffect(() => {
if (!router.isReady) return;
// Etc/GMT is not actually a timeZone, so handle this select option explicitly to prevent a hard crash.
if (timeZone === "Etc/GMT") {
setBrowsingDate(dayjs.utc(month).set("date", 1).set("hour", 0).set("minute", 0).set("second", 0));
if (date) {
setSelectedDate(dayjs.utc(date));
}
} else {
// Set the start of the month without shifting time like startOf() may do.
setBrowsingDate(
dayjs.tz(month, timeZone).set("date", 1).set("hour", 0).set("minute", 0).set("second", 0)
);
if (date) {
// It's important to set the date immediately to the timeZone, dayjs(date) will convert to browsertime.
setSelectedDate(dayjs.tz(date, timeZone));
}
}
}, [router.isReady, month, date, duration, timeZone]);
const { i18n, isLocaleReady } = useLocale();
const { slots: _1 } = useSlots({
eventTypeId: eventType.id,
eventTypeSlug: eventType.slug,
usernameList: users,
startTime: selectedDate?.startOf("day"),
endTime: selectedDate?.endOf("day"),
timeZone,
duration,
});
const { slots: _2, isLoading } = useSlots({
eventTypeId: eventType.id,
eventTypeSlug: eventType.slug,
usernameList: users,
startTime:
browsingDate === undefined || browsingDate.get("month") === dayjs.tz(undefined, timeZone).get("month")
? dayjs.tz(undefined, timeZone).subtract(2, "days").startOf("day")
: browsingDate?.startOf("month"),
endTime: browsingDate?.endOf("month"),
timeZone,
duration,
});
const slots = useMemo(() => ({ ..._2, ..._1 }), [_1, _2]);
return (
<>
<DatePicker
isLoading={isLoading}
className={classNames(
"mt-8 px-4 pb-4 sm:mt-0 md:min-w-[300px] md:px-5 lg:min-w-[455px]",
selectedDate ? "sm:dark:border-darkgray-200 border-gray-200 sm:border-r sm:p-4 sm:pr-6" : "sm:p-4"
)}
includedDates={Object.keys(slots).filter((k) => slots[k].length > 0)}
locale={isLocaleReady ? i18n.language : "en"}
selected={selectedDate}
onChange={(newDate) => {
setDate(newDate.format("YYYY-MM-DD"));
}}
onMonthChange={(newMonth) => {
setMonth(newMonth.format("YYYY-MM"));
}}
browsingDate={browsingDate}
weekStart={weekStart}
/>
<div ref={slotPickerRef}>
<AvailableTimes
isLoading={isLoading}
slots={selectedDate && slots[selectedDate.format("YYYY-MM-DD")]}
date={selectedDate}
timeFormat={timeFormat}
onTimeFormatChange={onTimeFormatChange}
eventTypeId={eventType.id}
eventTypeSlug={eventType.slug}
seatsPerTimeSlot={seatsPerTimeSlot}
recurringCount={recurringEventCount}
ethSignature={ethSignature}
/>
</div>
</>
);
};
function TimezoneDropdown({
onChangeTimeZone,
timeZone,
}: {
onChangeTimeZone: (newTimeZone: string) => void;
timeZone?: string;
}) {
const [isTimeOptionsOpen, setIsTimeOptionsOpen] = useState(false);
const handleSelectTimeZone = (newTimeZone: string) => {
onChangeTimeZone(newTimeZone);
localStorageTimeZone(newTimeZone);
setIsTimeOptionsOpen(false);
};
return (
<Popover.Root open={isTimeOptionsOpen} onOpenChange={setIsTimeOptionsOpen}>
<Popover.Trigger className="min-w-32 dark:text-darkgray-600 radix-state-open:bg-gray-200 dark:radix-state-open:bg-darkgray-200 group relative mb-2 -ml-2 !mt-2 inline-block self-start rounded-md px-2 py-2 text-left text-gray-600">
<p className="flex items-center text-sm font-medium">
<Icon.FiGlobe className="min-h-4 min-w-4 ml-[2px] -mt-[2px] inline-block ltr:mr-[10px] rtl:ml-[10px]" />
{timeZone}
{isTimeOptionsOpen ? (
<Icon.FiChevronUp className="min-h-4 min-w-4 ml-1 inline-block" />
) : (
<Icon.FiChevronDown className="min-h-4 min-w-4 ml-1 inline-block" />
)}
</p>
</Popover.Trigger>
<Popover.Portal>
<Popover.Content
hideWhenDetached
align="start"
className="animate-fade-in-up absolute left-0 top-2 w-80 max-w-[calc(100vw_-_1.5rem)]">
<TimeOptions onSelectTimeZone={handleSelectTimeZone} />
</Popover.Content>
</Popover.Portal>
</Popover.Root>
);
}
const Toaster = dynamic(() => import("react-hot-toast").then((mod) => mod.Toaster), { ssr: false });
/*const SlotPicker = dynamic(() => import("../SlotPicker").then((mod) => mod.SlotPicker), {
ssr: false,
loading: () => <div className="mt-8 px-4 pb-4 sm:mt-0 sm:p-4 md:min-w-[300px] md:px-5 lg:min-w-[455px]" />,
});*/
const TimezoneDropdown = dynamic(() => import("../TimezoneDropdown").then((mod) => mod.TimezoneDropdown), {
ssr: false,
});
const dateQuerySchema = z.object({
rescheduleUid: z.string().optional().default(""),
@@ -302,7 +109,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
() => <TimezoneDropdown timeZone={timeZone} onChangeTimeZone={setTimeZone} />,
[timeZone]
);
const stripeAppData = getStripeAppData(eventType);
const paymentAppData = getPaymentAppData(eventType);
const rainbowAppData = getEventTypeAppData(eventType, "rainbow") || {};
const rawSlug = profile.slug ? profile.slug.split("/") : [];
if (rawSlug.length > 1) rawSlug.pop(); //team events have team name as slug, but user events have [user]/[type] as slug.
@@ -353,10 +160,10 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
isBackgroundTransparent
? ""
: "dark:bg-darkgray-100 sm:dark:border-darkgray-300 bg-white pb-4 md:pb-0",
"border-bookinglightest overflow-hidden md:rounded-md md:border",
"border-bookinglightest md:rounded-md md:border",
isEmbed && "mx-auto"
)}>
<div className="overflow-hidden md:flex">
<div className="md:flex">
{showEventTypeDetails && (
<div
className={classNames(
@@ -367,7 +174,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
<BookingDescription profile={profile} eventType={eventType} rescheduleUid={rescheduleUid}>
{!rescheduleUid && eventType.recurringEvent && (
<div className="flex items-start text-sm font-medium">
<Icon.FiRefreshCcw className="float-left mt-[7px] ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px] " />
<FiRefreshCcw className="float-left mt-[7px] ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px] " />
<div>
<p className="mb-1 -ml-2 inline px-2 py-1">
{getRecurringFreq({ t, recurringEvent: eventType.recurringEvent })}
@@ -390,14 +197,14 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
</div>
</div>
)}
{stripeAppData.price > 0 && (
{paymentAppData.price > 0 && (
<p className="-ml-2 px-2 text-sm font-medium">
<Icon.FiCreditCard className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<FiCreditCard className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<IntlProvider locale="en">
<FormattedNumber
value={stripeAppData.price / 100.0}
value={paymentAppData.price / 100.0}
style="currency"
currency={stripeAppData.currency.toUpperCase()}
currency={paymentAppData.currency?.toUpperCase()}
/>
</IntlProvider>
</p>
+170 -97
View File
@@ -6,15 +6,14 @@ import { useSession } from "next-auth/react";
import Head from "next/head";
import { useRouter } from "next/router";
import { useEffect, useMemo, useReducer, useState } from "react";
import { Controller, useForm, useWatch } from "react-hook-form";
import { useFieldArray, useForm, useWatch } from "react-hook-form";
import { FormattedNumber, IntlProvider } from "react-intl";
import { ReactMultiEmail } from "react-multi-email";
import { v4 as uuidv4 } from "uuid";
import { z } from "zod";
import BookingPageTagManager from "@calcom/app-store/BookingPageTagManager";
import type { EventLocationType } from "@calcom/app-store/locations";
import {
EventLocationType,
getEventLocationType,
getEventLocationValue,
getHumanReadableLocationValue,
@@ -22,7 +21,8 @@ import {
} from "@calcom/app-store/locations";
import { createPaymentLink } from "@calcom/app-store/stripepayment/lib/client";
import { getEventTypeAppData } from "@calcom/app-store/utils";
import { LocationObject, LocationType } from "@calcom/core/location";
import type { LocationObject } from "@calcom/core/location";
import { LocationType } from "@calcom/core/location";
import dayjs from "@calcom/dayjs";
import {
useEmbedNonStylesConfig,
@@ -33,14 +33,34 @@ import {
import CustomBranding from "@calcom/lib/CustomBranding";
import classNames from "@calcom/lib/classNames";
import { APP_NAME } from "@calcom/lib/constants";
import getStripeAppData from "@calcom/lib/getStripeAppData";
import getPaymentAppData from "@calcom/lib/getPaymentAppData";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
import { HttpError } from "@calcom/lib/http-error";
import { getEveryFreqFor } from "@calcom/lib/recurringStrings";
import slugify from "@calcom/lib/slugify";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import { AddressInput, Button, EmailInput, Form, Icon, PhoneInput, Tooltip } from "@calcom/ui";
import { Group, RadioField } from "@calcom/ui";
import {
AddressInput,
Button,
EmailField,
EmailInput,
Form,
Group,
PhoneInput,
RadioField,
Tooltip,
} from "@calcom/ui";
import {
FiUserPlus,
FiCalendar,
FiX,
FiInfo,
FiCreditCard,
FiRefreshCw,
FiUser,
FiAlertTriangle,
} from "@calcom/ui/components/icon";
import { asStringOrNull } from "@lib/asStringOrNull";
import { timeZone } from "@lib/clock";
@@ -49,14 +69,14 @@ import useRouterQuery from "@lib/hooks/useRouterQuery";
import createBooking from "@lib/mutations/bookings/create-booking";
import createRecurringBooking from "@lib/mutations/bookings/create-recurring-booking";
import { parseDate, parseRecurringDates } from "@lib/parseDate";
import slugify from "@lib/slugify";
import Gates, { Gate, GateState } from "@components/Gates";
import type { Gate, GateState } from "@components/Gates";
import Gates from "@components/Gates";
import BookingDescription from "@components/booking/BookingDescription";
import { BookPageProps } from "../../../pages/[user]/book";
import { HashLinkPageProps } from "../../../pages/d/[link]/book";
import { TeamBookingPageProps } from "../../../pages/team/[slug]/book";
import type { BookPageProps } from "../../../pages/[user]/book";
import type { HashLinkPageProps } from "../../../pages/d/[link]/book";
import type { TeamBookingPageProps } from "../../../pages/team/[slug]/book";
type BookingPageProps = BookPageProps | TeamBookingPageProps | HashLinkPageProps;
@@ -65,7 +85,7 @@ type BookingFormValues = {
email: string;
notes?: string;
locationType?: EventLocationType["type"];
guests?: string[];
guests?: { email: string }[];
address?: string;
attendeeAddress?: string;
phone?: string;
@@ -104,10 +124,15 @@ const BookingPage = ({
}),
{}
);
const stripeAppData = getStripeAppData(eventType);
const paymentAppData = getPaymentAppData(eventType);
// Define duration now that we support multiple duration eventTypes
let duration = eventType.length;
if (queryDuration && !isNaN(Number(queryDuration))) {
if (
queryDuration &&
!isNaN(Number(queryDuration)) &&
eventType.metadata?.multipleDuration &&
eventType.metadata?.multipleDuration.includes(Number(queryDuration))
) {
duration = Number(queryDuration);
}
@@ -125,6 +150,7 @@ const BookingPage = ({
const mutation = useMutation(createBooking, {
onSuccess: async (responseData) => {
const { uid, paymentUid } = responseData;
if (paymentUid) {
return await router.push(
createPaymentLink({
@@ -143,7 +169,7 @@ const BookingPage = ({
isSuccessBookingPage: true,
email: bookingForm.getValues("email"),
eventTypeSlug: eventType.slug,
formerTime: booking?.startTime.toString(),
...(rescheduleUid && booking?.startTime && { formerTime: booking.startTime.toString() }),
},
});
},
@@ -184,7 +210,9 @@ const BookingPage = ({
const loggedInIsOwner = eventType?.users[0]?.id === session?.user?.id;
const guestListEmails = !isDynamicGroupBooking
? booking?.attendees.slice(1).map((attendee) => attendee.email)
? booking?.attendees.slice(1).map((attendee) => {
return { email: attendee.email };
})
: [];
// There should only exists one default userData variable for primaryAttendee.
@@ -203,7 +231,9 @@ const BookingPage = ({
name: defaultUserValues.name || (!loggedInIsOwner && session?.user?.name) || "",
email: defaultUserValues.email || (!loggedInIsOwner && session?.user?.email) || "",
notes: (router.query.notes as string) || "",
guests: ensureArray(router.query.guest) as string[],
guests: ensureArray(router.query.guest).map((guest) => {
return { email: guest as string };
}),
customInputs: eventType.customInputs.reduce(
(customInputs, input) => ({
...customInputs,
@@ -245,6 +275,7 @@ const BookingPage = ({
.object({
name: z.string().min(1),
email: z.string().trim().email(),
guests: z.array(z.object({ email: z.string().email() })).optional(),
phone: z
.string()
.refine((val) => isValidPhoneNumber(val))
@@ -263,6 +294,10 @@ const BookingPage = ({
defaultValues: defaultValues(),
resolver: zodResolver(bookingFormSchema), // Since this isn't set to strict we only validate the fields in the schema
});
const guestsField = useFieldArray({
name: "guests",
control: bookingForm.control,
});
const selectedLocationType = useWatch({
control: bookingForm.control,
@@ -301,6 +336,7 @@ const BookingPage = ({
}
const bookEvent = (booking: BookingFormValues) => {
bookingForm.clearErrors();
const bookingCustomInputs = Object.keys(booking.customInputs || {}).map((inputId) => ({
label: eventType.customInputs.find((input) => input.id === parseInt(inputId))?.label || "",
value: booking.customInputs && booking.customInputs[inputId] ? booking.customInputs[inputId] : "",
@@ -368,6 +404,29 @@ const BookingPage = ({
}
}
// Validate that guests are unique
let alreadyInvited = false;
booking.guests?.forEach((guest, index) => {
if (guest.email === booking.email) {
bookingForm.setError(`guests.${index}`, { type: "validate", message: t("already_invited") });
alreadyInvited = true;
}
if (booking.guests) {
let guestCount = 0;
for (const checkGuest of booking.guests) {
if (checkGuest.email === guest.email) guestCount++;
if (guestCount > 1) {
bookingForm.setError(`guests.${index}`, { type: "validate", message: t("already_invited") });
alreadyInvited = true;
break;
}
}
}
});
if (alreadyInvited) return;
if (recurringDates.length) {
// Identify set of bookings to one intance of recurring event to support batch changes
const recurringEventId = uuidv4();
@@ -398,6 +457,7 @@ const BookingPage = ({
? booking.phone
: booking.smsReminderNumber || undefined,
ethSignature: gateState.rainbowToken,
guests: booking.guests?.map((guest) => guest.email),
}));
recurringMutation.mutate(recurringBookings);
} else {
@@ -426,6 +486,7 @@ const BookingPage = ({
? booking.phone
: booking.smsReminderNumber || undefined,
ethSignature: gateState.rainbowToken,
guests: booking.guests?.map((guest) => guest.email),
});
}
};
@@ -479,7 +540,7 @@ const BookingPage = ({
})}{" "}
| {APP_NAME}
</title>
<link rel="icon" href="/favicon.ico" />
<link rel="icon" href="/favico.ico" />
</Head>
<BookingPageTagManager eventType={eventType} />
<CustomBranding lightVal={profile.brandColor} darkVal={profile.darkBrandColor} />
@@ -499,21 +560,21 @@ const BookingPage = ({
{showEventTypeDetails && (
<div className="sm:dark:border-darkgray-300 dark:text-darkgray-600 flex flex-col px-6 pt-6 pb-0 text-gray-600 sm:w-1/2 sm:border-r sm:pb-6">
<BookingDescription isBookingPage profile={profile} eventType={eventType}>
{stripeAppData.price > 0 && (
{paymentAppData.price > 0 && (
<p className="text-bookinglight -ml-2 px-2 text-sm ">
<Icon.FiCreditCard className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<FiCreditCard className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<IntlProvider locale="en">
<FormattedNumber
value={stripeAppData.price / 100.0}
value={paymentAppData.price / 100.0}
style="currency"
currency={stripeAppData.currency.toUpperCase()}
currency={paymentAppData?.currency?.toUpperCase()}
/>
</IntlProvider>
</p>
)}
{!rescheduleUid && eventType.recurringEvent?.freq && recurringEventCount && (
<div className="items-start text-sm font-medium text-gray-600 dark:text-white">
<Icon.FiRefreshCw className="ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<FiRefreshCw className="ml-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<p className="-ml-2 inline-block items-center px-2">
{getEveryFreqFor({
t,
@@ -524,7 +585,7 @@ const BookingPage = ({
</div>
)}
<div className="text-bookinghighlight flex items-start text-sm">
<Icon.FiCalendar className="ml-[2px] mt-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<FiCalendar className="ml-[2px] mt-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<div className="text-sm font-medium">
{(rescheduleUid || !eventType.recurringEvent?.freq) && `${parseDate(date, i18n)}`}
{!rescheduleUid &&
@@ -552,14 +613,14 @@ const BookingPage = ({
{t("former_time")}
</p>
<p className="line-through ">
<Icon.FiCalendar className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
<FiCalendar className="ml-[2px] -mt-1 inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px]" />
{typeof booking.startTime === "string" && parseDate(dayjs(booking.startTime), i18n)}
</p>
</div>
)}
{!!eventType.seatsPerTimeSlot && (
<div className="text-bookinghighlight flex items-start text-sm">
<Icon.FiUser
<FiUser
className={`ml-[2px] mt-[2px] inline-block h-4 w-4 ltr:mr-[10px] rtl:ml-[10px] ${
booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.5
? "text-rose-600"
@@ -623,7 +684,7 @@ const BookingPage = ({
/>
{bookingForm.formState.errors.email && (
<div className="mt-2 flex items-center text-sm text-red-700 ">
<Icon.FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p>{t("email_validation_error")}</p>
</div>
)}
@@ -716,7 +777,7 @@ const BookingPage = ({
</div>
{bookingForm.formState.errors.phone && (
<div className="mt-2 flex items-center text-sm text-red-700 ">
<Icon.FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p>{t("invalid_number")}</p>
</div>
)}
@@ -834,7 +895,7 @@ const BookingPage = ({
/>
{bookingForm.formState.errors?.customInputs?.[input.id] && (
<div className="mt-2 flex items-center text-sm text-red-700 ">
<Icon.FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p>{t("invalid_number")}</p>
</div>
)}
@@ -842,60 +903,7 @@ const BookingPage = ({
)}
</div>
))}
{!eventType.disableGuests && guestToggle && (
<div className="mb-4">
<div>
<label
htmlFor="guests"
className="mb-1 block text-sm font-medium text-gray-700 dark:text-white">
{t("guests")}
</label>
{!disableInput && (
<Controller
control={bookingForm.control}
name="guests"
render={({ field: { onChange, value } }) => (
<ReactMultiEmail
className="relative"
placeholder={<span className="dark:text-darkgray-600">guest@example.com</span>}
emails={value}
onChange={onChange}
getLabel={(
email: string,
index: number,
removeEmail: (index: number) => void
) => {
return (
<div data-tag key={index} className="cursor-pointer">
{email}
{!disableInput && (
<span data-tag-handle onClick={() => removeEmail(index)}>
×
</span>
)}
</div>
);
}}
/>
)}
/>
)}
{/* Custom code when guest emails should not be editable */}
{disableInput && guestListEmails && guestListEmails.length > 0 && (
<div data-tag className="react-multi-email">
{/* // @TODO: user owners are appearing as guest here when should be only user input */}
{guestListEmails.map((email, index) => {
return (
<div key={index} className="cursor-pointer">
<span data-tag>{email}</span>
</div>
);
})}
</div>
)}
</div>
</div>
)}
{isSmsReminderNumberNeeded && selectedLocationType !== LocationType.Phone && (
<div className="mb-4">
<label
@@ -914,7 +922,7 @@ const BookingPage = ({
</div>
{bookingForm.formState.errors.smsReminderNumber && (
<div className="mt-2 flex items-center text-sm text-red-700 ">
<Icon.FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p>{t("invalid_number")}</p>
</div>
)}
@@ -948,19 +956,84 @@ const BookingPage = ({
/>
)}
</div>
{!eventType.disableGuests && guestsField.fields.length ? (
<div className="mb-4">
<div>
<label
htmlFor="guests"
className="mb-1 block text-sm font-medium text-gray-700 dark:text-white">
{t("guests")}
</label>
<ul>
{guestsField.fields.map((field, index) => (
<li key={field.id}>
<EmailField
{...bookingForm.register(`guests.${index}.email` as const)}
className={classNames(
inputClassName,
bookingForm.formState.errors.guests?.[index] &&
"!focus:ring-red-700 !border-red-700",
"border-r-0"
)}
addOnClassname={classNames(
"border-gray-300 border block border-l-0 disabled:bg-gray-200 disabled:hover:cursor-not-allowed bg-transparent disabled:text-gray-500 dark:border-darkgray-300 ",
bookingForm.formState.errors.guests?.[index] &&
"!focus:ring-red-700 !border-red-700"
)}
placeholder="guest@example.com"
label={<></>}
required
addOnSuffix={
<Tooltip content="Remove guest">
<button
className="m-1 disabled:hover:cursor-not-allowed"
type="button"
onClick={() => guestsField.remove(index)}>
<FiX className="text-gray-600" />
</button>
</Tooltip>
}
/>
{bookingForm.formState.errors.guests?.[index] && (
<div className="mt-2 flex items-center text-sm text-red-700 ">
<FiInfo className="h-3 w-3 ltr:mr-2 rtl:ml-2" />
<p className="text-red-700">
{bookingForm.formState.errors.guests?.[index]?.message}
</p>
</div>
)}
</li>
))}
</ul>
<Button
type="button"
color="minimal"
StartIcon={FiUserPlus}
className="my-2.5"
// className="mb-1 block text-sm font-medium text-gray-700 dark:text-white"
onClick={() => guestsField.append({ email: "" })}>
{t("add_another")}
</Button>
</div>
</div>
) : (
<></>
)}
{!eventType.disableGuests && !guestsField.fields.length && (
<Button
color="minimal"
variant="button"
StartIcon={FiUserPlus}
onClick={() => {
guestsField.append({ email: "" });
}}
className="mr-auto">
{t("additional_guests")}
</Button>
)}
<div className="flex justify-end space-x-2 rtl:space-x-reverse">
{!eventType.disableGuests && !guestToggle && (
<Button
type="button"
color="minimal"
variant="icon"
tooltip={t("additional_guests")}
StartIcon={Icon.FiUserPlus}
onClick={() => setGuestToggle(!guestToggle)}
className="mr-auto"
/>
)}
<Button color="minimal" type="button" onClick={() => router.back()}>
{t("cancel")}
</Button>
@@ -993,7 +1066,7 @@ function ErrorMessage({ error }: { error: unknown }) {
<div data-testid="booking-fail" className="mt-2 border-l-4 border-yellow-400 bg-yellow-50 p-4">
<div className="flex">
<div className="flex-shrink-0">
<Icon.FiAlertTriangle className="h-5 w-5 text-yellow-400" aria-hidden="true" />
<FiAlertTriangle className="h-5 w-5 text-yellow-400" aria-hidden="true" />
</div>
<div className="ltr:ml-3 rtl:mr-3">
<p className="text-sm text-yellow-700">
@@ -1,26 +1,30 @@
import { ErrorMessage } from "@hookform/error-message";
import { zodResolver } from "@hookform/resolvers/zod";
import { isValidPhoneNumber } from "libphonenumber-js";
import { Trans } from "next-i18next";
import Link from "next/link";
import { useEffect } from "react";
import { Controller, useForm, useWatch } from "react-hook-form";
import { z } from "zod";
import type { EventLocationType, LocationObject } from "@calcom/app-store/locations";
import {
EventLocationType,
getEventLocationType,
getHumanReadableLocationValue,
getMessageForOrganizer,
LocationObject,
LocationType,
} from "@calcom/app-store/locations";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { RouterOutputs, trpc } from "@calcom/trpc/react";
import { Button, Dialog, DialogContent, DialogFooter, Form, Icon, PhoneInput } from "@calcom/ui";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import { Button, Dialog, DialogContent, DialogFooter, Form, PhoneInput } from "@calcom/ui";
import { FiMapPin } from "@calcom/ui/components/icon";
import { QueryCell } from "@lib/QueryCell";
import CheckboxField from "@components/ui/form/CheckboxField";
import LocationSelect, { LocationOption } from "@components/ui/form/LocationSelect";
import type { LocationOption } from "@components/ui/form/LocationSelect";
import LocationSelect from "@components/ui/form/LocationSelect";
type BookingItem = RouterOutputs["viewer"]["bookings"]["get"]["bookings"][number];
@@ -184,6 +188,7 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
control={locationFormMethods.control}
render={() => (
<CheckboxField
data-testid="display-location"
defaultChecked={defaultLocation?.displayLocationPublicly}
description={t("display_location_label")}
onChange={(e) =>
@@ -204,10 +209,10 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
return (
<Dialog open={isOpenDialog} onOpenChange={(open) => setShowLocationModal(open)}>
<DialogContent disableOverflow>
<DialogContent>
<div className="flex flex-row space-x-3">
<div className="bg-secondary-100 mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full sm:mx-0 sm:h-10 sm:w-10">
<Icon.FiMapPin className="text-primary-600 h-6 w-6" />
<FiMapPin className="text-primary-600 h-6 w-6" />
</div>
<div className="w-full">
<div className="mt-3 text-center sm:mt-0 sm:text-left">
@@ -215,7 +220,15 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
{t("edit_location")}
</h3>
{!booking && (
<p className="text-sm text-gray-400">{t("this_input_will_shown_booking_this_event")}</p>
<p className="text-sm text-gray-400">
<Trans i18nKey="cant_find_the_right_video_app_visit_our_app_store">
Can&apos;t find the right video app? Visit our
<Link className="cursor-pointer text-blue-500 underline" href="/apps/categories/video">
App Store
</Link>
.
</Trans>
</p>
)}
</div>
<div className="mt-3 text-center sm:mt-0 sm:text-left" />
@@ -288,30 +301,31 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
name="locationType"
control={locationFormMethods.control}
render={() => (
<LocationSelect
maxMenuHeight={300}
name="location"
defaultValue={selection}
options={locationOptions}
isSearchable
className="my-4 block w-full min-w-0 flex-1 rounded-sm border border-gray-300 text-sm"
onChange={(val) => {
if (val) {
locationFormMethods.setValue("locationType", val.value);
locationFormMethods.unregister([
"locationLink",
"locationAddress",
"locationPhoneNumber",
]);
locationFormMethods.clearErrors([
"locationLink",
"locationPhoneNumber",
"locationAddress",
]);
setSelectedLocation?.(val);
}
}}
/>
<div className="py-4">
<LocationSelect
maxMenuHeight={300}
name="location"
defaultValue={selection}
options={locationOptions}
isSearchable
onChange={(val) => {
if (val) {
locationFormMethods.setValue("locationType", val.value);
locationFormMethods.unregister([
"locationLink",
"locationAddress",
"locationPhoneNumber",
]);
locationFormMethods.clearErrors([
"locationLink",
"locationPhoneNumber",
"locationAddress",
]);
setSelectedLocation?.(val);
}
}}
/>
</div>
)}
/>
);
@@ -325,14 +339,16 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
setShowLocationModal(false);
setSelectedLocation?.(undefined);
setEditingLocationType?.("");
locationFormMethods.unregister("locationType");
locationFormMethods.unregister(["locationType", "locationLink"]);
}}
type="button"
color="secondary">
{t("cancel")}
</Button>
<Button type="submit">{t("update")}</Button>
<Button data-testid="update-location" type="submit">
{t("update")}
</Button>
</div>
</DialogFooter>
</Form>
@@ -1,4 +1,5 @@
import { Dispatch, SetStateAction, useState } from "react";
import type { Dispatch, SetStateAction } from "react";
import { useState } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
@@ -9,10 +10,10 @@ import {
DialogContent,
DialogFooter,
DialogHeader,
Icon,
showToast,
TextArea,
} from "@calcom/ui";
import { FiClock } from "@calcom/ui/components/icon";
interface IRescheduleDialog {
isOpenDialog: boolean;
@@ -43,7 +44,7 @@ export const RescheduleDialog = (props: IRescheduleDialog) => {
<DialogContent>
<div className="flex flex-row space-x-3">
<div className="flex h-10 w-10 flex-shrink-0 justify-center rounded-full bg-[#FAFAFA]">
<Icon.FiClock className="m-auto h-6 w-6" />
<FiClock className="m-auto h-6 w-6" />
</div>
<div className="pt-1">
<DialogHeader title={t("send_reschedule_request")} />
+105 -88
View File
@@ -1,6 +1,7 @@
import { FormValues } from "pages/event-types/[type]";
import type { FormValues } from "pages/event-types/[type]";
import { Controller, useFormContext } from "react-hook-form";
import { components, OptionProps, SingleValueProps } from "react-select";
import type { OptionProps, SingleValueProps } from "react-select";
import { components } from "react-select";
import dayjs from "@calcom/dayjs";
import classNames from "@calcom/lib/classNames";
@@ -8,7 +9,8 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
import { weekdayNames } from "@calcom/lib/weekday";
import { trpc } from "@calcom/trpc/react";
import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery";
import { Badge, Button, Icon, Select, SettingsToggle, SkeletonText } from "@calcom/ui";
import { Badge, Button, Select, SettingsToggle, SkeletonText } from "@calcom/ui";
import { FiExternalLink, FiGlobe } from "@calcom/ui/components/icon";
import { SelectSkeletonLoader } from "@components/availability/SkeletonLoader";
@@ -98,100 +100,106 @@ const format = (date: Date, hour12: boolean) =>
new Date(dayjs.utc(date).format("YYYY-MM-DDTHH:mm:ss"))
);
export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
const EventTypeScheduleDetails = () => {
const { data: loggedInUser } = useMeQuery();
const timeFormat = loggedInUser?.timeFormat;
const { t, i18n } = useLocale();
const { watch } = useFormContext<FormValues>();
const EventTypeSchedule = () => {
const me = useMeQuery();
const timeFormat = me?.data?.timeFormat;
return (
<div className="space-y-4">
<div>
<div className="min-w-4 mb-2">
<label htmlFor="availability" className="mt-0 flex text-sm font-medium text-gray-700">
{t("availability")}
</label>
</div>
<Controller
name="schedule"
render={({ field }) => (
<AvailabilitySelect
value={field.value}
onBlur={field.onBlur}
name={field.name}
onChange={(selected) => {
field.onChange(selected?.value || null);
}}
/>
)}
/>
</div>
<div className="space-y-4 rounded border p-4 py-6 pt-2 md:p-8">
<ol className="table border-collapse text-sm">
{weekdayNames(i18n.language, 1, "long").map((day, index) => {
const isAvailable = !!filterDays(index).length;
return (
<li key={day} className="my-6 flex border-transparent last:mb-2">
<span
className={classNames(
"w-20 font-medium sm:w-32",
!isAvailable && "text-gray-500 opacity-50"
)}>
{day}
</span>
{isLoading ? (
<SkeletonText className="block h-5 w-60" />
) : isAvailable ? (
<div className="space-y-3 text-right">
{filterDays(index).map((dayRange, i) => (
<div key={i} className="flex items-center leading-4">
<span className="w-16 sm:w-28 sm:text-left">
{format(dayRange.startTime, timeFormat === 12)}
</span>
<span className="ltr:ml-4 rtl:mr-4">-</span>
<div className="ml-6">{format(dayRange.endTime, timeFormat === 12)}</div>
</div>
))}
</div>
) : (
<span className="ml-6 text-gray-500 opacity-50 sm:ml-0">{t("unavailable")}</span>
)}
</li>
);
})}
</ol>
<hr />
<div className="flex flex-col justify-center gap-2 sm:flex-row sm:justify-between">
<span className="flex items-center justify-center text-sm text-gray-600 sm:justify-start">
<Icon.FiGlobe className="ltr:mr-2 rtl:ml-2" />
{schedule?.timeZone || <SkeletonText className="block h-5 w-32" />}
</span>
<Button
href={`/availability/${schedule?.schedule.id}`}
color="minimal"
EndIcon={Icon.FiExternalLink}
target="_blank"
className="justify-center border sm:border-0"
rel="noopener noreferrer">
{t("edit_availability")}
</Button>
</div>
</div>
</div>
);
};
const scheduleId = watch("schedule");
const { isLoading, data: schedule } = trpc.viewer.availability.schedule.get.useQuery({ scheduleId });
const { isLoading, data: schedule } = trpc.viewer.availability.schedule.get.useQuery(
{ scheduleId: scheduleId || loggedInUser?.defaultScheduleId || undefined },
{ enabled: !!scheduleId || !!loggedInUser?.defaultScheduleId }
);
const filterDays = (dayNum: number) =>
schedule?.schedule.availability.filter((item) => item.days.includes((dayNum + 1) % 7)) || [];
if (!isTeamEvent) {
return <EventTypeSchedule />;
}
return (
<div className="space-y-4 rounded border px-6 pb-4">
<ol className="table border-collapse text-sm">
{weekdayNames(i18n.language, 1, "long").map((day, index) => {
const isAvailable = !!filterDays(index).length;
return (
<li key={day} className="my-6 flex border-transparent last:mb-2">
<span
className={classNames(
"w-20 font-medium sm:w-32",
!isAvailable && "text-gray-500 opacity-50"
)}>
{day}
</span>
{isLoading ? (
<SkeletonText className="block h-5 w-60" />
) : isAvailable ? (
<div className="space-y-3 text-right">
{filterDays(index).map((dayRange, i) => (
<div key={i} className="flex items-center leading-4">
<span className="w-16 sm:w-28 sm:text-left">
{format(dayRange.startTime, timeFormat === 12)}
</span>
<span className="ltr:ml-4 rtl:mr-4">-</span>
<div className="ml-6">{format(dayRange.endTime, timeFormat === 12)}</div>
</div>
))}
</div>
) : (
<span className="ml-6 text-gray-500 opacity-50 sm:ml-0">{t("unavailable")}</span>
)}
</li>
);
})}
</ol>
<hr />
<div className="flex flex-col justify-center gap-2 sm:flex-row sm:justify-between">
<span className="flex items-center justify-center text-sm text-gray-600 sm:justify-start">
<FiGlobe className="ltr:mr-2 rtl:ml-2" />
{schedule?.timeZone || <SkeletonText className="block h-5 w-32" />}
</span>
<Button
href={`/availability/${schedule?.schedule.id}`}
disabled={isLoading}
color="minimal"
EndIcon={FiExternalLink}
target="_blank"
rel="noopener noreferrer">
{t("edit_availability")}
</Button>
</div>
</div>
);
};
const EventTypeSchedule = () => {
const { t } = useLocale();
return (
<div className="space-y-4">
<div>
<label htmlFor="availability" className="mb-2 block text-sm font-medium leading-none text-gray-700">
{t("availability")}
</label>
<Controller
name="schedule"
render={({ field }) => (
<AvailabilitySelect
value={field.value}
onBlur={field.onBlur}
name={field.name}
onChange={(selected) => {
field.onChange(selected?.value || null);
}}
/>
)}
/>
</div>
<EventTypeScheduleDetails />
</div>
);
};
const UseCommonScheduleSettingsToggle = () => {
const { t } = useLocale();
const { resetField, setValue } = useFormContext<FormValues>();
return (
<Controller
name="metadata.config.useHostSchedulesForTeamEvent"
@@ -200,6 +208,11 @@ export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
checked={!value}
onCheckedChange={(checked) => {
onChange(!checked);
if (checked) {
resetField("schedule");
} else {
setValue("schedule", null);
}
}}
title={t("choose_common_schedule_team_event")}
description={t("choose_common_schedule_team_event_description")}>
@@ -209,3 +222,7 @@ export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
/>
);
};
export const AvailabilityTab = ({ isTeamEvent }: { isTeamEvent: boolean }) => {
return isTeamEvent ? <UseCommonScheduleSettingsToggle /> : <EventTypeSchedule />;
};
@@ -1,11 +1,13 @@
import { useAutoAnimate } from "@formkit/auto-animate/react";
import { EventTypeCustomInputType } from "@prisma/client";
import type { CustomInputParsed } from "pages/event-types/[type]";
import { FC } from "react";
import { Control, Controller, useFieldArray, useForm, UseFormRegister, useWatch } from "react-hook-form";
import type { FC } from "react";
import type { Control, UseFormRegister } from "react-hook-form";
import { Controller, useFieldArray, useForm, useWatch } from "react-hook-form";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, Icon, Label, Select, TextField } from "@calcom/ui";
import { Button, Label, Select, TextField } from "@calcom/ui";
import { FiPlus, FiX } from "@calcom/ui/components/icon";
interface OptionTypeBase {
label: string;
@@ -77,7 +79,7 @@ const CustomInputTypeForm: FC<Props> = (props) => {
defaultValue={selectedInputOption}
options={inputOptions}
isSearchable={false}
className="mt-1 mb-2 block w-full min-w-0 flex-1 text-sm"
className="mt-1 mb-2 block w-full min-w-0 flex-1 text-sm"
onChange={(option) => option && field.onChange(option.value)}
value={selectedInputOption}
onBlur={field.onBlur}
@@ -185,7 +187,7 @@ function RadioInputHandler({
<Button
variant="icon"
color="minimal"
StartIcon={Icon.FiX}
StartIcon={FiX}
onClick={() => {
remove(index);
}}
@@ -196,7 +198,7 @@ function RadioInputHandler({
))}
<Button
color="minimal"
StartIcon={Icon.FiPlus}
StartIcon={FiPlus}
className="!text-sm !font-medium"
onClick={() => {
append({ label: "", type: "text" });
@@ -5,6 +5,8 @@ import { Controller, useFormContext } from "react-hook-form";
import short from "short-uuid";
import { v5 as uuidv5 } from "uuid";
import type { EventNameObjectType } from "@calcom/core/event";
import { getEventName } from "@calcom/core/event";
import DestinationCalendarSelector from "@calcom/features/calendars/DestinationCalendarSelector";
import CustomInputItem from "@calcom/features/eventtypes/components/CustomInputItem";
import { APP_NAME, CAL_URL, IS_SELF_HOSTED } from "@calcom/lib/constants";
@@ -18,13 +20,13 @@ import {
DialogClose,
DialogContent,
DialogFooter,
Icon,
Label,
SettingsToggle,
showToast,
TextField,
Tooltip,
} from "@calcom/ui";
import { FiEdit, FiCopy, FiPlus } from "@calcom/ui/components/icon";
import CustomInputTypeForm from "@components/eventtype/CustomInputTypeForm";
@@ -57,6 +59,14 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
const [hashedLinkVisible, setHashedLinkVisible] = useState(!!eventType.hashedLink);
const [redirectUrlVisible, setRedirectUrlVisible] = useState(!!eventType.successRedirectUrl);
const [hashedUrl, setHashedUrl] = useState(eventType.hashedLink?.link);
const eventNameObject: EventNameObjectType = {
attendeeName: t("scheduler"),
eventType: eventType.title,
eventName: eventType.eventName,
host: eventType.users[0]?.name || "Nameless",
t,
};
const [previewText, setPreviewText] = useState(getEventName(eventNameObject));
const [customInputs, setCustomInputs] = useState<CustomInputParsed[]>(
eventType.customInputs.sort((a, b) => a.id - b.id) || []
);
@@ -64,7 +74,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
const [selectedCustomInputModalOpen, setSelectedCustomInputModalOpen] = useState(false);
const [requiresConfirmation, setRequiresConfirmation] = useState(eventType.requiresConfirmation);
const placeholderHashedLink = `${CAL_URL}/d/${hashedUrl}/${eventType.slug}`;
const seatsEnabled = formMethods.getValues("seatsPerTimeSlotEnabled");
const seatsEnabled = formMethods.watch("seatsPerTimeSlotEnabled");
const removeCustom = (index: number) => {
formMethods.getValues("customInputs").splice(index, 1);
@@ -72,6 +82,16 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
setCustomInputs([...customInputs]);
};
const replaceEventNamePlaceholder = (eventNameObject: EventNameObjectType, previewEventName: string) =>
previewEventName
.replace("{Event type title}", eventNameObject.eventType)
.replace("{Scheduler}", eventNameObject.attendeeName)
.replace("{Organiser}", eventNameObject.host);
const changePreviewText = (eventNameObject: EventNameObjectType, previewEventName: string) => {
setPreviewText(replaceEventNamePlaceholder(eventNameObject, previewEventName));
};
useEffect(() => {
!hashedUrl && setHashedUrl(generateHashedLink(eventType.users[0]?.id ?? team?.id));
}, [eventType.users, hashedUrl, team?.id]);
@@ -82,6 +102,8 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
}
}, [eventType.customInputs]);
const eventNamePlaceholder = replaceEventNamePlaceholder(eventNameObject, t("meeting_with_user"));
return (
<div className="flex flex-col space-y-8">
{/**
@@ -120,15 +142,22 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
)}
<div className="w-full">
<TextField
label={t("event_name")}
label={t("event_name_in_calendar")}
type="text"
placeholder={t("meeting_with_user", { attendeeName: eventType.users[0]?.name })}
placeholder={eventNamePlaceholder}
defaultValue={eventType.eventName || ""}
{...formMethods.register("eventName")}
{...formMethods.register("eventName", {
onChange: (e) => {
if (!e.target.value || !formMethods.getValues("eventName")) {
return setPreviewText(getEventName(eventNameObject));
}
changePreviewText(eventNameObject, e.target.value);
},
})}
addOnSuffix={
<Button
type="button"
StartIcon={Icon.FiEdit}
StartIcon={FiEdit}
variant="icon"
color="minimal"
className="hover:stroke-3 min-w-fit px-0 hover:bg-transparent hover:text-black"
@@ -168,7 +197,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
</ul>
{customInputs.length > 0 && (
<Button
StartIcon={Icon.FiPlus}
StartIcon={FiPlus}
color="minimal"
type="button"
onClick={() => {
@@ -314,7 +343,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
}}
className="hover:stroke-3 hover:bg-transparent hover:text-black"
type="button">
<Icon.FiCopy />
<FiCopy />
</Button>
</Tooltip>
}
@@ -382,25 +411,66 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
<DialogContent
title={t("custom_event_name")}
description={t("custom_event_name_description")}
type="creation">
type="creation"
enableOverflow>
<TextField
label={t("event_name")}
label={t("event_name_in_calendar")}
type="text"
placeholder={t("meeting_with_user", { attendeeName: eventType.users[0]?.name })}
placeholder={eventNamePlaceholder}
defaultValue={eventType.eventName || ""}
{...formMethods.register("eventName")}
{...formMethods.register("eventName", {
onChange: (e) => {
if (!e.target.value || !formMethods.getValues("eventName")) {
return setPreviewText(getEventName(eventNameObject));
}
changePreviewText(eventNameObject, e.target.value);
},
})}
className="mb-0"
/>
<div className="mt-1 text-gray-500">
<p>{`{HOST} = ${t("your_name")}`}</p>
<p>{`{ATTENDEE} = ${t("attendee_name")}`}</p>
<p>{`{HOST/ATTENDEE} = ${t("dynamically_display_attendee_or_organizer")}`}</p>
<p>{`{LOCATION} = ${t("event_location")}`}</p>
<div className="text-sm">
<div className="mb-6 rounded-md bg-gray-100 p-2">
<h1 className="mb-2 ml-1 font-medium text-gray-900">{t("available_variables")}</h1>
<div className="mb-2.5 flex font-normal">
<p className="ml-1 mr-5 w-28 text-gray-400">{`{Event type title}`}</p>
<p className="text-gray-900">{t("event_name_info")}</p>
</div>
<div className="mb-2.5 flex font-normal">
<p className="ml-1 mr-5 w-28 text-gray-400">{`{Organiser}`}</p>
<p className="text-gray-900">{t("your_full_name")}</p>
</div>
<div className="mb-2.5 flex font-normal">
<p className="ml-1 mr-5 w-28 text-gray-400">{`{Scheduler}`}</p>
<p className="text-gray-900">{t("scheduler_full_name")}</p>
</div>
<div className="mb-1 flex font-normal">
<p className="ml-1 mr-5 w-28 text-gray-400">{`{Location}`}</p>
<p className="text-gray-900">{t("location_info")}</p>
</div>
</div>
<h1 className="mb-2 text-[14px] font-medium leading-4">{t("preview")}</h1>
<div
className="flex h-[212px] w-full rounded-md border-y bg-cover bg-center"
style={{
backgroundImage: "url(/calendar-preview.svg)",
}}>
<div className="m-auto flex items-center justify-center self-stretch">
<div className="mt-3 ml-11 box-border h-[110px] w-[120px] flex-col items-start gap-1 rounded-md border border-solid border-black bg-gray-100 text-[12px] leading-3">
<p className="overflow-hidden text-ellipsis p-1.5 font-medium text-gray-900">
{previewText}
</p>
<p className="ml-1.5 text-[10px] font-normal text-gray-600">8 - 10 AM</p>
</div>
</div>
</div>
</div>
<DialogFooter>
<DialogClose onClick={() => formMethods.setValue("eventName", eventType.eventName ?? "")}>
{t("cancel")}
</DialogClose>
<Button color="primary" onClick={() => setShowEventNameTip(false)}>
{t("create")}
</Button>
<DialogClose onClick={() => formMethods.setValue("eventName", eventType.eventName ?? "")} />
</DialogFooter>
</DialogContent>
</Dialog>
@@ -413,7 +483,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
<Dialog open={selectedCustomInputModalOpen} onOpenChange={setSelectedCustomInputModalOpen}>
<DialogContent
type="creation"
Icon={Icon.FiPlus}
Icon={FiPlus}
title={t("add_new_custom_input_field")}
description={t("this_input_will_shown_booking_this_event")}>
<CustomInputTypeForm
@@ -1,13 +1,14 @@
import { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import { useFormContext } from "react-hook-form";
import { GetAppData, SetAppData } from "@calcom/app-store/EventTypeAppContext";
import type { GetAppData, SetAppData } from "@calcom/app-store/EventTypeAppContext";
import { EventTypeAppCard } from "@calcom/app-store/_components/EventTypeAppCardInterface";
import { EventTypeAppCardComponentProps } from "@calcom/app-store/types";
import { EventTypeAppsList } from "@calcom/app-store/utils";
import type { EventTypeAppCardComponentProps } from "@calcom/app-store/types";
import type { EventTypeAppsList } from "@calcom/app-store/utils";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Button, EmptyScreen, Icon } from "@calcom/ui";
import { Button, EmptyScreen } from "@calcom/ui";
import { FiGrid } from "@calcom/ui/components/icon";
export type EventType = Pick<EventTypeSetupProps, "eventType">["eventType"] &
EventTypeAppCardComponentProps["eventType"];
@@ -60,7 +61,7 @@ export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
<div className="before:border-0">
{!isLoading && !installedApps?.length ? (
<EmptyScreen
Icon={Icon.FiGrid}
Icon={FiGrid}
headline={t("empty_installed_apps_headline")}
description={t("empty_installed_apps_description")}
buttonRaw={
@@ -1,16 +1,19 @@
import { useAutoAnimate } from "@formkit/auto-animate/react";
import * as RadioGroup from "@radix-ui/react-radio-group";
import { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import React, { useEffect, useState } from "react";
import { Controller, useFormContext, UseFormRegisterReturn, useWatch } from "react-hook-form";
import type { UseFormRegisterReturn } from "react-hook-form";
import { Controller, useFormContext, useWatch } from "react-hook-form";
import { classNames } from "@calcom/lib";
import convertToNewDurationType, { DurationType } from "@calcom/lib/convertToNewDurationType";
import type { DurationType } from "@calcom/lib/convertToNewDurationType";
import convertToNewDurationType from "@calcom/lib/convertToNewDurationType";
import findDurationType from "@calcom/lib/findDurationType";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { PeriodType } from "@calcom/prisma/client";
import type { PeriodType } from "@calcom/prisma/client";
import type { BookingLimit } from "@calcom/types/Calendar";
import { Button, DateRangePicker, Icon, Input, InputField, Label, Select, SettingsToggle } from "@calcom/ui";
import { Button, DateRangePicker, Input, InputField, Label, Select, SettingsToggle } from "@calcom/ui";
import { FiPlus, FiTrash } from "@calcom/ui/components/icon";
const MinimumBookingNoticeInput = React.forwardRef<
HTMLInputElement,
@@ -419,19 +422,21 @@ const BookingLimits = () => {
defaultValue={BOOKING_LIMIT_OPTIONS.find((option) => option.value === key)}
onChange={(val) => {
const current = currentBookingLimits;
const currentValue = watchBookingLimits[bookingLimitKey];
// Removes limit from previous selected value (eg when changed from per_week to per_month, we unset per_week here)
delete current[bookingLimitKey];
const newData = {
...current,
// Set limit to new selected value (in the example above this means we set the limit to per_week here).
[val?.value as BookingLimitsKey]: watchBookingLimits[bookingLimitKey],
[val?.value as BookingLimitsKey]: currentValue,
};
onChange(newData);
}}
/>
<Button
variant="icon"
StartIcon={Icon.FiTrash}
StartIcon={FiTrash}
color="destructive"
onClick={() => {
const current = currentBookingLimits;
@@ -445,7 +450,7 @@ const BookingLimits = () => {
{currentBookingLimits && Object.keys(currentBookingLimits).length <= 3 && (
<Button
color="minimal"
StartIcon={Icon.FiPlus}
StartIcon={FiPlus}
onClick={() => {
if (!currentBookingLimits || !watchBookingLimits) return;
const currentKeys = Object.keys(watchBookingLimits);
@@ -458,7 +463,7 @@ const BookingLimits = () => {
setValue("bookingLimits", {
...watchBookingLimits,
[rest[0].value]: undefined,
[rest[0].value]: 1,
});
}}>
{t("add_limit")}
@@ -1,13 +1,13 @@
import { EventTypeSetupProps } from "pages/event-types/[type]";
import type { EventTypeSetupProps } from "pages/event-types/[type]";
import getStripeAppData from "@calcom/lib/getStripeAppData";
import getPaymentAppData from "@calcom/lib/getPaymentAppData";
import RecurringEventController from "./RecurringEventController";
export const EventRecurringTab = ({ eventType }: Pick<EventTypeSetupProps, "eventType">) => {
const stripeAppData = getStripeAppData(eventType);
const paymentAppData = getPaymentAppData(eventType);
const requirePayment = stripeAppData.price > 0;
const requirePayment = paymentAppData.price > 0;
return (
<div className="">
+53 -28
View File
@@ -6,21 +6,20 @@ import Link from "next/link";
import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import { useState } from "react";
import { Controller, useForm, useFormContext } from "react-hook-form";
import { MultiValue } from "react-select";
import type { MultiValue } from "react-select";
import { z } from "zod";
import { EventLocationType, getEventLocationType, MeetLocationType } from "@calcom/app-store/locations";
import type { EventLocationType } from "@calcom/app-store/locations";
import { getEventLocationType, MeetLocationType, LocationType } from "@calcom/app-store/locations";
import { CAL_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Button, Icon, Label, Select, SettingsToggle, Skeleton, TextField } from "@calcom/ui";
import { slugify } from "@lib/slugify";
import { slugify } from "@calcom/lib/slugify";
import { Button, Label, Select, SettingsToggle, Skeleton, TextField } from "@calcom/ui";
import { FiEdit2, FiCheck, FiX, FiPlus } from "@calcom/ui/components/icon";
import { EditLocationDialog } from "@components/dialog/EditLocationDialog";
import LocationSelect, {
SingleValueLocationOption,
LocationOption,
} from "@components/ui/form/LocationSelect";
import type { SingleValueLocationOption, LocationOption } from "@components/ui/form/LocationSelect";
import LocationSelect from "@components/ui/form/LocationSelect";
const getLocationFromType = (
type: EventLocationType["type"],
@@ -34,6 +33,16 @@ const getLocationFromType = (
}
};
const getDefaultLocationValue = (options: EventTypeSetupProps["locationOptions"], type: string) => {
for (const locationType of options) {
for (const location of locationType.options) {
if (location.value === type && location.disabled === false) {
return location;
}
}
}
};
export const EventSetupTab = (
props: Pick<EventTypeSetupProps, "eventType" | "locationOptions" | "team" | "teamMembers">
) => {
@@ -66,10 +75,15 @@ export const EventSetupTab = (
setShowLocationModal(true);
};
const removeLocation = (selectedLocation: typeof eventType.locations[number]) => {
const removeLocation = (selectedLocation: (typeof eventType.locations)[number]) => {
formMethods.setValue(
"locations",
formMethods.getValues("locations").filter((location) => location.type !== selectedLocation.type),
formMethods.getValues("locations").filter((location) => {
if (location.type === LocationType.InPerson) {
return location.address !== selectedLocation.address;
}
return location.type !== selectedLocation.type;
}),
{ shouldValidate: true }
);
};
@@ -84,14 +98,14 @@ export const EventSetupTab = (
...details,
type: newLocationType,
};
} else {
copy[existingIdx] = {
...formMethods.getValues("locations")[existingIdx],
...details,
};
}
formMethods.setValue("locations", copy);
formMethods.setValue("locations", [
...copy,
...(newLocationType === LocationType.InPerson && editingLocationType === ""
? [{ ...details, type: newLocationType }]
: []),
]);
} else {
formMethods.setValue(
"locations",
@@ -147,6 +161,7 @@ export const EventSetupTab = (
options={locationOptions}
isSearchable={false}
className="block w-full min-w-0 flex-1 rounded-sm text-sm"
menuPlacement="auto"
onChange={(e: SingleValueLocationOption) => {
if (e?.value) {
const newLocationType = e.value;
@@ -172,18 +187,24 @@ export const EventSetupTab = (
if (!eventLocationType) {
return null;
}
// We dont want to translate the string link - it doesnt exist in common.json and it gets prefixed/suffixed with __ or //
const eventLabel =
eventLocationType.defaultValueVariable === "link"
? eventLocationType.label
: t(location[eventLocationType.defaultValueVariable] || eventLocationType.label);
return (
<li key={location.type} className="mb-2 rounded-md border border-gray-300 py-1.5 px-2">
<div className="flex max-w-full justify-between">
<div key={index} className="flex flex-grow items-center">
<li
key={`${location.type}${index}`}
className="mb-2 rounded-md border border-gray-300 py-1.5 px-2">
<div className="flex items-center justify-between">
<div className="flex items-center">
<img
src={eventLocationType.iconUrl}
className="h-4 w-4"
alt={`${eventLocationType.label} logo`}
/>
<span className="truncate text-sm ltr:ml-1 rtl:mr-1">
{t(location[eventLocationType.defaultValueVariable] || eventLocationType.label)}
</span>
<span className="line-clamp-1 text-sm ltr:ml-1 rtl:mr-1">{eventLabel}</span>
</div>
<div className="flex">
<button
@@ -198,10 +219,10 @@ export const EventSetupTab = (
}}
aria-label={t("edit")}
className="mr-1 p-1 text-gray-500 hover:text-gray-900">
<Icon.FiEdit2 className="h-4 w-4" />
<FiEdit2 className="h-4 w-4" />
</button>
<button type="button" onClick={() => removeLocation(location)} aria-label={t("remove")}>
<Icon.FiX className="border-l-1 h-6 w-6 pl-1 text-gray-500 hover:text-gray-900 " />
<FiX className="border-l-1 h-6 w-6 pl-1 text-gray-500 hover:text-gray-900 " />
</button>
</div>
</div>
@@ -210,7 +231,7 @@ export const EventSetupTab = (
})}
{validLocations.some((location) => location.type === MeetLocationType) && (
<div className="flex text-sm text-gray-600">
<Icon.FiCheck className="mt-0.5 mr-1.5 h-2 w-2.5" />
<FiCheck className="mt-0.5 mr-1.5 h-2 w-2.5" />
<Trans i18nKey="event_type_requres_google_cal">
<p>
The “Add to calendar” for this event type needs to be a Google Calendar for Meet to work.
@@ -225,9 +246,13 @@ export const EventSetupTab = (
</Trans>
</div>
)}
{validLocations.length > 0 && validLocations.length !== locationOptions.length && (
{validLocations.length > 0 && (
<li>
<Button StartIcon={Icon.FiPlus} color="minimal" onClick={() => setShowLocationModal(true)}>
<Button
data-testid="add-location"
StartIcon={FiPlus}
color="minimal"
onClick={() => setShowLocationModal(true)}>
{t("add_location")}
</Button>
</li>
+20 -12
View File
@@ -1,12 +1,12 @@
import { SchedulingType } from "@prisma/client";
import { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import { ComponentProps } from "react";
import { Controller, useFormContext, useWatch, Control } from "react-hook-form";
import { Options } from "react-select";
import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import type { ComponentProps } from "react";
import type { Control } from "react-hook-form";
import { Controller, useFormContext, useWatch } from "react-hook-form";
import type { Options } from "react-select";
import CheckedTeamSelect, {
CheckedSelectOption,
} from "@calcom/features/eventtypes/components/CheckedTeamSelect";
import type { CheckedSelectOption } from "@calcom/features/eventtypes/components/CheckedTeamSelect";
import CheckedTeamSelect from "@calcom/features/eventtypes/components/CheckedTeamSelect";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Label, Select } from "@calcom/ui";
@@ -25,6 +25,16 @@ const mapUserToValue = ({ id, name, username, email }: IMemberToValue) => ({
email,
});
const sortByLabel = (a: ReturnType<typeof mapUserToValue>, b: ReturnType<typeof mapUserToValue>) => {
if (a.label < b.label) {
return -1;
}
if (a.label > b.label) {
return 1;
}
return 0;
};
const FixedHosts = ({
control,
labelText,
@@ -103,7 +113,6 @@ export const EventTeamTab = ({ team, teamMembers }: Pick<EventTypeSetupProps, "t
];
const teamMembersOptions = teamMembers.map(mapUserToValue);
return (
<div>
{team && (
@@ -128,17 +137,16 @@ export const EventTeamTab = ({ team, teamMembers }: Pick<EventTypeSetupProps, "t
{schedulingType === SchedulingType.COLLECTIVE && (
<FixedHosts
options={teamMembersOptions}
options={teamMembersOptions.sort(sortByLabel)}
placeholder={t("add_attendees")}
labelText={t("team")}
control={formMethods.control}
/>
)}
{schedulingType === SchedulingType.ROUND_ROBIN && (
<>
<FixedHosts
options={teamMembersOptions}
options={teamMembersOptions.sort(sortByLabel)}
isOptionDisabled={(option) =>
!!formMethods.getValues("hosts").find((host) => host.userId.toString() === option.value)
}
@@ -173,7 +181,7 @@ export const EventTeamTab = ({ team, teamMembers }: Pick<EventTypeSetupProps, "t
)
.filter(Boolean)}
controlShouldRenderValue={false}
options={teamMembers.map(mapUserToValue)}
options={teamMembersOptions.sort(sortByLabel)}
isOptionDisabled={(option) =>
!!formMethods
.getValues("hostsFixed")
@@ -1,15 +1,16 @@
import { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import type { EventTypeSetupProps } from "pages/event-types/[type]";
import { useState } from "react";
import { TbWebhook } from "react-icons/tb";
import { WebhookForm } from "@calcom/features/webhooks/components";
import { WebhookFormSubmitData } from "@calcom/features/webhooks/components/WebhookForm";
import type { WebhookFormSubmitData } from "@calcom/features/webhooks/components/WebhookForm";
import WebhookListItem from "@calcom/features/webhooks/components/WebhookListItem";
import { APP_NAME } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Webhook } from "@calcom/prisma/client";
import type { Webhook } from "@calcom/prisma/client";
import { trpc } from "@calcom/trpc/react";
import { Button, Dialog, DialogContent, EmptyScreen, Icon, showToast } from "@calcom/ui";
import { Button, Dialog, DialogContent, EmptyScreen, showToast } from "@calcom/ui";
import { FiPlus } from "@calcom/ui/components/icon";
export const EventTeamWebhooksTab = ({
eventType,
@@ -84,7 +85,7 @@ export const EventTeamWebhooksTab = ({
<Button
color="secondary"
data-testid="new_webhook"
StartIcon={Icon.FiPlus}
StartIcon={FiPlus}
onClick={() => setCreateModalOpen(true)}>
{t("new_webhook")}
</Button>
@@ -99,7 +100,7 @@ export const EventTeamWebhooksTab = ({
<>
{webhooks.length ? (
<>
<div className="mt-4 mb-8 rounded-md border">
<div className="mb-8 rounded-md border">
{webhooks.map((webhook, index) => {
return (
<WebhookListItem
@@ -130,7 +131,10 @@ export const EventTeamWebhooksTab = ({
{/* New webhook dialog */}
<Dialog open={createModalOpen} onOpenChange={(isOpen) => !isOpen && setCreateModalOpen(false)}>
<DialogContent title={t("create_webhook")} description={t("create_webhook_team_event_type")}>
<DialogContent
enableOverflow
title={t("create_webhook")}
description={t("create_webhook_team_event_type")}>
<WebhookForm
onSubmit={onCreateWebhook}
onCancel={() => setCreateModalOpen(false)}
@@ -1,8 +1,8 @@
import { TFunction } from "next-i18next";
import type { TFunction } from "next-i18next";
import { useRouter } from "next/router";
import { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import type { EventTypeSetupProps, FormValues } from "pages/event-types/[type]";
import { useMemo, useState, Suspense } from "react";
import { UseFormReturn } from "react-hook-form";
import type { UseFormReturn } from "react-hook-form";
import { TbWebhook } from "react-icons/tb";
import Shell from "@calcom/features/shell/Shell";
@@ -23,7 +23,6 @@ import {
DropdownItem,
DropdownMenuTrigger,
HorizontalTabs,
Icon,
Label,
showToast,
Skeleton,
@@ -32,6 +31,21 @@ import {
VerticalDivider,
VerticalTabs,
} from "@calcom/ui";
import {
FiLink,
FiCalendar,
FiClock,
FiSliders,
FiRepeat,
FiGrid,
FiZap,
FiUsers,
FiExternalLink,
FiCode,
FiTrash,
FiMoreHorizontal,
FiLoader,
} from "@calcom/ui/components/icon";
import { EmbedButton, EmbedDialog } from "@components/Embed";
@@ -63,44 +77,44 @@ function getNavigation(props: {
{
name: "event_setup_tab_title",
href: `/event-types/${eventType.id}?tabName=setup`,
icon: Icon.FiLink,
icon: FiLink,
info: `${duration} ${t("minute_timeUnit")}`, // TODO: Get this from props
},
{
name: "availability",
href: `/event-types/${eventType.id}?tabName=availability`,
icon: Icon.FiCalendar,
icon: FiCalendar,
info: `default_schedule_name`, // TODO: Get this from props
},
{
name: "event_limit_tab_title",
href: `/event-types/${eventType.id}?tabName=limits`,
icon: Icon.FiClock,
icon: FiClock,
info: `event_limit_tab_description`,
},
{
name: "event_advanced_tab_title",
href: `/event-types/${eventType.id}?tabName=advanced`,
icon: Icon.FiSliders,
icon: FiSliders,
info: `event_advanced_tab_description`,
},
{
name: "recurring",
href: `/event-types/${eventType.id}?tabName=recurring`,
icon: Icon.FiRepeat,
icon: FiRepeat,
info: `recurring_event_tab_description`,
},
{
name: "apps",
href: `/event-types/${eventType.id}?tabName=apps`,
icon: Icon.FiGrid,
icon: FiGrid,
//TODO: Handle proper translation with count handling
info: `${installedAppsNumber} apps, ${enabledAppsNumber} ${t("active")}`,
},
{
name: "workflows",
href: `/event-types/${eventType.id}?tabName=workflows`,
icon: Icon.FiZap,
icon: FiZap,
info: `${enabledWorkflowsNumber} ${t("active")}`,
},
];
@@ -157,7 +171,7 @@ function EventTypeSingleLayout({
navigation.splice(2, 0, {
name: "assignment",
href: `/event-types/${eventType.id}?tabName=team`,
icon: Icon.FiUsers,
icon: FiUsers,
info: eventType.schedulingType === "COLLECTIVE" ? "collective" : "round_robin",
});
navigation.push({
@@ -181,10 +195,9 @@ function EventTypeSingleLayout({
backPath="/event-types"
title={eventType.title + " | " + t("event_type")}
heading={eventType.title}
subtitle={eventType.description || ""}
CTA={
<div className="flex items-center justify-end">
<div className="hidden items-center rounded-md px-2 sm:flex sm:hover:bg-gray-100">
<div className="hidden items-center rounded-md px-2 sm:hover:bg-gray-100 lg:flex">
<Skeleton
as={Label}
htmlFor="hiddenSwitch"
@@ -193,7 +206,7 @@ function EventTypeSingleLayout({
</Skeleton>
<Switch
id="hiddenSwitch"
defaultChecked={formMethods.getValues("hidden")}
checked={formMethods.watch("hidden")}
onCheckedChange={(e) => {
formMethods.setValue("hidden", e);
}}
@@ -211,14 +224,14 @@ function EventTypeSingleLayout({
variant="icon"
href={permalink}
rel="noreferrer"
StartIcon={Icon.FiExternalLink}
StartIcon={FiExternalLink}
/>
</Tooltip>
<Button
color="secondary"
variant="icon"
StartIcon={Icon.FiLink}
StartIcon={FiLink}
tooltip={t("copy_link")}
onClick={() => {
navigator.clipboard.writeText(permalink);
@@ -227,7 +240,7 @@ function EventTypeSingleLayout({
/>
<EmbedButton
embedUrl={encodeURIComponent(embedLink)}
StartIcon={Icon.FiCode}
StartIcon={FiCode}
color="secondary"
variant="icon"
tooltip={t("embed")}
@@ -235,7 +248,7 @@ function EventTypeSingleLayout({
<Button
color="secondary"
variant="icon"
StartIcon={Icon.FiTrash}
StartIcon={FiTrash}
tooltip={t("delete")}
disabled={!hasPermsToDelete}
onClick={() => setDeleteDialogOpen(true)}
@@ -246,19 +259,14 @@ function EventTypeSingleLayout({
<Dropdown>
<DropdownMenuTrigger asChild>
<Button
className="lg:hidden"
StartIcon={Icon.FiMoreHorizontal}
variant="icon"
color="secondary"
/>
<Button className="lg:hidden" StartIcon={FiMoreHorizontal} variant="icon" color="secondary" />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuContent style={{ minWidth: "200px" }}>
<DropdownMenuItem className="focus:ring-gray-100">
<DropdownItem
target="_blank"
type="button"
StartIcon={Icon.FiExternalLink}
StartIcon={FiExternalLink}
href={permalink}
rel="noreferrer">
{t("preview")}
@@ -267,7 +275,7 @@ function EventTypeSingleLayout({
<DropdownMenuItem className="focus:ring-gray-100">
<DropdownItem
type="button"
StartIcon={Icon.FiLink}
StartIcon={FiLink}
onClick={() => {
navigator.clipboard.writeText(permalink);
showToast("Link copied!", "success");
@@ -278,23 +286,24 @@ function EventTypeSingleLayout({
<DropdownMenuItem className="focus:ring-gray-100">
<DropdownItem
type="button"
StartIcon={Icon.FiTrash}
color="destructive"
StartIcon={FiTrash}
disabled={!hasPermsToDelete}
onClick={() => setDeleteDialogOpen(true)}>
{t("delete")}
</DropdownItem>
</DropdownMenuItem>
<DropdownMenuSeparator className="block sm:hidden" />
<div className="flex items-center rounded-md py-1.5 px-4 sm:hidden sm:hover:bg-gray-100">
<DropdownMenuSeparator />
<div className="flex h-9 flex-row items-center justify-between py-2 px-4 sm:hover:bg-gray-100">
<Skeleton
as={Label}
htmlFor="hiddenSwitch"
className="mt-2 inline cursor-pointer self-center pr-2 sm:hidden">
className="mt-2 inline cursor-pointer self-center pr-2 ">
{t("hide_from_profile")}
</Skeleton>
<Switch
id="hiddenSwitch"
defaultChecked={formMethods.getValues("hidden")}
checked={formMethods.watch("hidden")}
onCheckedChange={(e) => {
formMethods.setValue("hidden", e);
}}
@@ -313,8 +322,8 @@ function EventTypeSingleLayout({
</Button>
</div>
}>
<Suspense fallback={<Icon.FiLoader />}>
<div className="-mt-2 flex flex-col xl:flex-row xl:space-x-8">
<Suspense fallback={<FiLoader />}>
<div className="flex flex-col xl:flex-row xl:space-x-6">
<div className="hidden xl:block">
<VerticalTabs
className="primary-navigation"
@@ -330,7 +339,7 @@ function EventTypeSingleLayout({
<div
className={classNames(
"mt-4 rounded-md border-gray-200 bg-white sm:mx-0 xl:mt-0",
disableBorder ? "border-0 xl:-mt-4 " : "p-2 md:border md:p-6"
disableBorder ? "border-0 " : "p-2 md:border md:p-6"
)}>
{children}
</div>
@@ -1,13 +1,14 @@
import * as RadioGroup from "@radix-ui/react-radio-group";
import { UnitTypeLongPlural } from "dayjs";
import type { UnitTypeLongPlural } from "dayjs";
import { Trans } from "next-i18next";
import type { FormValues } from "pages/event-types/[type]";
import { Dispatch, SetStateAction, useEffect, useState } from "react";
import type { Dispatch, SetStateAction } from "react";
import { useEffect, useState } from "react";
import { Controller, useFormContext } from "react-hook-form";
import z from "zod";
import type z from "zod";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import type { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { Alert, Input, Label, SettingsToggle } from "@calcom/ui";
type RequiresConfirmationControllerProps = {
@@ -1,4 +1,5 @@
import { Icon, SkeletonAvatar, SkeletonContainer, SkeletonText } from "@calcom/ui";
import { SkeletonAvatar, SkeletonContainer, SkeletonText } from "@calcom/ui";
import { FiClock, FiUser } from "@calcom/ui/components/icon";
function SkeletonLoader() {
return (
@@ -31,11 +32,11 @@ function SkeletonItem() {
<div className="">
<ul className="mt-2 flex space-x-4 rtl:space-x-reverse ">
<li className="flex items-center whitespace-nowrap">
<Icon.FiClock className="mt-0.5 mr-1.5 inline h-4 w-4 text-gray-200" />
<FiClock className="mt-0.5 mr-1.5 inline h-4 w-4 text-gray-200" />
<SkeletonText className="h-4 w-12" />
</li>
<li className="flex items-center whitespace-nowrap">
<Icon.FiUser className="mt-0.5 mr-1.5 inline h-4 w-4 text-gray-200" />
<FiUser className="mt-0.5 mr-1.5 inline h-4 w-4 text-gray-200" />
<SkeletonText className="h-4 w-12" />
</li>
</ul>
@@ -1,5 +1,3 @@
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { CalendarSwitch } from "./CalendarSwitch";
interface IConnectedCalendarItem {
@@ -21,7 +19,7 @@ interface IConnectedCalendarItem {
const ConnectedCalendarItem = (prop: IConnectedCalendarItem) => {
const { name, logo, externalId, calendars, integrationType } = prop;
const { t } = useLocale();
return (
<>
<div className="flex flex-row items-center p-4">
@@ -1,5 +1,6 @@
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { RouterInputs, trpc } from "@calcom/trpc/react";
import type { RouterInputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import DestinationCalendarSelector from "@components/DestinationCalendarSelector";
@@ -5,8 +5,9 @@ import { useForm } from "react-hook-form";
import { Schedule } from "@calcom/features/schedules";
import { DEFAULT_SCHEDULE } from "@calcom/lib/availability";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc, TRPCClientErrorLike } from "@calcom/trpc/react";
import { AppRouter } from "@calcom/trpc/server/routers/_app";
import type { TRPCClientErrorLike } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import type { AppRouter } from "@calcom/trpc/server/routers/_app";
import { Button, Form } from "@calcom/ui";
interface ISetupAvailabilityProps {
@@ -1,15 +1,21 @@
import { ArrowRightIcon } from "@heroicons/react/solid";
import MarkdownIt from "markdown-it";
import { useRouter } from "next/router";
import { FormEvent, useRef, useState } from "react";
import type { FormEvent } from "react";
import { useRef, useState } from "react";
import { useForm } from "react-hook-form";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import turndown from "@calcom/lib/turndownService";
import { trpc } from "@calcom/trpc/react";
import { Button, ImageUploader, showToast, TextArea } from "@calcom/ui";
import { Button, Editor, ImageUploader, Label, showToast } from "@calcom/ui";
import { Avatar } from "@calcom/ui";
import type { IOnboardingPageProps } from "../../../pages/getting-started/[[...step]]";
const md = new MarkdownIt("default", { html: true, breaks: true });
type FormData = {
bio: string;
};
@@ -21,18 +27,16 @@ const UserProfile = (props: IUserProfileProps) => {
const { user } = props;
const { t } = useLocale();
const avatarRef = useRef<HTMLInputElement>(null!);
const bioRef = useRef<HTMLTextAreaElement>(null);
const {
register,
setValue,
handleSubmit,
formState: { errors },
} = useForm<FormData>({ defaultValues: { bio: user?.bio || "" } });
const { setValue, handleSubmit, getValues } = useForm<FormData>({
defaultValues: { bio: user?.bio || "" },
});
const { data: eventTypes } = trpc.viewer.eventTypes.list.useQuery();
const [imageSrc, setImageSrc] = useState<string>(user?.avatar || "");
const utils = trpc.useContext();
const router = useRouter();
const createEventType = trpc.viewer.eventTypes.create.useMutation();
const telemetry = useTelemetry();
const mutation = trpc.viewer.updateProfile.useMutation({
onSuccess: async (_data, context) => {
@@ -63,6 +67,8 @@ const UserProfile = (props: IUserProfileProps) => {
const onSubmit = handleSubmit((data: { bio: string }) => {
const { bio } = data;
telemetry.event(telemetryEventTypes.onboardingFinished);
mutation.mutate({
bio,
completedOnboarding: true,
@@ -138,25 +144,12 @@ const UserProfile = (props: IUserProfileProps) => {
</div>
</div>
<fieldset className="mt-8">
<label htmlFor="bio" className="mb-2 block text-sm font-medium text-gray-700">
{t("about")}
</label>
<TextArea
{...register("bio", { required: true })}
ref={bioRef}
name="bio"
id="bio"
className="mt-1 block h-[60px] w-full rounded-sm border border-gray-300 px-3 py-2 focus:border-gray-500 focus:outline-none focus:ring-gray-500 sm:text-sm"
defaultValue={user?.bio || undefined}
onChange={(event) => {
setValue("bio", event.target.value);
}}
<Label className="mb-2 block text-sm font-medium text-gray-700">{t("about")}</Label>
<Editor
getText={() => md.render(getValues("bio") || user?.bio || "")}
setText={(value: string) => setValue("bio", turndown(value))}
excludedToolbarItems={["blockType"]}
/>
{errors.bio && (
<p data-testid="required" className="py-2 text-xs text-red-500">
{t("required")}
</p>
)}
<p className="mt-2 font-sans text-sm font-normal text-gray-600 dark:text-white">
{t("few_sentences_about_yourself")}
</p>
@@ -1,9 +1,10 @@
import { ArrowRightIcon } from "@heroicons/react/outline";
import { useState } from "react";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import dayjs from "@calcom/dayjs";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import { trpc } from "@calcom/trpc/react";
import { Button, TimezoneSelect } from "@calcom/ui";
@@ -20,7 +21,7 @@ const UserSettings = (props: IUserSettingsProps) => {
const { user, nextStep } = props;
const { t } = useLocale();
const [selectedTimeZone, setSelectedTimeZone] = useState(dayjs.tz.guess());
const telemetry = useTelemetry();
const {
register,
handleSubmit,
@@ -31,6 +32,11 @@ const UserSettings = (props: IUserSettingsProps) => {
},
reValidateMode: "onChange",
});
useEffect(() => {
telemetry.event(telemetryEventTypes.onboardingStarted);
}, [telemetry]);
const defaultOptions = { required: true, maxLength: 255 };
const utils = trpc.useContext();
@@ -1,4 +1,4 @@
import { ReactNode } from "react";
import type { ReactNode } from "react";
import { Badge } from "@calcom/ui";
@@ -1,4 +1,5 @@
import { SyntheticEvent, useState } from "react";
import type { SyntheticEvent } from "react";
import { useState } from "react";
import { ErrorCode } from "@calcom/lib/auth";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -1,4 +1,5 @@
import React, { BaseSyntheticEvent, useState } from "react";
import type { BaseSyntheticEvent } from "react";
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { ErrorCode } from "@calcom/lib/auth";
@@ -1,9 +1,8 @@
import { useState } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Badge, Button } from "@calcom/ui";
import { useLocale } from "@lib/hooks/useLocale";
import DisableTwoFactorModal from "./DisableTwoFactorModal";
import EnableTwoFactorModal from "./EnableTwoFactorModal";
@@ -1,10 +1,10 @@
import { Icon } from "@calcom/ui";
import { ShieldCheckIcon } from "@calcom/ui/components/icon";
const TwoFactorModalHeader = ({ title, description }: { title: string; description: string }) => {
return (
<div className="mb-4 sm:flex sm:items-start">
<div className="bg-brand text-brandcontrast dark:bg-darkmodebrand dark:text-darkmodebrandcontrast mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-opacity-5 sm:mx-0 sm:h-10 sm:w-10">
<Icon.ShieldCheckIcon className="h-6 w-6 text-white" />
<ShieldCheckIcon className="h-6 w-6 text-white" />
</div>
<div className="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left">
<h3 className="font-cal text-lg font-medium leading-6 text-gray-900" id="modal-title">
@@ -2,7 +2,8 @@ import { useMutation } from "@tanstack/react-query";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react";
import { Badge, Icon, showToast, Switch } from "@calcom/ui";
import { Badge, showToast, Switch } from "@calcom/ui";
import { FiArrowLeft } from "@calcom/ui/components/icon";
export function CalendarSwitch(props: {
type: string;
@@ -74,7 +75,7 @@ export function CalendarSwitch(props: {
/>
{props.defaultSelected && (
<Badge variant="gray">
<Icon.FiArrowLeft className="mr-1" /> {t("adding_events_to")}
<FiArrowLeft className="mr-1" /> {t("adding_events_to")}
</Badge>
)}
</div>
@@ -1,4 +1,5 @@
import React, { BaseSyntheticEvent, useState } from "react";
import type { BaseSyntheticEvent } from "react";
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { ErrorCode } from "@calcom/lib/auth";
@@ -1,17 +1,39 @@
import { zodResolver } from "@hookform/resolvers/zod";
import classNames from "classnames";
import { signIn } from "next-auth/react";
import { useRouter } from "next/router";
import React from "react";
import { Controller, FormProvider, useForm } from "react-hook-form";
import * as z from "zod";
import { isPasswordValid } from "@calcom/lib/auth";
import { WEBSITE_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { EmailField, Label, PasswordField, TextField } from "@calcom/ui";
import { EmailField, EmptyScreen, Label, PasswordField, TextField } from "@calcom/ui";
import { FiUserCheck } from "@calcom/ui/components/icon";
const SetupFormStep1 = (props: { setIsLoading: (val: boolean) => void }) => {
const router = useRouter();
export const AdminUserContainer = (props: React.ComponentProps<typeof AdminUser> & { userCount: number }) => {
const { t } = useLocale();
if (props.userCount > 0)
return (
<form
id="wizard-step-1"
name="wizard-step-1"
className="space-y-4"
onSubmit={(e) => {
e.preventDefault();
props.onSuccess();
}}>
<EmptyScreen
Icon={FiUserCheck}
headline={t("admin_user_created")}
description={t("admin_user_created_description")}
/>
</form>
);
return <AdminUser {...props} />;
};
export const AdminUser = (props: { onSubmit: () => void; onError: () => void; onSuccess: () => void }) => {
const { t } = useLocale();
const formSchema = z.object({
@@ -45,11 +67,11 @@ const SetupFormStep1 = (props: { setIsLoading: (val: boolean) => void }) => {
});
const onError = () => {
props.setIsLoading(false);
props.onError();
};
const onSubmit = formMethods.handleSubmit(async (data: z.infer<typeof formSchema>) => {
props.setIsLoading(true);
props.onSubmit();
const response = await fetch("/api/auth/setup", {
method: "POST",
body: JSON.stringify({
@@ -69,9 +91,9 @@ const SetupFormStep1 = (props: { setIsLoading: (val: boolean) => void }) => {
email: data.email_address.toLowerCase(),
password: data.password,
});
router.replace(`/auth/setup?step=2&category=calendar`);
props.onSuccess();
} else {
router.replace("/auth/setup");
props.onError();
}
}, onError);
@@ -186,5 +208,3 @@ const SetupFormStep1 = (props: { setIsLoading: (val: boolean) => void }) => {
</FormProvider>
);
};
export default SetupFormStep1;
@@ -0,0 +1,76 @@
import * as RadioGroup from "@radix-ui/react-radio-group";
import classNames from "classnames";
import { useState } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
const ENTERPRISE_BOOKING_FEE = "$99"; // TODO: get this from a new API endpoint
const ChooseLicense = (
props: {
value: string;
onChange: (value: string) => void;
onSubmit: (value: string) => void;
} & Omit<JSX.IntrinsicElements["form"], "onSubmit" | "onChange">
) => {
const { value: initialValue = "FREE", onChange, onSubmit, ...rest } = props;
const [value, setValue] = useState(initialValue);
const { t } = useLocale();
return (
<form
{...rest}
className="space-y-4"
onSubmit={(e) => {
e.preventDefault();
onSubmit(value);
}}>
<RadioGroup.Root
defaultValue={initialValue}
value={value}
aria-label={t("choose_a_license")}
className="grid grid-rows-2 gap-4 md:grid-cols-2 md:grid-rows-1"
onValueChange={(value) => {
onChange(value);
setValue(value);
}}>
<RadioGroup.Item value="FREE">
<div
className={classNames(
"cursor-pointer space-y-2 rounded-md border bg-white p-4 hover:border-black",
value === "FREE" && "ring-2 ring-black"
)}>
<h2 className="font-cal text-xl text-black">{t("agplv3_license")}</h2>
<p className="font-medium text-green-800">{t("free_license_fee")}</p>
<p className="text-gray-500">{t("forever_open_and_free")}</p>
<ul className="ml-4 list-disc text-left text-xs text-gray-500">
<li>{t("required_to_keep_your_code_open_source")}</li>
<li>{t("cannot_repackage_and_resell")}</li>
<li>{t("no_enterprise_features")}</li>
</ul>
</div>
</RadioGroup.Item>
<RadioGroup.Item value="EE">
<div
className={classNames(
"cursor-pointer space-y-2 rounded-md border bg-white p-4 hover:border-black",
value === "EE" && "ring-2 ring-black"
)}>
<h2 className="font-cal text-xl text-black">{t("ee_enterprise_license")}</h2>
<p className="font-medium text-green-800">
{t("enterprise_booking_fee", { enterprise_booking_fee: ENTERPRISE_BOOKING_FEE })}
</p>
<p className="text-gray-500">{t("enterprise_license_includes")}</p>
<ul className="ml-4 list-disc text-left text-xs text-gray-500">
<li>{t("no_need_to_keep_your_code_open_source")}</li>
<li>{t("repackage_rebrand_resell")}</li>
<li>{t("a_vast_suite_of_enterprise_features")}</li>
</ul>
</div>
</RadioGroup.Item>
</RadioGroup.Root>
</form>
);
};
export default ChooseLicense;
@@ -0,0 +1,145 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { noop } from "lodash";
import { useCallback, useState } from "react";
import { Controller, FormProvider, useForm, useFormState } from "react-hook-form";
import * as z from "zod";
import { classNames } from "@calcom/lib";
import { CONSOLE_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { RouterInputs, RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import { Button, TextField } from "@calcom/ui";
import { FiCheck, FiExternalLink, FiLoader } from "@calcom/ui/components/icon";
type EnterpriseLicenseFormValues = {
licenseKey: string;
};
const makeSchemaLicenseKey = (args: { callback: (valid: boolean) => void; onSuccessValidate: () => void }) =>
z.object({
licenseKey: z
.string()
.uuid({
message: "License key must follow UUID format: 8-4-4-4-12",
})
.superRefine(async (data, ctx) => {
const parse = z.string().uuid().safeParse(data);
if (parse.success) {
args.callback(true);
const response = await fetch(`${CONSOLE_URL}/api/license?key=${data}`);
args.callback(false);
const json = await response.json();
if (!json.valid) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `License key ${json.message.toLowerCase()}`,
});
} else {
args.onSuccessValidate();
}
}
}),
});
const EnterpriseLicense = (
props: {
licenseKey?: string;
initialValue?: Partial<EnterpriseLicenseFormValues>;
onSuccessValidate: () => void;
onSubmit: (value: EnterpriseLicenseFormValues) => void;
onSuccess?: (
data: RouterOutputs["viewer"]["deploymentSetup"]["update"],
variables: RouterInputs["viewer"]["deploymentSetup"]["update"]
) => void;
} & Omit<JSX.IntrinsicElements["form"], "onSubmit">
) => {
const { onSubmit, onSuccess = noop, onSuccessValidate = noop, ...rest } = props;
const { t } = useLocale();
const [checkLicenseLoading, setCheckLicenseLoading] = useState(false);
const mutation = trpc.viewer.deploymentSetup.update.useMutation({
onSuccess,
});
const schemaLicenseKey = useCallback(
() =>
makeSchemaLicenseKey({
callback: setCheckLicenseLoading,
onSuccessValidate,
}),
[setCheckLicenseLoading, onSuccessValidate]
);
const formMethods = useForm<EnterpriseLicenseFormValues>({
defaultValues: {
licenseKey: props.licenseKey || "",
},
resolver: zodResolver(schemaLicenseKey()),
});
const handleSubmit = formMethods.handleSubmit((values) => {
onSubmit(values);
setCheckLicenseLoading(false);
mutation.mutate(values);
});
const { isDirty, errors } = useFormState(formMethods);
return (
<FormProvider {...formMethods}>
<form {...rest} className="space-y-4 rounded-md bg-white px-8 py-10" onSubmit={handleSubmit}>
<div>
<Button
className="w-full justify-center text-lg"
EndIcon={FiExternalLink}
href="https://console.cal.com"
target="_blank">
{t("purchase_license")}
</Button>
<div className="relative flex justify-center">
<hr className="my-8 w-full border-[1.5px] border-gray-200" />
<span className="absolute mt-[22px] bg-white px-3.5 text-sm">OR</span>
</div>
{t("already_have_key")}
<Controller
name="licenseKey"
control={formMethods.control}
render={({ field: { onBlur, onChange, value } }) => (
<TextField
{...formMethods.register("licenseKey")}
className={classNames(
"mb-0 group-hover:border-gray-400",
(checkLicenseLoading || (errors.licenseKey === undefined && isDirty)) && "border-r-0"
)}
placeholder="xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxx"
labelSrOnly={true}
value={value}
addOnFilled={false}
addOnClassname={classNames(
"hover:border-gray-300",
errors.licenseKey === undefined && isDirty && "group-hover:border-gray-400"
)}
addOnSuffix={
checkLicenseLoading ? (
<FiLoader className="h-5 w-5 animate-spin" />
) : errors.licenseKey === undefined && isDirty ? (
<FiCheck className="h-5 w-5 text-green-700" />
) : undefined
}
color={errors.licenseKey ? "warn" : ""}
onBlur={onBlur}
onChange={async (e: React.ChangeEvent<HTMLInputElement>) => {
onChange(e.target.value);
formMethods.setValue("licenseKey", e.target.value);
await formMethods.trigger("licenseKey");
}}
/>
)}
/>
</div>
</form>
</FormProvider>
);
};
export default EnterpriseLicense;
@@ -1,24 +1,30 @@
import { useRouter } from "next/router";
import type { Dispatch, SetStateAction } from "react";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Icon } from "@calcom/ui";
import { FiCheck } from "@calcom/ui/components/icon";
const StepDone = () => {
const StepDone = (props: {
currentStep: number;
nextStepPath: string;
setIsLoading: Dispatch<SetStateAction<boolean>>;
}) => {
const router = useRouter();
const { t } = useLocale();
return (
<form
id="wizard-step-1"
name="wizard-step-1"
className="space-y-4"
id={`wizard-step-${props.currentStep}`}
name={`wizard-step-${props.currentStep}`}
className="flex justify-center space-y-4"
onSubmit={(e) => {
props.setIsLoading(true);
e.preventDefault();
router.replace(`/auth/setup?step=2&category=calendar`);
router.replace(props.nextStepPath);
}}>
<div className="min-h-36 my-6 flex flex-col items-center justify-center">
<div className="flex h-[72px] w-[72px] items-center justify-center rounded-full bg-gray-600 dark:bg-white">
<Icon.FiCheck className="inline-block h-10 w-10 text-white dark:bg-white dark:text-gray-600" />
<FiCheck className="inline-block h-10 w-10 text-white dark:bg-white dark:text-gray-600" />
</div>
<div className="max-w-[420px] text-center">
<h2 className="mt-6 mb-1 text-lg font-medium dark:text-gray-300">{t("all_done")}</h2>
+20 -7
View File
@@ -1,10 +1,12 @@
import MarkdownIt from "markdown-it";
import Link from "next/link";
import { TeamPageProps } from "pages/team/[slug]";
import type { TeamPageProps } from "pages/team/[slug]";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { Avatar } from "@calcom/ui";
import { useLocale } from "@lib/hooks/useLocale";
const md = new MarkdownIt("default", { html: true, breaks: true, linkify: true });
type TeamType = TeamPageProps["team"];
type MembersType = TeamType["members"];
@@ -13,9 +15,11 @@ type MemberType = MembersType[number];
const Member = ({ member, teamName }: { member: MemberType; teamName: string | null }) => {
const { t } = useLocale();
const isBioEmpty = !member.bio || !member.bio.replace("<p><br></p>", "").length;
return (
<Link key={member.id} href={`/${member.username}`}>
<div className="sm:min-w-80 sm:max-w-80 dark:bg-darkgray-200 dark:hover:bg-darkgray-300 group flex min-h-full w-[90%] flex-col space-y-2 rounded-md bg-white p-4 hover:cursor-pointer hover:bg-gray-50 ">
<div className="sm:min-w-80 sm:max-w-80 dark:bg-darkgray-200 dark:hover:bg-darkgray-300 group flex min-h-full flex-col space-y-2 rounded-md bg-white p-4 hover:cursor-pointer hover:bg-gray-50 ">
<Avatar
size="md"
alt={member.name || ""}
@@ -23,9 +27,18 @@ const Member = ({ member, teamName }: { member: MemberType; teamName: string | n
/>
<section className="line-clamp-4 mt-2 w-full space-y-1">
<p className="font-medium text-gray-900 dark:text-white">{member.name}</p>
<p className="line-clamp-3 overflow-ellipsis text-sm font-normal text-gray-500 dark:text-white">
{member.bio || t("user_from_team", { user: member.name, team: teamName })}
</p>
<div className="line-clamp-3 overflow-ellipsis text-sm font-normal text-gray-500 dark:text-white">
{!isBioEmpty ? (
<>
<div
className="dark:text-darkgray-600 text-sm text-gray-500 [&_a]:text-blue-500 [&_a]:underline [&_a]:hover:text-blue-600"
dangerouslySetInnerHTML={{ __html: md.render(member.bio || "") }}
/>
</>
) : (
t("user_from_team", { user: member.name, team: teamName })
)}
</div>
</section>
</div>
</Link>
@@ -46,7 +59,7 @@ const Members = ({ members, teamName }: { members: MembersType; teamName: string
);
};
const Team = ({ team }: TeamPageProps) => {
const Team = ({ team }: Omit<TeamPageProps, "trpcState">) => {
return (
<div>
<Members members={team.members} teamName={team.name} />
+2 -1
View File
@@ -1,5 +1,6 @@
import { useSession } from "next-auth/react";
import { FC, Fragment } from "react";
import type { FC } from "react";
import { Fragment } from "react";
type AdminRequiredProps = {
as?: keyof JSX.IntrinsicElements;
+2 -5
View File
@@ -1,7 +1,7 @@
import classNames from "classnames";
import { APP_NAME, LOGO } from "@calcom/lib/constants";
import { Credits, HeadSeo } from "@calcom/ui";
import { HeadSeo } from "@calcom/ui";
import Loader from "@components/Loader";
@@ -35,10 +35,7 @@ export default function AuthContainer(props: React.PropsWithChildren<Props>) {
<div className="mx-2 rounded-md border border-gray-200 bg-white px-4 py-10 sm:px-10">
{props.children}
</div>
<div className="mt-8 text-center text-sm text-gray-600">
{props.footerText}
<Credits />
</div>
<div className="mt-8 text-center text-sm text-gray-600">{props.footerText}</div>
</div>
</div>
);

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