Compare commits

...
118 Commits
Author SHA1 Message Date
Alex van Andel e521bf6f0b v3.0.3
release.yml / release (push) Canceled after 0s
2023-06-20 12:26:14 +02:00
Jeroen Reumkensandalannnc a91a0f86e0 CAL-1904: Fixed bg color for all booked days as per design (#9630)
Co-authored-by: alannnc <alannnc@gmail.com>
2023-06-20 12:20:40 +02:00
GitStart-Cal.comandgitstart-calcom f654003f95 fix: settings: skeleton issues (CALCOM-9627) (#9641)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-06-20 12:20:13 +02:00
Hariom Balhara 4cc8a6fbf4 fix: embed booking 404 (#9652) 2023-06-20 15:42:39 +05:30
Peer Richelsenandalannnc 5167608404 chore: added commercial API to LICENSE (#9635)
Co-authored-by: alannnc <alannnc@gmail.com>
2023-06-20 09:33:43 +00:00
Crowdin Bot 9c93685431 New Crowdin translations by Github Action 2023-06-20 08:40:54 +00:00
Hariom Balhara a380087c9b reschedule_reason is used by Booking Form (#9656) 2023-06-20 10:39:46 +02:00
alannnc 3559e0d082 Improved with some try catch and removed old behaviour (#9650) 2023-06-20 00:10:47 +00:00
4323b0c2d1 chore: Upgrades Next.js to 13.4.6 (#9578)
* Upgrades Next.js to 13.4.6

* API handlers no longer receive a payload with req.method=DELETE

* Use DELETE with query params in Calendar Switch component

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
Co-authored-by: Efraín Rochín <roae.85@gmail.com>
2023-06-19 14:22:30 -07:00
Crowdin Bot 3a800f7511 New Crowdin translations by Github Action 2023-06-19 21:16:33 +00:00
Ujwal Kumarandalannnc c203e5a38b Fix margins in booking page (#9639)
Co-authored-by: alannnc <alannnc@gmail.com>
2023-06-19 21:15:44 +00:00
Crowdin Bot 3f5b3f06a2 New Crowdin translations by Github Action 2023-06-19 20:33:22 +00:00
Leo Giovanetti d52635efbb Org labels and typos (#9646) 2023-06-19 13:32:21 -07:00
Omar López 4add4df08e fix: regression of username case sensitivity (#9642) 2023-06-19 17:34:31 +00:00
Crowdin Bot df6d7e8df7 New Crowdin translations by Github Action 2023-06-19 17:16:51 +00:00
Samuel StroscheinandPeer Richelsen dc61640118 chore: add inlang ide extension for i18n (#9599)
* add: inlang for i18n

* chore: format file

* chore: re-add comments

VSCode removed them for unknown reasons.

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-06-19 10:15:45 -07:00
Alex van Andel 361108246e Created secondary function to read the owner from users array (#9638) 2023-06-19 08:53:31 -07:00
Abdurrahman RajabandKeith Williams a5e25b9b28 docs: improving developer experience (#9432)
* feat: add feedback to semantic commits

* feat: welcome new contributors

* feat: add triggers welcome message

* chore: fix lint issue

* chore: typos

* Fixed spacing

* Temporarily making this runnable via Actions page

* Removed workflow_call

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-06-19 16:45:41 +02:00
Leo Giovanetti ccff528765 fix: Creating teams for organizations in wizard (#9632)
* Expanding org slug check and adding proper error msg

* Duh &&
2023-06-19 14:37:23 +00:00
Peer Richelsen 24a1ef6721 Create LICENSE 2023-06-19 16:18:02 +02:00
Ninad Trivediandsean-brydon b89919129e Copy link button repositioned (#9613)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-06-19 16:15:48 +02:00
Keith Williams cbf3edefc7 chore: Added unit tests for CalendarManager->getCalendarCredentials (#9618)
* Added unit tests for CalendarManager->getCalendarCredentials

* Fixed spacing

* Made test data more accurate
2023-06-19 16:10:06 +02:00
Crowdin Bot 909ae5f2fb New Crowdin translations by Github Action 2023-06-19 14:01:31 +00:00
Syed Ali Shahbaz 0bbe5173dc docs: Update API documentation for Bookings endpoint (_post & _patch) (#9511)
* Fix swagger in _post bookings

* Update swagger doc for _patch

* Resolves two NITs

* Resolves metadata mistake
2023-06-19 14:00:36 +00:00
Jeroen Reumkens 84ad133077 Removed full height which incorrectly limited height in booker sidebar. Tested in Chrome, FF and Safari. (#9628) 2023-06-19 13:14:51 +00:00
Udit Takkar 43647a797f fix: remove enable_new_call_ui prop (#9625)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-06-19 15:03:40 +02:00
Ritik KumarandUdit Takkar f469a9c127 fix: redirect to 404 page for invalid email verification token (#9499)
* fix:redirect to 404 page for invalid email token

* update 404 page to include invalid token error

* fix: use i18n

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-06-19 13:24:10 +01:00
Carina WollendorferandCarinaWolli 212f7a374f fix name dropdown (#9621)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-06-19 11:44:47 +00:00
Alex van Andel 1929d5c7d4 v3.0.2
release.yml / release (push) Canceled after 0s
2023-06-19 13:33:13 +02:00
Papageorgiou Nikos 8ae54cd7cc fix: Storybook build and fix cal brand colors (#9588)
Storybook failed with satisfies operator
Fix cal brand colors in storybook
2023-06-19 13:28:49 +02:00
Hariom Balhara bb13009e64 + is %2B as well (#9624) 2023-06-19 11:22:13 +00:00
Jeroen Reumkens 648dd862f5 Tweaks to booker grid sizing to prevent buttons from overflow booker wrapper in Safari (#9620) 2023-06-19 11:34:49 +01:00
sean-brydonandzomars 8eccd3658e feat: Upstash implementation for rate limiting/redis (#9514)
* Introduce rate limiting that works on the edge

* typo

* Log once on init

* Update rateLimit.ts

---------

Co-authored-by: zomars <zomars@me.com>
2023-06-19 10:01:06 +00:00
Ujwal KumarandJeroen Reumkens ed65b2a3ab fix: Hide layout switcher when only 1 layout is enabled (#9610)
* Hide layout switcher when only 1 layouts is enabled

* Ran prettier

---------

Co-authored-by: Jeroen Reumkens <hello@jeroenreumkens.nl>
2023-06-19 08:55:25 +00:00
Manav Guptaandsean-brydon 0930121680 fix: event type filter in Mobile view (#9619)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2023-06-18 21:11:41 +00:00
Crowdin Bot 1068873f27 New Crowdin translations by Github Action 2023-06-18 20:55:42 +00:00
Udit TakkarandPeer Richelsen a1ece0be63 fix: sidebar ui (#9581)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-06-18 20:54:57 +00:00
Crowdin Bot c550b4c8fc New Crowdin translations by Github Action 2023-06-18 19:22:51 +00:00
VIvek ChavanandKeith Williams e95650637c fix: changes "cancelled" to canceled (#9505)
* fixed #9502 changes cancelled to cenceled

* fixed cancelled to cancelled from all places in common.json

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-06-18 19:21:52 +00:00
0f3e0a1554 fix: Alert component fixed (#9605)
* fix: Alert Component Fixed

* Update packages/ui/components/alert/Alert.tsx

---------

Co-authored-by: Peer Richelsen <peer@cal.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-06-17 20:57:15 +00:00
Peer Richelsen 761dfac033 3.0.1
release.yml / release (push) Canceled after 0s
2023-06-17 22:48:38 +02:00
Crowdin Bot 9fda4acc5b New Crowdin translations by Github Action 2023-06-17 20:45:08 +00:00
Jaideep Guntupalli 0470708aad refactor: translated request_password_reset in dutch (#9601) 2023-06-17 22:44:36 +02:00
Crowdin Bot bee392ba1a New Crowdin translations by Github Action 2023-06-17 20:43:01 +00:00
Hariom BalharaandPeer Richelsen 448f57442b Use the old booker redirect approach (#9589)
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-06-17 20:42:15 +00:00
Crowdin Bot 856b090b4b New Crowdin translations by Github Action 2023-06-17 20:28:18 +00:00
Ujwal Kumar b99661a411 Fix typo in email verification banner (#9595) 2023-06-17 22:27:24 +02:00
Crowdin Bot d96a26eb3c New Crowdin translations by Github Action 2023-06-17 15:48:23 +00:00
Eric Dantas 9d08f5c7c8 chore: Create add-PRs-to-project-reviewing-PRs.yml (#9597)
* Create add-PRs-to-project-eric.yml

* Update and rename add-PRs-to-project-eric.yml to add-PRs-to-project-reviewing-PRs.yml

* Update add-PRs-to-project-reviewing-PRs.yml
2023-06-17 17:47:29 +02:00
Crowdin Bot 4fe5f6ca6f New Crowdin translations by Github Action 2023-06-17 01:06:55 +00:00
Esaú MoraisandAlex van Andel af505935bd fix: update top banner (#9580)
* fix: update wrong banner message in english

* fix: update `resend_email` translation in pt-BR

* chore: add `Icon` prop to `TopBanner` component

* fix: remove unnecessary variant scope

* Remove translations so they can be retranslated, complete design

* Changed key of already translated entry

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-06-17 01:06:04 +00:00
Leo Giovanetti 4a30f60622 Configuring totp code when verifying too (#9584) 2023-06-16 20:08:12 +00:00
Alex van Andel 24ed04e6c7 v3.0.0.2
release.yml / release (push) Canceled after 0s
2023-06-16 19:21:26 +02:00
Hariom Balhara bed3595314 fix: Dynamic Group Links on vercel (#9576)
* Potential fix

* Debug

* Debug

* Use the same logic in new-booker
2023-06-16 19:00:23 +02:00
Alex van Andel 74671263bf fix: New booker selected date issues (#9570)
* Pick correct selected date

* Commented out unused booking page revalidation

* Fixed selected default bookerLayout not being applied

* Use the right weekdayOfFirst - date(1) of browsingDate
2023-06-16 18:08:58 +02:00
Crowdin Bot bdc5e9c7e9 New Crowdin translations by Github Action 2023-06-16 14:39:35 +00:00
Leo Giovanetti 8fa1c70a97 Adding more time to org admin email verif step (#9574) 2023-06-16 14:38:40 +00:00
Hariom Balhara 1343c8fa8d fix: Booking Page crash with prefilling guests (#9566)
* Fix Booking Page crash with prefilling guests

* Update packages/features/bookings/Booker/components/BookEventForm/BookEventForm.tsx
2023-06-16 15:02:59 +02:00
Crowdin Bot 5c0f9510a1 New Crowdin translations by Github Action 2023-06-16 12:46:06 +00:00
b2801170fa fix: Default tab selected issue (#9546)
* default tab selected issue

* refactor: improve cde

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

* fix: use onSuccess

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

* fix: move onsuccess and onerror

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: Vinoth Kumar V <vinoth_kumar_v@Vinoths-MacBook-Pro.local>
Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-06-16 12:45:20 +00:00
Alex van Andel 6ac19e8307 v3.0.0.1
release.yml / release (push) Canceled after 0s
2023-06-16 12:48:20 +02:00
Hariom Balhara 344241cfbf fix: New Booker Rewrites (#9557)
* Solve the problem using Next.config.js only

* Debug

* Avoid infinite rewritees

* Apply suggestions from code review

* Apply suggestions from code review

* Remove stale comments

* Update packages/embeds/embed-core/src/embed-iframe.ts
2023-06-16 12:31:57 +02:00
Carina WollendorferandCarinaWolli 66ebf18fa9 add team slug to team event link (#9558)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-06-16 11:05:47 +02:00
Crowdin Bot e6d6f3317e New Crowdin translations by Github Action 2023-06-16 08:38:03 +00:00
Carina WollendorferandCarinaWolli 55f66e6bcd remove slash (#9556)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-06-16 08:37:06 +00:00
Crowdin Bot 22e2b0a6a9 New Crowdin translations by Github Action 2023-06-16 06:27:50 +00:00
sydwardrae e24f3828cb Spelling chore common.json (#9550)
Fixed occured to occurred
2023-06-16 08:26:59 +02:00
Crowdin Bot 70f5bdc499 New Crowdin translations by Github Action 2023-06-15 22:38:02 +00:00
zomars 8731a39c3c fix: api build 2023-06-15 15:36:59 -07:00
Omar López e2d9e75475 v3.0.0
release.yml / release (push) Canceled after 0s
2023-06-15 15:15:39 -07:00
Crowdin Bot 55c7707b94 New Crowdin translations by Github Action 2023-06-15 22:15:20 +00:00
Crowdin Bot 98944d4815 New Crowdin translations by Github Action 2023-06-15 17:29:48 +00:00
Crowdin Bot faba25acbd New Crowdin translations by Github Action 2023-06-15 17:28:46 +00:00
aab5ee344c feat: Org settings - profile,appearance, child teams, create new child (#9231)
* Initial commit

* Adding feature flag

* Desktop first banner, mobile pending

* Removing dead code and img

* AppInstallButtonBase

* WIP

* Adds Email verification template+translations for organizations (#9202)

* feat: Orgs Schema Changing `scopedMembers` to `orgUsers` (#9209)

* Change scopedMembers to orgMembers

* Change to orgUsers

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Session logic to show org label

* Step 2 done, avatar not working

* List orgs and list teams specific if orgs exist

* Conditionally show org - fix settings layout - add labels for all pages

* Profile Page + update

* Org specific team creation

* appearance page

* Ensure members cant of org cant update settings in UI

* Fix update handler imports

* hide billing on sub teams

* Update profile slug page

* Letting duplicate slugs for teams to support orgs

* Add slug coliisions for org

* Covering null on unique clauses

* Covering null on unique clauses

* Extract to utils

* Update settings to use subdomain path in team url , team + org

* Supporting having the orgId in the session cookie

* Onboarding admins step

* Last step to create teams

* Update handler comments

* Upgrade ORG banner - disabled team banner for child teams

* Handle publishing ORGS

* Fix licenese issue

* Update packages/trpc/server/routers/viewer/teams/create.handler.ts

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Using meta component for head/descr

* Missing i18n strings

* A11ly

* Feedback

* Making an org avatar (temp)

* Add slug colission detection for user and team name

* Fix Import

* Remove update password func

* Fix module import over relative

* feat: organization event type filter (#9253)

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

* Missing changes to support orgs schema changes

* Remove app install button sa its in 9337

* Remove i18n key not being used

* feat: Onboarding process to create an organization (#9184)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* feedback

* Making sure we check requestedSlug now

---------

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

* feat: [CAL-1816] Organization subdomain support (#9345)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* Covering users and subteams, excluding non-org users

* Unpublished teams shows correctly

* Create subdomain in Vercel

* feedback

* Renaming Vercel env vars

* Vercel domain check before creation

* Supporting cal-staging.com

* Change to have vercel detect it

* vercel domain check data message error

* Remove check domain

* Making sure we check requestedSlug now

* Feedback and unneeded code

* Reverting unneeded changes

* Unneeded changes

---------

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

* Vercel subdomain creation in PROD only

* feat: organization settings general and members page (#9266)

* feat: organization settings general page

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

* feat: add members page

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

* chore: remove

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

* fix: use invalidate

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

* fix: delete mutation

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

* fix: remove organization id

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

* chore

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

* fix: use zod schema

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

---------

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

* Type fixes

* Reverting changes

* Update UsernameTextfield.tsx

* More reverts

* Update next-auth-options.ts

* Update common.json

* Type fixes

* Include invite token for orgs

* Update org schema

* Make token settings optional as it isnt used in orgs yet

* Fix missing prop

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Leo Giovanetti <hello@leog.me>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-06-15 10:27:39 -07:00
Leo Giovanettiandzomars 6880f88dbe Org teams (#9544)
Co-authored-by: zomars <zomars@me.com>
2023-06-15 16:55:45 +00:00
Crowdin Bot 9177fe86dc New Crowdin translations by Github Action 2023-06-15 16:37:15 +00:00
bf3f8acbc0 feat: Enable new booker globally for 3.0 (#9541)
* Update migration to be on by default - remove cookie check

* Use env variable to control enabling NEW_BOOKER for all

* Update packages/prisma/migrations/20230524105015_added_newbooker_feature_flag/migration.sql

* Update turbo.json

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
2023-06-15 16:36:25 +00:00
b4fa9826f2 feat: organizations sidebar (#9395)
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: Efraín Rochín <roae.85@gmail.com>
Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-06-15 16:12:47 +05:30
Jeroen ReumkensandPeer Richelsen 955de3133c feat: weekly view calendar improvements (#9491)
* Add correct start/end time for weekly calendar by looking at calendar's availability

* Always show 24h in weekly calendar, added scroll functionality, current time and events in correct timezone

* Improved current time style

* Show slots for every minute, so also odd timeslots due to offsets work

* Show correct timeformat for weekly view on left side time stamps

* Fix data attr for debug

* Position events differently so we can accomodate for offset start times.

* Removed schedule from public event api, because we don't use it anymore

* Fixed alignment of timeslots in weekview calendar.

* Added loading spinner to weekly calendar

* Force weekly view calendar hour labels to show 00 minutes, also for gmt x.5 timezones that are offset 30 mins.

* Change event duration blocks in weekly calendar when user changes duration in multi duration event

* Improved week view slot time label alignments for shorter durations

---------

Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-06-15 09:59:58 +00:00
Jeroen Reumkens faac3d0f57 fix: Fixed merge mistake in next.config breaking new booker redirects. (#9532) 2023-06-15 14:30:44 +05:30
Crowdin Bot 3fb1ede770 New Crowdin translations by Github Action 2023-06-15 08:59:05 +00:00
Hariom Balhara 53224886e3 feat: Routing Forms/Teams Support (#9417) 2023-06-15 08:58:07 +00:00
Udit Takkar e513180d7e fix: check user session in banner (#9530)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-06-15 09:36:09 +01:00
Udit Takkar 3116d6df1a fix: Email verification banner (#9519) 2023-06-15 11:41:32 +05:30
4284a4d16d feat: Organizations users calendar cache (#9498)
* Initial commit

* Adding feature flag

* feat: Orgs Schema Changing `scopedMembers` to `orgUsers` (#9209)

* Change scopedMembers to orgMembers

* Change to orgUsers

* Letting duplicate slugs for teams to support orgs

* Covering null on unique clauses

* Supporting having the orgId in the session cookie

* feat: organization event type filter (#9253)

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

* Missing changes to support orgs schema changes

* feat: Onboarding process to create an organization (#9184)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* feedback

* Making sure we check requestedSlug now

---------

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

* feat: [CAL-1816] Organization subdomain support (#9345)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* Covering users and subteams, excluding non-org users

* Unpublished teams shows correctly

* Create subdomain in Vercel

* feedback

* Renaming Vercel env vars

* Vercel domain check before creation

* Supporting cal-staging.com

* Change to have vercel detect it

* vercel domain check data message error

* Remove check domain

* Making sure we check requestedSlug now

* Feedback and unneeded code

* Reverting unneeded changes

* Unneeded changes

---------

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

* Vercel subdomain creation in PROD only

* Making sure we let localhost still work

* Feedback

* Type check fixes

* feat: Organization branding in side menu (#9279)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Org branding provider used in shell sidebar

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Using org avatar (temp)

* Not showing org logo if not set

* User onboarding with org branding (slug)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* feedback

* Feedback

* Org public profile

* Public profiles for team event types

* Added setup profile alert

* Using org avatar on subteams avatar

* Making sure we show the set up profile on org only

* Profile username availability rely on org hook

* Update apps/web/pages/team/[slug].tsx

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

* Update apps/web/pages/team/[slug].tsx

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

---------

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

* feat: Organization support for event types page (#9449)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Org branding provider used in shell sidebar

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Using org avatar (temp)

* Not showing org logo if not set

* User onboarding with org branding (slug)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* feedback

* Feedback

* Org public profile

* Public profiles for team event types

* Added setup profile alert

* Using org avatar on subteams avatar

* Processing orgs and children as profile options

* Reverting change not belonging to this PR

* Making sure we show the set up profile on org only

* Removing console.log

* Comparing memberships to choose the highest one

---------

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

* Type errors

* Refactor and type fixes

* Update orgDomains.ts

* Feedback

* Reverting

* NIT

* fix issue getting org slug from domain

* Improving orgDomains util

* Host comes with port

* Update useRouterQuery.ts

* add org users cache-calendar

* fix typo

* re-use the simple user calendar-cache page

* Apply suggestions from code review

* Update packages/core/CalendarManager.ts

* type fixes

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Leo Giovanetti <hello@leog.me>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: zomars <zomars@me.com>
2023-06-15 00:40:47 +00:00
zomars eadca3b2c0 Update .env.example 2023-06-14 14:45:53 -07:00
Crowdin Bot 68125af29f New Crowdin translations by Github Action 2023-06-14 21:44:55 +00:00
Crowdin Bot d436e628fe New Crowdin translations by Github Action 2023-06-14 21:41:30 +00:00
c5483c81de feat: Organizations (#8993)
* Initial commit

* Adding feature flag

* feat: Orgs Schema Changing `scopedMembers` to `orgUsers` (#9209)

* Change scopedMembers to orgMembers

* Change to orgUsers

* Letting duplicate slugs for teams to support orgs

* Covering null on unique clauses

* Supporting having the orgId in the session cookie

* feat: organization event type filter (#9253)

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

* Missing changes to support orgs schema changes

* feat: Onboarding process to create an organization (#9184)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* feedback

* Making sure we check requestedSlug now

---------

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

* feat: [CAL-1816] Organization subdomain support (#9345)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* Covering users and subteams, excluding non-org users

* Unpublished teams shows correctly

* Create subdomain in Vercel

* feedback

* Renaming Vercel env vars

* Vercel domain check before creation

* Supporting cal-staging.com

* Change to have vercel detect it

* vercel domain check data message error

* Remove check domain

* Making sure we check requestedSlug now

* Feedback and unneeded code

* Reverting unneeded changes

* Unneeded changes

---------

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

* Vercel subdomain creation in PROD only

* Making sure we let localhost still work

* Feedback

* Type check fixes

* feat: Organization branding in side menu (#9279)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Org branding provider used in shell sidebar

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Using org avatar (temp)

* Not showing org logo if not set

* User onboarding with org branding (slug)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* feedback

* Feedback

* Org public profile

* Public profiles for team event types

* Added setup profile alert

* Using org avatar on subteams avatar

* Making sure we show the set up profile on org only

* Profile username availability rely on org hook

* Update apps/web/pages/team/[slug].tsx

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

* Update apps/web/pages/team/[slug].tsx

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

---------

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

* feat: Organization support for event types page (#9449)

* Desktop first banner, mobile pending

* Removing dead code and img

* WIP

* Adds Email verification template+translations for organizations (#9202)

* First step done

* Merge branch 'feat/organizations-onboarding' of github.com:calcom/cal.com into feat/organizations-onboarding

* Step 2 done, avatar not working

* Covering null on unique clauses

* Onboarding admins step

* Last step to create teams

* Moving change password handler, improving verifying code flow

* Clearing error before submitting

* Reverting email testing api changes

* Reverting having the banner for now

* Consistent exported components

* Remove unneeded files from banner

* Removing uneeded code

* Fixing avatar selector

* Org branding provider used in shell sidebar

* Using meta component for head/descr

* Missing i18n strings

* Feedback

* Making an org avatar (temp)

* Using org avatar (temp)

* Not showing org logo if not set

* User onboarding with org branding (slug)

* Check for subteams slug clashes with usernames

* Fixing create teams onsuccess

* feedback

* Feedback

* Org public profile

* Public profiles for team event types

* Added setup profile alert

* Using org avatar on subteams avatar

* Processing orgs and children as profile options

* Reverting change not belonging to this PR

* Making sure we show the set up profile on org only

* Removing console.log

* Comparing memberships to choose the highest one

---------

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

* Type errors

* Refactor and type fixes

* Update orgDomains.ts

* Feedback

* Reverting

* NIT

* fix issue getting org slug from domain

* Improving orgDomains util

* Host comes with port

* Update useRouterQuery.ts

* Feedback

* Feedback

* Feedback

* Feedback: SSR for user event-types to have org context

* chore: Cache node_modules (#9492)

* Adding check for cache hit

* Adding a separate install step first

* Put the restore cache steps back

* Revert the uses type for restoring cache

* Added step to restore nm cache

* Removed the cache-hit check

* Comments and naming

* Removed extra install command

* Updated the name of the linting step to be more clear

* Removes the need for useEffect here

* Feedback

* Feedback

* Cookie domain needs a dot

* Type fix

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

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

* Update packages/emails/src/templates/OrganizationAccountVerifyEmail.tsx

* Feedback

---------

Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: zomars <zomars@me.com>
Co-authored-by: Efraín Rochín <roae.85@gmail.com>
Co-authored-by: Keith Williams <keithwillcode@gmail.com>
2023-06-14 21:40:20 +00:00
Keith Williams 9db4a04cd9 chore: Cache node_modules (#9492)
* Adding check for cache hit

* Adding a separate install step first

* Put the restore cache steps back

* Revert the uses type for restoring cache

* Added step to restore nm cache

* Removed the cache-hit check

* Comments and naming

* Removed extra install command

* Updated the name of the linting step to be more clear
2023-06-14 15:27:47 -03:00
Alex van Andel 8943e8c2f6 Fix: Sets null to undefined during workflow select (#9513) 2023-06-14 14:43:42 +00:00
Crowdin Bot f17fa55426 New Crowdin translations by Github Action 2023-06-14 14:39:25 +00:00
Hariom BalharaandLeo Giovanetti 9ff83075d6 Improve IP Ban (#9512)
Co-authored-by: Leo Giovanetti <hello@leog.me>
2023-06-14 16:38:34 +02:00
Jeroen Reumkens 6b6043afdc Added custom error with more details to debug the ciaran event issue (#9482) 2023-06-14 10:47:58 +00:00
Crowdin Bot fd9162e70f New Crowdin translations by Github Action 2023-06-14 09:54:17 +00:00
Jeroen ReumkensandHariom Balhara 8331059b7c feat: new booker embed (#9023)
* Added embed files for new booker routes.

* Updated nextjs config to redirect to correct embed url.

* Notify embed of booker size after animation completes.

* Don't use animations and 100vh in embed.

* Added booker layout toggles to embed settings (wip)

* Booker header positioning tweaks

* Show correct layout in embed

* Don't show pricing event meta if stripe app is not installed

* Support custom border booker for embed

* wip on passing layout prop to iframe for previews

* Only show booker layout settings in embed-create-popup if booker layout feature is enabled.

* Made layout prop in preview state for embed optional

* Made layout prop in preview state for embed optional

* Get layout toggle working

* Fixed types

* Added themebasis prop

* Fix potential circular import that should then fix type errors

* Fixed type error by fixing casing.

* Type fixes

* Added translations

* More translations

* Remove comment

* Removed uneccessary addition to package.json

* Removed todo since it's solved in another way

---------

Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-06-14 09:22:44 +00:00
Syed Ali Shahbaz f0992b4914 fix with object undefined check (#9493) 2023-06-13 20:27:42 +00:00
TachyonicBytesandTachyonicBytes e081a4cfc2 fix: Add e2e test for routing forms webhook subscription (#9401)
* add e2e test for routing forms webhook subscription

* remove debugging checks

* fixed missing method for e2e

* remove forced timeout for e2e test

* fix e2e webhook test

* use routing forms page for install

---------

Co-authored-by: TachyonicBytes <support@tachyonicbytes.com>
2023-06-13 15:22:19 +00:00
895b3ca7c9 feat: add paid webhook (#8721)
* feat: add BOOKING_PAID on enums

* feat: trigger the BOOKING_PAID webhook

* refactor: create payment variable

* feat: add REJECTED and REQUESTED on enums

* feat: create migration to booking werbhooks

* Update packages/features/webhooks/lib/constants.ts

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>

* Update packages/prisma/schema.prisma

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>

* Update packages/prisma/migrations/20230513235419_add_booking_webhooks/migration.sql

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>

---------

Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com>
Co-authored-by: alannnc <alannnc@gmail.com>
Co-authored-by: Omar López <zomars@me.com>
2023-06-13 14:57:59 +00:00
Jaideep GuntupalliandBailey Pumfleet 4d30264950 fix: Multiple In Person Locations not working as expected in Event Setup Tab (#9465)
Co-authored-by: Bailey Pumfleet <bailey@pumfleet.co.uk>
2023-06-13 14:54:53 +00:00
3a352a94f6 fix: phone input update state persistence (#9471)
* fix: phone input update state persistence

* refactor: use spreading

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: alannnc <alannnc@gmail.com>
Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-06-13 14:54:13 +00:00
Nikeshkumar TK 8623175612 fix: Routing form two "New" button issue. (#9479)
* event types public api fix

* Routing form new button issue

* Routing form new button issue

* Routing form new button issue

* Routing form new button issue

* Routing form new button issue
2023-06-13 14:53:50 +00:00
Udit TakkarandPeer Richelsen ea531777c4 fix: size of cell (#9486)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
2023-06-13 11:08:00 +00:00
Soham Datta 2639ef7e13 fix: #9217 | redirected unready /admin to one of its tabs (#9222) 2023-06-13 10:46:41 +00:00
Jeroen Reumkens 0e76a19c96 Pass event duration to schedule api call (#9484) 2023-06-13 10:14:45 +00:00
3ec9eb377d docs: Added command in manual section (#9433)
Co-authored-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-06-12 21:46:29 +01:00
Udit TakkarandBailey Pumfleet 44b7000509 fix: dark mode in Alert component (#9467)
* fix: dark mode in Alert component

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

* chore

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: Bailey Pumfleet <bailey@pumfleet.co.uk>
2023-06-12 17:49:44 +00:00
depfu[bot]andHariom Balhara 251307f1e6 chore: Update vite 2.9.15 → 2.9.16 (patch) (#9346)
* Update vite to version 2.9.16

* Upgrade vite to 4.1.2 everywhere

---------

Co-authored-by: depfu[bot] <23717796+depfu[bot]@users.noreply.github.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2023-06-12 16:51:02 +00:00
Balveer Singh RaoandUdit Takkar 75e638ec4d fix: copy icon for dark mode (#9459)
* fixed copy icon for dark mode

* fix: height

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-06-12 16:48:37 +00:00
Crowdin Bot 443ccdd6c0 New Crowdin translations by Github Action 2023-06-12 16:28:32 +00:00
Abhishek Sunil dbf11cc04b test: Add E2E test to verify theme change (#9455)
* Add E2E test to verify theme change

* PR fixes
2023-06-12 16:14:40 +00:00
Crowdin Bot a5c9729f5f New Crowdin translations by Github Action 2023-06-12 10:57:30 +00:00
sean-brydon a6e2983a22 Fix translations (#9466) 2023-06-12 10:43:50 +00:00
Meet Patel a21f0c46c7 enabled csv upload for team bulk invites (#9446) 2023-06-11 09:36:59 +00:00
Udit Takkar ed4a81e852 fix: theme in new booker (#9453)
Signed-off-by: Udit Takkar <udit.07814802719@cse.mait.ac.in>
2023-06-11 09:11:46 +00:00
9231218350 fix: carify what sender ID means (#9431)
* add tooltip on info icon

* fix text

* fix UI in addActionDialog

---------

Co-authored-by: CarinaWolli <wollencarina@gmail.com>
Co-authored-by: Alex van Andel <me@alexvanandel.com>
2023-06-11 03:20:13 +00:00
7d1ea4ee2b chore: moved viewport meta from document to PageWrapper (#9406)
* moved viewport meta from document to _app

* moved viewport meta from _app.tsx to PageWrapper.tsx

---------

Co-authored-by: Keith Williams <keithwillcode@gmail.com>
Co-authored-by: Efraín Rochín <roae.85@gmail.com>
2023-06-10 15:19:17 +00:00
Efraín Rochín 0c68e51930 fix: [CAL-1765] opt-in: clicking "confirm" or "reject" broken (#9443)
* Add support to a custom sessionGetter in trpc createContext

* type fixes
2023-06-10 11:02:50 +00:00
310 changed files with 8013 additions and 3001 deletions
+28
View File
@@ -5,6 +5,7 @@
# - SHARED
# - NEXTAUTH
# - E-MAIL SETTINGS
# - ORGANIZATIONS
# - LICENSE (DEPRECATED) ************************************************************************************
# https://github.com/calcom/cal.com/blob/main/LICENSE
@@ -22,6 +23,8 @@ CALCOM_LICENSE_KEY=
# - DATABASE ************************************************************************************************
DATABASE_URL="postgresql://postgres:@localhost:5450/calendso"
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
# Uncomment to enable a dedicated connection pool for Prisma using Prisma Data Proxy
# Cold boots will be faster and you'll be able to scale your DB independently of your app.
@@ -32,6 +35,8 @@ PRISMA_GENERATE_DATAPROXY=
# ***********************************************************************************************************
# - SHARED **************************************************************************************************
# Set this to http://app.cal.local:3000 if you want to enable organizations, and
# check variable ORGANIZATIONS_ENABLED at the bottom of this file
NEXT_PUBLIC_WEBAPP_URL='http://localhost:3000'
# Change to 'http://localhost:3001' if running the website simultaneously
NEXT_PUBLIC_WEBSITE_URL='http://localhost:3000'
@@ -183,3 +188,26 @@ CSP_POLICY=
EDGE_CONFIG=
NEXT_PUBLIC_MINUTES_TO_BOOK=5 # Minutes
# - ORGANIZATIONS *******************************************************************************************
# Enable Organizations non-prod domain setup, works in combination with organizations feature flag
# This is mainly needed locally, because for orgs to work a full domain name needs to point
# to the app, i.e. app.cal.local instead of using localhost, which is very disruptive
#
# This variable should only be set to 1 or true if you are in a non-prod environment and you want to
# use organizations
ORGANIZATIONS_ENABLED=
# Vercel Config to create subdomains for organizations
# Get it from https://vercel.com/<TEAM_OR_USER_NAME>/<PROJECT_SLUG>/settings
PROJECT_ID_VERCEL=
# Get it from: https://vercel.com/teams/<TEAM_SLUG>/settings
TEAM_ID_VERCEL=
# Get it from: https://vercel.com/account/tokens
AUTH_BEARER_TOKEN_VERCEL=
#Enables New booker for Embed only
NEW_BOOKER_ENABLED_FOR_EMBED=0
#Enables New booker for All but Embed requests
NEW_BOOKER_ENABLED_FOR_NON_EMBED=0
+9
View File
@@ -40,6 +40,14 @@ runs:
restore-keys: |
yarn-download-cache-
# Invalidated on yarn.lock changes
- name: Restore node_modules
id: yarn-nm-cache
uses: buildjet/cache@v3
with:
path: "**/node_modules/"
key: ${{ runner.os }}-yarn-nm-cache-${{ hashFiles('yarn.lock', '.yarnrc.yml') }}
# Invalidated on yarn.lock changes
- name: Restore yarn install state
id: yarn-install-state-cache
@@ -58,5 +66,6 @@ runs:
YARN_ENABLE_IMMUTABLE_INSTALLS: "false" # So it doesn't try to remove our private submodule deps
YARN_ENABLE_GLOBAL_CACHE: "false" # Use local cache folder to keep downloaded archives
YARN_INSTALL_STATE_PATH: .yarn/ci-cache/install-state.gz # Very small speedup when lock does not change
YARN_NM_MODE: "hardlinks-local" # Reduce node_modules size
# Other environment variables
HUSKY: "0" # By default do not run HUSKY install
@@ -0,0 +1,16 @@
name: Add PRs to project Reviewing PRs
on:
pull_request:
types:
- opened
jobs:
add-PR-to-project:
name: Add PRs to project Reviewing PRs
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v0.1.0
with:
project-url: https://github.com/orgs/calcom/projects/11
github-token: ${{ secrets.GH_ACCESS_TOKEN }}
+1 -1
View File
@@ -9,7 +9,7 @@ jobs:
- uses: actions/checkout@v3
- uses: ./.github/actions/dangerous-git-checkout
- uses: ./.github/actions/yarn-install
- name: Save Code Linting Reports
- name: Run Linting with Reports
run: yarn lint:report
continue-on-error: true
+1
View File
@@ -16,6 +16,7 @@ concurrency:
jobs:
changes:
name: Detect changes
runs-on: buildjet-4vcpu-ubuntu-2204
permissions:
pull-requests: read
+28 -2
View File
@@ -9,7 +9,7 @@ on:
- synchronize
permissions:
pull-requests: read
pull-requests: write
jobs:
validate-pr:
@@ -17,5 +17,31 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
id: lint_pr_title
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: marocchino/sticky-pull-request-comment@v2
# When the previous steps fails, the workflow would stop. By adding this
# condition you can continue the execution with the populated error message.
if: always() && (steps.lint_pr_title.outputs.error_message != null)
with:
header: pr-title-lint-error
message: |
Hey there and thank you for opening this pull request! 👋🏼
We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.
Details:
```
${{ steps.lint_pr_title.outputs.error_message }}
```
# Delete a previous comment when the issue has been resolved
- if: ${{ steps.lint_pr_title.outputs.error_message == null }}
uses: marocchino/sticky-pull-request-comment@v2
with:
header: pr-title-lint-error
message: |
Thank you for following the naming conventions! 🙏
@@ -0,0 +1,28 @@
name: "Welcome new contributors"
on:
issues:
types: opened
pull_request:
types: opened
permissions:
pull-requests: write
issues: write
jobs:
welcome-message:
name: Welcoming New Users
runs-on: ubuntu-latest
timeout-minutes: 10
needs: semantics
if: github.event.action == 'opened'
steps:
- uses: actions/first-interaction@v1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
pr-message: |-
Thank you for making your first Pull Request and taking the time to improve Cal.com ! ❤️🎉
Feel free to join the conversation at [slack](https://calendso.slack.com/)
issue-message: |
Thank you for opening your first issue, one of our team members will review it as soon as it possible. ❤️🎉
+2 -1
View File
@@ -8,6 +8,7 @@
"ban.spellright", // Spell check for docs
"stripe.vscode-stripe", // stripe VSCode extension
"Prisma.prisma", // syntax|format|completion for prisma
"rebornix.project-snippets" // Share useful snippets between collaborators
"rebornix.project-snippets", // Share useful snippets between collaborators
"inlang.vs-code-extension" // improved i18n DX
]
}
+1 -1
View File
@@ -2,7 +2,7 @@ Copyright (c) 2020-present Cal.com, Inc.
Portions of this software are licensed as follows:
* All content that resides under https://github.com/calcom/cal.com/tree/main/packages/features/ee directory of this repository (Commercial License) is licensed under the license defined in "ee/LICENSE".
* All content that resides under https://github.com/calcom/cal.com/tree/main/packages/features/ee and https://github.com/calcom/cal.com/tree/main/apps/api/ directory of this repository (Commercial License) is licensed under the license defined in "ee/LICENSE".
* All third party components incorporated into the Cal.com Software are licensed under the original license provided by the owner of the applicable component.
* Content outside of the above mentioned directories or restrictions above is available under the "AGPLv3" license as defined below.
+8
View File
@@ -201,6 +201,14 @@ echo 'NEXT_PUBLIC_DEBUG=1' >> .env
1. Set a 32 character random string in your `.env` file for the `CALENDSO_ENCRYPTION_KEY` (You can use a command like `openssl rand -base64 24` to generate one).
1. Set up the database using the Prisma schema (found in `packages/prisma/schema.prisma`)
In a development environment, run:
```sh
yarn workspace @calcom/prisma db-migrate
```
In a production environment, run:
```sh
yarn workspace @calcom/prisma db-deploy
```
+42
View File
@@ -0,0 +1,42 @@
The Cal.com Commercial License (the “Commercial License”)
Copyright (c) 2020-present Cal.com, Inc
With regard to the Cal.com Software:
This software and associated documentation files (the "Software") may only be
used in production, if you (and any entity that you represent) have agreed to,
and are in compliance with, the Cal.com Subscription Terms available
at https://cal.com/terms, or other agreements governing
the use of the Software, as mutually agreed by you and Cal.com, Inc ("Cal.com"),
and otherwise have a valid Cal.com Enterprise Edition subscription ("Commercial Subscription")
for the correct number of hosts as defined in the "Commercial Terms ("Hosts"). Subject to the foregoing sentence,
you are free to modify this Software and publish patches to the Software. You agree
that Cal.com and/or its licensors (as applicable) retain all right, title and interest in
and to all such modifications and/or patches, and all such modifications and/or
patches may only be used, copied, modified, displayed, distributed, or otherwise
exploited with a valid Commercial Subscription for the correct number of hosts.
Notwithstanding the foregoing, you may copy and modify the Software for development
and testing purposes, without requiring a subscription. You agree that Cal.com and/or
its licensors (as applicable) retain all right, title and interest in and to all such
modifications. You are not granted any other rights beyond what is expressly stated herein.
Subject to the foregoing, it is forbidden to copy, merge, publish, distribute, sublicense,
and/or sell the Software.
This Commercial License applies only to the part of this Software that is not distributed under
the AGPLv3 license. Any part of this Software distributed under the MIT license or which
is served client-side as an image, font, cascading stylesheet (CSS), file which produces
or is compiled, arranged, augmented, or combined into client-side JavaScript, in whole or
in part, is copyrighted under the AGPLv3 license. The full text of this Commercial License shall
be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
For all third party components incorporated into the Cal.com Software, those
components are licensed under the original license provided by the owner of the
applicable component.
+1 -1
View File
@@ -32,7 +32,7 @@
"@sentry/nextjs": "^7.20.0",
"bcryptjs": "^2.4.3",
"memory-cache": "^0.2.0",
"next": "~13.2.1",
"next": "~13.4.6",
"next-api-middleware": "^1.0.1",
"next-axiom": "^0.16.0",
"next-swagger-doc": "^0.3.6",
+3
View File
@@ -2,6 +2,7 @@ import type { NextApiRequest } from "next";
import { z } from "zod";
import { getUserAvailability } from "@calcom/core/getUserAvailability";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import { HttpError } from "@calcom/lib/http-error";
import { defaultResponder } from "@calcom/lib/server";
import { availabilityUserSelect } from "@calcom/prisma";
@@ -119,8 +120,10 @@ const availabilitySchema = z
async function handler(req: NextApiRequest) {
const { prisma, isAdmin, userId: reqUserId } = req;
const { username, userId, eventTypeId, dateTo, dateFrom, teamId } = availabilitySchema.parse(req.query);
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(req.headers.host ?? "");
if (!teamId)
return getUserAvailability({
orgSlug: isValidOrgDomain ? currentOrgDomain || undefined : undefined,
username,
dateFrom,
dateTo,
+12 -1
View File
@@ -35,6 +35,9 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform
* status:
* type: string
* description: 'Acceptable values one of ["ACCEPTED", "PENDING", "CANCELLED", "REJECTED"]'
* description:
* type: string
* description: 'Description of the meeting'
* examples:
* editBooking:
* value:
@@ -79,7 +82,15 @@ import { schemaQueryIdParseInt } from "~/lib/validations/shared/queryIdTransform
* "startTime": "2023-05-24T13:00:00.000Z",
* "endTime": "2023-05-24T13:30:00.000Z",
* "metadata": {},
* "status": "CANCELLED"
* "status": "CANCELLED",
* "responses": {
* "email": "john.doe@example.com",
* "name": "John Doe",
* "location": {
* "optionValue": "",
* "value": "inPerson"
* }
* }
* }
* }
* 400:
+69 -70
View File
@@ -26,13 +26,10 @@ import { defaultResponder } from "@calcom/lib/server";
* required:
* - eventTypeId
* - start
* - name
* - email
* - responses
* - timeZone
* - language
* - metadata
* - customInputs
* - location
* properties:
* eventTypeId:
* type: integer
@@ -45,29 +42,33 @@ import { defaultResponder } from "@calcom/lib/server";
* type: string
* format: date-time
* description: 'End time of the Event'
* name:
* type: string
* description: 'Name of the Attendee'
* email:
* type: string
* format: email
* description: 'Email ID of the Attendee'
* responses:
* type: object
* required:
* - name
* - email
* - location
* properties:
* name:
* type: string
* description: 'Attendee full name'
* email:
* type: string
* format: email
* description: 'Attendee email address'
* location:
* type: string
* description: 'Meeting location'
* metadata:
* type: object
* properties: {}
* description: 'Any metadata associated with the booking'
* timeZone:
* type: string
* description: 'TimeZone of the Attendee'
* language:
* type: string
* description: 'Language of the Attendee'
* metadata:
* type: object
* properties: {}
* description: 'Any metadata associated with the booking'
* customInputs:
* type: array
* items: {}
* location:
* type: string
* description: 'Meeting location'
* title:
* type: string
* description: 'Booking event title'
@@ -96,13 +97,14 @@ import { defaultResponder } from "@calcom/lib/server";
* "eventTypeId": 2323232,
* "start": "2023-05-24T13:00:00.000Z",
* "end": "2023-05-24T13:30:00.000Z",
* "name": "Hello Hello",
* "email": "hello@gmail.com",
* "responses":{
* "name": "Hello Hello",
* "email": "hello@gmail.com",
* "metadata": {},
* "location": "Calcom HQ",
* },
* "timeZone": "Europe/London",
* "language": "en",
* "metadata": {},
* "customInputs": [],
* "location": "Calcom HQ",
* "title": "Debugging between Syed Ali Shahbaz and Hello Hello",
* "description": null,
* "status": "PENDING",
@@ -117,53 +119,50 @@ import { defaultResponder } from "@calcom/lib/server";
* content:
* application/json:
* examples:
* bookings:
* booking created successfully example:
* value:
* {
* "id": 11223344,
* "uid": "5yUjmAYTDF6MXo98re8SkX",
* "userId": 123,
* "eventTypeId": 2323232,
* "title": "Debugging between Syed Ali Shahbaz and Hello Hello",
* "description": null,
* "customInputs": {},
* "responses": null,
* "startTime": "2023-05-24T13:00:00.000Z",
* "endTime": "2023-05-24T13:30:00.000Z",
* "location": "Calcom HQ",
* "createdAt": "2023-04-19T10:17:58.580Z",
* "updatedAt": null,
* "status": "PENDING",
* "paid": false,
* "destinationCalendarId": 2180,
* "cancellationReason": null,
* "rejectionReason": null,
* "dynamicEventSlugRef": null,
* "dynamicGroupSlugRef": null,
* "rescheduled": null,
* "fromReschedule": null,
* "recurringEventId": null,
* "smsReminderNumber": null,
* "scheduledJobs": [],
* "metadata": {},
* "isRecorded": false,
* "user": {
* "email": "test@cal.com",
* "name": "Syed Ali Shahbaz",
* "timeZone": "Asia/Calcutta"
* },
* "attendees": [
* {
* "id": 12345,
* "email": "hello@gmail.com",
* "name": "Hello Hello",
* "timeZone": "Europe/London",
* "locale": "en",
* "bookingId": 11223344
* "booking": {
* "id": 91,
* "userId": 5,
* "description": "",
* "eventTypeId": 7,
* "uid": "bFJeNb2uX8ANpT3JL5EfXw",
* "title": "60min between Pro Example and John Doe",
* "startTime": "2023-05-25T09:30:00.000Z",
* "endTime": "2023-05-25T10:30:00.000Z",
* "attendees": [
* {
* "email": "john.doe@example.com",
* "name": "John Doe",
* "timeZone": "Asia/Kolkata",
* "locale": "en"
* }
* ],
* "user": {
* "email": "pro@example.com",
* "name": "Pro Example",
* "timeZone": "Asia/Kolkata",
* "locale": "en"
* },
* "payment": [
* {
* "id": 1,
* "success": true,
* "paymentOption": "ON_BOOKING"
* }
* ],
* "metadata": {},
* "status": "ACCEPTED",
* "responses": {
* "email": "john.doe@example.com",
* "name": "John Doe",
* "location": {
* "optionValue": "",
* "value": "inPerson"
* }
* }
* ],
* "payment": [],
* "references": []
* }
* }
* 400:
* description: |
+2 -2
View File
@@ -20,7 +20,7 @@
"@radix-ui/react-slider": "^1.0.0",
"@radix-ui/react-switch": "^1.0.0",
"@radix-ui/react-tooltip": "^1.0.0",
"next": "^13.2.1",
"next": "^13.4.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"storybook-addon-rtl-direction": "^0.0.19"
@@ -50,6 +50,6 @@
"storybook-react-i18next": "^1.1.2",
"tailwindcss": "^3.2.1",
"typescript": "^4.9.4",
"vite": "^2.9.15"
"vite": "^4.1.2"
}
}
+4 -2
View File
@@ -235,6 +235,7 @@
*/
--cal-brand:#111827;
--cal-brand-emphasis:#101010;
--cal-brand-text: white;
}
.dark {
/* background */
@@ -274,7 +275,8 @@
/* Brand shenanigans
-> These will be computed for the users theme at runtime.
*/
--cal-brand: #111827;
--cal-brand-emphasis: #101010;
--cal-brand: white;
--cal-brand-emphasis: #e1e1e1;
--cal-brand-text: black;
}
}
+1 -1
View File
@@ -14,7 +14,7 @@
"dependencies": {
"highlight.js": "^11.6.0",
"isarray": "2.0.5",
"next": "^13.2.1",
"next": "^13.4.6",
"openapi-snippet": "^0.13.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
+44 -2
View File
@@ -8,8 +8,11 @@ import { createRef, forwardRef, useRef, useState } from "react";
import type { ControlProps } from "react-select";
import { components } from "react-select";
import type { BookerLayout } from "@calcom/features/bookings/Booker/types";
import { useFlagMap } from "@calcom/features/flags/context/provider";
import { APP_NAME, EMBED_LIB_URL, WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { BookerLayouts } from "@calcom/prisma/zod-utils";
import {
Button,
Dialog,
@@ -41,12 +44,13 @@ type PreviewState = {
height: string;
};
theme: Theme;
floatingPopup: Record<string, string>;
floatingPopup: Record<string, string | boolean | undefined>;
elementClick: Record<string, string>;
palette: {
brandColor: string;
};
hideEventTypeDetails: boolean;
layout: BookerLayouts;
};
const queryParamsForDialog = ["embedType", "embedTabName", "embedUrl"];
@@ -129,11 +133,13 @@ const getEmbedUIInstructionString = ({
theme,
brandColor,
hideEventTypeDetails,
layout,
}: {
apiName: string;
theme?: string;
brandColor: string;
hideEventTypeDetails: boolean;
layout?: string;
}) => {
theme = theme !== "auto" ? theme : undefined;
return getInstructionString({
@@ -147,6 +153,7 @@ const getEmbedUIInstructionString = ({
},
},
hideEventTypeDetails: hideEventTypeDetails,
layout,
},
});
};
@@ -260,6 +267,7 @@ const getEmbedTypeSpecificString = ({
theme: PreviewState["theme"];
brandColor: string;
hideEventTypeDetails: boolean;
layout?: BookerLayout;
};
if (embedFramework === "react") {
uiInstructionStringArg = {
@@ -267,6 +275,7 @@ const getEmbedTypeSpecificString = ({
theme: previewState.theme,
brandColor: previewState.palette.brandColor,
hideEventTypeDetails: previewState.hideEventTypeDetails,
layout: previewState.layout,
};
} else {
uiInstructionStringArg = {
@@ -274,6 +283,7 @@ const getEmbedTypeSpecificString = ({
theme: previewState.theme,
brandColor: previewState.palette.brandColor,
hideEventTypeDetails: previewState.hideEventTypeDetails,
layout: previewState.layout,
};
}
if (!frameworkCodes[embedType]) {
@@ -626,6 +636,7 @@ const ThemeSelectControl = ({ children, ...props }: ControlProps<{ value: Theme;
const ChooseEmbedTypesDialogContent = () => {
const { t } = useLocale();
const router = useRouter();
return (
<DialogContent className="rounded-lg p-10" type="creation" size="lg">
<div className="mb-2">
@@ -671,6 +682,8 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
const router = useRouter();
const iframeRef = useRef<HTMLIFrameElement>(null);
const dialogContentRef = useRef<HTMLDivElement>(null);
const flags = useFlagMap();
const isBookerLayoutsEnabled = flags["booker-layouts"] === true;
const s = (href: string) => {
const searchParams = new URLSearchParams(router.asPath.split("?")[1] || "");
@@ -691,7 +704,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
const [isEmbedCustomizationOpen, setIsEmbedCustomizationOpen] = useState(true);
const [isBookingCustomizationOpen, setIsBookingCustomizationOpen] = useState(true);
const [previewState, setPreviewState] = useState({
const [previewState, setPreviewState] = useState<PreviewState>({
inline: {
width: "100%",
height: "100%",
@@ -703,6 +716,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
palette: {
brandColor: "#000000",
},
layout: BookerLayouts.MONTH_VIEW,
});
const close = () => {
@@ -765,6 +779,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
arg: {
theme: previewState.theme,
hideEventTypeDetails: previewState.hideEventTypeDetails,
layout: previewState.layout,
styles: {
branding: {
...previewState.palette,
@@ -798,6 +813,12 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
{ value: Theme.light, label: "Light Theme" },
];
const layoutOptions = [
{ value: BookerLayouts.MONTH_VIEW, label: t("bookerlayout_month_view") },
{ value: BookerLayouts.WEEK_VIEW, label: t("bookerlayout_week_view") },
{ value: BookerLayouts.COLUMN_VIEW, label: t("bookerlayout_column_view") },
];
const FloatingPopupPositionOptions = [
{
value: "bottom-right",
@@ -1070,6 +1091,27 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
</div>
</Label>
))}
{isBookerLayoutsEnabled && (
<Label className="mb-6">
<div className="mb-2">{t("layout")}</div>
<Select
className="w-full"
defaultValue={layoutOptions[0]}
onChange={(option) => {
if (!option) {
return;
}
setPreviewState((previewState) => {
return {
...previewState,
layout: option.value,
};
});
}}
options={layoutOptions}
/>
</Label>
)}
</div>
</CollapsibleContent>
</Collapsible>
+7
View File
@@ -1,6 +1,7 @@
import { DefaultSeo } from "next-seo";
import { Inter } from "next/font/google";
import localFont from "next/font/local";
import Head from "next/head";
import Script from "next/script";
import "@calcom/embed-core/src/embed-iframe";
@@ -60,6 +61,12 @@ function PageWrapper(props: AppProps) {
return (
<AppProviders {...providerProps}>
<Head>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
/>
</Head>
<DefaultSeo
// Set canonical to https://cal.com or self-hosted URL
canonical={
@@ -83,7 +83,9 @@ const BookingDescription: FC<Props> = (props) => {
size="sm"
truncateAfter={3}
/>
<h2 className="text-default mt-1 mb-2 break-words text-sm font-medium ">{profile.name}</h2>
<h2 className="text-default mt-1 mb-2 break-words text-sm font-medium ">
{eventType.team?.parent?.name} {profile.name}
</h2>
<h1 className="font-cal text-emphasis mb-6 break-words text-2xl font-semibold leading-none">
{eventType.title}
</h1>
@@ -93,7 +93,7 @@ export default function CancelBooking(props: Props) {
headers: {
"Content-Type": "application/json",
},
method: "DELETE",
method: "POST",
});
if (res.status >= 200 && res.status < 300) {
@@ -57,12 +57,15 @@ const LocationInput = (props: {
<Input {...locationFormMethods.register(eventLocationType.variable)} type="text" {...remainingProps} />
);
} else if (eventLocationType?.organizerInputType === "phone") {
const { defaultValue, ...rest } = remainingProps;
return (
<Controller
name={eventLocationType.variable}
control={control}
defaultValue={defaultValue}
render={({ field: { onChange, value } }) => {
return <PhoneInput onChange={onChange} value={value} {...remainingProps} />;
return <PhoneInput onChange={onChange} value={value} {...rest} />;
}}
/>
);
@@ -88,6 +91,9 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
useEffect(() => {
if (selection) {
locationFormMethods.setValue("locationType", selection?.value);
if (selection?.address) {
locationFormMethods.setValue("locationAddress", selection?.address);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selection]);
@@ -149,12 +155,25 @@ export const EditLocationDialog = (props: ISetLocationDialog) => {
name: "locationType",
});
const selectedAddrValue = useWatch({
control: locationFormMethods.control,
name: "locationAddress",
});
const eventLocationType = getEventLocationType(selectedLocation);
const defaultLocation = defaultValues?.find(
(location: { type: EventLocationType["type"] }) => location.type === eventLocationType?.type
(location: { type: EventLocationType["type"]; address?: string }) => {
if (location.type === LocationType.InPerson) {
return location.type === eventLocationType?.type && location.address === selectedAddrValue;
} else {
return location.type === eventLocationType?.type;
}
}
);
console.log(defaultLocation);
const LocationOptions = (() => {
if (eventLocationType && eventLocationType.organizerInputType && LocationInput) {
if (!eventLocationType.variable) {
@@ -136,9 +136,17 @@ export const EventSetupTab = (
selectedMultipleDuration.find((opt) => opt.value === eventType.length) ?? null
);
const openLocationModal = (type: EventLocationType["type"]) => {
const openLocationModal = (type: EventLocationType["type"], address = "") => {
const option = getLocationFromType(type, locationOptions);
setSelectedLocation(option);
if (option && option.value === LocationType.InPerson) {
const inPersonOption = {
...option,
address,
};
setSelectedLocation(inPersonOption);
} else {
setSelectedLocation(option);
}
setShowLocationModal(true);
};
@@ -298,10 +306,14 @@ export const EventSetupTab = (
onClick={() => {
locationFormMethods.setValue("locationType", location.type);
locationFormMethods.unregister("locationLink");
locationFormMethods.unregister("locationAddress");
if (location.type === LocationType.InPerson) {
locationFormMethods.setValue("locationAddress", location.address);
} else {
locationFormMethods.unregister("locationAddress");
}
locationFormMethods.unregister("locationPhoneNumber");
setEditingLocationType(location.type);
openLocationModal(location.type);
openLocationModal(location.type, location.address);
}}
aria-label={t("edit")}
className="hover:text-emphasis text-subtle mr-1 p-1">
@@ -517,7 +529,18 @@ export const EventSetupTab = (
defaultValues={formMethods.getValues("locations")}
selection={
selectedLocation
? { value: selectedLocation.value, label: t(selectedLocation.label), icon: selectedLocation.icon }
? selectedLocation.address
? {
value: selectedLocation.value,
label: t(selectedLocation.label),
icon: selectedLocation.icon,
address: selectedLocation.address,
}
: {
value: selectedLocation.value,
label: t(selectedLocation.label),
icon: selectedLocation.icon,
}
: undefined
}
setSelectedLocation={setSelectedLocation}
@@ -8,21 +8,15 @@ import { md } from "@calcom/lib/markdownIt";
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import turndown from "@calcom/lib/turndownService";
import { trpc } from "@calcom/trpc/react";
import { Button, Editor, ImageUploader, Label, showToast } from "@calcom/ui";
import { Avatar } from "@calcom/ui";
import { Avatar, Button, Editor, ImageUploader, Label, showToast } from "@calcom/ui";
import { ArrowRight } from "@calcom/ui/components/icon";
import type { IOnboardingPageProps } from "../../../pages/getting-started/[[...step]]";
type FormData = {
bio: string;
};
interface IUserProfileProps {
user: IOnboardingPageProps["user"];
}
const UserProfile = (props: IUserProfileProps) => {
const { user } = props;
const UserProfile = () => {
const [user] = trpc.viewer.me.useSuspenseQuery();
const { t } = useLocale();
const avatarRef = useRef<HTMLInputElement>(null);
const { setValue, handleSubmit, getValues } = useForm<FormData>({
@@ -13,15 +13,13 @@ import { ArrowRight } from "@calcom/ui/components/icon";
import { UsernameAvailabilityField } from "@components/ui/UsernameAvailability";
import type { IOnboardingPageProps } from "../../../pages/getting-started/[[...step]]";
interface IUserSettingsProps {
user: IOnboardingPageProps["user"];
nextStep: () => void;
}
const UserSettings = (props: IUserSettingsProps) => {
const { user, nextStep } = props;
const { nextStep } = props;
const [user] = trpc.viewer.me.useSuspenseQuery();
const { t } = useLocale();
const [selectedTimeZone, setSelectedTimeZone] = useState(dayjs.tz.guess());
const telemetry = useTelemetry();
@@ -69,7 +67,7 @@ const UserSettings = (props: IUserSettingsProps) => {
<form onSubmit={onSubmit}>
<div className="space-y-6">
{/* Username textfield */}
<UsernameAvailabilityField user={user} />
<UsernameAvailabilityField />
{/* Full name textfield */}
<div className="w-full">
@@ -8,14 +8,12 @@ import { getPremiumPlanPriceValue } from "@calcom/app-store/stripepayment/lib/ut
import { fetchUsername } from "@calcom/lib/fetchUsername";
import hasKeyInMetadata from "@calcom/lib/hasKeyInMetadata";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { User } from "@calcom/prisma/client";
import type { TRPCClientErrorLike } from "@calcom/trpc/client";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import type { AppRouter } from "@calcom/trpc/server/routers/_app";
import { Button, Dialog, DialogClose, DialogContent, Input, Label } from "@calcom/ui";
import { Star as StarSolid } from "@calcom/ui/components/icon";
import { Check, Edit2, ExternalLink } from "@calcom/ui/components/icon";
import { Check, Edit2, ExternalLink, Star as StarSolid } from "@calcom/ui/components/icon";
export enum UsernameChangeStatusEnum {
UPGRADE = "UPGRADE",
@@ -29,7 +27,6 @@ interface ICustomUsernameProps {
setInputUsernameValue: (value: string) => void;
onSuccessMutation?: () => void;
onErrorMutation?: (error: TRPCClientErrorLike<AppRouter>) => void;
user: Pick<User, "username" | "metadata">;
readonly?: boolean;
}
@@ -57,8 +54,8 @@ const PremiumTextfield = (props: ICustomUsernameProps) => {
onSuccessMutation,
onErrorMutation,
readonly: disabled,
user,
} = props;
const [user] = trpc.viewer.me.useSuspenseQuery();
const [usernameIsAvailable, setUsernameIsAvailable] = useState(false);
const [markAsError, setMarkAsError] = useState(false);
const router = useRouter();
@@ -21,7 +21,7 @@ interface ICustomUsernameProps {
onErrorMutation?: (error: TRPCClientErrorLike<AppRouter>) => void;
}
const UsernameTextfield = (props: ICustomUsernameProps) => {
const UsernameTextfield = (props: ICustomUsernameProps & Partial<React.ComponentProps<typeof TextField>>) => {
const { t } = useLocale();
const {
currentUsername,
@@ -31,6 +31,7 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
usernameRef,
onSuccessMutation,
onErrorMutation,
...rest
} = props;
const [usernameIsAvailable, setUsernameIsAvailable] = useState(false);
const [markAsError, setMarkAsError] = useState(false);
@@ -116,9 +117,6 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
ref={usernameRef}
name="username"
value={inputUsernameValue}
addOnLeading={
<>{process.env.NEXT_PUBLIC_WEBSITE_URL.replace("https://", "").replace("http://", "")}/</>
}
autoComplete="none"
autoCapitalize="none"
autoCorrect="none"
@@ -133,6 +131,7 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
setInputUsernameValue(event.target.value);
}}
data-testid="username-input"
{...rest}
/>
{currentUsername !== inputUsernameValue && (
<div className="absolute right-[2px] top-6 flex flex-row">
@@ -2,9 +2,11 @@ import { useRouter } from "next/router";
import { useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { subdomainSuffix } from "@calcom/features/ee/organizations/lib/orgDomains";
import { IS_SELF_HOSTED } from "@calcom/lib/constants";
import type { User } from "@calcom/prisma/client";
import type { TRPCClientErrorLike } from "@calcom/trpc/client";
import type { RouterOutputs } from "@calcom/trpc/react";
import { trpc } from "@calcom/trpc/react";
import type { AppRouter } from "@calcom/trpc/server/routers/_app";
import useRouterQuery from "@lib/hooks/useRouterQuery";
@@ -17,14 +19,24 @@ export const UsernameAvailability = IS_SELF_HOSTED ? UsernameTextfield : Premium
interface UsernameAvailabilityFieldProps {
onSuccessMutation?: () => void;
onErrorMutation?: (error: TRPCClientErrorLike<AppRouter>) => void;
user: Pick<User, "username" | "metadata">;
}
function useUserNamePrefix(organization: RouterOutputs["viewer"]["me"]["organization"]): string {
return organization
? organization.slug
? `${organization.slug}.${subdomainSuffix()}/`
: organization.metadata && organization.metadata.requestedSlug
? `${organization.metadata.requestedSlug}.${subdomainSuffix()}/`
: process.env.NEXT_PUBLIC_WEBSITE_URL.replace("https://", "").replace("http://", "")
: process.env.NEXT_PUBLIC_WEBSITE_URL.replace("https://", "").replace("http://", "");
}
export const UsernameAvailabilityField = ({
onSuccessMutation,
onErrorMutation,
user,
}: UsernameAvailabilityFieldProps) => {
const router = useRouter();
const [user] = trpc.viewer.me.useSuspenseQuery();
const [currentUsernameState, setCurrentUsernameState] = useState(user.username || "");
const { username: usernameFromQuery, setQuery: setUsernameFromQuery } = useRouterQuery("username");
const { username: currentUsername, setQuery: setCurrentUsername } =
@@ -37,6 +49,8 @@ export const UsernameAvailabilityField = ({
},
});
const usernamePrefix = useUserNamePrefix(user.organization);
return (
<Controller
control={formMethods.control}
@@ -51,7 +65,7 @@ export const UsernameAvailabilityField = ({
setInputUsernameValue={onChange}
onSuccessMutation={onSuccessMutation}
onErrorMutation={onErrorMutation}
user={user}
addOnLeading={usernamePrefix}
/>
);
}}
@@ -11,6 +11,7 @@ export type LocationOption = {
value: EventLocationType["type"];
icon?: string;
disabled?: boolean;
address?: string;
};
export type SingleValueLocationOption = SingleValue<LocationOption>;
+10 -1
View File
@@ -9,6 +9,8 @@ import type { NextRouter } from "next/router";
import { useRouter } from "next/router";
import type { ComponentProps, PropsWithChildren, ReactNode } from "react";
import { OrgBrandingProvider } from "@calcom/features/ee/organizations/context/provider";
import { useOrgBrandingValues } from "@calcom/features/ee/organizations/hooks";
import DynamicHelpscoutProvider from "@calcom/features/ee/support/lib/helpscout/providerDynamic";
import DynamicIntercomProvider from "@calcom/features/ee/support/lib/intercom/providerDynamic";
import { FeatureProvider } from "@calcom/features/flags/context/provider";
@@ -205,6 +207,11 @@ function FeatureFlagsProvider({ children }: { children: React.ReactNode }) {
return <FeatureProvider value={flags}>{children}</FeatureProvider>;
}
function OrgBrandProvider({ children }: { children: React.ReactNode }) {
const orgBrand = useOrgBrandingValues();
return <OrgBrandingProvider value={orgBrand}>{children}</OrgBrandingProvider>;
}
const AppProviders = (props: AppPropsWithChildren) => {
const session = trpc.viewer.public.session.useQuery().data;
// No need to have intercom on public pages - Good for Page Performance
@@ -222,7 +229,9 @@ const AppProviders = (props: AppPropsWithChildren) => {
isThemeSupported={props.Component.isThemeSupported}
isBookingPage={props.Component.isBookingPage}>
<FeatureFlagsProvider>
<MetaProvider>{props.children}</MetaProvider>
<OrgBrandProvider>
<MetaProvider>{props.children}</MetaProvider>
</OrgBrandProvider>
</FeatureFlagsProvider>
</CalcomThemeProvider>
</TooltipProvider>
+3
View File
@@ -8,6 +8,7 @@ export default function withEmbedSsr(getServerSideProps: GetServerSideProps) {
return async (context: GetServerSidePropsContext): Promise<GetServerSidePropsResult<EmbedProps>> => {
const ssrResponse = await getServerSideProps(context);
const embed = context.query.embed;
const layout = context.query.layout;
if ("redirect" in ssrResponse) {
// Use a dummy URL https://base as the fallback base URL so that URL parsing works for relative URLs as well.
@@ -18,6 +19,8 @@ export default function withEmbedSsr(getServerSideProps: GetServerSideProps) {
destinationUrlObj.pathname +
"/embed?" +
destinationUrlObj.searchParams.toString() +
"&layout=" +
layout +
"&embed=" +
embed;
+41 -7
View File
@@ -3,6 +3,7 @@ import { collectEvents } from "next-collect/server";
import type { NextMiddleware } from "next/server";
import { NextResponse, userAgent } from "next/server";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import { CONSOLE_URL, WEBAPP_URL, WEBSITE_URL } from "@calcom/lib/constants";
import { isIpInBanlist } from "@calcom/lib/getIP";
import { extendEventData, nextCollectBasicSettings } from "@calcom/lib/telemetry";
@@ -10,6 +11,25 @@ import { extendEventData, nextCollectBasicSettings } from "@calcom/lib/telemetry
const middleware: NextMiddleware = async (req) => {
const url = req.nextUrl;
const requestHeaders = new Headers(req.headers);
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(req.headers.get("host") ?? "");
/**
* We are using env variable to toggle new-booker because using flags would be an unnecessary delay for booking pages
* Also, we can't easily identify the booker page requests here(to just fetch the flags for those requests)
*/
// Make sure we are in the presence of an organization
if (isValidOrgDomain && url.pathname === "/") {
// In the presence of an organization, cover its profile page at "/"
// rewrites for org profile page using team profile page
url.pathname = `/org/${currentOrgDomain}`;
return NextResponse.rewrite(url);
}
if (isIpInBanlist(req) && url.pathname !== "/api/nope") {
// DDOS Prevention: Immediately end request with no response - Avoids a redirect as well initiated by NextAuth on invalid callback
req.nextUrl.pathname = "/api/nope";
return NextResponse.redirect(req.nextUrl);
}
if (!url.pathname.startsWith("/api")) {
//
@@ -48,13 +68,6 @@ const middleware: NextMiddleware = async (req) => {
}
}
// Ensure that embed query param is there in when /embed is added.
// query param is the way in which client side code knows that it is in embed mode.
if (url.pathname.endsWith("/embed") && typeof url.searchParams.get("embed") !== "string") {
url.searchParams.set("embed", "");
return NextResponse.redirect(url);
}
// Don't 404 old routing_forms links
if (url.pathname.startsWith("/apps/routing_forms")) {
url.pathname = url.pathname.replace("/apps/routing_forms", "/apps/routing-forms");
@@ -70,6 +83,26 @@ const middleware: NextMiddleware = async (req) => {
requestHeaders.set("x-csp-enforce", "true");
}
if (isValidOrgDomain) {
// Match /:slug to determine if it corresponds to org subteam slug or org user slug
const slugs = /^\/([^/]+)(\/[^/]+)?$/.exec(url.pathname);
// In the presence of an organization, if not team profile, a user or team is being accessed
if (slugs) {
const [_, teamName, eventType] = slugs;
// Fetch the corresponding subteams for the entered organization
const getSubteams = await fetch(`${WEBAPP_URL}/api/organizations/${currentOrgDomain}/subteams`);
if (getSubteams.ok) {
const data = await getSubteams.json();
// Treat entered slug as a team if found in the subteams fetched
if (data.slugs.includes(teamName)) {
// Rewriting towards /team/:slug to bring up the team profile within the org
url.pathname = `/team/${teamName}${eventType ?? ""}`;
return NextResponse.rewrite(url);
}
}
}
}
return NextResponse.next({
request: {
headers: requestHeaders,
@@ -79,6 +112,7 @@ const middleware: NextMiddleware = async (req) => {
export const config = {
matcher: [
"/:path*",
"/api/collect-events/:path*",
"/api/auth/:path*",
"/apps/routing_forms/:path*",
+90 -16
View File
@@ -183,7 +183,17 @@ const nextConfig = {
return config;
},
async rewrites() {
return [
// .* matches / as well(Note: *(i.e wildcard) doesn't match / but .*(i.e. RegExp) does)
// It would match /free/30min but not /bookings/upcoming because 'bookings' is an item in pages
// It would also not match /free/30min/embed because we are ensuring just two slashes
// ?!book ensures it doesn't match /free/book page which doesn't have a corresponding new-booker page.
// [^/]+ makes the RegExp match the full path, it seems like a partial match doesn't work.
const userTypeRouteRegExp = `/:user((?!${pages.join("|")})[^/]*)/:type((?!book)[^/]+)`;
let rewrites = [
{
source: "/org/:slug",
destination: "/team/:slug",
},
{
source: "/:user/avatar.png",
destination: "/api/user/avatar?username=:user",
@@ -215,26 +225,85 @@ const nextConfig = {
source: "/cancel/:path*",
destination: "/booking/:path*",
},
// Keep cookie based booker enabled just in case we disable new-booker globally
...[
{
source: userTypeRouteRegExp,
destination: "/new-booker/:user/:type",
has: [{ type: "cookie", key: "new-booker-enabled" }],
},
{
source: "/team/:slug/:type",
destination: "/new-booker/team/:slug/:type",
has: [{ type: "cookie", key: "new-booker-enabled" }],
},
{
source: "/d/:link/:slug",
destination: "/new-booker/d/:link/:slug",
has: [{ type: "cookie", key: "new-booker-enabled" }],
},
],
// Keep cookie based booker enabled to test new-booker embed in production
...[
{
source: `/:user((?!${pages.join("|")}).*)/:type/embed`,
destination: "/new-booker/:user/:type/embed",
has: [{ type: "cookie", key: "new-booker-enabled" }],
},
{
source: "/team/:slug/:type/embed",
destination: "/new-booker/team/:slug/:type/embed",
has: [{ type: "cookie", key: "new-booker-enabled" }],
},
],
/* TODO: have these files being served from another deployment or CDN {
source: "/embed/embed.js",
destination: process.env.NEXT_PUBLIC_EMBED_LIB_URL?,
}, */
{
source: `/:user((?!${pages.join("|")}).*)/:type`,
destination: "/new-booker/:user/:type",
has: [{ type: "cookie", key: "new-booker-enabled" }],
},
{
source: "/team/:slug/:type",
destination: "/new-booker/team/:slug/:type",
has: [{ type: "cookie", key: "new-booker-enabled" }],
},
{
source: "/d/:link/:slug",
destination: "/new-booker/d/:link/:slug",
has: [{ type: "cookie", key: "new-booker-enabled" }],
},
/**
* Enables new booker using cookie. It works even if NEW_BOOKER_ENABLED_FOR_NON_EMBED, NEW_BOOKER_ENABLED_FOR_EMBED are disabled
*/
];
// Enable New Booker for all Embed Requests
if (process.env.NEW_BOOKER_ENABLED_FOR_EMBED === "1") {
console.log("Enabling New Booker for Embed");
rewrites.push(
...[
{
source: `/:user((?!${pages.join("|")}).*)/:type/embed`,
destination: "/new-booker/:user/:type/embed",
},
{
source: "/team/:slug/:type/embed",
destination: "/new-booker/team/:slug/:type/embed",
},
]
);
}
// Enable New Booker for All but embed Requests
if (process.env.NEW_BOOKER_ENABLED_FOR_NON_EMBED === "1") {
console.log("Enabling New Booker for Non-Embed");
rewrites.push(
...[
{
source: userTypeRouteRegExp,
destination: "/new-booker/:user/:type",
},
{
source: "/team/:slug/:type",
destination: "/new-booker/team/:slug/:type",
},
{
source: "/d/:link/:slug",
destination: "/new-booker/d/:link/:slug",
},
]
);
}
return rewrites;
},
async headers() {
return [
@@ -293,6 +362,11 @@ const nextConfig = {
destination: "/teams",
permanent: true,
},
{
source: "/settings/admin",
destination: "/settings/admin/flags",
permanent: true,
},
/* V2 testers get redirected to the new settings */
{
source: "/settings/profile",
+4 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@calcom/web",
"version": "2.9.8",
"version": "3.0.3",
"private": true,
"scripts": {
"analyze": "ANALYZE=true next build",
@@ -61,6 +61,8 @@
"@tanstack/react-query": "^4.3.9",
"@tremor/react": "^2.0.0",
"@types/turndown": "^5.0.1",
"@upstash/ratelimit": "^0.4.3",
"@upstash/redis": "^1.21.0",
"@vercel/edge-config": "^0.1.1",
"@vercel/edge-functions-ui": "^0.2.1",
"@vercel/og": "^0.5.0",
@@ -86,7 +88,7 @@
"memory-cache": "^0.2.0",
"micro": "^10.0.1",
"mime-types": "^2.1.35",
"next": "^13.2.1",
"next": "^13.4.6",
"next-auth": "^4.20.1",
"next-axiom": "^0.16.0",
"next-collect": "^0.2.1",
+11 -1
View File
@@ -42,6 +42,10 @@ export default function Custom404() {
const isSubpage = router.asPath.includes("/", 2) || isSuccessPage;
const isSignup = router.asPath.startsWith("/signup");
const isCalcom = process.env.NEXT_PUBLIC_WEBAPP_URL === "https://app.cal.com";
// In case of invalid email verification token, we intentionally redirect to 404 from the API
const isInvalidToken = router.asPath === "/404";
/**
* If we're on 404 and the route is insights it means it is disabled
* TODO: Abstract this for all disabled features
@@ -200,12 +204,18 @@ export default function Custom404() {
{t("error_404")}
</p>
<h1 className="font-cal text-emphasis mt-2 text-4xl font-extrabold sm:text-5xl">
{isSuccessPage ? "Booking not found" : t("page_doesnt_exist")}
{isSuccessPage
? t("booking_not_found")
: isInvalidToken
? t("invalid_verification_link")
: t("page_doesnt_exist")}
</h1>
{isSubpage ? (
<span className="mt-2 inline-block text-lg ">
{t("check_spelling_mistakes_or_go_back")}
</span>
) : isInvalidToken ? (
<span className="mt-2 inline-block text-lg">{t("token_invalid_expired")}</span>
) : isCalcom ? (
<a target="_blank" href={url} className="mt-2 inline-block text-lg" rel="noreferrer">
{t("the_username")}{" "}
+9 -1
View File
@@ -10,6 +10,7 @@ import {
useEmbedStyles,
useIsEmbed,
} from "@calcom/embed-core/embed-iframe";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import { EventTypeDescriptionLazy as EventTypeDescription } from "@calcom/features/eventtypes/components";
import EmptyPage from "@calcom/features/eventtypes/components/EmptyPage";
import { WEBAPP_URL } from "@calcom/lib/constants";
@@ -255,6 +256,7 @@ const getEventTypesWithHiddenFromDB = async (userId: number) => {
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const ssr = await ssrInit(context);
const crypto = await import("crypto");
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(context.req.headers.host ?? "");
const usernameList = getUsernameList(context.query.user as string);
const dataFetchStart = Date.now();
@@ -263,6 +265,11 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
username: {
in: usernameList,
},
organization: isValidOrgDomain
? {
slug: currentOrgDomain,
}
: null,
},
select: {
id: true,
@@ -272,6 +279,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
bio: true,
brandColor: true,
darkBrandColor: true,
organizationId: true,
theme: true,
away: true,
verified: true,
@@ -284,7 +292,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
avatar: `${WEBAPP_URL}/${user.username}/avatar.png`,
}));
if (!users.length) {
if (!users.length || (!isValidOrgDomain && !users.some((user) => user.organizationId === null))) {
return {
notFound: true,
} as {
+56 -22
View File
@@ -1,8 +1,10 @@
import type { GetStaticPaths, GetStaticPropsContext } from "next";
import type { GetServerSidePropsContext } from "next";
import { z } from "zod";
import type { LocationObject } from "@calcom/app-store/locations";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import { IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants";
import { getUsernameList } from "@calcom/lib/defaultEvents";
import hasKeyInMetadata from "@calcom/lib/hasKeyInMetadata";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { markdownToSafeHTML } from "@calcom/lib/markdownToSafeHTML";
@@ -15,7 +17,9 @@ import type { EmbedProps } from "@lib/withEmbedSsr";
import PageWrapper from "@components/PageWrapper";
import AvailabilityPage from "@components/booking/pages/AvailabilityPage";
export type AvailabilityPageProps = inferSSRProps<typeof getStaticProps> & EmbedProps;
import { ssrInit } from "@server/lib/ssr";
export type AvailabilityPageProps = inferSSRProps<typeof getServerSideProps> & EmbedProps;
export default function Type(props: AvailabilityPageProps) {
const { t } = useLocale();
@@ -50,6 +54,21 @@ export default function Type(props: AvailabilityPageProps) {
</div>
</main>
</div>
) : !props.isValidOrgDomain && props.organizationContext ? (
<div className="dark:bg-darkgray-50 h-screen">
<main className="mx-auto max-w-3xl px-4 py-24">
<div className="space-y-6" data-testid="event-types">
<div className="overflow-hidden rounded-sm border dark:border-gray-900">
<div className="text-muted dark:text-inverted p-8 text-center">
<h2 className="font-cal dark:text-inverted text-emphasis600 mb-2 text-3xl">
{" " + t("unavailable")}
</h2>
<p className="mx-auto max-w-md">{t("user_belongs_organization")}</p>
</div>
</div>
</div>
</main>
</div>
) : (
<AvailabilityPage {...props} />
);
@@ -59,21 +78,25 @@ Type.isBookingPage = true;
Type.PageWrapper = PageWrapper;
const paramsSchema = z.object({ type: z.string(), user: z.string() });
async function getUserPageProps(context: GetStaticPropsContext) {
async function getUserPageProps(context: GetServerSidePropsContext) {
// load server side dependencies
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
const { privacyFilteredLocations } = await import("@calcom/app-store/locations");
const { parseRecurringEvent } = await import("@calcom/lib/isRecurringEvent");
const { EventTypeMetaDataSchema, teamMetadataSchema } = await import("@calcom/prisma/zod-utils");
const { ssgInit } = await import("@server/lib/ssg");
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(context.req.headers.host ?? "");
const ssr = await ssrInit(context);
const { type: slug, user: username } = paramsSchema.parse(context.query);
const { type: slug, user: username } = paramsSchema.parse(context.params);
const ssg = await ssgInit(context);
const user = await prisma.user.findUnique({
const user = await prisma.user.findFirst({
where: {
/** TODO: We should standarize this */
username: username.toLowerCase().replace(/( |%20)/g, "+"),
organization: isValidOrgDomain
? {
slug: currentOrgDomain,
}
: null,
},
select: {
id: true,
@@ -87,6 +110,7 @@ async function getUserPageProps(context: GetStaticPropsContext) {
brandColor: true,
darkBrandColor: true,
metadata: true,
organizationId: true,
eventTypes: {
where: {
// Many-to-many relationship causes inclusion of the team events - cool -
@@ -108,6 +132,17 @@ async function getUserPageProps(context: GetStaticPropsContext) {
schedulingType: true,
metadata: true,
seatsPerTimeSlot: true,
team: {
select: {
logo: true,
parent: {
select: {
logo: true,
name: true,
},
},
},
},
},
orderBy: [
{
@@ -179,16 +214,17 @@ async function getUserPageProps(context: GetStaticPropsContext) {
},
// Dynamic group has no theme preference right now. It uses system theme.
themeBasis: user.username,
organizationContext: user?.organizationId !== null,
away: user?.away,
isDynamic: false,
trpcState: ssg.dehydrate(),
trpcState: ssr.dehydrate(),
isValidOrgDomain: orgDomainConfig(context.req.headers.host ?? ""),
isBrandingHidden: isBrandingHidden(user.hideBranding, hasActiveTeam || hasPremiumUserName),
},
revalidate: 10, // seconds
};
}
async function getDynamicGroupPageProps(context: GetStaticPropsContext) {
async function getDynamicGroupPageProps(context: GetServerSidePropsContext) {
// load server side dependencies
const { getDefaultEvent, getGroupName, getUsernameList } = await import("@calcom/lib/defaultEvents");
const { privacyFilteredLocations } = await import("@calcom/app-store/locations");
@@ -197,10 +233,10 @@ async function getDynamicGroupPageProps(context: GetStaticPropsContext) {
const { EventTypeMetaDataSchema, userMetadata: userMetadataSchema } = await import(
"@calcom/prisma/zod-utils"
);
const { ssgInit } = await import("@server/lib/ssg");
const ssr = await ssrInit(context);
const { getAppFromSlug } = await import("@calcom/app-store/utils");
const ssg = await ssgInit(context);
const { type: typeParam, user: userParam } = paramsSchema.parse(context.params);
const usernameList = getUsernameList(userParam);
const length = parseInt(typeParam);
@@ -230,6 +266,7 @@ async function getDynamicGroupPageProps(context: GetStaticPropsContext) {
defaultScheduleId: true,
allowDynamicBooking: true,
metadata: true,
organizationId: true,
away: true,
schedules: {
select: {
@@ -313,24 +350,21 @@ async function getDynamicGroupPageProps(context: GetStaticPropsContext) {
themeBasis: null,
isDynamic: true,
away: false,
trpcState: ssg.dehydrate(),
organizationContext: !users.some((user) => user.organizationId === null),
trpcState: ssr.dehydrate(),
isValidOrgDomain: orgDomainConfig(context.req.headers.host ?? ""),
isBrandingHidden: false, // I think we should always show branding for dynamic groups - saves us checking every single user
},
revalidate: 10, // seconds
};
}
export const getStaticProps = async (context: GetStaticPropsContext) => {
export async function getServerSideProps(context: GetServerSidePropsContext) {
const { user: userParam } = paramsSchema.parse(context.params);
// dynamic groups are not generated at build time, but otherwise are probably cached until infinity.
const isDynamicGroup = userParam.includes("+");
const isDynamicGroup = getUsernameList(userParam).length > 1;
if (isDynamicGroup) {
return await getDynamicGroupPageProps(context);
} else {
return await getUserPageProps(context);
}
};
export const getStaticPaths: GetStaticPaths = async () => {
return { paths: [], fallback: "blocking" };
};
}
+8 -10
View File
@@ -1,20 +1,18 @@
import type { GetStaticPropsContext } from "next";
import type { GetServerSidePropsContext } from "next";
import { getStaticProps as _getStaticProps } from "../[type]";
export { getStaticPaths } from "../[type]";
import { getServerSideProps as _getServerSideProps } from "../[type]";
export { default } from "../[type]";
export const getStaticProps = async (context: GetStaticPropsContext) => {
const staticResponse = await _getStaticProps(context);
if (staticResponse.notFound) {
return staticResponse;
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const ssrResponse = await _getServerSideProps(context);
if (ssrResponse.notFound) {
return ssrResponse;
}
return {
...staticResponse,
...ssrResponse,
props: {
...staticResponse.props,
...ssrResponse.props,
isEmbed: true,
},
};
@@ -0,0 +1 @@
export { getStaticProps, getStaticPaths, default } from "./index";
@@ -16,7 +16,7 @@ export const getStaticProps: GetStaticProps<
{ user: string }
> = async (context) => {
const { user: username, month } = paramsSchema.parse(context.params);
const userWithCredentials = await prisma.user.findUnique({
const userWithCredentials = await prisma.user.findFirst({
where: {
username,
},
-4
View File
@@ -48,10 +48,6 @@ class MyDocument extends Document<Props> {
<meta name="msapplication-TileColor" content="#ff0000" />
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#f9fafb" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1C1C1C" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
/>
</Head>
<body
+9 -9
View File
@@ -5,15 +5,12 @@ import { z } from "zod";
import dayjs from "@calcom/dayjs";
import { sendPasswordResetEmail } from "@calcom/emails";
import { PASSWORD_RESET_EXPIRY_HOURS } from "@calcom/emails/templates/forgot-password-email";
import rateLimit from "@calcom/lib/rateLimit";
import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
import rateLimiter from "@calcom/lib/rateLimit";
import { defaultHandler } from "@calcom/lib/server";
import { getTranslation } from "@calcom/lib/server/i18n";
import prisma from "@calcom/prisma";
const limiter = rateLimit({
intervalInMs: 60 * 1000, // 1 minute
});
async function handler(req: NextApiRequest, res: NextApiResponse) {
const t = await getTranslation(req.body.language ?? "en", "common");
@@ -37,10 +34,13 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
// 10 requests per minute
try {
limiter.check(10, ip);
} catch (e) {
return res.status(429).json({ message: "Too Many Requests." });
const limiter = await rateLimiter();
const limit = await limiter({
identifier: ip,
});
if (!limit.success) {
throw new Error(ErrorCode.RateLimitExceeded);
}
try {
+2 -2
View File
@@ -19,11 +19,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
});
if (!foundToken) {
return res.status(401).json({ message: "No token found" });
return res.redirect(`${WEBAPP_URL}/404`);
}
if (dayjs(foundToken?.expires).isBefore(dayjs())) {
return res.status(401).json({ message: "Token expired" });
return res.redirect(`${WEBAPP_URL}/404`);
}
const user = await prisma.user.update({
+14 -6
View File
@@ -1,4 +1,5 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { z } from "zod";
import { getCalendarCredentials, getConnectedCalendars } from "@calcom/core/CalendarManager";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
@@ -6,6 +7,11 @@ import notEmpty from "@calcom/lib/notEmpty";
import { revalidateCalendarCache } from "@calcom/lib/server/revalidateCalendarCache";
import prisma from "@calcom/prisma";
const selectedCalendarSelectSchema = z.object({
integration: z.string(),
externalId: z.string(),
});
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const session = await getServerSession({ req, res });
@@ -32,18 +38,19 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
const { credentials, ...user } = userWithCredentials;
if (req.method === "POST") {
const { integration, externalId } = selectedCalendarSelectSchema.parse(req.body);
await prisma.selectedCalendar.upsert({
where: {
userId_integration_externalId: {
userId: user.id,
integration: req.body.integration,
externalId: req.body.externalId,
integration,
externalId,
},
},
create: {
userId: user.id,
integration: req.body.integration,
externalId: req.body.externalId,
integration,
externalId,
},
// already exists
update: {},
@@ -52,12 +59,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
}
if (req.method === "DELETE") {
const { integration, externalId } = selectedCalendarSelectSchema.parse(req.query);
await prisma.selectedCalendar.delete({
where: {
userId_integration_externalId: {
userId: user.id,
externalId: req.body.externalId,
integration: req.body.integration,
externalId,
integration,
},
},
});
+16 -2
View File
@@ -4,6 +4,7 @@ import { z } from "zod";
import { symmetricDecrypt } from "@calcom/lib/crypto";
import { defaultResponder } from "@calcom/lib/server";
import prisma from "@calcom/prisma";
import { UserPermissionRole } from "@calcom/prisma/enums";
import { TRPCError } from "@calcom/trpc/server";
import { createContext } from "@calcom/trpc/server/createContext";
import { viewerRouter } from "@calcom/trpc/server/routers/viewer/_router";
@@ -38,9 +39,22 @@ async function handler(req: NextApiRequest, res: NextApiResponse<Response>) {
where: { id: userId },
});
/** We shape the session as required by tRPC router */
async function sessionGetter() {
return {
user: {
id: userId,
username: "" /* Not used in this context */,
role: UserPermissionRole.USER,
},
hasValidLicense: true,
expires: "" /* Not used in this context */,
};
}
try {
/** @see https://trpc.io/docs/server-side-calls */
const ctx = await createContext({ req, res });
const ctx = await createContext({ req, res }, sessionGetter);
const caller = viewerRouter.createCaller({
...ctx,
req,
@@ -55,7 +69,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse<Response>) {
});
} catch (e) {
let message = "Error confirming booking";
if (e instanceof TRPCError) message = e.message;
if (e instanceof TRPCError) message = (e as TRPCError).message;
res.redirect(`/booking/${bookingUid}?error=${encodeURIComponent(message)}`);
return;
}
+11 -3
View File
@@ -1,6 +1,7 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { z } from "zod";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import {
ANDROID_CHROME_ICON_192,
ANDROID_CHROME_ICON_256,
@@ -104,7 +105,7 @@ function isValidLogoType(type: string): type is LogoType {
return type in logoDefinitions;
}
async function getTeamLogos(subdomain: string) {
async function getTeamLogos(subdomain: string, isValidOrgDomain: boolean) {
try {
if (
// if not cal.com
@@ -118,9 +119,15 @@ async function getTeamLogos(subdomain: string) {
}
// load from DB
const { default: prisma } = await import("@calcom/prisma");
const team = await prisma.team.findUnique({
const team = await prisma.team.findFirst({
where: {
slug: subdomain,
...(isValidOrgDomain && {
metadata: {
path: ["isOrganization"],
equals: true,
},
}),
},
select: {
appLogo: true,
@@ -147,6 +154,7 @@ async function getTeamLogos(subdomain: string) {
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { query } = req;
const parsedQuery = logoApiSchema.parse(query);
const { isValidOrgDomain } = orgDomainConfig(req.headers.host ?? "");
const hostname = req?.headers["host"];
if (!hostname) throw new Error("No hostname");
@@ -154,7 +162,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (!domains) throw new Error("No domains");
const [subdomain] = domains;
const teamLogos = await getTeamLogos(subdomain);
const teamLogos = await getTeamLogos(subdomain, isValidOrgDomain);
// Resolve all icon types to team logos, falling back to Cal.com defaults.
const type: LogoType = parsedQuery?.type && isValidLogoType(parsedQuery.type) ? parsedQuery.type : "logo";
@@ -0,0 +1 @@
export { default } from "@calcom/features/ee/organizations/api/subteams";
@@ -0,0 +1,4 @@
import { createNextApiHandler } from "@calcom/trpc/server/createNextApiHandler";
import { viewerOrganizationsRouter } from "@calcom/trpc/server/routers/viewer/organizations/_router";
export default createNextApiHandler(viewerOrganizationsRouter);
+20 -4
View File
@@ -2,6 +2,7 @@ import crypto from "crypto";
import type { NextApiRequest, NextApiResponse } from "next";
import { z } from "zod";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
import prisma from "@calcom/prisma";
@@ -16,10 +17,18 @@ const querySchema = z
async function getIdentityData(req: NextApiRequest) {
const { username, teamname } = querySchema.parse(req.query);
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(req.headers.host ?? "");
if (username) {
const user = await prisma.user.findUnique({
where: { username },
const user = await prisma.user.findFirst({
where: {
username,
organization: isValidOrgDomain
? {
slug: currentOrgDomain,
}
: null,
},
select: { avatar: true, email: true },
});
return {
@@ -29,8 +38,15 @@ async function getIdentityData(req: NextApiRequest) {
};
}
if (teamname) {
const team = await prisma.team.findUnique({
where: { slug: teamname },
const team = await prisma.team.findFirst({
where: {
slug: teamname,
parent: isValidOrgDomain
? {
slug: currentOrgDomain,
}
: null,
},
select: { logo: true },
});
return {
+3 -1
View File
@@ -1,5 +1,6 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import { checkUsername } from "@calcom/lib/server/checkUsername";
type Response = {
@@ -8,6 +9,7 @@ type Response = {
};
export default async function handler(req: NextApiRequest, res: NextApiResponse<Response>): Promise<void> {
const result = await checkUsername(req.body.username);
const { currentOrgDomain } = orgDomainConfig(req.headers.host ?? "");
const result = await checkUsername(req.body.username, currentOrgDomain);
return res.status(200).json(result);
}
+3 -1
View File
@@ -5,6 +5,7 @@ import { useEffect } from "react";
import { getPremiumMonthlyPlanPriceId } from "@calcom/app-store/stripepayment/lib/utils";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import stripe from "@calcom/features/ee/payments/server/stripe";
import {
hostedCal,
@@ -68,11 +69,12 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
const session = await getServerSession({ req, res });
const ssr = await ssrInit(context);
const { currentOrgDomain } = orgDomainConfig(context.req.headers.host ?? "");
if (session) {
// Validating if username is Premium, while this is true an email its required for stripe user confirmation
if (usernameParam && session.user.email) {
const availability = await checkUsername(usernameParam);
const availability = await checkUsername(usernameParam, currentOrgDomain);
if (availability.available && availability.premium) {
const stripePremiumUrl = await getStripePremiumUsernameUrl({
userEmail: session.user.email,
+1 -1
View File
@@ -394,7 +394,7 @@ export default function Success(props: SuccessProps) {
{(isCancelled || reschedule) && cancellationReason && (
<>
<div className="font-medium">
{isCancelled ? t("reason") : t("reschedule_reason_success_page")}
{isCancelled ? t("reason") : t("reschedule_reason")}
</div>
<div className="col-span-2 mb-6 last:mb-0">{cancellationReason}</div>
</>
+2 -2
View File
@@ -22,7 +22,7 @@ import SkeletonLoader from "@components/booking/SkeletonLoader";
import { ssgInit } from "@server/lib/ssg";
type BookingListingStatus = z.infer<typeof filterQuerySchema>["status"];
type BookingListingStatus = z.infer<NonNullable<typeof filterQuerySchema>>["status"];
type BookingOutput = RouterOutputs["viewer"]["bookings"]["get"]["bookings"][0];
type RecurringInfo = {
@@ -34,7 +34,7 @@ type RecurringInfo = {
const validStatuses = ["upcoming", "recurring", "past", "cancelled", "unconfirmed"] as const;
const descriptionByStatus: Record<BookingListingStatus, string> = {
const descriptionByStatus: Record<NonNullable<BookingListingStatus>, string> = {
upcoming: "upcoming_bookings",
recurring: "recurring_bookings",
past: "past_bookings",
+69 -2
View File
@@ -7,10 +7,13 @@ import type { FC } from "react";
import { useEffect, useState, memo } from "react";
import { z } from "zod";
import { useOrgBrandingValues } from "@calcom/features/ee/organizations/hooks";
import { subdomainSuffix } from "@calcom/features/ee/organizations/lib/orgDomains";
import useIntercom from "@calcom/features/ee/support/lib/intercom/useIntercom";
import { EventTypeDescriptionLazy as EventTypeDescription } from "@calcom/features/eventtypes/components";
import CreateEventTypeDialog from "@calcom/features/eventtypes/components/CreateEventTypeDialog";
import { DuplicateDialog } from "@calcom/features/eventtypes/components/DuplicateDialog";
import { OrganizationEventTypeFilter } from "@calcom/features/eventtypes/components/OrganizationEventTypeFilter";
import Shell from "@calcom/features/shell/Shell";
import { APP_NAME, CAL_URL, WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -44,6 +47,8 @@ import {
HeadSeo,
Skeleton,
Label,
VerticalDivider,
Alert,
} from "@calcom/ui";
import {
ArrowDown,
@@ -59,9 +64,11 @@ import {
Trash,
Upload,
Users,
User as UserIcon,
} from "@calcom/ui/components/icon";
import { withQuery } from "@lib/QueryCell";
import useMeQuery from "@lib/hooks/useMeQuery";
import { EmbedButton, EmbedDialog } from "@components/Embed";
import PageWrapper from "@components/PageWrapper";
@@ -74,6 +81,7 @@ interface EventTypeListHeadingProps {
profile: EventTypeGroupProfile;
membershipCount: number;
teamId?: number | null;
orgSlug?: string;
}
type EventTypeGroup = EventTypeGroups[number];
@@ -194,6 +202,7 @@ const MemoizedItem = memo(Item);
export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeListProps): JSX.Element => {
const { t } = useLocale();
const router = useRouter();
const orgBranding = useOrgBrandingValues();
const [parent] = useAutoAnimate<HTMLUListElement>();
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
const [deleteDialogTypeId, setDeleteDialogTypeId] = useState(0);
@@ -362,7 +371,9 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
<ul ref={parent} className="divide-subtle !static w-full divide-y" data-testid="event-types">
{types.map((type, index) => {
const embedLink = `${group.profile.slug}/${type.slug}`;
const calLink = `${CAL_URL}/${embedLink}`;
const calLink = `${
orgBranding ? `${new URL(CAL_URL).protocol}//${orgBranding.slug}.${subdomainSuffix()}` : CAL_URL
}/${embedLink}`;
const isManagedEventType = type.schedulingType === SchedulingType.MANAGED;
const isChildrenManagedEventType =
type.metadata?.managedEventConfig !== undefined && type.schedulingType !== SchedulingType.MANAGED;
@@ -687,6 +698,7 @@ const EventTypeListHeading = ({
profile,
membershipCount,
teamId,
orgSlug,
}: EventTypeListHeadingProps): JSX.Element => {
const { t } = useLocale();
const router = useRouter();
@@ -727,7 +739,9 @@ const EventTypeListHeading = ({
)}
{profile?.slug && (
<Link href={`${CAL_URL}/${profile.slug}`} className="text-subtle block text-xs">
{`${CAL_URL?.replace("https://", "")}/${profile.slug}`}
{orgSlug
? `${orgSlug}.${subdomainSuffix()}/${profile.slug}`
: `${CAL_URL?.replace("https://", "")}/${profile.slug}`}
</Link>
)}
</div>
@@ -775,6 +789,7 @@ const CTA = () => {
return (
<CreateButton
data-testid="new-event-type"
subtitle={t("create_event_on").toUpperCase()}
options={profileOptions}
createDialog={() => <CreateEventTypeDialog profileOptions={profileOptions} />}
@@ -782,6 +797,43 @@ const CTA = () => {
);
};
const Actions = () => {
return (
<div className="hidden items-center md:flex">
<OrganizationEventTypeFilter />
<VerticalDivider />
</div>
);
};
const SetupProfileBanner = ({ closeAction }: { closeAction: () => void }) => {
const { t } = useLocale();
const orgBranding = useOrgBrandingValues();
return (
<Alert
className="my-4"
severity="info"
title={t("set_up_your_profile")}
message={t("set_up_your_profile_description", { orgName: orgBranding?.name })}
CustomIcon={UserIcon}
actions={
<div className="flex gap-1">
<Button color="minimal" className="text-sky-700 hover:bg-sky-100" onClick={closeAction}>
{t("dismiss")}
</Button>
<Button
color="secondary"
className="border-sky-700 bg-sky-50 text-sky-700 hover:border-sky-900 hover:bg-sky-200"
href="/getting-started">
{t("set_up")}
</Button>
</div>
}
/>
);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const WithQuery = withQuery(trpc.viewer.eventTypes.getByViewer as any);
@@ -790,12 +842,24 @@ const EventTypesPage = () => {
const router = useRouter();
const { open } = useIntercom();
const { query } = router;
const { data: user } = useMeQuery();
const isMobile = useMediaQuery("(max-width: 768px)");
const [showProfileBanner, setShowProfileBanner] = useState(false);
const orgBranding = useOrgBrandingValues();
function closeBanner() {
setShowProfileBanner(false);
document.cookie = `calcom-profile-banner=1;max-age=${60 * 60 * 24 * 90}`; // 3 months
showToast(t("we_wont_show_again"), "success");
}
useEffect(() => {
if (query?.openIntercom && query?.openIntercom === "true") {
open();
}
setShowProfileBanner(
!!orgBranding && !document.cookie.includes("calcom-profile-banner=1") && !user?.completedOnboarding
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
@@ -810,6 +874,8 @@ const EventTypesPage = () => {
heading={t("event_types_page_title")}
hideHeadingOnMobile
subtitle={t("event_types_page_subtitle")}
afterHeading={showProfileBanner && <SetupProfileBanner closeAction={closeBanner} />}
beforeCTAactions={<Actions />}
CTA={<CTA />}>
<WithQuery
customLoader={<SkeletonLoader />}
@@ -826,6 +892,7 @@ const EventTypesPage = () => {
profile={group.profile}
membershipCount={group.metadata.membershipCount}
teamId={group.teamId}
orgSlug={orgBranding?.slug}
/>
<EventTypeList
+23 -35
View File
@@ -3,15 +3,16 @@ import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import Head from "next/head";
import { useRouter } from "next/router";
import type { CSSProperties } from "react";
import { Suspense } from "react";
import { z } from "zod";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { APP_NAME } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import prisma from "@calcom/prisma";
import { trpc } from "@calcom/trpc";
import { Button, StepCard, Steps } from "@calcom/ui";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
import { Loader } from "@calcom/ui/components/icon";
import PageWrapper from "@components/PageWrapper";
import { ConnectedCalendars } from "@components/getting-started/steps-views/ConnectCalendars";
@@ -20,7 +21,7 @@ import { SetupAvailability } from "@components/getting-started/steps-views/Setup
import UserProfile from "@components/getting-started/steps-views/UserProfile";
import { UserSettings } from "@components/getting-started/steps-views/UserSettings";
export type IOnboardingPageProps = inferSSRProps<typeof getServerSideProps>;
import { ssrInit } from "@server/lib/ssr";
const INITIAL_STEP = "user-settings";
const steps = [
@@ -44,9 +45,9 @@ const stepRouteSchema = z.object({
});
// TODO: Refactor how steps work to be contained in one array/object. Currently we have steps,initalsteps,headers etc. These can all be in one place
const OnboardingPage = (props: IOnboardingPageProps) => {
const OnboardingPage = () => {
const router = useRouter();
const { user } = props;
const [user] = trpc.viewer.me.useSuspenseQuery();
const { t } = useLocale();
const result = stepRouteSchema.safeParse(router.query);
@@ -139,17 +140,20 @@ const OnboardingPage = (props: IOnboardingPageProps) => {
<Steps maxSteps={steps.length} currentStep={currentStepIndex + 1} navigateToStep={goToIndex} />
</div>
<StepCard>
{currentStep === "user-settings" && <UserSettings user={user} nextStep={() => goToIndex(1)} />}
<Suspense fallback={<Loader />}>
{currentStep === "user-settings" && <UserSettings nextStep={() => goToIndex(1)} />}
{currentStep === "connected-calendar" && <ConnectedCalendars nextStep={() => goToIndex(2)} />}
{currentStep === "connected-calendar" && <ConnectedCalendars nextStep={() => goToIndex(2)} />}
{currentStep === "connected-video" && <ConnectedVideoStep nextStep={() => goToIndex(3)} />}
{currentStep === "connected-video" && <ConnectedVideoStep nextStep={() => goToIndex(3)} />}
{currentStep === "setup-availability" && (
<SetupAvailability nextStep={() => goToIndex(4)} defaultScheduleId={user.defaultScheduleId} />
)}
{currentStep === "user-profile" && <UserProfile user={user} />}
{currentStep === "setup-availability" && (
<SetupAvailability
nextStep={() => goToIndex(4)}
defaultScheduleId={user.defaultScheduleId}
/>
)}
{currentStep === "user-profile" && <UserProfile />}
</Suspense>
</StepCard>
{headers[currentStepIndex]?.skipText && (
@@ -176,34 +180,21 @@ const OnboardingPage = (props: IOnboardingPageProps) => {
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const { req, res } = context;
const crypto = await import("crypto");
const session = await getServerSession({ req, res });
if (!session?.user?.id) {
return { redirect: { permanent: false, destination: "/auth/login" } };
}
const ssr = await ssrInit(context);
await ssr.viewer.me.prefetch();
const user = await prisma.user.findUnique({
where: {
id: session.user.id,
},
select: {
id: true,
username: true,
name: true,
email: true,
bio: true,
avatar: true,
timeZone: true,
weekStart: true,
hideBranding: true,
theme: true,
brandColor: true,
darkBrandColor: true,
metadata: true,
timeFormat: true,
allowDynamicBooking: true,
defaultScheduleId: true,
completedOnboarding: true,
teams: {
select: {
@@ -231,10 +222,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
return {
props: {
...(await serverSideTranslations(context.locale ?? "", ["common"])),
user: {
...user,
emailMd5: crypto.createHash("md5").update(user.email).digest("hex"),
},
trpcState: ssr.dehydrate(),
hasPendingInvites: user.teams.find((team) => team.accepted === false) ?? false,
},
};
+16 -4
View File
@@ -5,6 +5,8 @@ import { Booker } from "@calcom/atoms";
import { BookerSeo } from "@calcom/features/bookings/components/BookerSeo";
import { getBookingByUidOrRescheduleUid } from "@calcom/features/bookings/lib/get-booking";
import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import { classNames } from "@calcom/lib";
import { getUsernameList } from "@calcom/lib/defaultEvents";
import prisma from "@calcom/prisma";
@@ -15,8 +17,9 @@ import PageWrapper from "@components/PageWrapper";
type PageProps = inferSSRProps<typeof getServerSideProps>;
export default function Type({ slug, user, booking, away, isBrandingHidden }: PageProps) {
const isEmbed = typeof window !== "undefined" && window?.isEmbed?.();
return (
<main className="flex h-full min-h-[100dvh] items-center justify-center">
<main className={classNames("flex h-full items-center justify-center", !isEmbed && "min-h-[100dvh]")}>
<BookerSeo
username={user}
eventSlug={slug}
@@ -84,6 +87,7 @@ async function getDynamicGroupPageProps(context: GetServerSidePropsContext) {
away: false,
trpcState: ssr.dehydrate(),
isBrandingHidden: false,
themeBasis: null,
},
};
}
@@ -91,12 +95,19 @@ async function getDynamicGroupPageProps(context: GetServerSidePropsContext) {
async function getUserPageProps(context: GetServerSidePropsContext) {
const { user: username, type: slug } = paramsSchema.parse(context.params);
const { rescheduleUid } = context.query;
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(context.req.headers.host ?? "");
const { ssrInit } = await import("@server/lib/ssr");
const ssr = await ssrInit(context);
const user = await prisma.user.findUnique({
const user = await prisma.user.findFirst({
where: {
username,
/** TODO: We should standarize this */
username: username.toLowerCase().replace(/( |%20)/g, "+"),
organization: isValidOrgDomain
? {
slug: currentOrgDomain,
}
: null,
},
select: {
away: true,
@@ -133,6 +144,7 @@ async function getUserPageProps(context: GetServerSidePropsContext) {
slug,
trpcState: ssr.dehydrate(),
isBrandingHidden: user?.hideBranding,
themeBasis: username,
},
};
}
@@ -143,7 +155,7 @@ const paramsSchema = z.object({ type: z.string(), user: z.string() });
// whether the page should show an away state or dynamic booking not allowed.
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const { user } = paramsSchema.parse(context.params);
const isDynamicGroup = user.includes("+");
const isDynamicGroup = getUsernameList(user).length > 1;
return isDynamicGroup ? await getDynamicGroupPageProps(context) : await getUserPageProps(context);
};
@@ -0,0 +1,11 @@
import withEmbedSsr from "@lib/withEmbedSsr";
import { getServerSideProps as _getServerSideProps } from "../[type]";
export { default } from "../[type]";
// Somehow these types don't accept the {notFound: true} return type.
// Probably still need to fix this. I don't know why this isn't allowed yet.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
export const getServerSideProps = withEmbedSsr(_getServerSideProps);
@@ -0,0 +1,7 @@
import withEmbedSsr from "@lib/withEmbedSsr";
import { getServerSideProps as _getServerSideProps } from "../../[user]";
export { default } from "../../[user]";
export const getServerSideProps = withEmbedSsr(_getServerSideProps);
@@ -5,6 +5,7 @@ import { Booker } from "@calcom/atoms";
import { BookerSeo } from "@calcom/features/bookings/components/BookerSeo";
import { getBookingByUidOrRescheduleUid } from "@calcom/features/bookings/lib/get-booking";
import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import prisma from "@calcom/prisma";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
@@ -38,6 +39,7 @@ Type.PageWrapper = PageWrapper;
async function getUserPageProps(context: GetServerSidePropsContext) {
const { link, slug } = paramsSchema.parse(context.params);
const { rescheduleUid } = context.query;
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(context.req.headers.host ?? "");
const { ssrInit } = await import("@server/lib/ssr");
const ssr = await ssrInit(context);
@@ -68,9 +70,14 @@ async function getUserPageProps(context: GetServerSidePropsContext) {
};
}
const user = await prisma.user.findUnique({
const user = await prisma.user.findFirst({
where: {
username,
organization: isValidOrgDomain
? {
slug: currentOrgDomain,
}
: null,
},
select: {
away: true,
@@ -5,6 +5,7 @@ import { Booker } from "@calcom/atoms";
import { BookerSeo } from "@calcom/features/bookings/components/BookerSeo";
import { getBookingByUidOrRescheduleUid } from "@calcom/features/bookings/lib/get-booking";
import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking";
import { classNames } from "@calcom/lib";
import prisma from "@calcom/prisma";
import type { inferSSRProps } from "@lib/types/inferSSRProps";
@@ -14,8 +15,9 @@ import PageWrapper from "@components/PageWrapper";
type PageProps = inferSSRProps<typeof getServerSideProps>;
export default function Type({ slug, user, booking, away, isBrandingHidden }: PageProps) {
const isEmbed = typeof window !== "undefined" && window?.isEmbed?.();
return (
<main className="flex h-full min-h-[100dvh] items-center justify-center">
<main className={classNames("flex h-full items-center justify-center", !isEmbed && "min-h-[100dvh]")}>
<BookerSeo
username={user}
eventSlug={slug}
@@ -85,6 +87,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
slug: meetingSlug,
trpcState: ssr.dehydrate(),
isBrandingHidden: team?.hideBranding,
themeBasis: null,
},
};
};
@@ -0,0 +1,9 @@
import withEmbedSsr from "@lib/withEmbedSsr";
import { getServerSideProps as _getServerSideProps } from "../[type]";
export { default } from "../[type]";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
export const getServerSideProps = withEmbedSsr(_getServerSideProps);
@@ -0,0 +1,7 @@
import withEmbedSsr from "@lib/withEmbedSsr";
import { getServerSideProps as _getServerSideProps } from "../../../team/[slug]";
export { default } from "../../../team/[slug]";
export const getServerSideProps = withEmbedSsr(_getServerSideProps);
@@ -263,7 +263,8 @@ const AppearanceView = () => {
type="submit"
loading={mutation.isLoading}
color="primary"
className="mt-8">
className="mt-8"
data-testid="update-theme-btn">
{t("update")}
</Button>
</Form>
@@ -50,7 +50,7 @@ const SkeletonLoader = ({ title, description }: { title: string; description: st
<Meta title={title} description={description} />
<div className="mt-6 mb-8 space-y-6">
<div className="flex items-center">
<SkeletonAvatar className="h-12 w-12 px-4" />
<SkeletonAvatar className="me-4 h-16 w-16 px-4" />
<SkeletonButton className="h-6 w-32 rounded-md p-5" />
</div>
<SkeletonText className="h-8 w-full" />
@@ -215,7 +215,6 @@ const ProfileView = () => {
extraField={
<div className="mt-8">
<UsernameAvailabilityField
user={user}
onSuccessMutation={async () => {
showToast(t("settings_updated_successfully"), "success");
await utils.viewer.me.invalidate();
@@ -0,0 +1,31 @@
import { useRouter } from "next/router";
import { AboutOrganizationForm } from "@calcom/features/ee/organizations/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { WizardLayout, Meta } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
const AboutOrganizationPage = () => {
const { t } = useLocale();
const router = useRouter();
if (!router.isReady) return null;
return (
<>
<Meta title={t("about_your_organization")} description={t("about_your_organization_description")} />
<AboutOrganizationForm />
</>
);
};
const LayoutWrapper = (page: React.ReactElement) => {
return (
<WizardLayout currentStep={3} maxSteps={5}>
{page}
</WizardLayout>
);
};
AboutOrganizationPage.getLayout = LayoutWrapper;
AboutOrganizationPage.PageWrapper = PageWrapper;
export default AboutOrganizationPage;
@@ -0,0 +1,37 @@
import type { NextRouter } from "next/router";
import { useRouter } from "next/router";
import { AddNewTeamsForm } from "@calcom/features/ee/organizations/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { WizardLayout, Meta } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
const AddNewTeamsPage = () => {
const { t } = useLocale();
const router = useRouter();
if (!router.isReady) return null;
return (
<>
<Meta title={t("create_your_teams")} description={t("create_your_teams_description")} />
<AddNewTeamsForm />
</>
);
};
AddNewTeamsPage.getLayout = (page: React.ReactElement, router: NextRouter) => (
<>
<WizardLayout
currentStep={5}
maxSteps={5}
isOptionalCallback={() => {
router.push(`/event-types`);
}}>
{page}
</WizardLayout>
</>
);
AddNewTeamsPage.PageWrapper = PageWrapper;
export default AddNewTeamsPage;
@@ -0,0 +1,38 @@
import type { NextRouter } from "next/router";
import { useRouter } from "next/router";
import { AddNewOrgAdminsForm } from "@calcom/features/ee/organizations/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { WizardLayout, Meta } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
const OnboardTeamMembersPage = () => {
const { t } = useLocale();
const router = useRouter();
if (!router.isReady) return null;
return (
<>
<Meta
title={t("invite_organization_admins")}
description={t("invite_organization_admins_description")}
/>
<AddNewOrgAdminsForm />
</>
);
};
OnboardTeamMembersPage.getLayout = (page: React.ReactElement, router: NextRouter) => (
<WizardLayout
currentStep={4}
maxSteps={5}
isOptionalCallback={() => {
router.push(`/settings/organizations/${router.query.id}/add-teams`);
}}>
{page}
</WizardLayout>
);
OnboardTeamMembersPage.PageWrapper = PageWrapper;
export default OnboardTeamMembersPage;
@@ -0,0 +1,31 @@
import { useRouter } from "next/router";
import { SetPasswordForm } from "@calcom/features/ee/organizations/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { WizardLayout, Meta } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
const SetPasswordPage = () => {
const { t } = useLocale();
const router = useRouter();
if (!router.isReady) return null;
return (
<>
<Meta title={t("set_a_password")} description={t("set_a_password_description")} />
<SetPasswordForm />
</>
);
};
const LayoutWrapper = (page: React.ReactElement) => {
return (
<WizardLayout currentStep={2} maxSteps={5}>
{page}
</WizardLayout>
);
};
SetPasswordPage.getLayout = LayoutWrapper;
SetPasswordPage.PageWrapper = PageWrapper;
export default SetPasswordPage;
@@ -0,0 +1,9 @@
import OrgAppearanceView from "@calcom/features/ee/organizations/pages/settings/appearance";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = OrgAppearanceView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -0,0 +1,9 @@
import OrgGeneralView from "@calcom/features/ee/organizations/pages/settings/general";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = OrgGeneralView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -0,0 +1,9 @@
import MembersView from "@calcom/features/ee/organizations/pages/settings/members";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = MembersView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -0,0 +1,27 @@
import { CreateANewOrganizationForm } from "@calcom/features/ee/organizations/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { WizardLayout, Meta } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
const CreateNewOrganizationPage = () => {
const { t } = useLocale();
return (
<>
<Meta title={t("set_up_your_organization")} description={t("organizations_description")} />
<CreateANewOrganizationForm />
</>
);
};
const LayoutWrapper = (page: React.ReactElement) => {
return (
<WizardLayout currentStep={1} maxSteps={5}>
{page}
</WizardLayout>
);
};
CreateNewOrganizationPage.getLayout = LayoutWrapper;
CreateNewOrganizationPage.PageWrapper = PageWrapper;
export default CreateNewOrganizationPage;
@@ -0,0 +1,9 @@
import OrgProfileView from "@calcom/features/ee/organizations/pages/settings/profile";
import type { CalPageWrapper } from "@components/PageWrapper";
import PageWrapper from "@components/PageWrapper";
const Page = OrgProfileView as CalPageWrapper;
Page.PageWrapper = PageWrapper;
export default Page;
@@ -2,9 +2,9 @@ import Head from "next/head";
import AddNewTeamMembers from "@calcom/features/ee/teams/components/AddNewTeamMembers";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { WizardLayout } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import WizardLayout from "@components/layouts/WizardLayout";
const OnboardTeamMembersPage = () => {
const { t } = useLocale();
+1 -1
View File
@@ -2,9 +2,9 @@ import Head from "next/head";
import { CreateANewTeamForm } from "@calcom/features/ee/teams/components";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { WizardLayout } from "@calcom/ui";
import PageWrapper from "@components/PageWrapper";
import WizardLayout from "@components/layouts/WizardLayout";
const CreateNewTeamPage = () => {
const { t } = useLocale();
+122 -41
View File
@@ -5,8 +5,9 @@ import { useRouter } from "next/router";
import { useEffect } from "react";
import { sdkActionManager, useIsEmbed } from "@calcom/embed-core/embed-iframe";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import EventTypeDescription from "@calcom/features/eventtypes/components/EventTypeDescription";
import { CAL_URL } from "@calcom/lib/constants";
import { CAL_URL, WEBAPP_URL } from "@calcom/lib/constants";
import { getPlaceholderAvatar } from "@calcom/lib/defaultAvatarImage";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useTheme from "@calcom/lib/hooks/useTheme";
@@ -15,6 +16,7 @@ import { getTeamWithMembers } from "@calcom/lib/server/queries/teams";
import { stripMarkdown } from "@calcom/lib/stripMarkdown";
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import prisma from "@calcom/prisma";
import { teamMetadataSchema } from "@calcom/prisma/zod-utils";
import { Avatar, AvatarGroup, Button, EmptyScreen, HeadSeo } from "@calcom/ui";
import { ArrowRight } from "@calcom/ui/components/icon";
@@ -27,7 +29,7 @@ import Team from "@components/team/screens/Team";
import { ssrInit } from "@server/lib/ssr";
export type TeamPageProps = inferSSRProps<typeof getServerSideProps>;
function TeamPage({ team, isUnpublished, markdownStrippedBio }: TeamPageProps) {
function TeamPage({ team, isUnpublished, markdownStrippedBio, isValidOrgDomain }: TeamPageProps) {
useTheme(team.theme);
const showMembers = useToggleQuery("members");
const { t } = useLocale();
@@ -36,6 +38,7 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio }: TeamPageProps) {
const router = useRouter();
const teamName = team.name || "Nameless Team";
const isBioEmpty = !team.bio || !team.bio.replace("<p><br></p>", "").length;
const metadata = teamMetadataSchema.parse(team.metadata);
useEffect(() => {
telemetry.event(
@@ -49,8 +52,12 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio }: TeamPageProps) {
<div className="m-8 flex items-center justify-center">
<EmptyScreen
avatar={<Avatar alt={teamName} imageSrc={getPlaceholderAvatar(team.logo, team.name)} size="lg" />}
headline={t("team_is_unpublished", { team: teamName })}
description={t("team_is_unpublished_description")}
headline={t("team_is_unpublished", {
team: teamName,
})}
description={t("team_is_unpublished_description", {
entity: metadata?.isOrganization ? t("organization").toLowerCase() : t("team").toLowerCase(),
})}
/>
</div>
);
@@ -71,7 +78,7 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio }: TeamPageProps) {
<div className="px-6 py-4 ">
<Link
href={{
pathname: `/team/${team.slug}/${type.slug}`,
pathname: `${isValidOrgDomain ? "" : "/team"}/${team.slug}/${type.slug}`,
query: queryParamsToForward,
}}
onClick={async () => {
@@ -106,6 +113,53 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio }: TeamPageProps) {
</ul>
);
const SubTeams = () =>
team.children.length ? (
<ul className="divide-subtle border-subtle bg-default !static w-full divide-y rounded-md border">
{team.children.map((ch, i) => (
<li key={i} className="hover:bg-muted w-full">
<Link href={`/${ch.slug}`} className="flex items-center justify-between">
<div className="flex items-center px-5 py-5">
<Avatar
size="md"
imageSrc={getPlaceholderAvatar(ch?.logo, ch?.name as string)}
alt="Team Logo"
className="inline-flex justify-center"
/>
<div className="ms-3 inline-block truncate">
<span className="text-default text-sm font-bold">{ch.name}</span>
<span className="text-subtle block text-xs">
{t("number_member", { count: ch.members.length })}
</span>
</div>
</div>
<AvatarGroup
className="mr-6"
size="sm"
truncateAfter={4}
items={ch.members.map(({ user: member }) => ({
alt: member.name || "",
image: `${WEBAPP_URL}/${member.username}/avatar.png`,
title: member.name || "",
}))}
/>
</Link>
</li>
))}
</ul>
) : (
<div className="space-y-6" data-testid="event-types">
<div className="overflow-hidden rounded-sm border dark:border-gray-900">
<div className="text-muted dark:text-inverted p-8 text-center">
<h2 className="font-cal dark:text-inverted text-emphasis600 mb-2 text-3xl">
{" " + t("no_teams_yet")}
</h2>
<p className="mx-auto max-w-md">{t("no_teams_yet_description")}</p>
</div>
</div>
</div>
);
return (
<>
<HeadSeo
@@ -118,8 +172,17 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio }: TeamPageProps) {
/>
<main className="dark:bg-darkgray-50 bg-subtle mx-auto max-w-3xl rounded-md px-4 pt-12 pb-12">
<div className="mx-auto mb-8 max-w-3xl text-center">
<Avatar alt={teamName} imageSrc={getPlaceholderAvatar(team.logo, team.name)} size="lg" />
<p className="font-cal text-emphasis mb-2 text-2xl tracking-wider">{teamName}</p>
<div className="relative">
<Avatar
alt={teamName}
imageSrc={getPlaceholderAvatar(team.parent ? team.parent.logo : team.logo, team.name)}
size="lg"
/>
</div>
<p className="font-cal text-emphasis mb-2 text-2xl tracking-wider">
{team.parent && `${team.parent.name} `}
{teamName}
</p>
{!isBioEmpty && (
<>
<div
@@ -129,43 +192,49 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio }: TeamPageProps) {
</>
)}
</div>
{(showMembers.isOn || !team.eventTypes.length) && <Team team={team} />}
{!showMembers.isOn && team.eventTypes.length > 0 && (
<div className="mx-auto max-w-3xl ">
<EventTypes />
{metadata?.isOrganization ? (
<SubTeams />
) : (
<>
{(showMembers.isOn || !team.eventTypes.length) && <Team team={team} />}
{!showMembers.isOn && team.eventTypes.length > 0 && (
<div className="mx-auto max-w-3xl ">
<EventTypes />
{!team.hideBookATeamMember && (
<div>
<div className="relative mt-12">
<div className="absolute inset-0 flex items-center" aria-hidden="true">
<div className="border-subtle w-full border-t" />
</div>
<div className="relative flex justify-center">
<span className="dark:bg-darkgray-50 bg-subtle text-subtle dark:text-inverted px-2 text-sm">
{t("or")}
</span>
</div>
</div>
{!team.hideBookATeamMember && (
<div>
<div className="relative mt-12">
<div className="absolute inset-0 flex items-center" aria-hidden="true">
<div className="border-subtle w-full border-t" />
</div>
<div className="relative flex justify-center">
<span className="dark:bg-darkgray-50 bg-subtle text-subtle dark:text-inverted px-2 text-sm">
{t("or")}
</span>
</div>
</div>
<aside className="dark:text-inverted mt-8 flex justify-center text-center">
<Button
color="minimal"
EndIcon={ArrowRight}
className="dark:hover:bg-darkgray-200"
href={{
pathname: `/team/${team.slug}`,
query: {
members: "1",
...queryParamsToForward,
},
}}
shallow={true}>
{t("book_a_team_member")}
</Button>
</aside>
<aside className="dark:text-inverted mt-8 flex justify-center text-center">
<Button
color="minimal"
EndIcon={ArrowRight}
className="dark:hover:bg-darkgray-200"
href={{
pathname: `${isValidOrgDomain ? "" : "/team"}/${team.slug}`,
query: {
members: "1",
...queryParamsToForward,
},
}}
shallow={true}>
{t("book_a_team_member")}
</Button>
</aside>
</div>
)}
</div>
)}
</div>
</>
)}
</main>
</>
@@ -175,8 +244,19 @@ function TeamPage({ team, isUnpublished, markdownStrippedBio }: TeamPageProps) {
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const ssr = await ssrInit(context);
const slug = Array.isArray(context.query?.slug) ? context.query.slug.pop() : context.query.slug;
const { isValidOrgDomain } = orgDomainConfig(context.req.headers.host ?? "");
const team = await getTeamWithMembers(undefined, slug);
const metadata = teamMetadataSchema.parse(team?.metadata ?? {});
// Taking care of sub-teams and orgs
if (
(isValidOrgDomain && team?.parent && !!metadata?.isOrganization) ||
(!isValidOrgDomain && team?.parent) ||
(!isValidOrgDomain && !!metadata?.isOrganization)
) {
return { notFound: true } as const;
}
if (!team) {
const unpublishedTeam = await prisma.team.findFirst({
@@ -193,7 +273,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
return {
props: {
isUnpublished: true,
team: unpublishedTeam,
team: { ...unpublishedTeam, createdAt: null },
trpcState: ssr.dehydrate(),
},
} as const;
@@ -222,6 +302,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
themeBasis: team.slug,
trpcState: ssr.dehydrate(),
markdownStrippedBio,
isValidOrgDomain,
},
} as const;
};
+6 -1
View File
@@ -76,7 +76,6 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
},
},
},
title: true,
availability: true,
description: true,
@@ -132,6 +131,12 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
},
},
},
parent: {
select: {
logo: true,
name: true,
},
},
},
},
},
+6
View File
@@ -86,6 +86,12 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
theme: true,
brandColor: true,
darkBrandColor: true,
parent: {
select: {
logo: true,
name: true,
},
},
},
},
users: {
+45
View File
@@ -0,0 +1,45 @@
import { expect } from "@playwright/test";
import { test } from "./lib/fixtures";
test.describe("Change Theme Test", () => {
test("change theme to dark", async ({ page, users }) => {
const pro = await users.create();
await pro.apiLogin();
await page.goto("/settings/my-account/appearance");
await page.waitForLoadState("networkidle");
//Click the "Dark" theme label
await page.click('[data-testid="theme-dark"]');
//Click the update button
await page.click('[data-testid="update-theme-btn"]');
//Wait for the toast to appear
const toast = await page.waitForSelector("div[class*='data-testid-toast-success']");
expect(toast).toBeTruthy();
//Go to the profile page and check if the theme is dark
await page.goto(`/${pro.username}`);
const darkModeClass = await page.getAttribute("html", "class");
expect(darkModeClass).toContain("dark");
});
test("change theme to light", async ({ page, users }) => {
const pro = await users.create();
await pro.apiLogin();
await page.goto("/settings/my-account/appearance");
await page.waitForLoadState("networkidle");
//Click the "Light" theme label
await page.click('[data-testid="theme-light"]');
//Click the update theme button
await page.click('[data-testid="update-theme-btn"]');
//Wait for the toast to appear
const toast = await page.waitForSelector("div[class*='data-testid-toast-success']");
expect(toast).toBeTruthy();
//Go to the profile page and check if the theme is light
await page.goto(`/${pro.username}`);
const darkModeClass = await page.getAttribute("html", "class");
expect(darkModeClass).toContain("light");
});
});
+27
View File
@@ -170,3 +170,30 @@ export const createNewSeatedEventType = async (page: Page, args: { eventTitle: s
await page.locator('[data-testid="offer-seats-toggle"]').click();
await page.locator('[data-testid="update-eventtype"]').click();
};
export async function gotoRoutingLink({
page,
formId,
queryString = "",
}: {
page: Page;
formId?: string;
queryString?: string;
}) {
let previewLink = null;
if (!formId) {
// Instead of clicking on the preview link, we are going to the preview link directly because the earlier opens a new tab which is a bit difficult to manage with Playwright
const href = await page.locator('[data-testid="form-action-preview"]').getAttribute("href");
if (!href) {
throw new Error("Preview link not found");
}
previewLink = href;
} else {
previewLink = `/forms/${formId}`;
}
await page.goto(`${previewLink}${queryString ? `?${queryString}` : ""}`);
// HACK: There seems to be some issue with the inputs to the form getting reset if we don't wait.
await new Promise((resolve) => setTimeout(resolve, 1000));
}
@@ -32,7 +32,7 @@ test.describe("Managed Event Types tests", () => {
await page.waitForURL("/settings/teams/**");
// Going to create an event type
await page.goto("/event-types");
await page.getByTestId("new-event-type-dropdown").click();
await page.getByTestId("new-event-type").click();
await page.getByTestId("option-team-1").click();
// Expecting we can add a managed event type as team owner
await expect(page.locator('button[value="MANAGED"]')).toBeVisible();
+60
View File
@@ -6,6 +6,7 @@ import {
createHttpServer,
selectFirstAvailableTimeSlotNextMonth,
waitFor,
gotoRoutingLink,
} from "./lib/testUtils";
test.afterEach(({ users }) => users.deleteAll());
@@ -387,3 +388,62 @@ test.describe("BOOKING_REQUESTED", async () => {
webhookReceiver.close();
});
});
test.describe("FORM_SUBMITTED", async () => {
test("can submit a form and get a submission event", async ({ page, users }) => {
const webhookReceiver = createHttpServer();
const user = await users.create();
await user.apiLogin();
await page.goto("/settings/teams/new");
await page.waitForLoadState("networkidle");
const teamName = `${user.username}'s Team`;
// Create a new team
await page.locator('input[name="name"]').fill(teamName);
await page.locator('input[name="slug"]').fill(teamName);
await page.locator('button[type="submit"]').click();
await page.locator("text=Publish team").click();
await page.waitForURL(/\/settings\/teams\/(\d+)\/profile$/i);
await page.waitForLoadState("networkidle");
// Install Routing Forms App
await page.goto(`/apps/routing-forms`);
// eslint-disable-next-line playwright/no-conditional-in-test
await page.click('[data-testid="install-app-button"]');
await page.waitForLoadState("networkidle");
await page.goto(`/settings/developer/webhooks/new`);
// Add webhook
await page.fill('[name="subscriberUrl"]', webhookReceiver.url);
await page.fill('[name="secret"]', "secret");
await Promise.all([page.click("[type=submit]"), page.goForward()]);
// Page contains the url
expect(page.locator(`text='${webhookReceiver.url}'`)).toBeDefined();
await page.waitForLoadState("networkidle");
await page.goto("/apps/routing-forms/forms");
await page.click('[data-testid="new-routing-form"]');
// Choose to create the Form for the user(which is the first option) and not the team
await page.click('[data-testid="option-0"]');
await page.fill("input[name]", "TEST FORM");
await page.click('[data-testid="add-form"]');
await page.waitForSelector('[data-testid="add-field"]');
const url = page.url();
const formId = new URL(url).pathname.split("/").at(-1);
await gotoRoutingLink({ page, formId: formId });
page.click('button[type="submit"]');
await waitFor(() => {
expect(webhookReceiver.requestList.length).toBe(1);
});
webhookReceiver.close();
});
});
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

+7 -24
View File
@@ -12,10 +12,8 @@
"have_any_questions": "هل لديك أسئلة؟ نحن هنا للمساعدة.",
"reset_password_subject": "{{appName}}: إرشادات إعادة تعيين كلمة المرور",
"event_declined_subject": "تم الرفض: {{title}} في {{date}}",
"event_cancelled_subject": "تم الإلغاء: {{title}} في {{date}}",
"event_request_declined": "تم رفض طلب الحدث الخاص بك",
"event_request_declined_recurring": "تم رفض طلب الحدث المتكرر الخاص بك",
"event_request_cancelled": "تم إلغاء حدثك المُجَدْوَل",
"organizer": "المنظِّم",
"need_to_reschedule_or_cancel": "هل تحتاج إلى إعادة جدولة أو إلغاء؟",
"cancellation_reason": "سبب الإلغاء (اختياري)",
@@ -77,9 +75,7 @@
"your_meeting_has_been_booked": "لقد تم حجز الاجتماع الخاص بك",
"event_type_has_been_rescheduled_on_time_date": "تم إعادة جدولة {{title}} إلى {{date}}.",
"event_has_been_rescheduled": "تم التحديث - تم إعادة جدولة الحدث الخاص بك",
"request_reschedule_subtitle": "ألغى {{organizer}} الحجز وطلب منك اختيار حجز في وقت آخر.",
"request_reschedule_title_organizer": "لقد طلبت من {{attendee}} إعادة جدولة موعد",
"request_reschedule_subtitle_organizer": "لقد ألغيت الحجز ويجب أن يختار {{attendee}} وقتًا جديداً للحجز معك.",
"rescheduled_event_type_subject": "تم إرسال طلب لإعادة الجدولة: {{eventType}} مع {{name}} في {{date}}",
"requested_to_reschedule_subject_attendee": "الإجراء المطلوب إعادة الجدولة: يُرجى حجز وقت جديد لمدة {{eventType}} مع {{name}}",
"hi_user_name": "مرحبا {{name}}",
@@ -119,6 +115,7 @@
"team_upgrade_banner_description": "شكراً لك على تجربة خطة الفريق الجديدة التي نقدمها. لقد لاحظنا أن فريقك \"{{teamName}}\" بحاجة إلى الترقية.",
"team_upgrade_banner_action": "قم بالترقية هنا",
"team_upgraded_successfully": "تمت ترقية فريقك بنجاح!",
"org_upgrade_banner_action": "قم بالترقية هنا",
"use_link_to_reset_password": "استخدم الرابط أدناه لإعادة تعيين كلمة المرور",
"hey_there": "مرحبًا،",
"forgot_your_password_calcom": "نسيت كلمة المرور الخاصة بك؟ - {{appName}}",
@@ -228,6 +225,7 @@
"done": "تم",
"all_done": "اكتمل كل شيء!",
"all_apps": "الكل",
"all": "الكل",
"available_apps": "التطبيقات المتوفرة",
"check_email_reset_password": "تحقق من البريد الإلكتروني. لقد أرسلنا رابطًا لإعادة تعيين كلمة المرور.",
"finish": "إنهاء",
@@ -301,7 +299,6 @@
"error_end_time_next_day": "لا يمكن أن يكون وقت الانتهاء أطول من 24 ساعة",
"back_to_bookings": "العودة إلى عمليات الحجز",
"free_to_pick_another_event_type": "لا تتردد في اختيار حدث آخر في أي وقت.",
"cancelled": "تم الإلغاء",
"cancellation_successful": "تم الإلغاء بنجاح",
"really_cancel_booking": "هل تريد حقًا إلغاء الحجز؟",
"cannot_cancel_booking": "لا يمكنك إلغاء هذا الحجز",
@@ -310,7 +307,6 @@
"cancelling_event_recurring": "إن هذا الحدث أحد الأمثلة على حدث متكرر.",
"cancelling_all_recurring": "هذه هي كل الأمثلة المتبقية في الحدث المتكرر.",
"error_with_status_code_occured": "حدث خطأ برمز الحالة {{status}}.",
"booking_already_cancelled": "تم إلغاء هذا الحجز بالفعل",
"booking_already_accepted_rejected": "تم بالفعل قبول هذا الحجز أو رفضه",
"go_back_home": "العودة إلى الشاشة الرئيسية",
"or_go_back_home": "أو العودة إلى الشاشة الرئيسية",
@@ -324,7 +320,6 @@
"upcoming_bookings": "بمجرد أن يحجز شخص ما موعدًا معك، سيظهر هنا.",
"recurring_bookings": "بمجرد أن يحجز شخص ما اجتماعًا متكررًا معك، سيظهر هنا.",
"past_bookings": "ستظهر هنا عمليات حجزك السابقة.",
"cancelled_bookings": "ستظهر هنا عمليات حجزك التي تم إلغاؤها.",
"unconfirmed_bookings": "ستظهر هنا كل حجوزات غير المؤكدة بعد.",
"unconfirmed_bookings_tooltip": "الحجوزات غير المؤكدة",
"on": "في",
@@ -364,7 +359,6 @@
"browse_api_documentation": "استعراض مستندات واجهة برمجة التطبيقات (API) لدينا",
"leverage_our_api": "استفد من واجهة برمجة التطبيقات (API) لدينا من أجل قدرة كاملة على التحكم والتخصيص.",
"create_webhook": "إنشاء الويب هوك",
"booking_cancelled": "تم إلغاء الحجز",
"booking_rescheduled": "تمت إعادة جدولة الحجز",
"recording_ready": "رابط تنزيل التسجيل جاهز",
"booking_created": "تم إنشاء الحجز",
@@ -377,8 +371,6 @@
"team_webhooks": "فريق ويبهوكس",
"create_new_webhook_to_account": "إنشاء ويب هوك جديد لحسابك",
"new_webhook": "ويب هوك جديد",
"receive_cal_meeting_data": "تلقَّ بيانات اجتماعات {{appName}} على عنوان URL محدد، وفي الوقت الفعلي، عندما تتم جدولة حدث ما أو يتم إلغاؤه.",
"receive_cal_event_meeting_data": "تلقي بيانات اجتماعات {{appName}} على عنوان URL محدد، وفي الوقت الحقيقي، عندما تتم جدولة حدث ما أو إلغاؤه.",
"responsive_fullscreen_iframe": "إطار iframe سريع الاستجابة بكامل الشاشة",
"loading": "يجري التحميل...",
"deleting": "جارٍ الحذف...",
@@ -514,6 +506,8 @@
"team_description": "بضع جمل عن فريقك. ستظهر على صفحة رابط فريقك.",
"members": "الأعضاء",
"member": "العضو",
"number_member_one": "{{count}} عضو",
"number_member_other": "{{count}} من الأعضاء",
"owner": "المالك",
"admin": "المشرف",
"administrator_user": "المستخدم المسؤول",
@@ -1014,14 +1008,12 @@
"event_location": "موقع الحدث",
"reschedule_optional": "سبب إعادة الجدولة (اختياري)",
"reschedule_placeholder": "أخبر الآخرين لماذا تحتاج إلى إعادة جدولة",
"event_cancelled": "تم إلغاء هذا الحدث",
"emailed_information_about_cancelled_event": "لقد أرسلنا إليك وإلى الحاضرين الآخرين بريداً إلكترونياً لإعلامهم.",
"this_input_will_shown_booking_this_event": "سيُعرَض هذا المُدخَل عند حجز هذا الحدث",
"meeting_url_in_conformation_email": "عنوان رابط الاجتماع موجود في رسالة التأكيد الإلكترونية",
"url_start_with_https": "يجب أن يبدأ العنوان بـ http:// أو https://",
"number_provided": "سيتم توفير رقم الهاتف",
"before_event_trigger": "قبل بدء الحدث",
"event_cancelled_trigger": "متى تم إلغاء هذا الحدث",
"new_event_trigger": "متى تم حجز الحدث الجديد",
"email_host_action": "إرسال رسالة إلكترونية إلى المضيف",
"email_attendee_action": "إرسال رسالة إلكترونية إلى الحضور",
@@ -1183,7 +1175,6 @@
"start_of_week": "بداية الأسبوع",
"recordings_title": "التسجيلات",
"recording": "التسجيل",
"happy_scheduling": "جدولة سعيدة",
"select_calendars": "حدد الرزنامات التي تريد التحقق منها بحثًا عن تضاربات لمنع الحجوزات المزدوجة.",
"check_for_conflicts": "التحقق من وجود تضاربات",
"view_recordings": "عرض التسجيلات",
@@ -1410,7 +1401,6 @@
"your_team_disbanded_successfully": "تم حل فريقك بنجاح",
"error_creating_team": "خطأ في إنشاء فريق",
"you": "أنت",
"send_email": "إرسال بريد إلكتروني",
"member_already_invited": "تمت دعوة العضو بالفعل",
"enter_email_or_username": "أدخل بريد إلكتروني أو اسم مستخدم",
"team_name_taken": "هذا الاسم مأخوذ بالفعل",
@@ -1423,7 +1413,7 @@
"attendee_email_info": "البريد الإلكتروني للشخص الحجز",
"kbar_search_placeholder": "اكتب أمرًا أو بحثًا...",
"invalid_credential": "لا! يبدو أن الصلاحية انتهت أو تم إلغاؤها. يرجى إعادة التثبيت مرة أخرى.",
"reschedule_reason_success_page": "سبب إعادة الجدولة",
"reschedule_reason": "سبب إعادة الجدولة",
"choose_common_schedule_team_event": "اختر جدولًا زمنيًا مشتركًا",
"choose_common_schedule_team_event_description": "قم بتمكين هذا الخيار إذا كنت ترغب في استخدام جدول زمني مشترك بين المضيفين. عند تعطيل هذا الخيار، سيتم حجز كل مضيف على أساس جدوله الافتراضي.",
"reason": "السبب",
@@ -1578,10 +1568,7 @@
"delete_sso_configuration_confirmation_description": "هل تريد بالتأكيد حذف تكوين {{connectionType}}؟ لن يتمكن أعضاء فريقك الذين يستخدمون معلومات تسجيل الدخول إلى {{connectionType}} من الوصول إلى Cal.com بعد الآن.",
"organizer_timezone": "منظم المناطق الزمنية",
"email_user_cta": "عرض الدعوة",
"email_no_user_invite_heading": "لقد تمت دعوتك للانضمام إلى فريق في {{appName}}",
"email_no_user_invite_subheading": "دعاك {{invitedBy}} للانضمام إلى فريقه على {{appName}}. إن {{appName}} هو برنامج جدولة الأحداث الذي يمكّنك أنت وفريقك من جدولة الاجتماعات دون الحاجة إلى المراسلة عبر البريد الإلكتروني.",
"email_user_invite_subheading": "دعاك {{invitedBy}} للانضمام إلى فريقه {{teamName}} على {{appName}}. إن {{appName}} هو برنامج جدولة الأحداث الذي يمكّنك أنت وفريقك من جدولة الاجتماعات دون الحاجة إلى المراسلة عبر البريد الإلكتروني.",
"email_no_user_invite_steps_intro": "سنرشدك خلال بضع خطوات قصيرة وستستمتع بجدولة خالية من الإجهاد مع فريقك وسريعة.",
"email_no_user_step_one": "اختر اسم المستخدم الخاص بك",
"email_no_user_step_two": "ربط حساب التقويم الخاص بك",
"email_no_user_step_three": "تعيين أوقاتك المتاحة",
@@ -1602,7 +1589,6 @@
"no_longer_attending": "لن تحضر هذا الحدث",
"attendee_no_longer_attending_subject": "أحد الحضور لن يحضر {{title}} في {{date}}",
"attendee_no_longer_attending": "أحد الحضور لن يحضر الحدث الخاص بك",
"attendee_no_longer_attending_subtitle": "تم إلغاء الحدث {{name}}، وهو ما يعني توافر معقد شاغر في هذا التوقيت",
"create_event_on": "إنشاء حدث في",
"default_app_link_title": "تعيين رابط تطبيق افتراضي",
"default_app_link_description": "يسمح تعيين رابط التطبيق الافتراضي لجميع أنواع الأحداث التي تم إنشاؤها حديثًا باستخدام رابط التطبيق الذي عينته.",
@@ -1623,7 +1609,6 @@
"show_on_booking_page": "إظهار في صفحة الحجز",
"get_started_zapier_templates": "البدء في استخدام قوالب Zapier",
"team_is_unpublished": "لم يُنشر {{team}}",
"team_is_unpublished_description": "رابط هذا الفريق غير متاح حاليًا. يرجى الاتصال بمالك الفريق أو طلب نشره منه.",
"team_member": "عضو الفريق",
"a_routing_form": "نموذج توجيه",
"form_description_placeholder": "وصف النموذج",
@@ -1654,7 +1639,6 @@
"spot_popular_event_types_description": "تعرف أي أنواع من الأحداث لديك تتلقى أكبر عدد من النقرات والحجوزات",
"no_responses_yet": "لا توجد ردود بعد",
"this_will_be_the_placeholder": "سيكون هذا هو العنصر النائب",
"error_booking_event": "حدث خطأ عند حجز الحدث، الرجاء تحديث الصفحة والمحاولة ثانيةً",
"timeslot_missing_title": "لم يتم تحديد مساحة زمنية",
"timeslot_missing_description": "الرجاء تحديد فترة زمنية لحجز الحدث.",
"timeslot_missing_cta": "حدد الوقت",
@@ -1715,7 +1699,6 @@
"least_booked_members": "الأعضاء الأقل حجزًا",
"events_created": "تم إنشاء الأحداث",
"events_completed": "تم اكتمال الأحداث",
"events_cancelled": "تم إلغاء الأحداث",
"events_rescheduled": "تمت إعادة جدولة الأحداث",
"from_last_period": "من آخر فترة",
"from_to_date_period": "من: {{startDate}} إلى: {{endDate}}",
@@ -1767,7 +1750,6 @@
"book_my_cal": "ثبّت الحجز في رزنامتي",
"invite_as": "دعوة باسم",
"form_updated_successfully": "تم تحديث الاستمارة بنجاح.",
"email_not_cal_member_cta": "انضم إلى فريقك",
"disable_attendees_confirmation_emails": "تعطيل رسائل التأكيد الافتراضية للحضور",
"disable_attendees_confirmation_emails_description": "يوجد مسار عمل واحد على الأقل نشط في هذا النوع من الأحداث يقوم بإرسال رسائل إلكترونية إلى الحاضرين عند حجز الحدث.",
"disable_host_confirmation_emails": "تعطيل رسائل التأكيد الافتراضية لمضيف",
@@ -1777,5 +1759,6 @@
"connect_google_workspace": "ربط مساحة عمل Google",
"google_workspace_admin_tooltip": "يجب أن تكون مشرفًا على مساحة العمل لاستخدام هذه الميزة",
"first_event_type_webhook_description": "قم بإنشاء أول شبكة ويب هوك لهذا النوع من الفعاليات",
"create_for": "إنشاء من أجل"
"create_for": "إنشاء من أجل",
"organization_url_taken": "عنوان URL هذا مأخوذ بالفعل"
}
+7 -24
View File
@@ -12,10 +12,8 @@
"have_any_questions": "Máte otázky? Jsme tu, abychom vám pomohli.",
"reset_password_subject": "{{appName}}: Pokyny pro obnovení hesla",
"event_declined_subject": "Odmítnuto: {{title}} v {{date}}",
"event_cancelled_subject": "Zrušeno: {{title}} v {{date}}",
"event_request_declined": "Žádost o událost byla zamítnuta",
"event_request_declined_recurring": "Žádost o opakovanou událost byla zamítnuta",
"event_request_cancelled": "Vaše naplánovaná událost byla zrušena",
"organizer": "Organizátor",
"need_to_reschedule_or_cancel": "Přeplánovat nebo zrušit?",
"cancellation_reason": "Důvod zrušení",
@@ -77,9 +75,7 @@
"your_meeting_has_been_booked": "Vaše schůzka byla rezervována",
"event_type_has_been_rescheduled_on_time_date": "Váš {{title}} byl přeplánován na {{date}}.",
"event_has_been_rescheduled": "Změna - Vaše událost byla přesunuta na jindy",
"request_reschedule_subtitle": "Organizátor {{organizer}} zrušil rezervaci a požádal vás, abyste si vybrali jiný čas.",
"request_reschedule_title_organizer": "Požádali jste uživatele {{attendee}} o změnu časového plánu",
"request_reschedule_subtitle_organizer": "Zrušili jste rezervaci a uživatel {{attendee}} by si s vámi měl zarezervovat nový čas.",
"rescheduled_event_type_subject": "Žádost o přesunutí schůzky: {{eventType}} s {{name}} dne {{date}}",
"requested_to_reschedule_subject_attendee": "Akce vyžadovaná k přeplánování: zarezervujte si nový čas pro událost {{eventType}} s osobou {{name}}",
"hi_user_name": "Hezký den, {{name}}",
@@ -119,6 +115,7 @@
"team_upgrade_banner_description": "Děkujeme vám za vyzkoušení našeho nového týmového plánu. Všimli jsme si, že váš tým „{{teamName}}“ je nutné upgradovat.",
"team_upgrade_banner_action": "Upgradovat zde",
"team_upgraded_successfully": "Váš tým byl úspěšně přešel na vyšší verzi!",
"org_upgrade_banner_action": "Upgradovat zde",
"use_link_to_reset_password": "Pro obnovení hesla použijte odkaz níž",
"hey_there": "Zdravíme,",
"forgot_your_password_calcom": "Zapomněli jste heslo? - {{appName}}",
@@ -228,6 +225,7 @@
"done": "Hotovo",
"all_done": "Hotovo!",
"all_apps": "Všechny aplikace",
"all": "Všechny aplikace",
"available_apps": "Dostupné aplikace",
"check_email_reset_password": "Podívejte se do e-mailu. Poslali jsme vám odkaz pro obnovení hesla.",
"finish": "Dokončit",
@@ -301,7 +299,6 @@
"error_end_time_next_day": "Čas konce nemůže být delší než 24 hodin",
"back_to_bookings": "Zpět na rezervace",
"free_to_pick_another_event_type": "Kdykoliv si můžete vybrat jinou událost.",
"cancelled": "Zrušeno",
"cancellation_successful": "Zrušení proběhlo úspěšně",
"really_cancel_booking": "Opravdu chcete zrušit svou rezervaci?",
"cannot_cancel_booking": "Tuto rezervaci nelze zrušit",
@@ -310,7 +307,6 @@
"cancelling_event_recurring": "Tato událost je jedním z případů opakující se události.",
"cancelling_all_recurring": "Toto jsou všechny zbývající instance opakující se události.",
"error_with_status_code_occured": "Došlo k chybě se stavovým kódem {{status}}.",
"booking_already_cancelled": "Tato rezervace již byla zrušena",
"booking_already_accepted_rejected": "Tato rezervace již byla přijata nebo zamítnuta",
"go_back_home": "Přejít na úvod",
"or_go_back_home": "Nebo přejít na úvod",
@@ -324,7 +320,6 @@
"upcoming_bookings": "Jakmile si někdo rezervuje váš čas, zobrazí se to zde.",
"recurring_bookings": "Jakmile si někdo s vámi zarezervuje opakovanou schůzku, zobrazí se to zde.",
"past_bookings": "Vaše proběhlé rezervace se zobrazí zde.",
"cancelled_bookings": "Vaše zrušené rezervace se zobrazí zde.",
"unconfirmed_bookings": "Vaše nepotvrzené rezervace se zobrazí zde.",
"unconfirmed_bookings_tooltip": "Nepotvrzené rezervace",
"on": "dne",
@@ -364,7 +359,6 @@
"browse_api_documentation": "Procházejte naši API dokumentaci",
"leverage_our_api": "Pro plnou kontrolu a přizpůsobení využijte naše API.",
"create_webhook": "Vytvořit webhook",
"booking_cancelled": "Rezervace zrušena",
"booking_rescheduled": "Rezervace přesunuta",
"recording_ready": "Odkaz ke stažení záznamu je připraven",
"booking_created": "Rezervace vytvořena",
@@ -377,8 +371,6 @@
"team_webhooks": "Týmové Webhooky",
"create_new_webhook_to_account": "Vytvořit nový webhook pro váš účet",
"new_webhook": "Nový webhook",
"receive_cal_meeting_data": "Přijímat v reálném čase data schůzky na zadanou adresu URL, když je událost naplánována nebo zrušena.",
"receive_cal_event_meeting_data": "Přijmout real-time data o {{appName}} události na určené URL adrese, jakmile je událost naplánována nebo zrušena.",
"responsive_fullscreen_iframe": "Responzivní iframe na celou obrazovku",
"loading": "Načítám...",
"deleting": "Odstraňování...",
@@ -514,6 +506,8 @@
"team_description": "Pár vět o vašem týmu. Objeví se na URL stránce vašeho týmu.",
"members": "Členové",
"member": "Člen",
"number_member_one": "Počet členů: {{count}}",
"number_member_other": "Počet členů: {{count}}",
"owner": "Vlastník",
"admin": "Administrátor",
"administrator_user": "Uživatel administrátor",
@@ -1014,14 +1008,12 @@
"event_location": "Místo události",
"reschedule_optional": "Důvod pro změnu plánu (volitelné)",
"reschedule_placeholder": "Dejte ostatním vědět, proč potřebujete změnit plán",
"event_cancelled": "Tato událost je zrušena",
"emailed_information_about_cancelled_event": "Poslali jsme vám a ostatním účastníkům informační e-mail.",
"this_input_will_shown_booking_this_event": "Toto pole se zobrazí při rezervaci této události",
"meeting_url_in_conformation_email": "Adresa URL schůzky je v potvrzovacím e-mailu",
"url_start_with_https": "Adresa URL musí začínat http:// nebo https://",
"number_provided": "Bude uvedeno telefonní číslo",
"before_event_trigger": "před zahájením události",
"event_cancelled_trigger": "při zrušení události",
"new_event_trigger": "při rezervaci nové události",
"email_host_action": "odeslání e-mailu hostiteli",
"email_attendee_action": "odeslat e-mail účastníkům",
@@ -1183,7 +1175,6 @@
"start_of_week": "Začátek týdne",
"recordings_title": "Nahrávky",
"recording": "Nahrávka",
"happy_scheduling": "Hodně štěstí s plánováním",
"select_calendars": "Vyberte kalendáře, u kterých chcete kontrolovat konflikty v zájmu prevence dvojích rezervací.",
"check_for_conflicts": "Zkontrolovat konflikty",
"view_recordings": "Zobrazit nahrávky",
@@ -1410,7 +1401,6 @@
"your_team_disbanded_successfully": "Váš tým byl úspěšně rozpuštěn",
"error_creating_team": "Chyba při vytváření týmu",
"you": "Vy",
"send_email": "Odeslat e-mail",
"member_already_invited": "Člen byl už pozván",
"enter_email_or_username": "Zadejte e-mail nebo uživatelské jméno",
"team_name_taken": "Toto jméno je už obsazeno",
@@ -1423,7 +1413,7 @@
"attendee_email_info": "E-mail osoby provádějící rezervaci",
"kbar_search_placeholder": "Zadejte příkaz nebo vyhledejte...",
"invalid_credential": "Ale ne! Zdá se, že platnost oprávnění vypršela nebo byla zrušena. Proveďte novou instalaci.",
"reschedule_reason_success_page": "Důvod změny termínu",
"reschedule_reason": "Důvod změny termínu",
"choose_common_schedule_team_event": "Vyberte společný plán",
"choose_common_schedule_team_event_description": "Tuto možnost povolte, pokud chcete používat společný plán mezi hostiteli. Při zakázání této možnosti bude každý hostitel rezervován na základě svého výchozího plánu.",
"reason": "Důvod",
@@ -1578,10 +1568,7 @@
"delete_sso_configuration_confirmation_description": "Opravdu chcete odstranit konfiguraci {{connectionType}}? Členové vašeho týmu, kteří používají přihlášení {{connectionType}}, ztratí přístup k webu Cal.com.",
"organizer_timezone": "Časové pásmo organizátora",
"email_user_cta": "Zobrazit pozvánku",
"email_no_user_invite_heading": "Byli jste pozváni do týmu v aplikaci {{appName}}",
"email_no_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k jeho týmu v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu týmu umožňuje plánovat schůzky bez e-mailového ping-pongu.",
"email_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k jeho týmu „{{teamName}}“ v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu týmu umožňuje plánovat schůzky bez e-mailového pingpongu.",
"email_no_user_invite_steps_intro": "Provedeme vás několika krátkými kroky a za malou chvíli si budete se svým týmem užívat plánování bez stresu.",
"email_no_user_step_one": "Vyberte si uživatelské jméno",
"email_no_user_step_two": "Připojte svůj účet kalendáře",
"email_no_user_step_three": "Nastavte si dostupnost",
@@ -1602,7 +1589,6 @@
"no_longer_attending": "Této události se již neúčastníte",
"attendee_no_longer_attending_subject": "Účastník se již neúčastní události {{title}} v den {{date}}",
"attendee_no_longer_attending": "Účastník se již neúčastní vaší události",
"attendee_no_longer_attending_subtitle": "Uživatel {{name}} zrušil svou účast. V tomto časovém intervalu se tedy uvolnilo místo",
"create_event_on": "Vytvořit událost v:",
"default_app_link_title": "Nastavte výchozí odkaz na aplikaci",
"default_app_link_description": "Nastavení výchozího odkazu na aplikaci umožní, aby všechny nově vytvořené typy událostí používaly vámi nastavený odkaz na aplikaci.",
@@ -1623,7 +1609,6 @@
"show_on_booking_page": "Zobrazit na stránce rezervace",
"get_started_zapier_templates": "Začněte používat šablony Zapier",
"team_is_unpublished": "Tým {{team}} není zveřejněn",
"team_is_unpublished_description": "Tento týmový odkaz není v současné době k dispozici. Kontaktujte vlastníka týmu nebo ho požádejte o jeho zveřejnění.",
"team_member": "Člen týmu",
"a_routing_form": "Směrovací formulář",
"form_description_placeholder": "Popis formuláře",
@@ -1654,7 +1639,6 @@
"spot_popular_event_types_description": "Zjistěte, které typy vašich událostí získávají nejvíce kliknutí a rezervací",
"no_responses_yet": "Zatím žádné odpovědi",
"this_will_be_the_placeholder": "Toto bude zástupný znak",
"error_booking_event": "Při rezervaci události došlo k chybě, obnovte prosím stránku a zkuste to znovu",
"timeslot_missing_title": "Nebyl vybrán žádný časový slot",
"timeslot_missing_description": "Vyberte časový slot, aby mohla být událost zaregistrována.",
"timeslot_missing_cta": "Vybrat časový slot",
@@ -1715,7 +1699,6 @@
"least_booked_members": "Nejméně rezervovaných členů",
"events_created": "Události vytvořeny",
"events_completed": "Události dokončeny",
"events_cancelled": "Události zrušeny",
"events_rescheduled": "Události přesunuty",
"from_last_period": "z posledního období",
"from_to_date_period": "Od: {{startDate}} do: {{endDate}}",
@@ -1767,7 +1750,6 @@
"book_my_cal": "Book my Cal",
"invite_as": "Pozvat jako",
"form_updated_successfully": "Formulář byl aktualizován.",
"email_not_cal_member_cta": "Připojte se ke svému týmu",
"disable_attendees_confirmation_emails": "Vypnutí výchozích potvrzovacích e-mailů pro účastníky",
"disable_attendees_confirmation_emails_description": "U tohoto typu události je aktivní alespoň jeden pracovní postup, který po rezervaci události odešle účastníkům e-mail.",
"disable_host_confirmation_emails": "Vypnutí výchozích potvrzovacích e-mailů pro hostitele",
@@ -1777,5 +1759,6 @@
"connect_google_workspace": "Propojit s Google Workspace",
"google_workspace_admin_tooltip": "Používání této funkce vyžaduje, abyste byli administrátory Google Workspace",
"first_event_type_webhook_description": "Vytvořte svůj první webhook pro tento typ události",
"create_for": "Vytvořit pro"
"create_for": "Vytvořit pro",
"organization_url_taken": "Tato adresa URL je už obsazená"
}
+5 -17
View File
@@ -11,10 +11,8 @@
"have_any_questions": "Har du spørgsmål? Vi er her for at hjælpe.",
"reset_password_subject": "{{appName}}: Nulstil adgangskodeinstruktioner",
"event_declined_subject": "Afvist: {{title}} den {{date}}",
"event_cancelled_subject": "Aflyst: {{title}} den {{date}}",
"event_request_declined": "Din begivenhedsanmodning er blevet afvist",
"event_request_declined_recurring": "Din tilbagevendende begivenhedsanmodning er blevet afvist",
"event_request_cancelled": "Din planlagte begivenhed blev aflyst",
"organizer": "Arrangør",
"need_to_reschedule_or_cancel": "Behov for at omlægge eller annullere?",
"cancellation_reason": "Årsag til aflysning (valgfri)",
@@ -72,9 +70,7 @@
"your_meeting_has_been_booked": "Dit møde er blevet booket",
"event_type_has_been_rescheduled_on_time_date": "Din {{title}} er blevet flyttet til {{date}}.",
"event_has_been_rescheduled": "Opdateret - Din begivenhed er blevet flyttet",
"request_reschedule_subtitle": "{{organizer}} har annulleret bookingen og anmodet dig om at vælge et andet tidspunkt.",
"request_reschedule_title_organizer": "Du har anmodet {{attendee}} om at omlægge",
"request_reschedule_subtitle_organizer": "Du har annulleret bookingen og {{attendee}} bør vælge en ny bookingtid med dig.",
"rescheduled_event_type_subject": "Anmodning om omlægning sendt: {{eventType}} med {{name}} den {{date}}",
"requested_to_reschedule_subject_attendee": "Handling Påkrævet Omlægning: Reservér en ny tid for {{eventType}} med {{name}}",
"hi_user_name": "Hej {{name}}",
@@ -112,6 +108,7 @@
"team_upgrade_banner_description": "Tak fordi du har prøvet vores nye teamplan. Vi har bemærket at dit team \"{{teamName}}\" skal opgraderes.",
"team_upgrade_banner_action": "Opgradér her",
"team_upgraded_successfully": "Dit team blev opgraderet!",
"org_upgrade_banner_action": "Opgradér her",
"use_link_to_reset_password": "Brug nedenstående link for at nulstille din adgangskode",
"hey_there": "Hej,",
"forgot_your_password_calcom": "Glemt din adgangskode? - {{appName}}",
@@ -220,6 +217,7 @@
"done": "Udført",
"all_done": "Alt er klart!",
"all_apps": "Alle",
"all": "Alle",
"check_email_reset_password": "Tjek din e-mail. Vi har sendt dig et link til at nulstille din adgangskode.",
"finish": "Afslut",
"few_sentences_about_yourself": "Et par sætninger om dig selv. Dette vil blive vist på din personlige url side.",
@@ -290,7 +288,6 @@
"error_end_time_next_day": "Sluttidspunktet kan ikke være længere end 24 timer",
"back_to_bookings": "Tilbage til bookinger",
"free_to_pick_another_event_type": "Du er til enhver tid velkommen til at vælge en anden begivenhed.",
"cancelled": "Annullerede",
"cancellation_successful": "Annullering lykkedes",
"really_cancel_booking": "Vil du virkelig annullere din booking?",
"cannot_cancel_booking": "Du kan ikke annullere denne booking",
@@ -299,7 +296,6 @@
"cancelling_event_recurring": "Begivenheden er en forekomst af en tilbagevendende begivenhed.",
"cancelling_all_recurring": "Disse er alle resterende forekomster i den tilbagevendende begivenhed.",
"error_with_status_code_occured": "Der opstod en fejl med statuskoden {{status}}.",
"booking_already_cancelled": "Denne booking er allerede aflyst",
"booking_already_accepted_rejected": "Denne booking er allerede accepteret eller afvist",
"go_back_home": "Gå tilbage til hjem",
"or_go_back_home": "Eller gå tilbage til hjem",
@@ -313,7 +309,6 @@
"upcoming_bookings": "Så snart nogen booker en tid med dig, vil det dukke op her.",
"recurring_bookings": "Så snart nogen booker et tilbagevendende møde med dig, vil det dukke op her.",
"past_bookings": "Dine tidligere bookinger vil blive vist her.",
"cancelled_bookings": "Dine annullerede bookinger vil blive vist her.",
"unconfirmed_bookings": "Dine ubekræftede bookinger vil dukke op her.",
"unconfirmed_bookings_tooltip": "Ubekræftede bookinger",
"on": "den",
@@ -353,7 +348,6 @@
"browse_api_documentation": "Gennemse vores API-dokumentation",
"leverage_our_api": "Udnyt vores API til fuld kontrol og tilpasning.",
"create_webhook": "Opret Webhook",
"booking_cancelled": "Booking Aflyst",
"booking_rescheduled": "Booking Omlagt",
"booking_created": "Booking Oprettet",
"meeting_ended": "Møde Afsluttet",
@@ -365,8 +359,6 @@
"team_webhooks": "Team Webhooks",
"create_new_webhook_to_account": "Opret en ny webhook til din konto",
"new_webhook": "Ny Webhook",
"receive_cal_meeting_data": "Modtag {{appName}} mødedata på en specificeret URL, i realtid, når en begivenhed bliver planlagt eller aflyst.",
"receive_cal_event_meeting_data": "Modtag {{appName}} mødedata på en specificeret URL, i realtid, når denne begivenhed bliver planlagt eller aflyst.",
"responsive_fullscreen_iframe": "Responsiv fuldskærms-iframe",
"loading": "Indlæser...",
"deleting": "Sletter...",
@@ -974,14 +966,12 @@
"event_location": "Begivenhedens placering",
"reschedule_optional": "Årsag til omlægning (valgfri)",
"reschedule_placeholder": "Lad andre vide, hvorfor du har brug for at omlægge",
"event_cancelled": "Denne begivenhed er aflyst",
"emailed_information_about_cancelled_event": "Vi har sendt en e-mail til dig og de andre deltagere for at give dem besked.",
"this_input_will_shown_booking_this_event": "Dette input vil blive vist ved booking af denne begivenhed",
"meeting_url_in_conformation_email": "Møde-url er i bekræftelses-mailen",
"url_start_with_https": "URL'en skal starte med http:// eller https://",
"number_provided": "Telefonnummer vil blive angivet",
"before_event_trigger": "før begivenheden starter",
"event_cancelled_trigger": "når begivenheden er aflyst",
"new_event_trigger": "når ny begivenhed er booket",
"email_host_action": "send e-mail til vært",
"sms_number_action": "send SMS til et specifikt nummer",
@@ -1347,7 +1337,6 @@
"your_team_disbanded_successfully": "Dit team er blevet opløst",
"error_creating_team": "Fejl ved oprettelse af team",
"you": "Dig",
"send_email": "Send e-mail",
"member_already_invited": "Medlemmet er allerede blevet inviteret",
"enter_email_or_username": "Indtast e-mail eller brugernavn",
"team_name_taken": "Dette navn er allerede i brug",
@@ -1360,7 +1349,7 @@
"attendee_email_info": "Personen der booker's e-mail",
"kbar_search_placeholder": "Indtast en kommando eller søgning...",
"invalid_credential": "Åh nej! Det ser ud til at tilladelsen er udløbet eller blevet tilbagekaldt. Geninstaller venligst igen.",
"reschedule_reason_success_page": "Årsag til omlægning",
"reschedule_reason": "Årsag til omlægning",
"choose_common_schedule_team_event": "Vælg en fælles tidsplan",
"choose_common_schedule_team_event_description": "Aktivér dette hvis du ønsker at bruge en fælles tidsplan mellem værter. Når deaktiveret, vil hver vært blive booket baseret på deres standardtidsplan.",
"reason": "Årsag",
@@ -1506,9 +1495,7 @@
"delete_sso_configuration_confirmation_description": "Er du sikker på, at du vil slette {{connectionType}} konfigurationen? Dine teammedlemmer, der bruger {{connectionType}} login, vil ikke længere kunne få adgang til Cal.com.",
"organizer_timezone": "Arrangørens tidszone",
"email_user_cta": "Vis Invitation",
"email_no_user_invite_heading": "Du er blevet inviteret til at deltage i et team den {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} har inviteret dig til at deltage i deres team på {{appName}}. {{appName}} er den begivenheds-jonglerende planlægger, der gør det muligt for dig og dit team at planlægge møder uden e-mail tennis.",
"email_no_user_invite_steps_intro": "Vi fører dig gennem et par korte trin, og du vil kunne nyde stressfri planlægning med dit team på ingen tid.",
"email_no_user_step_one": "Vælg dit brugernavn",
"email_no_user_step_two": "Tilslut din kalender konto",
"email_no_user_step_three": "Angiv din tilgængelighed",
@@ -1558,5 +1545,6 @@
"no_responses_yet": "Ingen svar endnu",
"this_will_be_the_placeholder": "Dette vil være pladsholderen",
"verification_code": "Bekræftelseskode",
"verify": "Bekræft"
"verify": "Bekræft",
"organization_url_taken": "Denne URL er allerede i brug"
}
+7 -24
View File
@@ -12,10 +12,8 @@
"have_any_questions": "Haben Sie Fragen? Wir sind hier um Ihnen zu helfen.",
"reset_password_subject": "{{appName}}: Anleitung zum Zurücksetzen des Passworts",
"event_declined_subject": "Abgelehnt: {{title}} am {{date}}",
"event_cancelled_subject": "Storniert: {{title}} um {{date}}",
"event_request_declined": "Ihre Event-Anfrage wurde abgelehnt",
"event_request_declined_recurring": "Ihre wiederkehrende Terminanfrage wurde abgelehnt",
"event_request_cancelled": "Ihr geplanter Termin wurde abgesagt",
"organizer": "Organisator",
"need_to_reschedule_or_cancel": "Möchten Sie einen neuen Termin finden oder absagen?",
"cancellation_reason": "Grund für Ihre Absage (optional)",
@@ -77,9 +75,7 @@
"your_meeting_has_been_booked": "Dein Termin wurde gebucht",
"event_type_has_been_rescheduled_on_time_date": "Ihr {{title}} wurde auf den {{date}} verschoben.",
"event_has_been_rescheduled": "Ihr Termin wurde verschoben.",
"request_reschedule_subtitle": "{{organizer}} hat die Buchung storniert und Sie gebeten, eine andere Zeit auszuwählen.",
"request_reschedule_title_organizer": "Sie haben {{attendee}} zur Neuplanung aufgefordert",
"request_reschedule_subtitle_organizer": "Sie haben die Buchung storniert und {{attendee}} muss eine neue Buchungszeit mit Ihnen vereinbaren.",
"rescheduled_event_type_subject": "Anfrage für Neuplanung gesendet: {{eventType}} mit {{name}} am {{date}}",
"requested_to_reschedule_subject_attendee": "Aktion erforderlich - Neuplanung: Bitte buchen Sie eine neue Zeit für „{{eventType}}“ mit {{name}}",
"hi_user_name": "Hallo, {{name}}",
@@ -119,6 +115,7 @@
"team_upgrade_banner_description": "Vielen Dank, dass Sie unseren neuen Teamplan getestet haben. Wir haben festgestellt, dass Ihr Team „{{teamName}}“ aktualisiert werden muss.",
"team_upgrade_banner_action": "Hier aufrüsten",
"team_upgraded_successfully": "Das Update für Ihr Team war erfolgreich!",
"org_upgrade_banner_action": "Hier aufrüsten",
"use_link_to_reset_password": "Benutzen Sie den Link, um Ihr Passwort zurückzusetzen",
"hey_there": "Hallo,",
"forgot_your_password_calcom": "Passwort vergessen? - {{appName}}",
@@ -228,6 +225,7 @@
"done": "Erledigt",
"all_done": "Erledigt!",
"all_apps": "Alle Apps",
"all": "Alle Apps",
"available_apps": "Verfügbare Apps",
"check_email_reset_password": "Überprüfen Sie Ihre E-Mail. Wir haben Ihnen einen Link zum Zurücksetzen Ihres Passworts gesendet.",
"finish": "Fertig",
@@ -301,7 +299,6 @@
"error_end_time_next_day": "Die Endzeit darf nicht größer als 24 Stunden sein",
"back_to_bookings": "Zurück zu den Buchungen",
"free_to_pick_another_event_type": "Sie können jederzeit einen anderen Termin wählen.",
"cancelled": "Abgesagte",
"cancellation_successful": "Stornierung erfolgreich",
"really_cancel_booking": "Möchten Sie wirklich stornieren?",
"cannot_cancel_booking": "Sie können diese Buchung nicht stornieren",
@@ -310,7 +307,6 @@
"cancelling_event_recurring": "Der Termin ist eine Instanz eines wiederkehrenden Termins.",
"cancelling_all_recurring": "Dies sind alle verbleibende Instanzen im wiederkehrenden Termin.",
"error_with_status_code_occured": "Ein Fehler mit dem Statuscode {{status}} ist aufgetreten.",
"booking_already_cancelled": "Dieser Termin wurde bereits storniert",
"booking_already_accepted_rejected": "Diese Buchung wurde bereits angenommen oder abgelehnt",
"go_back_home": "Zurück zum Anfang",
"or_go_back_home": "Oder navigieren Sie zurück",
@@ -324,7 +320,6 @@
"upcoming_bookings": "Sobald jemand eine Zeit bei Ihnen bucht können Sie das hier sehen.",
"recurring_bookings": "Sobald jemand einen wiederkehrenden Termin mit Ihnen bucht wird er hier erscheinen.",
"past_bookings": "Ihre früheren Buchungen werden hier angezeigt.",
"cancelled_bookings": "Ihre stornierten Buchungen werden hier angezeigt.",
"unconfirmed_bookings": "Ihre unbestätigten Buchungen werden hier angezeigt.",
"unconfirmed_bookings_tooltip": "Unbestätigte Buchungen",
"on": "auf",
@@ -364,7 +359,6 @@
"browse_api_documentation": "Durchsuchen Sie unsere API Dokumentation",
"leverage_our_api": "Nutzen Sie unsere API für die volle Kontrolle und Anpassbarkeit.",
"create_webhook": "Webhook erstellen",
"booking_cancelled": "Termin abgesagt",
"booking_rescheduled": "Termin verlegt",
"recording_ready": "Download-Link der Aufnahme bereit",
"booking_created": "Termin erstellt",
@@ -377,8 +371,6 @@
"team_webhooks": "Team-Webhooks",
"create_new_webhook_to_account": "Erstellen Sie einen neuen Webhook in Ihrem Account",
"new_webhook": "Neuer Webhook",
"receive_cal_meeting_data": "Erhalte {{appName}} Termindaten unter einer bestimmten URL in Echtzeit, wenn ein Termin geplant oder abgesagt wird.",
"receive_cal_event_meeting_data": "Erhalte {{appName}} Termindaten unter einer bestimmten URL in Echtzeit, wenn dieser Termin geplant oder abgesagt wird.",
"responsive_fullscreen_iframe": "Responsives Vollbild-iFrame",
"loading": "Wird geladen...",
"deleting": "Lösche...",
@@ -514,6 +506,8 @@
"team_description": "Ein paar Sätze über Ihr Team auf der öffentlichen Teamseite.",
"members": "Mitglieder",
"member": "Mitglied",
"number_member_one": "{{count}} Mitglied",
"number_member_other": "{{count}} Mitglieder",
"owner": "Inhaber",
"admin": "Administrator",
"administrator_user": "Administrator Benutzer",
@@ -1014,14 +1008,12 @@
"event_location": "Ort des Ereignisses",
"reschedule_optional": "Grund für die Verschiebung (optional)",
"reschedule_placeholder": "Lassen Sie andere wissen, warum Sie den Termin verschieben müssen",
"event_cancelled": "Dieser Termin ist abgesagt",
"emailed_information_about_cancelled_event": "Wir haben Ihnen und den anderen Teilnehmern eine E-Mail gesendet, damit alle Bescheid wissen.",
"this_input_will_shown_booking_this_event": "Diese Eingabe wird bei der Buchung dieses Termins angezeigt",
"meeting_url_in_conformation_email": "Termin-URL ist in der Bestätigungsmail",
"url_start_with_https": "URL muss mit http:// oder https:// beginnen",
"number_provided": "Telefonnummer wird angegeben",
"before_event_trigger": "vor Beginn des Termins",
"event_cancelled_trigger": "wenn das Ereignis abgesagt wird",
"new_event_trigger": "wenn ein neer Termin gebucht wird",
"email_host_action": "E-Mail an den Veranstalter senden",
"email_attendee_action": "E-Mail an Teilnehmende senden",
@@ -1183,7 +1175,6 @@
"start_of_week": "Wochenstart",
"recordings_title": "Aufnahmen",
"recording": "Aufnahme",
"happy_scheduling": "Fröhliche Terminplanung",
"select_calendars": "Wählen Sie aus, in welchen Kalendern Sie nach Konflikten suchen wollen, um Doppelbuchungen zu vermeiden.",
"check_for_conflicts": "Auf Konflikte prüfen",
"view_recordings": "Aufnahmen anzeigen",
@@ -1410,7 +1401,6 @@
"your_team_disbanded_successfully": "Ihr Team wurde erfolgreich aufgelöst",
"error_creating_team": "Fehler beim Erstellen des Teams",
"you": "Sie",
"send_email": "E-Mail senden",
"member_already_invited": "Mitglied wurde bereits eingeladen",
"enter_email_or_username": "E-Mail oder Benutzername eingeben",
"team_name_taken": "Dieser Name ist bereits vergeben",
@@ -1423,7 +1413,7 @@
"attendee_email_info": "Die E-Mail-Adresse der buchenden Person",
"kbar_search_placeholder": "Geben Sie einen Befehl ein oder suchen Sie ...",
"invalid_credential": "Oh nein! Es sieht so aus, als ob die Berechtigung abgelaufen ist oder entzogen wurden. Bitte erneut installieren.",
"reschedule_reason_success_page": "Verlegungsgrund",
"reschedule_reason": "Verlegungsgrund",
"choose_common_schedule_team_event": "Gemeinsamen Zeitplan auswählen",
"choose_common_schedule_team_event_description": "Aktivieren Sie dies, wenn Sie einen gemeinsamen Zeitplan zwischen Hosts verwenden möchten. Wenn deaktiviert, ist jeder Host basierend auf seinen Standardplan buchbar.",
"reason": "Grund",
@@ -1578,10 +1568,7 @@
"delete_sso_configuration_confirmation_description": "Sind Sie sicher, dass Sie die {{connectionType}}-Konfiguration löschen möchten? Ihre Teammitglieder, die sich über {{connectionType}} anmelden, werden keinen Zugriff mehr auf Cal.com haben.",
"organizer_timezone": "Zeitzone des Veranstalters",
"email_user_cta": "Einladung anzeigen",
"email_no_user_invite_heading": "Sie wurden eingeladen, dem Team in {{appName}} beizutreten",
"email_no_user_invite_subheading": "{{invitedBy}} hat Sie eingeladen, dem Team in {{appName}} beizutreten. {{appName}} ist der Event-Planer, der es Ihnen und Ihrem Team ermöglicht, Meetings ohne ständiges hin und her zu planen.",
"email_user_invite_subheading": "{{invitedBy}} hat Sie eingeladen, dem Team „{{teamName}}“ beizutreten. {{appName}} ist der Event-Planer, der es Ihnen und Ihrem Team ermöglicht, Meetings ohne Hin und Her zu planen.",
"email_no_user_invite_steps_intro": "Wir begleiten Sie durch ein paar Schritte, danach können Sie stressfreie Planung mit Ihrem Team in kürzester Zeit genießen.",
"email_no_user_step_one": "Wählen Sie Ihren Benutzernamen",
"email_no_user_step_two": "Verbinden Sie Ihr Kalenderkonto",
"email_no_user_step_three": "Legen Sie Ihre Verfügbarkeit fest",
@@ -1602,7 +1589,6 @@
"no_longer_attending": "Sie nehmen an diesem Termin nicht mehr teil",
"attendee_no_longer_attending_subject": "Ein Teilnehmer nimmt nicht mehr an {{title}} am {{date}} teil",
"attendee_no_longer_attending": "Ein Teilnehmer nimmt nicht mehr an Ihrem Termin teil",
"attendee_no_longer_attending_subtitle": "{{name}} hat abgesagt. Das bedeutet, dass ein Platz für dieses Zeitfenster geöffnet wurde",
"create_event_on": "Erstelle Termin am",
"default_app_link_title": "Standard-App-Link festlegen",
"default_app_link_description": "Mit dem Festlegen eines Standard-App-Links können alle neu erstellten Ereignistypen den App-Link verwenden, den Sie gesetzt haben.",
@@ -1623,7 +1609,6 @@
"show_on_booking_page": "Auf der Buchungsseite anzeigen",
"get_started_zapier_templates": "Legen Sie mit Zapier-Vorlagen los",
"team_is_unpublished": "{{team}} ist unveröffentlicht",
"team_is_unpublished_description": "Dieser Team-Link ist derzeit nicht verfügbar. Bitte kontaktieren Sie den Team-Besitzer oder fragen Sie ihn, ob er ihn veröffentlicht.",
"team_member": "Teammitglied",
"a_routing_form": "Ein Weiterleitungsformular",
"form_description_placeholder": "Formularbeschreibung",
@@ -1654,7 +1639,6 @@
"spot_popular_event_types_description": "Sehen Sie, welche Ihrer Ereignistypen die meisten Klicks und Buchungen erhalten",
"no_responses_yet": "Noch keine Antworten",
"this_will_be_the_placeholder": "Dies wird der Platzhalter sein",
"error_booking_event": "Bei der Buchung dieses Termins ist ein Fehler aufgetreten, bitte aktualisieren Sie die Seite und versuchen Sie es erneut",
"timeslot_missing_title": "Kein Zeitfenster ausgewählt",
"timeslot_missing_description": "Bitte wählen Sie einen Zeitraum aus, um den Termin zu buchen.",
"timeslot_missing_cta": "Zeitfenster auswählen",
@@ -1715,7 +1699,6 @@
"least_booked_members": "Am wenigsten gebuchte Mitglieder",
"events_created": "Ereignisse erstellt",
"events_completed": "Ereignisse abgeschlossen",
"events_cancelled": "Ereignisse abgesagt",
"events_rescheduled": "Ereignisse neu geplant",
"from_last_period": "seit dem letzten Zeitraum",
"from_to_date_period": "Von: {{startDate}} Bis: {{endDate}}",
@@ -1767,7 +1750,6 @@
"book_my_cal": "Mein Cal buchen",
"invite_as": "Einladen als",
"form_updated_successfully": "Formular erfolgreich aktualisiert.",
"email_not_cal_member_cta": "Treten Sie Ihrem Team bei",
"disable_attendees_confirmation_emails": "Standardmäßige Bestätigungs-E-Mails für Teilnehmer deaktivieren",
"disable_attendees_confirmation_emails_description": "Mindestens ein Workflow ist für diesen Termintyp aktiv, welcher bei Buchung eine E-Mail an die Teilnehmer sendet.",
"disable_host_confirmation_emails": "Standardmäßige Bestätigungs-E-Mails für Veranstalter deaktivieren",
@@ -1777,5 +1759,6 @@
"connect_google_workspace": "Google Workspace verbinden",
"google_workspace_admin_tooltip": "Sie müssen ein Workspace-Admin sein, um diese Funktion nutzen zu können",
"first_event_type_webhook_description": "Erstellen Sie Ihren ersten Webhook für diesen Termintypen",
"create_for": "Erstellen für"
"create_for": "Erstellen für",
"organization_url_taken": "Diese URL ist bereits vergeben"
}
@@ -8,7 +8,6 @@
"have_any_questions": "Έχετε ερωτήσεις? Είμαστε εδώ για να βοηθήσουμε.",
"reset_password_subject": "{{appName}}: Οδηγίες επαναφοράς κωδικού πρόσβασης",
"event_declined_subject": "Απορρίφθηκε: {{title}} στις {{date}}",
"event_cancelled_subject": "Ακύρωση: {{title}} στις {{date}}",
"need_to_reschedule_or_cancel": "Χρειάζεται να επαναπρογραμματίσετε ή να ακυρώσετε;",
"cancellation_reason": "Λόγος ακύρωσης (προαιρετικό)",
"rejection_reason": "Λόγος απόρριψης",
@@ -57,6 +56,7 @@
"link_expires": "Υ.Γ. Λήγει σε {{expiresIn}} ώρες.",
"team_upgrade_banner_action": "Αναβάθμισε εδώ",
"team_upgraded_successfully": "Η ομάδα σας αναβαθμίστηκε επιτυχώς!",
"org_upgrade_banner_action": "Αναβάθμισε εδώ",
"use_link_to_reset_password": "Χρησιμοποιήστε τον παρακάτω σύνδεσμο για να επαναφέρετε τον κωδικό πρόσβασης",
"hey_there": "Γεια σας,",
"forgot_your_password_calcom": "Ξεχάσατε τον κωδικό πρόσβασης? - {{appName}}",
@@ -117,6 +117,7 @@
"request_password_reset": "Αποστολή email επαναφοράς",
"forgot_password": "Ξεχάσατε τον κωδικό πρόσβασης?",
"all_apps": "Όλα",
"all": "Όλα",
"check_email_reset_password": "Ελέγξτε το email σας. Σας στείλαμε ένα σύνδεσμο για να επαναφέρετε τον κωδικό πρόσβασής σας.",
"few_sentences_about_yourself": "Μερικά λόγια για τον εσάς. Αυτό θα εμφανιστεί στην προσωπική σελίδα σας.",
"set_availability": "Όρισε τη διαθεσιμότητά σου",
@@ -150,7 +151,6 @@
"friday_time_error": "Μη έγκυρη ώρα την Παρασκευή",
"saturday_time_error": "Μη έγκυρη ώρα το Σάββατο",
"error_with_status_code_occured": "Παρουσιάστηκε ένα σφάλμα με κωδικό κατάστασης {{status}}.",
"booking_already_cancelled": "Αυτή η κράτηση είχε ήδη ακυρωθεί",
"booking_already_accepted_rejected": "Αυτή η κράτηση έγινε ήδη αποδεκτή ή απορρίφθηκε",
"go_back_home": "Επιστροφή στην αρχική σελίδα",
"or_go_back_home": "Ή επιστροφή στην αρχική σελίδα",
+108 -39
View File
@@ -14,17 +14,17 @@
"verify_email_subject": "{{appName}}: Verify your account",
"check_your_email": "Check your email",
"verify_email_page_body": "We've sent an email to {{email}}. It is important to verify your email address to guarantee the best email and calendar deliverability from {{appName}}.",
"verify_email_banner_body": "Please verify your email adress to guarantee the best email and calendar deliverability from {{appName}}.",
"verify_email_banner_body": "Verify your email address to guarantee the best email and calendar deliverability",
"verify_email_email_header": "Verify your email address",
"verify_email_email_button": "Verify email",
"verify_email_email_body": "Please verify your email address by clicking the button below.",
"verify_email_email_link_text": "Here's the link incase you don't like clicking buttons:",
"verify_email_email_link_text": "Here's the link in case you don't like clicking buttons:",
"email_sent": "Email sent successfully",
"event_declined_subject": "Declined: {{title}} at {{date}}",
"event_cancelled_subject": "Cancelled: {{title}} at {{date}}",
"event_cancelled_subject": "Canceled: {{title}} at {{date}}",
"event_request_declined": "Your event request has been declined",
"event_request_declined_recurring": "Your recurring event request has been declined",
"event_request_cancelled": "Your scheduled event was cancelled",
"event_request_cancelled": "Your scheduled event was canceled",
"organizer": "Organizer",
"need_to_reschedule_or_cancel": "Need to reschedule or cancel?",
"cancellation_reason": "Reason for cancellation (optional)",
@@ -86,9 +86,9 @@
"your_meeting_has_been_booked": "Your meeting has been booked",
"event_type_has_been_rescheduled_on_time_date": "Your {{title}} has been rescheduled to {{date}}.",
"event_has_been_rescheduled": "Updated - Your event has been rescheduled",
"request_reschedule_subtitle": "{{organizer}} has cancelled the booking and requested you to pick another time.",
"request_reschedule_subtitle": "{{organizer}} has canceled the booking and requested you to pick another time.",
"request_reschedule_title_organizer": "You have requested {{attendee}} to reschedule",
"request_reschedule_subtitle_organizer": "You have cancelled the booking and {{attendee}} should pick a new booking time with you.",
"request_reschedule_subtitle_organizer": "You have canceled the booking and {{attendee}} should pick a new booking time with you.",
"rescheduled_event_type_subject": "Request for reschedule sent: {{eventType}} with {{name}} at {{date}}",
"requested_to_reschedule_subject_attendee": "Action Required Reschedule: Please book a new time for {{eventType}} with {{name}}",
"hi_user_name": "Hi {{name}}",
@@ -128,6 +128,9 @@
"team_upgrade_banner_description": "Thank you for trialing our new team plan. We noticed your team \"{{teamName}}\" needs to be upgraded.",
"team_upgrade_banner_action": "Upgrade here",
"team_upgraded_successfully": "Your team was upgraded successfully!",
"org_upgrade_banner_description": "Thank you for trialing our Organization plan. We noticed your Organization \"{{teamName}}\" needs to be upgraded.",
"org_upgrade_banner_action": "Upgrade here",
"org_upgraded_successfully": "Your Organization was upgraded successfully!",
"use_link_to_reset_password": "Use the link below to reset your password",
"hey_there": "Hey there,",
"forgot_your_password_calcom": "Forgot your password? - {{appName}}",
@@ -238,9 +241,12 @@
"done": "Done",
"all_done": "All done!",
"all_apps": "All",
"all": "All",
"yours": "Yours",
"available_apps": "Available Apps",
"check_email_reset_password": "Check your email. We sent you a link to reset your password.",
"finish": "Finish",
"organization_general_description":"Manage settings for your team language and timezone",
"few_sentences_about_yourself": "A few sentences about yourself. This will appear on your personal url page.",
"nearly_there": "Nearly there!",
"nearly_there_instructions": "Last thing, a brief description about you and a photo really help you get bookings and let people know who they’re booking with.",
@@ -248,8 +254,8 @@
"set_availability": "Set your availability",
"continue_without_calendar": "Continue without calendar",
"connect_your_calendar": "Connect your calendar",
"connect_your_video_app":"Connect your video apps",
"connect_your_video_app_instructions":"Connect your video apps to use them on your event types.",
"connect_your_video_app": "Connect your video apps",
"connect_your_video_app_instructions": "Connect your video apps to use them on your event types.",
"connect_your_calendar_instructions": "Connect your calendar to automatically check for busy times and new events as they’re scheduled.",
"set_up_later": "Set up later",
"current_time": "Current time",
@@ -300,6 +306,7 @@
"failed": "Failed",
"password_has_been_reset_login": "Your password has been reset. You can now login with your newly created password.",
"bookerlayout_title": "Layout",
"layout": "Layout",
"bookerlayout_default_title": "Default view",
"bookerlayout_description": "You can select multiple and your bookers can switch views.",
"bookerlayout_user_settings_title": "Booking layout",
@@ -323,7 +330,7 @@
"error_end_time_next_day": "End time cannot be greater than 24 hours",
"back_to_bookings": "Back to bookings",
"free_to_pick_another_event_type": "Feel free to pick another event anytime.",
"cancelled": "Cancelled",
"cancelled": "Canceled",
"cancellation_successful": "Cancellation successful",
"really_cancel_booking": "Really cancel your booking?",
"cannot_cancel_booking": "You cannot cancel this booking",
@@ -332,7 +339,7 @@
"cancelling_event_recurring": "The event is one instance of a recurring event.",
"cancelling_all_recurring": "These are all remaining instances in the recurring event.",
"error_with_status_code_occured": "An error with status code {{status}} occurred.",
"booking_already_cancelled": "This booking was already cancelled",
"booking_already_cancelled": "This booking was already canceled",
"booking_already_accepted_rejected": "This booking was already accepted or rejected",
"go_back_home": "Go back home",
"or_go_back_home": "Or go back home",
@@ -342,11 +349,12 @@
"no_status_bookings_yet_description": "You have no {{status}} bookings. {{description}}",
"event_between_users": "{{eventName}} between {{host}} and {{attendeeName}}",
"bookings": "Bookings",
"booking_not_found":"Booking not found",
"bookings_description": "See upcoming and past events booked through your event type links.",
"upcoming_bookings": "As soon as someone books a time with you it will show up here.",
"recurring_bookings": "As soon as someone books a recurring meeting with you it will show up here.",
"past_bookings": "Your past bookings will show up here.",
"cancelled_bookings": "Your cancelled bookings will show up here.",
"cancelled_bookings": "Your canceled bookings will show up here.",
"unconfirmed_bookings": "Your unconfirmed bookings will show up here.",
"unconfirmed_bookings_tooltip": "Unconfirmed bookings",
"on": "on",
@@ -387,12 +395,12 @@
"browse_api_documentation": "Browse our API documentation",
"leverage_our_api": "Leverage our API for full control and customizability.",
"create_webhook": "Create Webhook",
"booking_cancelled": "Booking Cancelled",
"booking_cancelled": "Booking Canceled",
"booking_rescheduled": "Booking Rescheduled",
"recording_ready":"Recording Download Link Ready",
"recording_ready": "Recording Download Link Ready",
"booking_created": "Booking Created",
"booking_rejected":"Booking Rejected",
"booking_requested":"Booking Requested",
"booking_rejected": "Booking Rejected",
"booking_requested": "Booking Requested",
"meeting_ended": "Meeting Ended",
"form_submitted": "Form Submitted",
"event_triggers": "Event Triggers",
@@ -402,8 +410,8 @@
"team_webhooks": "Team Webhooks",
"create_new_webhook_to_account": "Create a new webhook to your account",
"new_webhook": "New Webhook",
"receive_cal_meeting_data": "Receive {{appName}} meeting data at a specified URL, in real-time, when an event is scheduled or cancelled.",
"receive_cal_event_meeting_data": "Receive {{appName}} meeting data at a specified URL, in real-time, when this event is scheduled or cancelled.",
"receive_cal_meeting_data": "Receive {{appName}} meeting data at a specified URL, in real-time, when an event is scheduled or canceled.",
"receive_cal_event_meeting_data": "Receive {{appName}} meeting data at a specified URL, in real-time, when this event is scheduled or canceled.",
"responsive_fullscreen_iframe": "Responsive full screen iframe",
"loading": "Loading...",
"deleting": "Deleting...",
@@ -537,8 +545,12 @@
"your_team_updated_successfully": "Your team has been updated successfully.",
"about": "About",
"team_description": "A few sentences about your team. This will appear on your team's url page.",
"org_description": "A few sentances about your organization. This will appear on your organization's url page.",
"members": "Members",
"organization_members":"Organization members",
"member": "Member",
"number_member_one": "{{count}} member",
"number_member_other": "{{count}} members",
"owner": "Owner",
"admin": "Admin",
"administrator_user": "Administrator user",
@@ -569,6 +581,8 @@
"confirm_all": "Confirm all",
"disband_team": "Disband Team",
"disband_team_confirmation_message": "Are you sure you want to disband this team? Anyone who you've shared this team link with will no longer be able to book using it.",
"disband_org": "Disband Organization",
"disband_org_confirmation_message": "Are you sure you want to disband this Org? All teams and members will be deleted.",
"remove_member_confirmation_message": "Are you sure you want to remove this member from the team?",
"confirm_disband_team": "Yes, disband team",
"confirm_remove_member": "Yes, remove member",
@@ -679,6 +693,7 @@
"create_team_to_get_started": "Create a team to get started",
"teams": "Teams",
"team": "Team",
"organization": "Organization",
"team_billing": "Team Billing",
"team_billing_description": "Manage billing for your team",
"upgrade_to_flexible_pro_title": "We've changed billing for teams",
@@ -854,6 +869,7 @@
"installed_app_payment_description": "Configure which payment processing services to use when charging your clients.",
"installed_app_analytics_description": "Configure which analytics apps to use for your booking pages",
"installed_app_other_description": "All your installed apps from other categories.",
"installed_app_conferencing_description": "Configure which conferencing apps to use",
"installed_app_automation_description": "Configure which automation apps to use",
"installed_app_web3_description": "Configure which web3 apps to use for your booking pages",
"analytics": "Analytics",
@@ -919,7 +935,7 @@
"duplicate": "Duplicate",
"offer_seats": "Offer seats",
"offer_seats_description": "Offer seats for booking. This automatically disables guest & opt-in bookings.",
"seats_available_one":"Seat available",
"seats_available_one": "Seat available",
"seats_available_other": "Seats available",
"number_of_seats": "Number of seats per booking",
"enter_number_of_seats": "Enter number of seats",
@@ -1039,14 +1055,14 @@
"event_location": "Event's location",
"reschedule_optional": "Reason for rescheduling (optional)",
"reschedule_placeholder": "Let others know why you need to reschedule",
"event_cancelled": "This event is cancelled",
"event_cancelled": "This event is canceled",
"emailed_information_about_cancelled_event": "We emailed you and the other attendees to let them know.",
"this_input_will_shown_booking_this_event": "This input will be shown when booking this event",
"meeting_url_in_conformation_email": "Meeting url is in the confirmation email",
"url_start_with_https": "URL needs to start with http:// or https://",
"number_provided": "Phone number will be provided",
"before_event_trigger": "before event starts",
"event_cancelled_trigger": "when event is cancelled",
"event_cancelled_trigger": "when event is canceled",
"new_event_trigger": "when new event is booked",
"email_host_action": "send email to host",
"email_attendee_action": "send email to attendees",
@@ -1209,7 +1225,7 @@
"start_of_week": "Start of week",
"recordings_title": "Recordings",
"recording": "Recording",
"happy_scheduling": "Happy Scheduling",
"happy_scheduling": "Happy scheduling",
"select_calendars": "Select which calendars you want to check for conflicts to prevent double bookings.",
"check_for_conflicts": "Check for conflicts",
"view_recordings": "View recordings",
@@ -1283,7 +1299,7 @@
"download_responses_description": "Download all responses to your form in CSV format.",
"download": "Download",
"download_recording": "Download Recording",
"recording_from_your_recent_call":"A recording from your recent call on {{appName}} is ready for download",
"recording_from_your_recent_call": "A recording from your recent call on {{appName}} is ready for download",
"create_your_first_form": "Create your first form",
"create_your_first_form_description": "With Routing Forms you can ask qualifying questions and route to the correct person or event type.",
"create_your_first_webhook": "Create your first Webhook",
@@ -1292,7 +1308,9 @@
"event_one": "event",
"event_other": "events",
"profile_team_description": "Manage settings for your team profile",
"profile_org_description": "Manage settings for your organization profile",
"members_team_description": "Users that are in the group",
"organization_description": "Manage the admins and members in your organization",
"team_url": "Team URL",
"team_members": "Team members",
"more": "More",
@@ -1333,6 +1351,7 @@
"routing_forms_send_email_owner": "Send Email to Owner",
"routing_forms_send_email_owner_description": "Sends an email to the owner when the form is submitted",
"add_new_form": "Add new form",
"add_new_team_form": "Add new form to your team",
"create_your_first_route": "Create your first route",
"route_to_the_right_person": "Route to the right person based on the answers to your form",
"form_description": "Create your form to route a booker",
@@ -1436,9 +1455,10 @@
"yearly": "Yearly",
"checkout": "Checkout",
"your_team_disbanded_successfully": "Your team has been disbanded successfully",
"your_org_disbanded_successfully": "Your organization has been disbanded successfully",
"error_creating_team": "Error creating team",
"you": "You",
"send_email": "Send email",
"resend_email": "Resend email",
"member_already_invited": "Member has already been invited",
"enter_email_or_username": "Enter an email or username",
"team_name_taken": "This name is already taken",
@@ -1451,7 +1471,7 @@
"attendee_email_info": "The person booking's email",
"kbar_search_placeholder": "Type a command or search...",
"invalid_credential": "Oh no! Looks like permission expired or was revoked. Please reinstall again.",
"reschedule_reason_success_page": "Reschedule reason",
"reschedule_reason": "Reschedule reason",
"choose_common_schedule_team_event": "Choose a common schedule",
"choose_common_schedule_team_event_description": "Enable this if you want to use a common schedule between hosts. When disabled, each host will be booked based on their default schedule.",
"reason": "Reason",
@@ -1470,7 +1490,7 @@
"fixed_round_robin": "Fixed round robin",
"add_one_fixed_attendee": "Add one fixed attendee and round robin through a number of attendees.",
"calcom_is_better_with_team": "{{appName}} is better with teams",
"the_calcom_team":"The {{companyName}} team",
"the_calcom_team": "The {{companyName}} team",
"add_your_team_members": "Add your team members to your event types. Use collective scheduling to include everyone or find the most suitable person with round robin scheduling.",
"booking_limit_reached": "Booking Limit for this event type has been reached",
"duration_limit_reached": "Duration Limit for this event type has been reached",
@@ -1609,10 +1629,10 @@
"delete_sso_configuration_confirmation_description": "Are you sure you want to delete the {{connectionType}} configuration? Your team members who use {{connectionType}} login will no longer be able to access Cal.com.",
"organizer_timezone": "Organizer timezone",
"email_user_cta": "View Invitation",
"email_no_user_invite_heading": "You’ve been invited to join a team on {{appName}}",
"email_no_user_invite_heading": "You’ve been invited to join a {{appName}} {{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} has invited you to join their team on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
"email_user_invite_subheading": "{{invitedBy}} has invited you to join their team `{{teamName}}` on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
"email_no_user_invite_steps_intro": "We’ll walk you through a few short steps and you’ll be enjoying stress free scheduling with your team in no time.",
"email_user_invite_subheading": "{{invitedBy}} has invited you to join their {{entity}} `{{teamName}}` on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your {{entity}} to schedule meetings without the email tennis.",
"email_no_user_invite_steps_intro": "We’ll walk you through a few short steps and you’ll be enjoying stress free scheduling with your {{entity}} in no time.",
"email_no_user_step_one": "Choose your username",
"email_no_user_step_two": "Connect your calendar account",
"email_no_user_step_three": "Set your Availability",
@@ -1623,6 +1643,8 @@
"scheduler": "{Scheduler}",
"no_workflows": "No workflows",
"change_filter": "Change filter to see your personal and team workflows.",
"change_filter_common": "Change filter to see the results.",
"no_results_for_filter": "No results for the filter",
"recommended_next_steps": "Recommended next steps",
"create_a_managed_event": "Create a managed event type",
"meetings_are_better_with_the_right": "Meetings are better with the right team members there. Invite them now.",
@@ -1633,8 +1655,9 @@
"no_longer_attending": "You are no longer attending this event",
"attendee_no_longer_attending_subject": "An attendee is no longer attending {{title}} at {{date}}",
"attendee_no_longer_attending": "An attendee is no longer attending your event",
"attendee_no_longer_attending_subtitle": "{{name}} has cancelled. This means a seat has opened up for this time slot",
"attendee_no_longer_attending_subtitle": "{{name}} has canceled. This means a seat has opened up for this time slot",
"create_event_on": "Create event on",
"create_routing_form_on": "Create routing form on",
"default_app_link_title": "Set a default app link",
"default_app_link_description": "Setting a default app link allows all newly created event types to use the app link you set.",
"organizer_default_conferencing_app": "Organizer's default app",
@@ -1652,10 +1675,10 @@
"booking_confirmation_failed": "Booking confirmation failed",
"not_enough_seats": "Not enough seats",
"form_builder_field_already_exists": "A field with this name already exists",
"show_on_booking_page":"Show on booking page",
"show_on_booking_page": "Show on booking page",
"get_started_zapier_templates": "Get started with Zapier templates",
"team_is_unpublished": "{{team}} is unpublished",
"team_is_unpublished_description": "This team link is currently not available. Please contact the team owner or ask them publish it.",
"team_is_unpublished_description": "This {{entity}} link is currently not available. Please contact the {{entity}} owner or ask them publish it.",
"team_member": "Team member",
"a_routing_form": "A Routing Form",
"form_description_placeholder": "Form Description",
@@ -1687,7 +1710,7 @@
"no_responses_yet": "No responses yet",
"no_routes_defined": "No routes defined",
"this_will_be_the_placeholder": "This will be the placeholder",
"error_booking_event": "An error occured when booking the event, please refresh the page and try again",
"error_booking_event": "An error occurred when booking the event, please refresh the page and try again",
"timeslot_missing_title": "No timeslot selected",
"timeslot_missing_description": "Please select a timeslot to book the event.",
"timeslot_missing_cta": "Select timeslot",
@@ -1703,6 +1726,7 @@
"app_is_connected": "{{dependencyName}} is connected",
"requires_app": "Requires {{dependencyName}}",
"verification_code": "Verification code",
"invalid_verification_link": "Invalid verification link",
"can_you_try_again": "Can you try again with a different time?",
"verify": "Verify",
"timezone_info": "The timezone of the person receiving",
@@ -1749,7 +1773,7 @@
"least_booked_members": "Least Booked Members",
"events_created": "Events Created",
"events_completed": "Events Completed",
"events_cancelled": "Events Cancelled",
"events_cancelled": "Events Canceled",
"events_rescheduled": "Events Rescheduled",
"from_last_period": "from last period",
"from_to_date_period": "From: {{startDate}} To: {{endDate}}",
@@ -1810,19 +1834,64 @@
"open_dialog_with_element_click": "Open your Cal dialog when someone clicks an element.",
"need_help_embedding": "Need help? See our guides for embedding Cal on Wix, Squarespace, or WordPress, check our common questions, or explore advanced embed options.",
"book_my_cal": "Book my Cal",
"invite_as":"Invite as",
"form_updated_successfully":"Form updated successfully.",
"email_not_cal_member_cta": "Join your team",
"invite_as": "Invite as",
"form_updated_successfully": "Form updated successfully.",
"disable_attendees_confirmation_emails": "Disable default confirmation emails for attendees",
"disable_attendees_confirmation_emails_description": "At least one workflow is active on this event type that sends an email to the attendees when the event is booked.",
"disable_host_confirmation_emails": "Disable default confirmation emails for host",
"disable_host_confirmation_emails_description": "At least one workflow is active on this event type that sends an email to the host when the event is booked.",
"add_an_override": "Add an override",
"import_from_google_workspace":"Import users from Google Workspace",
"connect_google_workspace":"Connect Google Workspace",
"google_workspace_admin_tooltip":"You must be a Workspace Admin to use this feature",
"import_from_google_workspace": "Import users from Google Workspace",
"connect_google_workspace": "Connect Google Workspace",
"google_workspace_admin_tooltip": "You must be a Workspace Admin to use this feature",
"first_event_type_webhook_description": "Create your first webhook for this event type",
"create_for": "Create for",
"setup_organization": "Setup an Organization",
"organization_banner_description": "Create an environments where your teams can create shared apps, workflows and event types with round-robin and collective scheduling.",
"organization_banner_title": "Manage organizations with multiple teams",
"set_up_your_organization": "Set up your organization",
"organizations_description": "Organizations are shared environments where teams can create shared event types, apps, workflows and more.",
"organization_url_taken": "This URL is already taken",
"must_enter_organization_name": "Must enter an organization name",
"must_enter_organization_admin_email": "Must enter your organization email address",
"admin_email": "Your organization email address",
"admin_username": "Administrator's username",
"organization_name": "Organization name",
"organization_url": "Organization URL",
"organization_verify_header": "Verify your organization email",
"organization_verify_email_body": "Please use the code below to verify your email address to continue setting up your organization.",
"additional_url_parameters": "Additional URL parameters",
"about_your_organization": "About your organization",
"about_your_organization_description": "Organizations are shared environments where you can create multiple teams with shared members, event types, apps, workflows and more.",
"create_your_teams": "Create your teams",
"create_your_teams_description": "Start scheduling together by adding your team members to your organization",
"invite_organization_admins": "Invite your organization admins",
"invite_organization_admins_description": "These admins will have access to all teams in your organization. You can add team admins and members later.",
"set_a_password": "Set a password",
"set_a_password_description": "This will create a new user account with your organization email and this password.",
"organization_logo": "Organization Logo",
"organization_about_description": "A few sentences about your organization. This will appear on your organization public profile page.",
"ill_do_this_later": "I'll do this later",
"verify_your_email": "Verify your email",
"enter_digit_code": "Enter the 6 digit code we sent to {{email}}",
"verify_email_organization": "Verify your email to create an organization",
"code_provided_invalid": "The code provided is not valid, try again",
"email_already_used": "Email already being used",
"duplicated_slugs_warning": "The following teams couldn't be created due to duplicated slugs: {{slugs}}",
"team_names_empty": "Team names can't be empty",
"team_names_repeated": "Team names can't be repeated",
"user_belongs_organization": "User belongs to an organization",
"no_teams_yet": "This organization has no teams yet",
"no_teams_yet_description": "if you are an administrator, be sure to create teams to be shown here.",
"set_up": "Set up",
"set_up_your_profile": "Set up your profile",
"set_up_your_profile_description": "Let people know who you are within {{orgName}}, and when they engage with your public link.",
"my_profile": "My Profile",
"my_settings": "My Settings",
"sender_id_info": "Name or number shown as the sender of an SMS (some countries do not allow alphanumeric sender IDs)",
"no_organization_slug": "There was an error creating teams for this organization. Missing URL slug.",
"org_name": "Organization name",
"org_url": "Organization URL",
"copy_link_org": "Copy link to organization",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
}
+7 -24
View File
@@ -12,10 +12,8 @@
"have_any_questions": "¿Tienes preguntas? Estamos aquí para ayudar.",
"reset_password_subject": "{{appName}}: Instrucciones para restablecer la contraseña",
"event_declined_subject": "Rechazado: {{title}} en {{date}}",
"event_cancelled_subject": "Cancelado: {{title}} en {{date}}",
"event_request_declined": "Su solicitud de reunión ha sido rechazada",
"event_request_declined_recurring": "Su solicitud de evento recurrente se ha rechazado",
"event_request_cancelled": "Tu evento programado fue cancelado",
"organizer": "Organizador",
"need_to_reschedule_or_cancel": "¿Necesita reprogramar o cancelar?",
"cancellation_reason": "Motivo de la cancelación (opcional)",
@@ -77,9 +75,7 @@
"your_meeting_has_been_booked": "Su reunión ha sido reservada",
"event_type_has_been_rescheduled_on_time_date": "Tu {{title}} ha sido reprogramado para el {{date}}.",
"event_has_been_rescheduled": "Tu evento ha sido reprogramado.",
"request_reschedule_subtitle": "{{organizer}} ha cancelado la reserva y le ha solicitado que elija otra hora.",
"request_reschedule_title_organizer": "Le ha solicitado a {{attendee}} que reprograme",
"request_reschedule_subtitle_organizer": "Ha cancelado la reserva y {{attendee}} deberá seleccionar una nueva hora de reserva con usted.",
"rescheduled_event_type_subject": "Solicitud de reprogramación enviada: {{eventType}} con {{name}} el {{date}}",
"requested_to_reschedule_subject_attendee": "Reprogramar acción requerida: reserva una nueva hora para {{eventType}} con {{name}}",
"hi_user_name": "Hola {{name}}",
@@ -119,6 +115,7 @@
"team_upgrade_banner_description": "Gracias por probar nuestro nuevo plan de equipo. Notamos que su equipo \"{{teamName}}\" necesita actualizarse.",
"team_upgrade_banner_action": "Actualizar aquí",
"team_upgraded_successfully": "¡Tu equipo se actualizó con éxito!",
"org_upgrade_banner_action": "Actualizar aquí",
"use_link_to_reset_password": "Utilice el enlace de abajo para restablecer su contraseña",
"hey_there": "Hola,",
"forgot_your_password_calcom": "¿Olvidaste tu contraseña? - {{appName}}",
@@ -228,6 +225,7 @@
"done": "Hecho",
"all_done": "¡Todo listo!",
"all_apps": "Todas las aplicaciones",
"all": "Todas las aplicaciones",
"available_apps": "Aplicaciones disponibles",
"check_email_reset_password": "Revisa tu email. Te hemos enviado un enlace para restablecer tu contraseña.",
"finish": "Terminar",
@@ -301,7 +299,6 @@
"error_end_time_next_day": "La hora final no puede ser mayor de 24 horas",
"back_to_bookings": "Volver a Reservas",
"free_to_pick_another_event_type": "No dude en elegir otro evento en cualquier momento.",
"cancelled": "Cancelado",
"cancellation_successful": "Cancelación Realizada",
"really_cancel_booking": "¿Realmente deseas cancelar tu reserva?",
"cannot_cancel_booking": "No puedes cancelar esta reserva",
@@ -310,7 +307,6 @@
"cancelling_event_recurring": "El evento es un caso de un evento recurrente.",
"cancelling_all_recurring": "Todas estas son instancias restantes en el evento recurrente.",
"error_with_status_code_occured": "Se produjo un error con el código de estado {{status}}.",
"booking_already_cancelled": "Esta reserva ya fue cancelada",
"booking_already_accepted_rejected": "Esta reserva ya se aceptó o rechazó",
"go_back_home": "Volver a Inicio",
"or_go_back_home": "O Volver al Inicio",
@@ -324,7 +320,6 @@
"upcoming_bookings": "Tan pronto como alguien reserve una hora contigo, aparecerá aquí.",
"recurring_bookings": "Tan pronto como alguien reserve una reunión recurrente con usted, aparecerá aquí.",
"past_bookings": "Sus reservas pasadas aparecerán aquí.",
"cancelled_bookings": "Las reservas canceladas aparecerán aquí.",
"unconfirmed_bookings": "Las reservas sin confirmar aparecerán aquí.",
"unconfirmed_bookings_tooltip": "Reservas sin confirmar",
"on": "en",
@@ -364,7 +359,6 @@
"browse_api_documentation": "Consulte la documentación de nuestra API",
"leverage_our_api": "Aproveche nuestra API para un control total y personalización.",
"create_webhook": "Crear Webhook",
"booking_cancelled": "Reserva Cancelada",
"booking_rescheduled": "Reserva habilitada",
"recording_ready": "Enlace de descarga de grabación listo",
"booking_created": "Reserva Creada",
@@ -377,8 +371,6 @@
"team_webhooks": "Webhooks del equipo",
"create_new_webhook_to_account": "Crear un nuevo webhook en tu cuenta",
"new_webhook": "Nuevo Webhook",
"receive_cal_meeting_data": "Reciba datos de reuniones de {{appName}} en una URL específica, en tiempo real, cuando se programe o cancele un evento.",
"receive_cal_event_meeting_data": "Reciba los datos de la reunión de {{appName}} en una URL especificada, en tiempo real, cuando este evento se programe o se cancele.",
"responsive_fullscreen_iframe": "Iframe receptivo a pantalla completa",
"loading": "Cargando...",
"deleting": "Eliminando...",
@@ -514,6 +506,8 @@
"team_description": "Comentarios sobre tu equipo. Esta información aparecerá en la página de la URL de tu equipo.",
"members": "Miembros",
"member": "Miembro",
"number_member_one": "{{count}} miembro",
"number_member_other": "{{count}} miembros",
"owner": "Propietario",
"admin": "Administrador",
"administrator_user": "Usuario administrador",
@@ -1014,14 +1008,12 @@
"event_location": "Ubicación del evento",
"reschedule_optional": "Razón para reagendar (opcional)",
"reschedule_placeholder": "Informa a los demás la razón por la que necesitas reagendar",
"event_cancelled": "Este evento se canceló",
"emailed_information_about_cancelled_event": "Le enviamos un correo electrónico a usted y a los demás asistentes para informarles.",
"this_input_will_shown_booking_this_event": "Esta entrada se mostrará al reservar este evento.",
"meeting_url_in_conformation_email": "La URL de la reunión está en el correo de confirmación",
"url_start_with_https": "La URL debe empezar por http:// o https://",
"number_provided": "Se proporcionará el número de teléfono",
"before_event_trigger": "antes del inicio del evento",
"event_cancelled_trigger": "cuando se cancela el evento",
"new_event_trigger": "cuando se reserva un nuevo evento",
"email_host_action": "enviar correo electrónico al anfitrión",
"email_attendee_action": "enviar correo electrónico a los asistentes",
@@ -1183,7 +1175,6 @@
"start_of_week": "Inicio de la semana",
"recordings_title": "Grabaciones",
"recording": "Grabación",
"happy_scheduling": "Feliz programación",
"select_calendars": "Seleccione los calendarios en los que desee comprobar conflictos para evitar reservas dobles.",
"check_for_conflicts": "Comprobar conflictos",
"view_recordings": "Ver grabaciones",
@@ -1410,7 +1401,6 @@
"your_team_disbanded_successfully": "Su equipo se ha disuelto con éxito",
"error_creating_team": "Error al crear el equipo",
"you": "Usted",
"send_email": "Enviar correo electrónico",
"member_already_invited": "El miembro ya se ha invitado",
"enter_email_or_username": "Introduzca un correo electrónico o nombre de usuario",
"team_name_taken": "Este nombre ya está en uso",
@@ -1423,7 +1413,7 @@
"attendee_email_info": "El correo electrónico de la persona que reserva",
"kbar_search_placeholder": "Escriba un comando o búsqueda...",
"invalid_credential": "¡Oh no! Parece que el permiso ha caducado o se ha revocado. Vuelva a instalarlo.",
"reschedule_reason_success_page": "Razón de la reprogramación",
"reschedule_reason": "Razón de la reprogramación",
"choose_common_schedule_team_event": "Elige un horario común para todos",
"choose_common_schedule_team_event_description": "Habilite esto si desea utilizar un cronograma común entre anfitriones. Cuando esté desactivado, cada anfitrión se reservará en relación a su horario predeterminado.",
"reason": "Motivo",
@@ -1578,10 +1568,7 @@
"delete_sso_configuration_confirmation_description": "¿Está seguro de que desea eliminar la configuración de {{connectionType}}? Los miembros de su equipo que utilicen el inicio de sesión {{connectionType}} ya no podrán acceder a Cal.com.",
"organizer_timezone": "Zona horaria del organizador",
"email_user_cta": "Ver la invitación",
"email_no_user_invite_heading": "Lo han invitado a unirse a un equipo en {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} lo invitó a unirse a su equipo en {{appName}}. {{appName}} es el programador de eventos que les permite a usted y a su equipo programar reuniones sin necesidad de enviar correos electrónicos.",
"email_user_invite_subheading": "{{invitedBy}} lo ha invitado a unirse a su equipo \"{{teamName}}\" en {{appName}}. {{appName}} es el planificador de eventos que le permite a usted y a su equipo programar reuniones sin correos electrónicos de ida y vuelta.",
"email_no_user_invite_steps_intro": "Lo guiaremos a través de unos pocos pasos y disfrutará de una programación con su equipo sin estresarse y empleando muy poco tiempo.",
"email_no_user_step_one": "Elija su nombre de usuario",
"email_no_user_step_two": "Conecte su cuenta de calendario",
"email_no_user_step_three": "Establezca su disponibilidad",
@@ -1602,7 +1589,6 @@
"no_longer_attending": "Ya no asistirá a este evento",
"attendee_no_longer_attending_subject": "Un asistente ya no asistirá a {{title}} a las {{date}}",
"attendee_no_longer_attending": "Un asistente ya no asistirá a su evento",
"attendee_no_longer_attending_subtitle": "{{name}} ha cancelado. Esto significa que está disponible una plaza para esta franja horaria",
"create_event_on": "Crear evento en",
"default_app_link_title": "Establecer un enlace de aplicación predeterminado",
"default_app_link_description": "Establecer un enlace de aplicación predeterminado permite que todos los tipos de eventos recién creados utilicen el enlace de aplicación que establezca.",
@@ -1623,7 +1609,6 @@
"show_on_booking_page": "Mostrar en la página de reserva",
"get_started_zapier_templates": "Comience con las plantillas de Zapier",
"team_is_unpublished": "{{team}} no está publicado",
"team_is_unpublished_description": "Este enlace del equipo no está disponible actualmente. Póngase en contacto con el propietario del equipo o pídale que lo publique.",
"team_member": "Miembro del equipo",
"a_routing_form": "Un formulario de enrutamiento",
"form_description_placeholder": "Descripción del formulario",
@@ -1654,7 +1639,6 @@
"spot_popular_event_types_description": "Consulte cuál de sus tipos de eventos están recibiendo más clics y reservas",
"no_responses_yet": "Aún no hay respuestas",
"this_will_be_the_placeholder": "Este será el marcador de posición",
"error_booking_event": "Ocurrió un error al reservar el evento, actualice la página e intente nuevamente",
"timeslot_missing_title": "No hay intervalo de tiempo seleccionado",
"timeslot_missing_description": "Seleccione un intervalo de tiempo para reservar el evento.",
"timeslot_missing_cta": "Seleccionar intervalo de tiempo",
@@ -1715,7 +1699,6 @@
"least_booked_members": "Miembros con menos reservas",
"events_created": "Eventos creados",
"events_completed": "Eventos completados",
"events_cancelled": "Eventos cancelados",
"events_rescheduled": "Eventos reprogramados",
"from_last_period": "desde el último período",
"from_to_date_period": "Desde: {{startDate}} Hasta: {{endDate}}",
@@ -1767,7 +1750,6 @@
"book_my_cal": "Reservar mi Cal",
"invite_as": "Invitar como",
"form_updated_successfully": "Formulario actualizado con éxito.",
"email_not_cal_member_cta": "Únase a su equipo",
"disable_attendees_confirmation_emails": "Desactivar los correos electrónicos de confirmación predeterminados para los asistentes",
"disable_attendees_confirmation_emails_description": "Al menos un flujo de trabajo está activo en este tipo de evento que envía un correo electrónico a los asistentes cuando se reserva el evento.",
"disable_host_confirmation_emails": "Desactivar los correos electrónicos de confirmación predeterminados para el anfitrión",
@@ -1777,5 +1759,6 @@
"connect_google_workspace": "Conectar Google Workspace",
"google_workspace_admin_tooltip": "Debe ser administrador del espacio de trabajo para usar esta función",
"first_event_type_webhook_description": "Cree su primer webhook para este tipo de evento",
"create_for": "Crear para"
"create_for": "Crear para",
"organization_url_taken": "Esta URL ya está en uso"
}
@@ -14,10 +14,8 @@
"verify_email_email_header": "Egiaztatu zure email helbidea",
"verify_email_email_button": "Egiaztatu emaila",
"event_declined_subject": "Baztertua: {{title}} {{date}}(e)an",
"event_cancelled_subject": "Bertan behera: {{title}} {{date}}(e)an",
"event_request_declined": "Zure gertaera-eskaera baztertua izan da",
"event_request_declined_recurring": "Zure gertaera errepikari-eskaera baztertua izan da",
"event_request_cancelled": "Zure programatutako gertaera baztertua izan da",
"organizer": "Antolatzailea",
"need_to_reschedule_or_cancel": "Programazioa aldatu edo bertan behera utzi behar duzu?",
"cancellation_reason": "Bertan behera uztearen arrazoia (aukerakoa)",
@@ -62,14 +60,11 @@
"back_to_bookings": "Itzuli erreserbatara",
"really_cancel_booking": "Benetan bertan behera utzi nahi duzu zure erreserba?",
"cannot_cancel_booking": "Ezin duzu erreserba hau bertan behera utzi",
"booking_already_cancelled": "Erreserba hau bertan behera utzi da dagoeneko",
"booking_already_accepted_rejected": "Erreserba hau onartu edo errefusatu da dagoeneko",
"bookings": "Erreserbak",
"past_bookings": "Zure iraganeko erreserbak agertuko dira hemen.",
"cancelled_bookings": "Zure bertan behera utzitako erreserbak agertuko dira hemen.",
"unconfirmed_bookings": "Zure baieztatu gabeko erreserbak agertuko dira hemen.",
"unconfirmed_bookings_tooltip": "Baieztatu gabeko erreserbak",
"booking_cancelled": "Erreserba bertan behera",
"booking_rescheduled": "Erreserbaren programazioa aldatuta",
"booking_created": "Erreserba sortuta",
"edit_booking": "Aldatu erreserba",
+96 -23
View File
@@ -14,7 +14,7 @@
"verify_email_subject": "{{appName}} : Vérifiez votre compte",
"check_your_email": "Vérifiez votre e-mail",
"verify_email_page_body": "Nous avons envoyé un e-mail à {{email}}. Il est important de vérifier votre adresse e-mail pour garantir la meilleure délivrabilité des e-mails et des calendriers de {{appName}}.",
"verify_email_banner_body": "Veuillez vérifier votre adresse e-mail pour garantir la meilleure délivrabilité des e-mails et des calendriers de {{appName}}.",
"verify_email_banner_body": "Vérifiez votre adresse e-mail pour garantir la meilleure délivrabilité des e-mails et des calendriers",
"verify_email_email_header": "Vérifiez votre adresse e-mail",
"verify_email_email_button": "Vérifier l'adresse e-mail",
"verify_email_email_body": "Veuillez vérifier votre adresse e-mail en cliquant sur le bouton ci-dessous.",
@@ -117,7 +117,7 @@
"team_info": "Informations sur l'équipe",
"request_another_invitation_email": "Si vous préférez ne pas utiliser {{toEmail}} comme votre adresse e-mail {{appName}} ou si vous avez déjà un compte {{appName}}, veuillez demander une autre invitation à cette adresse.",
"you_have_been_invited": "Vous avez été invité(e) à rejoindre l'équipe {{teamName}}",
"user_invited_you": "{{user}} vous a invité(e) à rejoindre l'équipe {{team}} sur {{appName}}",
"user_invited_you": "{{user}} vous a invité à rejoindre l'équipe {{team}} sur {{appName}}",
"hidden_team_member_title": "Vous êtes masqué(e) dans cette équipe",
"hidden_team_member_message": "Votre place n'est pas payée, passez au plan Pro ou faites savoir au propriétaire de l'équipe qu'il peut payer votre place.",
"hidden_team_owner_message": "Vous avez besoin d'un compte Pro pour utiliser les équipes, vous êtes masqué(e) jusqu'à ce que vous mettiez à niveau.",
@@ -128,6 +128,9 @@
"team_upgrade_banner_description": "Merci d'avoir essayé notre nouveau plan Équipes. Nous avons remarqué que votre équipe « {{teamName}} » doit être mise à niveau.",
"team_upgrade_banner_action": "Mettre à niveau",
"team_upgraded_successfully": "Votre équipe a été mise à niveau avec succès !",
"org_upgrade_banner_description": "Merci d'avoir testé notre plan Organisation. Nous avons remarqué que votre organisation « {{teamName}} » doit être mise à niveau.",
"org_upgrade_banner_action": "Mettre à niveau",
"org_upgraded_successfully": "Votre organisation a été mise à niveau avec succès !",
"use_link_to_reset_password": "Utilisez le lien ci-dessous pour réinitialiser votre mot de passe",
"hey_there": "Salut,",
"forgot_your_password_calcom": "Mot de passe oublié ? - {{appName}}",
@@ -238,9 +241,12 @@
"done": "Terminé",
"all_done": "Terminé !",
"all_apps": "Toutes",
"all": "Tous",
"yours": "Les vôtres",
"available_apps": "Applications disponibles",
"check_email_reset_password": "Vérifiez vos e-mails. Nous vous avons envoyé un lien pour réinitialiser votre mot de passe.",
"finish": "Terminer",
"organization_general_description": "Gérez les paramètres de langue et de fuseau horaire de votre équipe.",
"few_sentences_about_yourself": "Quelques mots à propos de vous. Ces informations apparaîtront sur votre page publique.",
"nearly_there": "C'est bientôt terminé !",
"nearly_there_instructions": "Pour finir, une brève description de vous et une photo vous aideront vraiment à obtenir des réservations et à faire savoir aux gens avec qui ils prennent rendez-vous.",
@@ -300,13 +306,14 @@
"failed": "Échoué",
"password_has_been_reset_login": "Votre mot de passe a été réinitialisé. Vous pouvez désormais vous connecter avec votre nouveau mot de passe.",
"bookerlayout_title": "Mise en page",
"layout": "Mise en page",
"bookerlayout_default_title": "Vue par défaut",
"bookerlayout_description": "Vous pouvez en sélectionner plusieurs, vos utilisateurs peuvent basculer entre les vues.",
"bookerlayout_user_settings_title": "Mise en page de réservation",
"bookerlayout_user_settings_description": "Vous pouvez en sélectionner plusieurs, les utilisateurs peuvent basculer entre les vues. Cela peut être remplacé individuellement pour événement.",
"bookerlayout_month_view": "Mensuelle",
"bookerlayout_week_view": "Hebdomadaire",
"bookerlayout_column_view": "Colonne",
"bookerlayout_column_view": "Colonnes",
"bookerlayout_error_min_one_enabled": "Au moins une mise en page doit être activée.",
"bookerlayout_error_default_not_enabled": "La mise en page sélectionnée comme vue par défaut ne fait pas partie des mises en page activées.",
"bookerlayout_error_unknown_layout": "La mise en page que vous avez sélectionnée n'est pas une mise en page valide.",
@@ -342,6 +349,7 @@
"no_status_bookings_yet_description": "Vous n'avez pas de réservations {{status}}. {{description}}",
"event_between_users": "{{eventName}} entre {{host}} et {{attendeeName}}",
"bookings": "Réservations",
"booking_not_found": "Réservation introuvable",
"bookings_description": "Consultez les événements à venir et passés réservés via vos liens de type d'événement.",
"upcoming_bookings": "Dès que quelqu'un réservera un rendez-vous avec vous, il apparaîtra ici.",
"recurring_bookings": "Dès que quelqu'un réserve un rendez-vous récurrent avec vous, il apparaît ici.",
@@ -389,7 +397,7 @@
"create_webhook": "Créer un webhook",
"booking_cancelled": "Réservation annulée",
"booking_rescheduled": "Réservation replanifiée",
"recording_ready": "Lien de téléchargement d'enregistrement prêt",
"recording_ready": "Lien de téléchargement de l'enregistrement prêt",
"booking_created": "Réservation créée",
"booking_rejected": "Réservation rejetée",
"booking_requested": "Réservation demandée",
@@ -462,7 +470,7 @@
"password_hint_caplow": "Mélange de lettres majuscules et minuscules",
"password_hint_min": "7 caractères minimum",
"password_hint_admin_min": "Minimum 15 caractères",
"password_hint_num": "Contient au moins 1 chiffre",
"password_hint_num": "Doit contenir au moins 1 chiffre",
"max_limit_allowed_hint": "Doit contenir {{limit}} caractères ou moins",
"invalid_password_hint": "Le mot de passe doit contenir au moins {{passwordLength}} caractères, un chiffre et un mélange de lettres majuscules et minuscules.",
"incorrect_password": "Le mot de passe est incorrect.",
@@ -537,8 +545,12 @@
"your_team_updated_successfully": "Votre équipe a été mise à jour avec succès.",
"about": "À propos",
"team_description": "Quelques mots à propos de votre équipe. Ces informations apparaîtront sur la page publique de votre équipe.",
"org_description": "Quelques phrases à propos de votre organisation. Elles apparaîtront sur la page de profil public de votre organisation.",
"members": "Membres",
"organization_members": "Membres de l'organisation",
"member": "Membre",
"number_member_one": "{{count}} membre",
"number_member_other": "{{count}} membres",
"owner": "Propriétaire",
"admin": "Administrateur",
"administrator_user": "Utilisateur administrateur",
@@ -569,6 +581,8 @@
"confirm_all": "Confirmer tout",
"disband_team": "Dissoudre l'équipe",
"disband_team_confirmation_message": "Voulez-vous vraiment dissoudre cette équipe ? Toute personne avec qui vous avez partagé ce lien d'équipe ne pourra plus faire de réservation en l'utilisant.",
"disband_org": "Dissoudre l'organisation",
"disband_org_confirmation_message": "Voulez-vous vraiment dissoudre cette organisation ? Toutes les équipes et tous les membres seront supprimés.",
"remove_member_confirmation_message": "Voulez-vous vraiment supprimer ce membre de l'équipe ?",
"confirm_disband_team": "Oui, dissoudre l'équipe",
"confirm_remove_member": "Oui, retirer le membre",
@@ -679,6 +693,7 @@
"create_team_to_get_started": "Créez une équipe pour commencer",
"teams": "Équipes",
"team": "Équipe",
"organization": "Organisation",
"team_billing": "Facturation de l'équipe",
"team_billing_description": "Gérez la facturation pour votre équipe.",
"upgrade_to_flexible_pro_title": "Nous avons modifié la facturation pour les équipes",
@@ -776,7 +791,7 @@
"slot_interval_default": "Utiliser la durée de l'événement (par défaut)",
"delete_event_type": "Supprimer le type d'événement ?",
"delete_managed_event_type": "Supprimer le type d'événement géré ?",
"delete_event_type_description": "Toute personne avec qui vous avez partagé ce lien ne pourra plus réserver en l'utilisant.",
"delete_event_type_description": "Toute personne avec qui vous avez partagé ce lien ne pourra plus réserver avec.",
"delete_managed_event_type_description": "<ul><li>Les membres affectés à ce type d'événement verront également leurs types d'événement supprimés.</li><li>Toute personne avec qui ils ont partagé leur lien ne pourra plus réserver en l'utilisant.</li></ul>",
"confirm_delete_event_type": "Oui, supprimer",
"delete_account": "Supprimer le compte",
@@ -854,6 +869,7 @@
"installed_app_payment_description": "Configurez les services de traitement de paiement à utiliser lors de la facturation de vos clients.",
"installed_app_analytics_description": "Configurez les applications d'analyse à utiliser pour vos pages de réservation.",
"installed_app_other_description": "Toutes vos applications installées à partir d'autres catégories.",
"installed_app_conferencing_description": "Configurez les applications de conférence à utiliser.",
"installed_app_automation_description": "Configurez les applications d'automatisation à utiliser.",
"installed_app_web3_description": "Configurez les applications Web3 à utiliser pour vos pages de réservation.",
"analytics": "Analytiques",
@@ -889,7 +905,7 @@
"the_infrastructure_plan": "Le plan d'infrastructure est basé sur l'utilisation et propose des réductions adaptées aux startups.",
"prisma_studio_tip": "Créer un compte via Prisma Studio",
"prisma_studio_tip_description": "Découvrez comment configurer votre premier utilisateur",
"contact_sales": "Contacter les ventes",
"contact_sales": "Contacter le service commercial",
"error_404": "Erreur 404",
"default": "Par défaut",
"set_to_default": "Définir par défaut",
@@ -1291,8 +1307,10 @@
"for_a_maximum_of": "Pour un maximum de",
"event_one": "événement",
"event_other": "événements",
"profile_team_description": "Gérez les paramètres de votre profil d'équipe.",
"profile_team_description": "Gérez les paramètres du profil de votre équipe.",
"profile_org_description": "Gérez les paramètres de votre profil d'organisation.",
"members_team_description": "Utilisateurs présents dans le groupe.",
"organization_description": "Gérez les administrateurs et les membres de votre organisation.",
"team_url": "Lien de l'équipe",
"team_members": "Membres de l'équipe",
"more": "Plus",
@@ -1333,6 +1351,7 @@
"routing_forms_send_email_owner": "Envoyer un e-mail au propriétaire",
"routing_forms_send_email_owner_description": "Envoie un e-mail au propriétaire lorsque le formulaire est soumis",
"add_new_form": "Ajouter un nouveau formulaire",
"add_new_team_form": "Ajouter un nouveau formulaire à votre équipe",
"create_your_first_route": "Créez votre première route",
"route_to_the_right_person": "Acheminez vers la bonne personne en fonction des réponses à votre formulaire.",
"form_description": "Créez votre formulaire pour rediriger un utilisateur.",
@@ -1436,9 +1455,10 @@
"yearly": "Annuellement",
"checkout": "Paiement",
"your_team_disbanded_successfully": "Votre équipe a bien été dissoute",
"your_org_disbanded_successfully": "Votre organisation a bien été dissoute",
"error_creating_team": "Erreur lors de la création de l'équipe",
"you": "Vous",
"send_email": "Envoyer un e-mail",
"resend_email": "Renvoyer l’e-mail",
"member_already_invited": "Le membre a déjà été invité",
"enter_email_or_username": "Saisissez une adresse e-mail ou un nom d'utilisateur",
"team_name_taken": "Ce nom est déjà pris",
@@ -1451,7 +1471,7 @@
"attendee_email_info": "Adresse e-mail du participant",
"kbar_search_placeholder": "Saisissez une commande ou une recherche...",
"invalid_credential": "Oh non ! On dirait que l’autorisation a expiré ou a été révoquée. Veuillez la réinstaller.",
"reschedule_reason_success_page": "Raison de la replanification",
"reschedule_reason": "Raison de la replanification",
"choose_common_schedule_team_event": "Choisissez un horaire commun",
"choose_common_schedule_team_event_description": "Activez cette option si vous souhaitez utiliser des disponibilités communes entre les hôtes. Si cette option est désactivée, chaque hôte recevra les réservations en fonction de ses disponibilités par défaut.",
"reason": "Raison",
@@ -1479,7 +1499,7 @@
"event_replaced_notice": "Un administrateur a remplacé l'un de vos types d'événements",
"email_subject_slug_replacement": "Un administrateur d'équipe a remplacé votre événement /{{slug}}",
"email_body_slug_replacement_notice": "Un administrateur de l'équipe <strong>{{teamName}}</strong> a remplacé votre type d'événement <strong>/{{slug}}</strong> par un type d'événement géré qu'il contrôle.",
"email_body_slug_replacement_info": "Votre lien continuera à fonctionner, mais certains de ses paramètres peuvent avoir changé. Vous pouvez l'examiner dans les types d'événements.",
"email_body_slug_replacement_info": "Votre lien continuera de fonctionner, mais certains de ses paramètres peuvent avoir changé. Vous pouvez l'examiner dans les types d'événements.",
"email_body_slug_replacement_suggestion": "Si vous avez des questions sur le type d'événement, veuillez contacter votre administrateur.<br /><br />Bonne planification, <br />L'équipe Cal.com",
"disable_payment_app": "L'administrateur a désactivé {{appName}} qui affecte votre type d'événement {{title}}. Les participants sont toujours en mesure de réserver ce type d'événement, mais ne seront pas invités à payer. Vous pouvez masquer le type d'événement pour l'empêcher jusqu'à ce que votre administrateur réactive votre moyen de paiement.",
"payment_disabled_still_able_to_book": "Les participants sont toujours en mesure de réserver ce type d'événement, mais ne seront pas invités à payer. Vous pouvez masquer le type d'événement pour l'empêcher jusqu'à ce que votre administrateur réactive votre mode de paiement.",
@@ -1510,7 +1530,7 @@
"add_an_option": "Ajouter une option",
"radio": "Radio",
"google_meet_warning": "Pour utiliser Google Meet, vous devez définir votre calendrier de destination sur un calendrier Google",
"individual": "Individuel",
"individual": "Particulier",
"all_bookings_filter_label": "Toutes les réservations",
"all_users_filter_label": "Tous les utilisateurs",
"your_bookings_filter_label": "Vos réservations",
@@ -1609,10 +1629,10 @@
"delete_sso_configuration_confirmation_description": "Voulez-vous vraiment supprimer la configuration {{connectionType}} ? Les membres de votre équipe utilisant la connexion {{connectionType}} ne pourront plus accéder à Cal.com.",
"organizer_timezone": "Fuseau horaire de l'organisateur",
"email_user_cta": "Voir l'invitation",
"email_no_user_invite_heading": "Vous avez été invité(e) à rejoindre une équipe sur {{appName}}",
"email_no_user_invite_heading": "Vous avez été invité à rejoindre une {{entity}} {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} vous a invité à rejoindre son équipe sur {{appName}}. {{appName}} est le planificateur d'événements qui vous permet à vous et à votre équipe d'organiser des rendez-vous sans échanges d'e-mails.",
"email_user_invite_subheading": "{{invitedBy}} vous a invité à rejoindre son équipe « {{teamName}} » sur {{appName}}. {{appName}} est le planificateur d'événements qui vous permet à vous et à votre équipe d'organiser des rendez-vous sans échanges d'e-mails.",
"email_no_user_invite_steps_intro": "Nous vous guiderons à travers quelques étapes courtes et vous profiterez d'une planification sans stress avec votre équipe en un rien de temps.",
"email_user_invite_subheading": "{{invitedBy}} vous a invité à rejoindre son {{entity}} « {{teamName}} » sur {{appName}}. {{appName}} est le planificateur d'événements qui vous permet à vous et à votre {{entity}} d'organiser des rendez-vous sans échanges d'e-mails.",
"email_no_user_invite_steps_intro": "Nous vous guiderons à travers quelques étapes courtes et vous profiterez d'une planification sans stress avec votre {{entity}} en un rien de temps.",
"email_no_user_step_one": "Choisissez votre nom d'utilisateur",
"email_no_user_step_two": "Connectez votre compte de calendrier",
"email_no_user_step_three": "Définissez vos disponibilités",
@@ -1623,6 +1643,8 @@
"scheduler": "{Scheduler}",
"no_workflows": "Aucun workflow",
"change_filter": "Changez le filtre pour voir vos workflows personnels et d'équipe.",
"change_filter_common": "Changez le filtre pour voir les résultats.",
"no_results_for_filter": "Aucun résultat pour le filtre",
"recommended_next_steps": "Étapes suivantes recommandées",
"create_a_managed_event": "Créer un type d'événement géré",
"meetings_are_better_with_the_right": "Les rendez-vous sont meilleurs avec les bons membres d'équipe. Invitez-les maintenant.",
@@ -1635,6 +1657,7 @@
"attendee_no_longer_attending": "Un participant ne participe plus à votre événement",
"attendee_no_longer_attending_subtitle": "{{name}} a annulé. Cela signifie qu'une place s'est libérée pour ce créneau horaire",
"create_event_on": "Créer un événement dans",
"create_routing_form_on": "Créer un formulaire de routage sur",
"default_app_link_title": "Définir un lien d'application par défaut",
"default_app_link_description": "Définir un lien d'application par défaut permet à tous les nouveaux types d'événements d'utiliser le lien d'application que vous avez défini.",
"organizer_default_conferencing_app": "Application par défaut de l'organisateur",
@@ -1655,7 +1678,7 @@
"show_on_booking_page": "Afficher sur la page de réservation",
"get_started_zapier_templates": "Démarrer avec les modèles Zapier",
"team_is_unpublished": "{{team}} n'est pas publiée",
"team_is_unpublished_description": "Ce lien d'équipe n'est actuellement pas disponible. Veuillez contacter le propriétaire de l'équipe ou lui demander de le publier.",
"team_is_unpublished_description": "Ce lien d'{{entity}} n'est actuellement pas disponible. Veuillez contacter le propriétaire de l'{{entity}} ou lui demander de le publier.",
"team_member": "Membre d'équipe",
"a_routing_form": "Un formulaire de routage",
"form_description_placeholder": "Description du formulaire",
@@ -1694,7 +1717,7 @@
"switch_monthly": "Passer en vue mensuelle",
"switch_weekly": "Passer en vue hebdomadaire",
"switch_multiday": "Passer en vue journalière",
"switch_columnview": "Passer en vue colonne",
"switch_columnview": "Passer en vue colonnes",
"num_locations": "{{num}} options de lieu",
"select_on_next_step": "Sélectionner à l'étape suivante",
"this_meeting_has_not_started_yet": "Ce rendez-vous n'a pas encore commencé",
@@ -1703,6 +1726,7 @@
"app_is_connected": "{{dependencyName}} est connectée",
"requires_app": "Requiert {{dependencyName}}",
"verification_code": "Code de vérification",
"invalid_verification_link": "Lien de vérification introuvable",
"can_you_try_again": "Pouvez-vous réessayer avec un autre créneau ?",
"verify": "Vérifier",
"timezone_info": "Le fuseau horaire du destinataire",
@@ -1780,8 +1804,8 @@
"acknowledge_booking_no_show_fee": "Je reconnais que si je ne participe pas à cet événement, des frais d'absence de {{amount, currency}} seront appliqués à ma carte.",
"card_details": "Détails de la carte",
"seats_and_no_show_fee_error": "Il n'est pas possible d'activer les places et de facturer des frais d'absence pour le moment",
"complete_your_booking": "Terminer votre réservation",
"complete_your_booking_subject": "Terminer votre réservation : {{title}} le {{date}}",
"complete_your_booking": "Terminez votre réservation",
"complete_your_booking_subject": "Terminez votre réservation : {{title}} le {{date}}",
"confirm_your_details": "Confirmez vos coordonnées",
"copy_invite_link": "Copier le lien d'invitation",
"edit_invite_link": "Modifier les paramètres du lien",
@@ -1799,16 +1823,18 @@
"payment_app_commission": "Exiger un paiement ({{paymentFeePercentage}} % + {{fee, currency}} de commission par transaction)",
"email_invite_team": "{{email}} a été invité",
"email_invite_team_bulk": "{{userCount}} utilisateurs ont été invités",
"error_collecting_card": "Erreur lors de la collecte de la carte",
"error_collecting_card": "Erreur lors de la récupération de la carte",
"image_size_limit_exceed": "L'image téléchargée ne doit pas dépasser 5 Mo",
"unauthorized_workflow_error_message": "{{errorCode}} : Vous n'êtes pas autorisé à activer ou désactiver ce workflow",
"inline_embed": "Intégration en ligne",
"load_inline_content": "Charge votre type d'événement directement en ligne avec le contenu de votre site web.",
"floating_pop_up_button": "Bouton pop-up flottant",
"load_inline_content": "Charge votre type d'événement directement dans le contenu de votre site web.",
"floating_pop_up_button": "Bouton flottant",
"floating_button_trigger_modal": "Place un bouton flottant sur votre site qui déclenche une modale avec votre type d'événement.",
"pop_up_element_click": "Clic sur un élément",
"open_dialog_with_element_click": "Ouvre votre boîte de dialogue Cal lorsque quelqu'un clique sur un élément.",
"need_help_embedding": "Besoin d'aide ? Consultez nos guides pour intégrer Cal sur Wix, Squarespace ou WordPress, consultez nos questions fréquentes ou explorez les options d'intégration avancées.",
"invite_as": "Inviter en tant que",
"form_updated_successfully": "Formulaire mis à jour avec succès.",
"email_not_cal_member_cta": "Rejoignez votre équipe",
"disable_attendees_confirmation_emails": "Désactiver les e-mails de confirmation par défaut pour les participants",
"disable_attendees_confirmation_emails_description": "Au moins un workflow est actif sur ce type d'événement qui envoie un e-mail aux participants lorsque l'événement est réservé.",
"disable_host_confirmation_emails": "Désactiver les e-mails de confirmation par défaut pour l'hôte",
@@ -1816,8 +1842,55 @@
"add_an_override": "Ajouter une superposition",
"import_from_google_workspace": "Importer des utilisateurs depuis Google Workspace",
"connect_google_workspace": "Connecter Google Workspace",
"google_workspace_admin_tooltip": "Vous devez être un administrateur d'espace de travail pour utiliser cette fonctionnalité",
"first_event_type_webhook_description": "Créez votre premier webhook pour ce type d'événement",
"create_for": "Créer pour",
"setup_organization": "Configurer une organisation",
"organization_banner_description": "Créez un environnement où vos équipes peuvent créer des applications partagées, des workflows et des types d'événements avec une planification Round-Robin et collective.",
"organization_banner_title": "Gérer les organisations avec plusieurs équipes",
"set_up_your_organization": "Configurer votre organisation",
"organizations_description": "Les organisations sont des environnements partagés dans lesquels les équipes peuvent créer des types d'événements partagés, des applications, des workflows, etc.",
"organization_url_taken": "Ce lien est déjà pris",
"must_enter_organization_name": "Vous devez entrer un nom d'organisation",
"must_enter_organization_admin_email": "Vous devez entrer l'adresse e-mail de votre organisation",
"admin_email": "Adresse e-mail de votre organisation",
"admin_username": "Nom d'utilisateur de l'administrateur",
"organization_name": "Nom de l'organisation",
"organization_url": "Lien de l'organisation",
"organization_verify_header": "Vérifier l'adresse e-mail de votre organisation",
"organization_verify_email_body": "Veuillez utiliser le code ci-dessous pour vérifier votre adresse e-mail et continuer à configurer votre organisation.",
"additional_url_parameters": "Paramètres d'URL supplémentaires",
"about_your_organization": "À propos de votre organisation",
"about_your_organization_description": "Les organisations sont des environnements partagés dans lesquels vous pouvez créer plusieurs équipes avec des membres partagés, des types d'événements, des applications, des workflows, etc.",
"create_your_teams": "Créer vos équipes",
"create_your_teams_description": "Commencez à planifier ensemble en ajoutant les membres de votre équipe à votre organisation",
"invite_organization_admins": "Inviter les administrateurs de votre organisation",
"invite_organization_admins_description": "Ces administrateurs auront accès à toutes les équipes de votre organisation. Vous pouvez ajouter des administrateurs et des membres d'équipe plus tard.",
"set_a_password": "Définir un mot de passe",
"set_a_password_description": "Cela créera un nouveau compte utilisateur avec l'adresse e-mail de votre organisation et ce mot de passe.",
"organization_logo": "Logo de l'organisation",
"organization_about_description": "Quelques phrases à propos de votre organisation. Elles apparaîtront sur la page de profil public de votre organisation.",
"ill_do_this_later": "Je le ferai plus tard",
"verify_your_email": "Vérifier votre adresse e-mail",
"enter_digit_code": "Entrez le code à 6 chiffres que nous avons envoyé à {{email}}",
"verify_email_organization": "Vérifiez votre adresse e-mail pour créer une organisation",
"code_provided_invalid": "Le code fourni n'est pas valide, veuillez réessayer",
"email_already_used": "L'adresse e-mail est déjà utilisée",
"duplicated_slugs_warning": "Les équipes suivantes n'ont pas pu être créées en raison de slugs identiques : {{slugs}}",
"team_names_empty": "Les noms d'équipe ne peuvent pas être vides",
"team_names_repeated": "Les noms d'équipe ne peuvent pas être répétés",
"user_belongs_organization": "L'utilisateur appartient à une organisation",
"no_teams_yet": "Cette organisation n'a pas encore d'équipe",
"no_teams_yet_description": "si vous êtes administrateur, assurez-vous de créer des équipes à afficher ici.",
"set_up": "Configurer",
"set_up_your_profile": "Configurer votre profil",
"set_up_your_profile_description": "Faites savoir aux gens qui vous êtes au sein de {{orgName}} et quand ils interagissent avec votre lien public.",
"my_profile": "Mon profil",
"my_settings": "Mes paramètres",
"sender_id_info": "Nom ou numéro affiché comme expéditeur d'un SMS (certains pays n'autorisent pas les ID d'expéditeur alphanumériques)",
"no_organization_slug": "Une erreur s'est produite lors de la création des équipes pour cette organisation. Le slug du lien est manquant.",
"org_name": "Nom de l'organisation",
"org_url": "Lien de l'organisation",
"copy_link_org": "Copier le lien vers l’organisation",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Ajoutez vos nouvelles chaînes ci-dessus ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
}
+8 -26
View File
@@ -14,17 +14,13 @@
"verify_email_subject": "{{appName}}: אמת את החשבון",
"check_your_email": "בדוק את הדוא״ל שלך",
"verify_email_page_body": "שלחנו מייל ל- {{email}}. חשוב שתאמת את כתובת הדוא״ל שלך כדי להבטיח את תעבורת הדוא״ל והיומן מ- {{appName}}.",
"verify_email_banner_body": "אנא אמת את חשבון הדוא״ל שלך כדי להבטיח את תעבורת מ- {{appName}}.",
"verify_email_email_header": "אמת את חשבון הדוא״ל שלך",
"verify_email_email_button": "אמת דוא״ל",
"verify_email_email_body": "אנא אמת את חשבון הדוא״ל שלך על ידי לחיצה על הכפתור מטה.",
"verify_email_email_link_text": "הנה הקישור, אם אתה לא אוהב ללחוץ על כפתורים:",
"email_sent": "מייל נשלח בהצלחה",
"event_declined_subject": "נדחה: {{title}} ב- {{date}}",
"event_cancelled_subject": "בוטל: {{title}} ב- {{date}}",
"event_request_declined": "בקשת האירוע שלך נדחתה",
"event_request_declined_recurring": "בקשת האירוע החוזר שלך נדחתה",
"event_request_cancelled": "האירוע המתוכנן בוטל",
"organizer": "מארגן",
"need_to_reschedule_or_cancel": "רוצה לקבוע מועד חדש או לבטל?",
"cancellation_reason": "הסיבה לביטול (לא חובה)",
@@ -86,9 +82,7 @@
"your_meeting_has_been_booked": "הפגישה שלך הוזמנה",
"event_type_has_been_rescheduled_on_time_date": "{{title}} תוזמן מחדש לתאריך {{date}}.",
"event_has_been_rescheduled": "עודכן – מועד האירוע שלך השתנה",
"request_reschedule_subtitle": "{{organizer}} ביטל/ה את ההזמנה וביקש/ה שתבחר/י מועד אחר.",
"request_reschedule_title_organizer": "ביקשת מ{{attendee}} לקבוע מועד חדש",
"request_reschedule_subtitle_organizer": "ביטלת את ההזמנה ו-{{attendee}} צריך/ה לתאם איתך מועד חדש.",
"rescheduled_event_type_subject": "נשלחה בקשה לקביעת מועד חדש: {{eventType}} עם {{name}} בתאריך {{date}}",
"requested_to_reschedule_subject_attendee": "הפעולה חייבה קביעת מועד חדש: יש לקבוע מועד חדש עבור {{eventType}} עם {{name}}",
"hi_user_name": "שלום {{name}}",
@@ -128,6 +122,7 @@
"team_upgrade_banner_description": "אנחנו מודים לך על כך שניסית את החבילה החדשה שלנו לצוותים. שמנו לב שהצוות שלך, \"{{teamName}}\", זקוק לשדרוג.",
"team_upgrade_banner_action": "כאן משדרגים",
"team_upgraded_successfully": "הצוות שלך שודרג בהצלחה!",
"org_upgrade_banner_action": "כאן משדרגים",
"use_link_to_reset_password": "נא להשתמש בקישור הבא כדי לאפס את הסיסמה",
"hey_there": "שלום,",
"forgot_your_password_calcom": "שכחתה את הסיסמה? - {{appName}}",
@@ -238,6 +233,7 @@
"done": "בוצע",
"all_done": "זהו, סיימת!",
"all_apps": "כל האפליקציות",
"all": "כל האפליקציות",
"available_apps": "אפליקציות זמינות",
"check_email_reset_password": "בדוק/י בתיבת הדוא\"ל – שלחנו לך קישור לאיפוס הסיסמה.",
"finish": "סיום",
@@ -300,6 +296,7 @@
"failed": "הפעולה נכשלה",
"password_has_been_reset_login": "הסיסמה שלך אופסה. עכשיו ניתן להיכנס עם הסיסמה החדשה.",
"bookerlayout_title": "פריסה",
"layout": "פריסה",
"bookerlayout_default_title": "תצוגת ברירת מחדל",
"bookerlayout_description": "אתה יכול לבחור כמה והמתזמנים שלך יכולים לשנות תצוגות.",
"bookerlayout_user_settings_title": "פריסת תזמון",
@@ -315,7 +312,6 @@
"error_end_time_next_day": "שעת הסיום לא יכולה לחרוג מ-24 שעות",
"back_to_bookings": "בחזרה להזמנות",
"free_to_pick_another_event_type": "ניתן לבחור אירוע אחר בכל עת.",
"cancelled": "בוטלו",
"cancellation_successful": "פעולת הביטול בוצעה בהצלחה",
"really_cancel_booking": "בטוח שברצונך לבטל את ההזמנה?",
"cannot_cancel_booking": "לא ניתן לבטל את ההזמנה הזו",
@@ -324,7 +320,6 @@
"cancelling_event_recurring": "האירוע הוא מופע אחד מתוך אירוע חוזר.",
"cancelling_all_recurring": "כל אלה הם יתר המופעים של האירוע החוזר.",
"error_with_status_code_occured": "אירעה שגיאה עם קוד הסטטוס {{status}}.",
"booking_already_cancelled": "ההזמנה הזו כבר בוטלה",
"booking_already_accepted_rejected": "ההזמנה הזו כבר אושרה או נדחתה",
"go_back_home": "חזרה אל מסך הבית",
"or_go_back_home": "או חזור אל מסך הבית",
@@ -338,7 +333,6 @@
"upcoming_bookings": "ברגע שמישהו יקבע איתך פגישה, המועד שנקבע יוצג כאן.",
"recurring_bookings": "ברגע שמישהו יקבע איתך פגישה חוזרת, המועד שנקבע יוצג כאן.",
"past_bookings": "ההזמנות הקודמות שלך יוצגו כאן.",
"cancelled_bookings": "ההזמנות המבוטלות שלך יוצגו כאן.",
"unconfirmed_bookings": "ההזמנות שלך שלא אושרו יוצגו כאן.",
"unconfirmed_bookings_tooltip": "הזמנות שלא אושרו",
"on": "בתאריך",
@@ -378,7 +372,6 @@
"browse_api_documentation": "עיון במסמכי ממשק תכנות היישומים (API) שלנו",
"leverage_our_api": "מומלץ להיעזר בממשק תכנות היישומים (API) שלנו לקבלת שליטה מלאה ויכולת התאמה אישית.",
"create_webhook": "יצירת Webhook",
"booking_cancelled": "ההזמנה בוטלה",
"booking_rescheduled": "מועד ההזמנה השתנה",
"recording_ready": "הקישור להורדת ההקלטה מוכן",
"booking_created": "ההזמנה נוצרה",
@@ -391,8 +384,6 @@
"team_webhooks": "רכיבי Webhook של הצוות",
"create_new_webhook_to_account": "יצירת Webhook חדש לחשבון",
"new_webhook": "Webhook חדש",
"receive_cal_meeting_data": "קבל נתוני פגישות מ-{{appName}} בכתובת URL שציינת ובזמן אמת, כאשר נקבע מועד לאירוע או כאשר אירוע מבוטל.",
"receive_cal_event_meeting_data": "קבל/י נתוני פגישות מ-{{appName}} בכתובת URL שציינת ובזמן אמת, כאשר נקבע מועד לאירוע זה או כאשר הוא מבוטל.",
"responsive_fullscreen_iframe": "iframe רספונסיבי על מסך מלא",
"loading": "טוען...",
"deleting": "מתבצעת מחיקה...",
@@ -528,6 +519,8 @@
"team_description": "מספר משפטים אודות הצוות. המידע הזה יופיע בדף ה-URL של הצוות.",
"members": "חברים",
"member": "חבר/ת",
"number_member_one": "חבר {{count}}",
"number_member_other": "{{count}} חברים",
"owner": "בעלים",
"admin": "מנהל/ת מערכת",
"administrator_user": "משתמש המוגדר כמנהל מערכת",
@@ -1028,14 +1021,12 @@
"event_location": "מיקום האירוע",
"reschedule_optional": "הסיבה לשינוי המועד (לא חובה)",
"reschedule_placeholder": "אפשר לאחרים לדעת מדוע עליך לשנות את המועד",
"event_cancelled": "אירוע זה מבוטל",
"emailed_information_about_cancelled_event": "שלחנו לך ולשאר המשתתפים הודעת דוא״ל כדי ליידע אותם על כך.",
"this_input_will_shown_booking_this_event": "הקלט יוצג בעת הזמנת אירוע זה",
"meeting_url_in_conformation_email": "כתובת ה-URL של הפגישה נמצאת בהודעת הדוא״ל שנשלחה לאישור הפגישה",
"url_start_with_https": "כתובת ה-URL צריכה להתחיל עם הקידומת http://‎ או https://‎",
"number_provided": "מספר הטלפון יסופק",
"before_event_trigger": "לפני שהאירוע מתחיל",
"event_cancelled_trigger": "כאשר אירוע מבוטל",
"new_event_trigger": "כאשר אירוע חדש מוזמן",
"email_host_action": "שלח מייל למארח",
"email_attendee_action": "שליחת דוא\"ל למשתתפים",
@@ -1197,7 +1188,6 @@
"start_of_week": "תחילת השבוע",
"recordings_title": "הקלטות",
"recording": "הקלטה",
"happy_scheduling": "תזמון נעים!",
"select_calendars": "בחר את לוחות השנה שבהם ברצונך לבדוק אם יש התנגשויות, כדי למנוע כפל הזמנות.",
"check_for_conflicts": "בדיקת התנגשויות",
"view_recordings": "צפייה בהקלטות",
@@ -1424,7 +1414,6 @@
"your_team_disbanded_successfully": "פיזור הצוות שלך בוצע בהצלחה",
"error_creating_team": "אירעה שגיאה במהלך יצירת הצוות",
"you": "את/ה",
"send_email": "שליחת דוא\"ל",
"member_already_invited": "החבר כבר הוזמן",
"enter_email_or_username": "יש להזין כתובת דוא\"ל או שם משתמש",
"team_name_taken": "השם הזה כבר תפוס",
@@ -1437,7 +1426,7 @@
"attendee_email_info": "כתובת הדוא\"ל של האדם שביצע את ההזמנה",
"kbar_search_placeholder": "הקלד/י פקודה או חפש/י...",
"invalid_credential": "נראה שתוקף ההרשאה פג או שההרשאה בוטלה. יש להתקין מחדש שוב.",
"reschedule_reason_success_page": "הסיבה לקביעת מועד חדש",
"reschedule_reason": "הסיבה לקביעת מועד חדש",
"choose_common_schedule_team_event": "בחירת לוח זמנים משותף",
"choose_common_schedule_team_event_description": "יש להפעיל אפשרות זו אם רוצים להשתמש בלוח זמנים משותף בין המארחים. אם האפשרות הזו מבוטלת, כל מארח יוזמן לפי לוח הזמנים המשמש כברירת המחדל שלו.",
"reason": "סיבה",
@@ -1592,10 +1581,7 @@
"delete_sso_configuration_confirmation_description": "אתה בטוח שאתה רוצה למחוק את הגדרות {{connectionType}}? חברי הצוות שלך שמשתמשים ב- {{connectionType}} להזדהות לא יוכלו להשתמש בו להכנס ל- Cal.com.",
"organizer_timezone": "מארגן אזורי זמן",
"email_user_cta": "צפה בהזמנה",
"email_no_user_invite_heading": "הוזמנת להצטרף לצוות ב- {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} הזמין אותך להצטרף לצוות שלו ב- {{appName}}. {{appName}} הינה מתזמן זימונים שמאפשר לך ולצוות שלך לזמן פגישות בלי כל הפינג פונג במיילים.",
"email_user_invite_subheading": "{{invitedBy}} הזמין/ה אותך להצטרף לצוות שלו/ה בשם '{{teamName}}' באפליקציה {{appName}}. אפליקציית {{appName}} היא כלי לקביעת מועדים לאירועים שמאפשר לך ולצוות שלך לתזמן פגישות בלי כל הפינג פונג במיילים.",
"email_no_user_invite_steps_intro": "אנחנו נדריך אותך במספר צעדים קצרים ואתה תהנה תזמון נטול מתח עם הצוות שלך כהרף עין.",
"email_no_user_step_one": "בחר שם משתמש",
"email_no_user_step_two": "קשר את לוח השנה שלך",
"email_no_user_step_three": "הגדר את הזמינות שלך",
@@ -1616,7 +1602,6 @@
"no_longer_attending": "אתה לא משתתף יותר בארוע זה",
"attendee_no_longer_attending_subject": "משתתף מסויים אינו משתתף עוד ב- {{title}} במועד {{date}}",
"attendee_no_longer_attending": "משתתף מסויים אינו משתתף עוד בארוע שלך",
"attendee_no_longer_attending_subtitle": "{{name}} ביטל. פירוש הדבר שהתפנה מושב לשעה זו",
"create_event_on": "צור ארוע ב-",
"default_app_link_title": "צור קישור אפליקציה ברירת מחדל",
"default_app_link_description": "הגדרת קישור אפליקציה ברירת מחדל מאפשר לכל הארועים החדשים להשתמש בקישור שהגדרת.",
@@ -1637,7 +1622,6 @@
"show_on_booking_page": "להציג בדף ההזמנות",
"get_started_zapier_templates": "התחל עם תבניות Zapier",
"team_is_unpublished": "צוות {{team}} אינו מפורסם",
"team_is_unpublished_description": "קישור הצוות הזה אינו זמין כעת. אנא צור קשר עם הבעלים של הצוות או בקש מהם לפרסם אותו.",
"team_member": "חבר צוות",
"a_routing_form": "טופס ניתוב",
"form_description_placeholder": "תיאור הטופס",
@@ -1668,7 +1652,6 @@
"spot_popular_event_types_description": "צפה איזה ארועים מקבלים הכי הרבה גישות ותזמונים",
"no_responses_yet": "אין עדיין תגובות",
"this_will_be_the_placeholder": "זה יהיה הממלא מקום",
"error_booking_event": "אירעה שגיאה בעת הזמנת האירוע, רענן/י את הדף ונסה/י שוב",
"timeslot_missing_title": "לא נבחר חלון זמן",
"timeslot_missing_description": "כדי להזמין את האירוע, יש לבחור חלון זמן.",
"timeslot_missing_cta": "חלון הזמן שנבחר",
@@ -1729,7 +1712,6 @@
"least_booked_members": "החברים שמתוזמנים הכי פחות",
"events_created": "ארועים שנוצרו",
"events_completed": "ארועים שהושלמו",
"events_cancelled": "ארועים שבוטלו",
"events_rescheduled": "ארועים שתוזמנו מחדש",
"from_last_period": "מפרק הזמן האחרון",
"from_to_date_period": "מ: {{startDate}} עד: {{endDate}}",
@@ -1781,7 +1763,6 @@
"book_my_cal": "הזמנה ביומן שלי",
"invite_as": "הזמנה בְתור",
"form_updated_successfully": "עדכון הטופס בוצע בהצלחה.",
"email_not_cal_member_cta": "הצטרף/י לצוות שלך",
"disable_attendees_confirmation_emails": "השבתת הודעות דוא\"ל לאישור שנשלחות כברירת מחדל עבור המשתתפים",
"disable_attendees_confirmation_emails_description": "בסוג האירוע הזה פעיל לפחות תהליך עבודה אחד ששולח דוא\"ל למשתתפים כשהאירוע מוזמן.",
"disable_host_confirmation_emails": "השבתת הודעות דוא\"ל לאישור שנשלחות כברירת מחדל עבור המארח/ת",
@@ -1791,5 +1772,6 @@
"connect_google_workspace": "חיבור Google Workspace",
"google_workspace_admin_tooltip": "עליך להיות אדמין/ית ב-Workspace כדי להשתמש בתכונה הזו",
"first_event_type_webhook_description": "צור/צרי את ה-Webhook הראשון שלך עבור סוג זה של אירוע",
"create_for": "צור/צרי עבור"
"create_for": "צור/צרי עבור",
"organization_url_taken": "כתובת ה-URL הזו כבר תפוסה"
}
@@ -10,10 +10,8 @@
"have_any_questions": "Imate pitanja? Tu smo da pomognemo.",
"reset_password_subject": "{{appName}}: Uputstva za resetiranje lozinke",
"event_declined_subject": "Odbijeno: {{title}} u {{date}}",
"event_cancelled_subject": "Otkazano: {{title}} u {{date}}",
"event_request_declined": "Vaš zahtjev za događaj je odbijen",
"event_request_declined_recurring": "Vaš zahtjev za ponavljajući događaj je odbijen",
"event_request_cancelled": "Vaš zakazan događaj je odbijen",
"organizer": "Organizator",
"need_to_reschedule_or_cancel": "Trebate odgoditi ili otkazati?",
"cancellation_reason": "Razlog otkazivanja (neobavezno)",
@@ -68,9 +66,7 @@
"your_meeting_has_been_booked": "Vaš sastanak je zakazan",
"event_type_has_been_rescheduled_on_time_date": "Vaš {{title}} je odgođen za {{date}}.",
"event_has_been_rescheduled": "Ažurirano - Vaš događaj je odgođen",
"request_reschedule_subtitle": "{{organizer}} je otkazao/la rezervaciju i zatražio/la da odaberete drugi termin.",
"request_reschedule_title_organizer": "Zatražili ste da {{attendee}} promijeni termin",
"request_reschedule_subtitle_organizer": "Otkazali ste rezervaciju i {{attendee}} bi trebao odabrati novi termin s vama.",
"rescheduled_event_type_subject": "Zahtjev za odgodu poslan: {{eventType}} s {{name}} u {{date}}",
"requested_to_reschedule_subject_attendee": "Potrebna radnja za promjenu termina: rezervirajte novi termin za {{eventType}} s {{name}}",
"hi_user_name": "Pozdrav {{name}}",
@@ -108,6 +104,7 @@
"team_upgrade_banner_description": "Hvala vam što isprobavate naš novi plan za timove. Primijetili smo da se vaš tim „{{teamName}}“ treba nadograditi.",
"team_upgrade_banner_action": "Nadogradite ovdje",
"team_upgraded_successfully": "Vaš tim je uspješno pretplaćen!",
"org_upgrade_banner_action": "Nadogradite ovdje",
"use_link_to_reset_password": "Resetirajte lozinku koristeći donji link",
"hey_there": "Pozdrav,",
"forgot_your_password_calcom": "Zaboravili ste lozinku? - {{appName}}",
@@ -216,6 +213,7 @@
"done": "Učinjeno",
"all_done": "Završeno!",
"all_apps": "Sve",
"all": "Sve",
"check_email_reset_password": "Provjerite svoju e-poštu. Poslali smo vam link za resetiranje lozinke.",
"finish": "Završi",
"few_sentences_about_yourself": "Nekoliko rečenica o sebi. Ovo će se pojaviti na vašoj osobnoj stranici.",
@@ -286,7 +284,6 @@
"error_end_time_next_day": "Vrijeme završetka ne može biti dulje od 24 sata",
"back_to_bookings": "Povratak na rezervacije",
"free_to_pick_another_event_type": "Slobodno odaberite neki drugi događaj bilo kada.",
"cancelled": "Otkazano",
"cancellation_successful": "Otkazivanje uspješno",
"really_cancel_booking": "Stvarno otkazujete svoju rezervaciju?",
"cannot_cancel_booking": "Ne možete otkazati ovu rezervaciju",
@@ -295,7 +292,6 @@
"cancelling_event_recurring": "Događaj je jedan od ponavljajućih događaja.",
"cancelling_all_recurring": "Ovo su svi preostali događaji u ponavljajućem događaju.",
"error_with_status_code_occured": "Došlo je do pogreške sa statusnim kodom {{status}}.",
"booking_already_cancelled": "Ova rezervacija je već otkazana",
"booking_already_accepted_rejected": "Ova rezervacija je već prihvaćena ili odbijena",
"go_back_home": "Nazad na početnu stranicu",
"or_go_back_home": "Ili nazad na početnu stranicu",
@@ -309,7 +305,6 @@
"upcoming_bookings": "Čim netko rezervira termin s vama, pokazat će se ovdje.",
"recurring_bookings": "Čim netko rezervira ponavljajući sastanak s vama, pokazat će se ovdje.",
"past_bookings": "Ovdje će se prikazati vaše prethodne rezervacije.",
"cancelled_bookings": "Ovdje će se prikazati vaše otkazane rezervacije.",
"unconfirmed_bookings": "Ovdje će se prikazati vaše nepotvrđene rezervacije.",
"unconfirmed_bookings_tooltip": "Nepotvrđene rezervacije",
"on": "u",
@@ -66,6 +66,7 @@
"forgot": "Elfelejtetted?",
"done": "Kész",
"all_apps": "Minden alkalmazás",
"all": "Minden alkalmazás",
"finish": "Befelyezés",
"current_time": "Jelenlegi idő",
"welcome": "Üdvözöljük",
@@ -81,7 +82,6 @@
"try_again": "Próbáld újra",
"login": "Bejelentkezés",
"success": "Siker",
"cancelled": "Lemondva",
"and": "és",
"light": "Világos",
"dark": "Sötét",
@@ -11,10 +11,8 @@
"have_any_questions": "Punya pertanyaan? Kami siap membantu.",
"reset_password_subject": "{{appName}}: Petunjuk pengaturan ulang kata sandi",
"event_declined_subject": "Ditolak: {{title}} pada {{date}}",
"event_cancelled_subject": "Dibatalkan: {{title}} pada {{date}}",
"event_request_declined": "Permintaan acara kamu telah ditolak",
"event_request_declined_recurring": "Acara berulang kamu telah ditolak",
"event_request_cancelled": "Acara terjadwal kamu telah dibatalkan",
"organizer": "Pengelola",
"need_to_reschedule_or_cancel": "Perlu penjadwalan ulang atau pembatalan?",
"cancellation_reason": "Alasan pembatalan (opsional)",
@@ -71,9 +69,7 @@
"your_meeting_has_been_booked": "Pertemuanmu telah terdaftar",
"event_type_has_been_rescheduled_on_time_date": "{{title}} kamu telah dijadwalkan ulang menjadi {{date}}.",
"event_has_been_rescheduled": "Terkini - Acara kamu telah dijadwalkan ulang",
"request_reschedule_subtitle": "{{organizer}} telah membatalkan acara dan meminta kamu untuk memilih waktu lain.",
"request_reschedule_title_organizer": "Kamu telah meminta {{attendee}} untuk menjadwalkan ulang",
"request_reschedule_subtitle_organizer": "Kamu telah membatalkan acara dan {{attendee}} akan memilih waktu lain.",
"rescheduled_event_type_subject": "Permintaan penjadwalan ulang terkirim: {{eventType}} dengan {{name}} pada {{date}}",
"team_info": "Informasi Tim",
"request_another_invitation_email": "Jika kamu lebih suka tidak menggukan {{toEmail}} sebagai email {{appName}} atau telah memiliki akun {{appName}} silakan membuat permintaan lain kepada email tersebut.",
@@ -88,6 +84,7 @@
"team_upgrade_banner_description": "Terimakasih telah mencoba paket tim kami. Kami perhatikan tim kamu \"{{teamName}}\" perlu diupgrade.",
"team_upgrade_banner_action": "Upgrade disini",
"team_upgraded_successfully": "Tim kamu telah berhasil diupgrade!",
"org_upgrade_banner_action": "Upgrade disini",
"use_link_to_reset_password": "Gunakan link di bawah ini untuk mengatur ulang kata sandi kamu",
"hey_there": "Halo,",
"forgot_your_password_calcom": "Lupa kata sandi? - {{appName}}",
+50 -25
View File
@@ -14,16 +14,14 @@
"verify_email_subject": "{{appName}}: verifica il tuo account",
"check_your_email": "Controlla la tua e-mail",
"verify_email_page_body": "Abbiamo inviato un'e-mail a {{email}}. È importante verificare il tuo indirizzo e-mail per garantire un migliore funzionamento dell'e-mail e del calendario {{appName}}.",
"verify_email_banner_body": "Verifica il tuo indirizzo e-mail per garantire un migliore funzionamento dell'e-mail e del calendario {{appName}}.",
"verify_email_email_header": "Verifica il tuo indirizzo e-mail",
"verify_email_email_button": "Verifica l'e-mail",
"verify_email_email_body": "Verifica il tuo indirizzo e-mail cliccando sul pulsante qui in basso.",
"verify_email_email_link_text": "Ecco il link nel caso tu non voglia fare clic su pulsanti:",
"email_sent": "Email inviata con successo",
"event_declined_subject": "Rifiutato: {{title}} il {{date}}",
"event_cancelled_subject": "Cancellato: {{title}} il {{date}}",
"event_request_declined": "La tua richiesta per l'evento è stata rifiutata",
"event_request_declined_recurring": "La tua richiesta per l'evento ricorrente è stata rifiutata",
"event_request_cancelled": "Il tuo evento programmato è stato cancellato",
"organizer": "Organizzatore",
"need_to_reschedule_or_cancel": "È necessario riprogrammare o annullare?",
"cancellation_reason": "Motivo dell'annullamento (facoltativo)",
@@ -85,9 +83,7 @@
"your_meeting_has_been_booked": "Il tuo meeting è stata prenotato",
"event_type_has_been_rescheduled_on_time_date": "Il tuo {{title}} è stato riprogrammato per il {{date}}.",
"event_has_been_rescheduled": "Aggiornato: il tuo evento è stato riprogrammato",
"request_reschedule_subtitle": "{{organizer}} ha annullato la prenotazione e ti ha chiesto di scegliere un altro orario.",
"request_reschedule_title_organizer": "Hai richiesto a {{attendee}} di riprogrammare",
"request_reschedule_subtitle_organizer": "Hai annullato la prenotazione e {{attendee}} deve selezionare un nuovo orario per la prenotazione.",
"rescheduled_event_type_subject": "Richiesta di riprogrammazione inviata: {{eventType}} con {{name}} il {{date}}",
"requested_to_reschedule_subject_attendee": "Azione richiesta per la riprogrammazione: prenota un nuovo orario per {{eventType}} con {{name}}",
"hi_user_name": "Ciao {{name}}",
@@ -127,6 +123,7 @@
"team_upgrade_banner_description": "Grazie per aver provato il nostro piano team. Abbiamo notato che è necessario effettuare l'upgrade del tuo team \"{{teamName}}\".",
"team_upgrade_banner_action": "Effettua l'upgrade",
"team_upgraded_successfully": "Il tuo team è stato aggiornato!",
"org_upgrade_banner_action": "Effettua l'upgrade",
"use_link_to_reset_password": "Usa il link qui sotto per reimpostare la tua password",
"hey_there": "Ciao,",
"forgot_your_password_calcom": "Hai dimenticato la password? - {{appName}}",
@@ -201,6 +198,7 @@
"page_doesnt_exist": "Questa pagina non esiste.",
"check_spelling_mistakes_or_go_back": "Controlla gli errori di ortografia o torna alla pagina precedente.",
"404_page_not_found": "404: Questa pagina non è stata trovata.",
"booker_event_not_found": "Non siamo riusciti a trovare l'evento che stai cercando di fissare.",
"getting_started": "Stiamo iniziando",
"15min_meeting": "Meeting di 15 minuti",
"30min_meeting": "Meeting di 30 minuti",
@@ -236,6 +234,7 @@
"done": "Fatto",
"all_done": "Operazione completata!",
"all_apps": "Tutte le app",
"all": "Tutte le app",
"available_apps": "Applicazioni disponibili",
"check_email_reset_password": "Controlla la tua email. Ti abbiamo inviato un link per reimpostare la password.",
"finish": "Fine",
@@ -297,6 +296,19 @@
"success": "Riuscito",
"failed": "Fallito",
"password_has_been_reset_login": "La tua password è stata reimpostata. Ora puoi accedere con la tua password appena creata.",
"bookerlayout_title": "Layout",
"layout": "Layout",
"bookerlayout_default_title": "Vista predefinita",
"bookerlayout_description": "È possibile selezionarne vari e chi fissa gli appuntamenti può cambiare visualizzazione.",
"bookerlayout_user_settings_title": "Layout di programmazione appuntamenti",
"bookerlayout_user_settings_description": "È possibile selezionare più librerie e chi fissa gli appuntamenti può cambiare vista. Il tutto può poi essere cambiato in base agli eventi.",
"bookerlayout_month_view": "Mese",
"bookerlayout_week_view": "Settimanale",
"bookerlayout_column_view": "Colonna",
"bookerlayout_error_min_one_enabled": "Deve essere abilitato almeno un layout.",
"bookerlayout_error_default_not_enabled": "Il layout selezionato come vista predefinita non fa parte dei layout abilitati.",
"bookerlayout_error_unknown_layout": "Il layout selezionato non è un layout valido.",
"bookerlayout_override_global_settings": "Puoi gestirlo per tutti i tipi di eventi in <2>impostazioni / aspetto</2> o <6>sostituire solo per questo evento</6>.",
"unexpected_error_try_again": "Si è verificato un errore imprevisto. Riprova.",
"sunday_time_error": "Ora non valida la domenica",
"monday_time_error": "Ora non valida il lunedì",
@@ -309,7 +321,6 @@
"error_end_time_next_day": "L'ora di conclusione non può essere maggiore di 24 ore",
"back_to_bookings": "Torna alle prenotazioni",
"free_to_pick_another_event_type": "Sentiti libero di scegliere un altro evento in qualsiasi momento.",
"cancelled": "Annullato",
"cancellation_successful": "Cancellazione riuscita",
"really_cancel_booking": "Davvero vuoi annullare la prenotazione?",
"cannot_cancel_booking": "Non puoi annullare questa prenotazione",
@@ -318,7 +329,6 @@
"cancelling_event_recurring": "L'evento è un'istanza di un evento ricorrente.",
"cancelling_all_recurring": "Queste sono tutte le istanze rimanenti dell'evento ricorrente.",
"error_with_status_code_occured": "Si è verificato un errore con il codice di stato {{status}}.",
"booking_already_cancelled": "Questa prenotazione è stata già annullata",
"booking_already_accepted_rejected": "Questa prenotazione è già stata accettata o rifiutata",
"go_back_home": "Torna alla home",
"or_go_back_home": "Torna alla home",
@@ -332,7 +342,6 @@
"upcoming_bookings": "Non appena qualcuno prenota una riunione con voi apparirà qui.",
"recurring_bookings": "Quando qualcuno prenoterà una riunione ricorrente con te, la riunione apparirà qui.",
"past_bookings": "Le tue prenotazioni passate appariranno qui.",
"cancelled_bookings": "Le tue prenotazioni passate appariranno qui.",
"unconfirmed_bookings": "Le tue prenotazioni non confermate appariranno qui.",
"unconfirmed_bookings_tooltip": "Prenotazioni non confermate",
"on": "su",
@@ -366,16 +375,18 @@
"user_dynamic_booking_disabled": "Alcuni degli utenti del gruppo hanno attualmente disabilitato le prenotazioni di gruppo dinamiche",
"allow_dynamic_booking_tooltip": "È possibile creare dinamicamente collegamenti a prenotazioni di gruppo inserendo più nomi utente separati da '+'. Esempio: '{{appName}}/bailey+peer'",
"allow_dynamic_booking": "Consenti ai partecipanti di prenotare per te utilizzando le prenotazioni di gruppo dinamiche",
"dynamic_booking": "Collegamenti dinamici di gruppo",
"email": "Email",
"email_placeholder": "jdoe@example.com",
"full_name": "Nome completo",
"browse_api_documentation": "Sfoglia la nostra documentazione API",
"leverage_our_api": "Sfrutta la nostra API per il pieno controllo e la personalizzabilità.",
"create_webhook": "Crea Webhook",
"booking_cancelled": "Prenotazione Annullata",
"booking_rescheduled": "Prenotazione Riprogrammata",
"recording_ready": "Link per scaricare la registrazione pronto",
"booking_created": "Prenotazione Creata",
"booking_rejected": "Prenotazione Rifiutata",
"booking_requested": "Prenotazione Richiesta",
"meeting_ended": "Riunione terminata",
"form_submitted": "Modulo inviato",
"event_triggers": "Attivatori Evento",
@@ -385,8 +396,6 @@
"team_webhooks": "Webhook del team",
"create_new_webhook_to_account": "Crea un nuovo webhook sul tuo account",
"new_webhook": "Nuovo Webhook",
"receive_cal_meeting_data": "Ricevi i dati di riunione {{appName}} ad un URL specificato, in tempo reale, quando un evento è programmato o annullato.",
"receive_cal_event_meeting_data": "Ricevi i dati della riunione {{appName}} a un URL specificato, in tempo reale, quando questo evento viene programmato o annullato.",
"responsive_fullscreen_iframe": "Iframe full screen responsive",
"loading": "Caricamento...",
"deleting": "Eliminazione...",
@@ -522,6 +531,8 @@
"team_description": "Alcune frasi sul tuo team. Appariranno nella pagina URL del team.",
"members": "Membri",
"member": "Membri",
"number_member_one": "{{count}} membro",
"number_member_other": "{{count}} membri",
"owner": "Proprietario",
"admin": "Amministratore",
"administrator_user": "Utente amministratore",
@@ -837,6 +848,7 @@
"installed_app_payment_description": "Configura quale servizio di elaborazione dei pagamenti usare per addebitare i clienti.",
"installed_app_analytics_description": "Imposta quali app di analisi usare per le tue pagine di prenotazione",
"installed_app_other_description": "Tutte le app installate appartenenti ad altre categorie.",
"installed_app_conferencing_description": "Configura quali app di conferenza utilizzare",
"installed_app_automation_description": "Imposta quali app di automazione usare",
"installed_app_web3_description": "Imposta quali app Web3 usare per le tue pagine di prenotazione",
"analytics": "Analisi",
@@ -1022,17 +1034,16 @@
"event_location": "Luogo dell'evento",
"reschedule_optional": "Motivo della riprogrammazione (facoltativo)",
"reschedule_placeholder": "Fai sapere agli alti perché hai bisogno di riprogrammare",
"event_cancelled": "Questo evento è stato annullato",
"emailed_information_about_cancelled_event": "Abbiamo inviato un'e-mail di notifica a te e agli altri partecipanti.",
"this_input_will_shown_booking_this_event": "Questo input verrà mostrato durante la prenotazione di questo evento",
"meeting_url_in_conformation_email": "L'URL della riunione è riportato nell'e-mail di conferma",
"url_start_with_https": "L'URL deve iniziare con http:// o https://",
"number_provided": "Verrà fornito il numero di telefono",
"before_event_trigger": "prima dell'inizio dell'evento",
"event_cancelled_trigger": "quando l'evento viene annullato",
"new_event_trigger": "quando viene prenotato un nuovo evento",
"email_host_action": "invia e-mail all'organizzatore",
"email_attendee_action": "invia e-mail ai partecipanti",
"sms_attendee_action": "Invia SMS al partecipante",
"sms_number_action": "invia SMS a un numero specifico",
"workflows": "Flussi di lavoro",
"new_workflow_btn": "Nuovo flusso di lavoro",
@@ -1191,7 +1202,7 @@
"start_of_week": "Inizio della settimana",
"recordings_title": "Registrazioni",
"recording": "Registrazione",
"happy_scheduling": "Ti auguriamo una piacevole esperienza di pianificazione",
"happy_scheduling": "Buona pianificazione",
"select_calendars": "Seleziona su quali calendari desideri controllare i conflitti per evitare doppie prenotazioni.",
"check_for_conflicts": "Controlla conflitti",
"view_recordings": "Visualizza registrazioni",
@@ -1233,6 +1244,7 @@
"conferencing_description": "Aggiungi le tue app di videoconferenza preferite per le tue riunioni",
"add_conferencing_app": "Aggiungi app di videoconferenza",
"password_description": "Gestisci le impostazioni relative alle password del tuo account",
"set_up_two_factor_authentication": "Imposta l'autenticazione a due fattori",
"we_just_need_basic_info": "Abbiamo bisogno di alcune semplici informazioni per completare la configurazione del tuo profilo.",
"skip": "Salta",
"do_this_later": "Più tardi",
@@ -1264,6 +1276,7 @@
"download_responses_description": "Scarica tutte le risposte al tuo modulo in formato CSV.",
"download": "Scarica",
"download_recording": "Scarica registrazione",
"recording_from_your_recent_call": "Una registrazione della tua recente chiamata su {{appName}} è pronta per il download",
"create_your_first_form": "Crea il tuo primo modulo",
"create_your_first_form_description": "I Moduli di instradamento consentono di porre domande qualificanti agli utenti per indirizzarli a persone o eventi pertinenti.",
"create_your_first_webhook": "Crea il tuo primo Webhook",
@@ -1418,7 +1431,6 @@
"your_team_disbanded_successfully": "Il tuo team è stato sciolto correttamente",
"error_creating_team": "Errore durante la creazione del team",
"you": "Tu",
"send_email": "Invia e-mail",
"member_already_invited": "Membro già invitato",
"enter_email_or_username": "Immettere un indirizzo e-mail o un nome utente",
"team_name_taken": "Nome già utilizzato",
@@ -1431,7 +1443,7 @@
"attendee_email_info": "E-mail della persona che prenota",
"kbar_search_placeholder": "Digita un comando o esegui una ricerca...",
"invalid_credential": "Errore! Sembra che l'autorizzazione sia scaduta o che sia stata revocata. Prova a reinstallare.",
"reschedule_reason_success_page": "Motivo della riprogrammazione",
"reschedule_reason": "Motivo della riprogrammazione",
"choose_common_schedule_team_event": "Scegli un programma comune",
"choose_common_schedule_team_event_description": "Abilita questa opzione se desideri utilizzare un programma comune per tutti gli organizzatori. Quando l'opzione è disabilitata, ciascun organizzatore verrà prenotato in base al proprio programma predefinito.",
"reason": "Motivo",
@@ -1449,6 +1461,8 @@
"find_the_best_person": "Trova la persona più adatta disponibile e fai ruotare i membri del team.",
"fixed_round_robin": "Round robin fisso",
"add_one_fixed_attendee": "Aggiungi un partecipante fisso e fai intervenire a turno altri partecipanti.",
"calcom_is_better_with_team": "{{appName}} funziona meglio in team",
"the_calcom_team": "Il team {{companyName}}",
"add_your_team_members": "Aggiungi i membri del tuo team ai tuoi tipi di eventi. Usa la pianificazione collettiva per includere tutti o trova la persona più adatta con la pianificazione round robin.",
"booking_limit_reached": "È stato raggiunto il limite di prenotazione per questo tipo di evento",
"duration_limit_reached": "È stato raggiunto il limite di durata per questo tipo di evento",
@@ -1467,6 +1481,7 @@
"navigate_installed_apps": "Vai alle app installate",
"disabled_calendar": "Se hai un altro calendario installato, le nuove prenotazioni saranno aggiunte a quel calendario. Altrimenti, collega un nuovo calendario in modo da non perdere nessuna nuova prenotazione.",
"enable_apps": "Abilita app",
"enable_apps_description": "Abilita le app che gli utenti possono integrare con {{appName}}",
"purchase_license": "Acquista una licenza",
"already_have_key": "Ho già una chiave:",
"already_have_key_suggestion": "Copia qui la variabile di ambiente CALCOM_LICENSE_KEY esistente.",
@@ -1586,10 +1601,7 @@
"delete_sso_configuration_confirmation_description": "Eliminare la configurazione {{connectionType}}? I membri del tuo team che utilizzano l'accesso {{connectionType}} non saranno più in grado di accedere a Cal.com.",
"organizer_timezone": "Fuso orario organizzatore",
"email_user_cta": "Visualizza invito",
"email_no_user_invite_heading": "Sei stato invitato a unirti a un team su {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti al suo team su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette al tuo team di pianificare le riunioni senza scambiare decine di e-mail.",
"email_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti al suo team `{{teamName}}` su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette a te e al tuo team di pianificare le riunioni senza scambiare decine di e-mail.",
"email_no_user_invite_steps_intro": "Ti assisteremo nei passaggi iniziali in modo che tu possa pianificare eventi per il tuo team senza stress e in pochissimo tempo.",
"email_no_user_step_one": "Scegli il tuo nome utente",
"email_no_user_step_two": "Collega il tuo account di calendario",
"email_no_user_step_three": "Imposta la tua disponibilità",
@@ -1610,7 +1622,6 @@
"no_longer_attending": "Non partecipi più a questo evento",
"attendee_no_longer_attending_subject": "Un partecipante non partecipa più a {{title}} con il seguente orario {{date}}",
"attendee_no_longer_attending": "Un partecipante non partecipa più al tuo evento",
"attendee_no_longer_attending_subtitle": "{{name}} ha disdetto. Di conseguenza, si è liberato un posto in questa fascia oraria",
"create_event_on": "Crea evento in",
"default_app_link_title": "Imposta il link dell'app predefinita",
"default_app_link_description": "L'impostazione di un link dell'app predefinita permette a tutti i nuovi tipi di eventi di usare il link dell'app impostato.",
@@ -1621,6 +1632,7 @@
"booking_questions_title": "Domande per la prenotazione",
"booking_questions_description": "Personalizza le domande poste nella pagina di prenotazione",
"add_a_booking_question": "Aggiungi una domanda",
"identifier": "Identificatore",
"duplicate_email": "Indirizzo e-mail duplicato",
"booking_with_payment_cancelled": "Non è più possibile pagare per questo evento",
"booking_with_payment_cancelled_already_paid": "È in corso il rimborso del pagamento per questa prenotazione.",
@@ -1631,7 +1643,6 @@
"show_on_booking_page": "Mostra nella pagina di prenotazione",
"get_started_zapier_templates": "Inizia con i modelli Zapier",
"team_is_unpublished": "{{team}} non è pubblicato",
"team_is_unpublished_description": "Questo link del team non è attualmente disponibile. Contattare il proprietario del team o chiedergli di pubblicarlo.",
"team_member": "Membro del team",
"a_routing_form": "Un modulo di instradamento",
"form_description_placeholder": "Descrizione modulo",
@@ -1661,14 +1672,15 @@
"spot_popular_event_types": "Individua i tipi di evento popolari",
"spot_popular_event_types_description": "Scopri quali tipi di evento ricevono più clic e prenotazioni",
"no_responses_yet": "Per ora non ci sono risposte",
"no_routes_defined": "Nessun percorso definito",
"this_will_be_the_placeholder": "Questo sarà il segnaposto",
"error_booking_event": "Si è verificato un errore durante la prenotazione dell'evento. Aggiornare la pagina e riprovare",
"timeslot_missing_title": "Nessuna fascia oraria selezionata",
"timeslot_missing_description": "Selezionare una fascia oraria per prenotare l'evento.",
"timeslot_missing_cta": "Seleziona fascia oraria",
"switch_monthly": "Passa alla vista mensile",
"switch_weekly": "Passa alla vista settimanale",
"switch_multiday": "Passa alla vista giornaliera",
"switch_columnview": "Passa alla vista colonna",
"num_locations": "{{num}} opzioni di luogo",
"select_on_next_step": "Seleziona nel passaggio successivo",
"this_meeting_has_not_started_yet": "Questa riunione non è ancora iniziata",
@@ -1723,7 +1735,6 @@
"least_booked_members": "Membri meno prenotati",
"events_created": "Eventi creati",
"events_completed": "Eventi completati",
"events_cancelled": "Eventi annullati",
"events_rescheduled": "Eventi riprogrammati",
"from_last_period": "dal periodo precedente",
"from_to_date_period": "Da: {{startDate}} A: {{endDate}}",
@@ -1757,6 +1768,16 @@
"complete_your_booking": "Completa la prenotazione",
"complete_your_booking_subject": "Completa la prenotazione: {{title}} del {{date}}",
"confirm_your_details": "Conferma i tuoi dati",
"copy_invite_link": "Copia link d'invito",
"edit_invite_link": "Modifica impostazioni link",
"invite_link_copied": "Link d'invito copiato",
"invite_link_deleted": "Link d'invito eliminato",
"invite_link_updated": "Impostazioni link d'invito salvate",
"link_expires_after": "La scadenza dei link è impostata dopo...",
"one_day": "1 giorno",
"seven_days": "7 giorni",
"thirty_days": "30 giorni",
"team_invite_received": "Hai ricevuto un invito a unirti al team {{teamName}}",
"currency_string": "{{amount, currency}}",
"charge_card_dialog_body": "Stai per addebitare {{amount, currency}} al partecipante. Continuare?",
"charge_attendee": "Addebita {{amount, currency}} al partecipante",
@@ -1765,6 +1786,7 @@
"email_invite_team_bulk": "{{userCount}} utenti sono stati invitati",
"error_collecting_card": "Errore durante la raccolta dei dati della carta",
"image_size_limit_exceed": "Le dimensioni delle immagini caricate non devono superare il limite di 5 MB",
"unauthorized_workflow_error_message": "{{errorCode}}: Non hai l'autorizzazione ad abilitare o disabilitare questo flusso di lavoro",
"inline_embed": "Incorporamento inline",
"load_inline_content": "Carica il tuo tipo di evento direttamente inline con altri contenuti del sito web.",
"floating_pop_up_button": "Pulsante a comparsa mobile",
@@ -1775,7 +1797,6 @@
"book_my_cal": "Prenota il mio Cal",
"invite_as": "Invita come",
"form_updated_successfully": "Modulo aggiornato correttamente.",
"email_not_cal_member_cta": "Unisciti al tuo team",
"disable_attendees_confirmation_emails": "Disabilita le e-mail di conferma predefinite per i partecipanti",
"disable_attendees_confirmation_emails_description": "Per questo tipo di evento è attivo almeno un flusso di lavoro che invia un'e-mail ai partecipanti quando l'evento viene prenotato.",
"disable_host_confirmation_emails": "Disabilita le e-mail di conferma predefinite per gli organizzatori",
@@ -1785,5 +1806,9 @@
"connect_google_workspace": "Collega Google Workspace",
"google_workspace_admin_tooltip": "Per usare questa funzione è necessario essere un amministratore di Workspace",
"first_event_type_webhook_description": "Crea il primo webhook per questo tipo di evento",
"create_for": "Crea per"
"create_for": "Crea per",
"organization_url_taken": "URL già occupato",
"additional_url_parameters": "Parametri URL aggiuntivi",
"sender_id_info": "Nome o numero mostrato come mittente di un SMS (alcuni paesi non consentono ID alfanumerici dei mittenti)",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑↑ Aggiungi qui le tue nuove stringhe al di sopra di questa riga ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ↑"
}
+7 -24
View File
@@ -12,10 +12,8 @@
"have_any_questions": "ご不明な点があれば、お気軽にお問い合わせください。",
"reset_password_subject": "{{appName}}: パスワードのリセット手順",
"event_declined_subject": "却下: {{title}} {{date}}",
"event_cancelled_subject": "キャンセル: {{title}} {{date}}",
"event_request_declined": "イベントのリクエストが拒否されました",
"event_request_declined_recurring": "繰り返しイベントのリクエストが拒否されました",
"event_request_cancelled": "スケジュールされていた予定がキャンセルされました",
"organizer": "主催者",
"need_to_reschedule_or_cancel": "再スケジュールまたはキャンセルが必要ですか?",
"cancellation_reason": "キャンセルの理由 (オプション)",
@@ -77,9 +75,7 @@
"your_meeting_has_been_booked": "ミーティングが予約されました",
"event_type_has_been_rescheduled_on_time_date": "あなたの {{title}} は {{date}} に再スケジュールされました。",
"event_has_been_rescheduled": "更新 - イベントのスケジュールが変更されました",
"request_reschedule_subtitle": "{{organizer}} が予約をキャンセルしました。別の時間を選択することをあなたにリクエストしています。",
"request_reschedule_title_organizer": "{{attendee}} にスケジュールの変更をリクエストしました",
"request_reschedule_subtitle_organizer": "予約をキャンセルしました。{{attendee}} はあなたとの予約の時間を新しく選択する必要があります。",
"rescheduled_event_type_subject": "スケジュール変更のリクエストを送信しました: {{date}} の {{name}} との {{eventType}}",
"requested_to_reschedule_subject_attendee": "スケジュール変更のアクションが必要です: {{name}} との {{eventType}} に新しい時間を予約してください",
"hi_user_name": "こんにちは、{{name}} さん",
@@ -119,6 +115,7 @@
"team_upgrade_banner_description": "新しいチームプランをお試しいただき、ありがとうございます。あなたのチーム「{{teamName}}」には、アップグレードが必要なようです。",
"team_upgrade_banner_action": "アップグレードはこちら",
"team_upgraded_successfully": "チームのアップグレードが正常に完了しました!",
"org_upgrade_banner_action": "アップグレードはこちら",
"use_link_to_reset_password": "以下のリンクを使用してパスワードをリセットしてください",
"hey_there": "こんにちは!",
"forgot_your_password_calcom": "パスワードをお忘れですか? - {{appName}}",
@@ -228,6 +225,7 @@
"done": "完了",
"all_done": "すべて完了!",
"all_apps": "すべて",
"all": "すべて",
"available_apps": "利用可能なアプリ",
"check_email_reset_password": "メールをご確認ください。パスワードをリセットするためのリンクを送信しました。",
"finish": "完了",
@@ -301,7 +299,6 @@
"error_end_time_next_day": "終了時刻に 24 時を超える時刻を設定することはできません",
"back_to_bookings": "予約に戻る",
"free_to_pick_another_event_type": "他の好きなイベントを選んでください。",
"cancelled": "キャンセル済み",
"cancellation_successful": "キャンセルしました",
"really_cancel_booking": "本当に予約をキャンセルしますか?",
"cannot_cancel_booking": "この予約はキャンセルできません",
@@ -310,7 +307,6 @@
"cancelling_event_recurring": "このイベントは、繰り返しイベントに含まれている 1 つのインスタンスです。",
"cancelling_all_recurring": "これらはすべて、繰り返しイベントに含まれているインスタンスの残りです。",
"error_with_status_code_occured": "ステータスコード {{status}} に関するエラーが発生しました。",
"booking_already_cancelled": "この予約はすでにキャンセルされています",
"booking_already_accepted_rejected": "この予約はすでに承認または拒否が行われています。",
"go_back_home": "ホームに戻る",
"or_go_back_home": "またはホームに戻る",
@@ -324,7 +320,6 @@
"upcoming_bookings": "誰かがあなたとの時間を予約すると、すぐにここに表示されます。",
"recurring_bookings": "別のユーザーがあなたとの繰り返しイベントを予約すると、ここに表示されます。",
"past_bookings": "過去の予約はここに表示されます。",
"cancelled_bookings": "キャンセルされた予約はここに表示されます。",
"unconfirmed_bookings": "未確認の予約はここに表示されます。",
"unconfirmed_bookings_tooltip": "未確認の予約",
"on": "上",
@@ -364,7 +359,6 @@
"browse_api_documentation": "APIドキュメントを参照する",
"leverage_our_api": "APIを活用して、完全な制御とカスタマイズが可能です。",
"create_webhook": "Webhook を作成",
"booking_cancelled": "予約がキャンセルされました",
"booking_rescheduled": "予約の再スケジュール済",
"recording_ready": "レコーディングのダウンロード リンクの準備ができています",
"booking_created": "予約を作成しました",
@@ -377,8 +371,6 @@
"team_webhooks": "チームのウェブフック",
"create_new_webhook_to_account": "アカウントに新しいウェブフックを作成します",
"new_webhook": "新しいウェブフック",
"receive_cal_meeting_data": "イベントが予定またはキャンセルされた場合、特定の URL で開かれる {{appName}} ミーティングデータをリアルタイムに受信する。",
"receive_cal_event_meeting_data": "このイベントが予定またはキャンセルされた場合、特定の URL で開かれる {{appName}} ミーティングデータをリアルタイムに受信する。",
"responsive_fullscreen_iframe": "レスポンシブフルスクリーン iframe",
"loading": "読み込み中...",
"deleting": "削除中...",
@@ -514,6 +506,8 @@
"team_description": "あなたのチームについての簡単な説明文です。あなたのチームの URL ページに表示されます。",
"members": "メンバー",
"member": "メンバー",
"number_member_one": "{{count}} 人のメンバー",
"number_member_other": "{{count}} 人のメンバー",
"owner": "所有者",
"admin": "管理者",
"administrator_user": "管理者ユーザー",
@@ -1014,14 +1008,12 @@
"event_location": "イベントの場所",
"reschedule_optional": "スケジュール変更の理由 (任意)",
"reschedule_placeholder": "スケジュール変更が必要な理由を他の人に知らせる",
"event_cancelled": "このイベントはキャンセルされました",
"emailed_information_about_cancelled_event": "あなたと他の出席者に電子メールでお知らせしました。",
"this_input_will_shown_booking_this_event": "この入力は、このイベントを予約する際に表示されます",
"meeting_url_in_conformation_email": "ミーティングURLは確認メールに記載されています",
"url_start_with_https": "URLは、http://またはhttps://で始まる必要があります",
"number_provided": "電話番号が提供されます",
"before_event_trigger": "イベント開始前に",
"event_cancelled_trigger": "イベントキャンセル時に",
"new_event_trigger": "新しいイベント予約時に",
"email_host_action": "ホストにメールを送信",
"email_attendee_action": "出席者にメールを送る",
@@ -1183,7 +1175,6 @@
"start_of_week": "週の始まり",
"recordings_title": "録音",
"recording": "録音",
"happy_scheduling": "スケジュール設定をお楽しみください",
"select_calendars": "ダブルブッキングを防ぐために、スケジュールの重なりをチェックするカレンダーを選択してください。",
"check_for_conflicts": "スケジュールの重なりをチェック",
"view_recordings": "録音を表示",
@@ -1410,7 +1401,6 @@
"your_team_disbanded_successfully": "チームは正常に解散されました",
"error_creating_team": "チームの作成中にエラーが発生しました",
"you": "あなた",
"send_email": "メールを送信",
"member_already_invited": "メンバーは既に招待されています",
"enter_email_or_username": "メールアドレスまたはユーザー名を入力してください",
"team_name_taken": "この名前は既に使用されています",
@@ -1423,7 +1413,7 @@
"attendee_email_info": "予約者のメールアドレス",
"kbar_search_placeholder": "コマンドを入力するか、検索してください...",
"invalid_credential": "アクセス許可の有効期限が切れたか、取り消されたようです。もう一度インストールしてください。",
"reschedule_reason_success_page": "スケジュール変更の理由",
"reschedule_reason": "スケジュール変更の理由",
"choose_common_schedule_team_event": "共通のスケジュールを選択",
"choose_common_schedule_team_event_description": "ホスト間で共通のスケジュールを使用する場合には、これを有効にしてください。無効にすると、各ホストに対してはデフォルトのスケジュールに基づいて予約が行われます。",
"reason": "理由",
@@ -1578,10 +1568,7 @@
"delete_sso_configuration_confirmation_description": "{{connectionType}} の構成を削除してもよろしいですか?{{connectionType}} でのログインを使用しているチームメンバーは、Cal.com にアクセスできなくなります。",
"organizer_timezone": "主催者のタイムゾーン",
"email_user_cta": "招待を表示",
"email_no_user_invite_heading": "{{appName}} のチームに参加するよう招待されました",
"email_no_user_invite_subheading": "{{invitedBy}} は {{appName}} のチームに参加するようあなたを招待しました。{{appName}} は、イベント調整スケジューラーです。チームと延々とメールのやりとりをすることなくミーティングのスケジュール設定を行うことができます。",
"email_user_invite_subheading": "{{invitedBy}}から{{appName}}の「{{teamName}}」に参加するよう招待されました。{{appName}}はイベント調整スケジューラーで、チーム内で延々とメールのやりとりをすることなく、ミーティングのスケジュールを設定できます。",
"email_no_user_invite_steps_intro": "いくつかの短い手順を踏むだけで、すぐにチームとの間のストレスフリーなスケジュール設定をお楽しみいただけます。",
"email_no_user_step_one": "ユーザー名を選択",
"email_no_user_step_two": "カレンダーアカウントを接続",
"email_no_user_step_three": "空き状況を設定する",
@@ -1602,7 +1589,6 @@
"no_longer_attending": "このイベントには出席しなくなりました",
"attendee_no_longer_attending_subject": "出席者は {{date}} の {{title}} には出席しなくなりました",
"attendee_no_longer_attending": "出席者はあなたのイベントに出席しなくなりました",
"attendee_no_longer_attending_subtitle": "{{name}} がキャンセルしました。これにより、この時間帯の座席が 1 つ利用可能になりました",
"create_event_on": "次のカレンダーにイベントを作成",
"default_app_link_title": "デフォルトのアプリリンクを設定",
"default_app_link_description": "デフォルトのアプリリンクを設定することで、新たに作成するすべてのイベントの種類が設定したアプリリンクを使用できるようになります。",
@@ -1623,7 +1609,6 @@
"show_on_booking_page": "予約ページに表示",
"get_started_zapier_templates": "Zapier テンプレートの使用を開始する",
"team_is_unpublished": "{{team}} は公開されていません",
"team_is_unpublished_description": "このチームのリンクは現在利用できません。チームの所有者に問い合わせるか、リンクを公開するように依頼してください。",
"team_member": "チームメンバー",
"a_routing_form": "ルーティングフォーム",
"form_description_placeholder": "フォームの説明",
@@ -1654,7 +1639,6 @@
"spot_popular_event_types_description": "どのイベントの種類が最もクリックされ、予約されているのかを確認します",
"no_responses_yet": "回答はまだありません",
"this_will_be_the_placeholder": "これがプレースホルダーになります",
"error_booking_event": "イベントを予約する際にエラーが発生しました。ページを再読み込みして、もう一度お試しください",
"timeslot_missing_title": "時間帯が選択されていません",
"timeslot_missing_description": "イベントを予約するには時間帯を選んでください。",
"timeslot_missing_cta": "時間帯を選ぶ",
@@ -1715,7 +1699,6 @@
"least_booked_members": "最も予約数が少ないメンバー",
"events_created": "イベントが作成されました",
"events_completed": "イベントが完了しました",
"events_cancelled": "イベントがキャンセルされました",
"events_rescheduled": "イベントのスケジュールが変更されました",
"from_last_period": "最後の期間から",
"from_to_date_period": "開始: {{startDate}} 終了: {{endDate}}",
@@ -1767,7 +1750,6 @@
"book_my_cal": "Cal を予約",
"invite_as": "次の役割で招待",
"form_updated_successfully": "フォームは正常に更新されました。",
"email_not_cal_member_cta": "チームに参加",
"disable_attendees_confirmation_emails": "出席者へのデフォルトの確認メールを無効にする",
"disable_attendees_confirmation_emails_description": "このイベントタイプでは少なくとも1つのワークフローがアクティブで、イベントが予約されると出席者にメールが送られます。",
"disable_host_confirmation_emails": "ホストへのデフォルトの確認メールを無効にする",
@@ -1777,5 +1759,6 @@
"connect_google_workspace": "Google Workspace を接続",
"google_workspace_admin_tooltip": "この機能を使うには Workspace の管理者になる必要があります",
"first_event_type_webhook_description": "このイベントタイプの最初のウェブフックを作成",
"create_for": "作成対象"
"create_for": "作成対象",
"organization_url_taken": "この URL は既に使用されています"
}
+8 -24
View File
@@ -11,11 +11,10 @@
"calcom_explained_new_user": "{{appName}} 계정 설정을 완료하세요! 몇 단계만 거치면 모든 일정 문제를 해결할 수 있습니다.",
"have_any_questions": "질문이 있나요? 도와드릴게요.",
"reset_password_subject": "{{appName}}: 비밀번호 재설정 방법",
"email_sent": "이메일이 성공적으로 전송되었습니다",
"event_declined_subject": "거절됨: {{date}} {{title}}",
"event_cancelled_subject": "취소됨: {{date}} {{title}}",
"event_request_declined": "회의 요청이 거절되었습니다.",
"event_request_declined_recurring": "되풀이 이벤트 요청이 거부되었습니다",
"event_request_cancelled": "회의 일정이 취소되었습니다.",
"organizer": "주최자",
"need_to_reschedule_or_cancel": "다시 일정을 잡거나 취소하시겠습니까?",
"cancellation_reason": "취소 사유(선택사항)",
@@ -77,9 +76,7 @@
"your_meeting_has_been_booked": "회의가 예약되었습니다.",
"event_type_has_been_rescheduled_on_time_date": "귀하의 {{title}} 일정이 {{date}}로 변경되었습니다.",
"event_has_been_rescheduled": "업데이트 - 이벤트 일정이 변경되었습니다.",
"request_reschedule_subtitle": "{{organizer}}에서 예약을 취소했고 다른 시간을 선택할 것을 요청했습니다.",
"request_reschedule_title_organizer": "{{attendee}}에게 일정 변경을 요청하셨습니다",
"request_reschedule_subtitle_organizer": "예약을 취소하셨기 때문에 {{attendee}} 님이 새 예약 시간을 선택해야 합니다.",
"rescheduled_event_type_subject": "일정 변경 요청이 보내짐: {{date}}에 {{name}}(으)로 {{eventType}}",
"requested_to_reschedule_subject_attendee": "일정 변경 조치 필요: {{name}} 님과 함께 새로운 {{eventType}} 시간을 예약하십시오",
"hi_user_name": "안녕하세요 {{name}}",
@@ -119,6 +116,7 @@
"team_upgrade_banner_description": "당사의 새로운 팀 플랜을 사용해 주셔서 감사합니다. 귀하의 \"{{teamName}}\" 팀에 업그레이드가 필요한 것으로 확인되었습니다.",
"team_upgrade_banner_action": "여기서 업그레이드",
"team_upgraded_successfully": "팀이 성공적으로 업그레이드되었습니다!",
"org_upgrade_banner_action": "여기서 업그레이드",
"use_link_to_reset_password": "비밀번호를 재설정하시려면 아래 링크를 사용하세요.",
"hey_there": "안녕하세요.",
"forgot_your_password_calcom": "비밀번호를 잊어버리셨나요? - {{appName}}",
@@ -228,6 +226,7 @@
"done": "완료",
"all_done": "다 되었습니다!",
"all_apps": "모두",
"all": "모두",
"available_apps": "사용 가능한 앱",
"check_email_reset_password": "이메일을 확인하세요. 비밀번호 재설정을 위한 링크를 보냈습니다.",
"finish": "끝",
@@ -301,7 +300,6 @@
"error_end_time_next_day": "종료 시간은 24시간보다 클 수 없습니다",
"back_to_bookings": "예약으로 돌아가기",
"free_to_pick_another_event_type": "언제든지 다른 이벤트를 선택할 수 있습니다.",
"cancelled": "취소됨",
"cancellation_successful": "취소 성공",
"really_cancel_booking": "예약을 정말 취소하시겠습니까?",
"cannot_cancel_booking": "예약을 취소하실 수 없습니다.",
@@ -310,7 +308,6 @@
"cancelling_event_recurring": "이 이벤트는 되풀이 이벤트의 한 인스턴스입니다.",
"cancelling_all_recurring": "이들은 모두 되풀이 이벤트의 나머지 인스턴스입니다.",
"error_with_status_code_occured": "상태 코드가 {{status}}인 오류가 발생했습니다.",
"booking_already_cancelled": "이 예약은 이미 취소되었습니다",
"booking_already_accepted_rejected": "이 예약은 이미 승인 또는 거부되었습니다",
"go_back_home": "홈으로 돌아가기",
"or_go_back_home": "또는 홈으로 돌아가기",
@@ -324,7 +321,6 @@
"upcoming_bookings": "누군가 당신과 회의를 예약하는 즉시 여기에 표시됩니다.",
"recurring_bookings": "누군가가 귀하와 되풀이 회의를 예약하는 즉시 여기에 표시됩니다.",
"past_bookings": "과거 예약이 여기에 표시됩니다.",
"cancelled_bookings": "취소된 예약이 여기에 표시됩니다.",
"unconfirmed_bookings": "확인되지 않은 예약은 여기에 표시됩니다.",
"unconfirmed_bookings_tooltip": "미확인된 예약",
"on": "-",
@@ -364,7 +360,6 @@
"browse_api_documentation": "API 문서 찾아보기",
"leverage_our_api": "API를 활용하여 전체 제어 및 사용자 정의",
"create_webhook": "웹훅 만들기",
"booking_cancelled": "예약 취소",
"booking_rescheduled": "예약 변경",
"recording_ready": "녹화 다운로드 링크 준비됨",
"booking_created": "예약 생성",
@@ -377,8 +372,6 @@
"team_webhooks": "팀 웹훅",
"create_new_webhook_to_account": "내 계정에 새 웹훅 만들기",
"new_webhook": "새 웹훅",
"receive_cal_meeting_data": "일정이 잡히거나 취소될 때 지정된 URL에서 실시간으로 {{appName}} 회의 데이터를 수신합니다.",
"receive_cal_event_meeting_data": "일정이 잡혔거나 취소되었을 때 지정된 URL에서 실시간으로 {{appName}} 회의 데이터를 수신합니다.",
"responsive_fullscreen_iframe": "반응형 전체 화면 iframe",
"loading": "로드 중",
"deleting": "삭제 중...",
@@ -514,6 +507,8 @@
"team_description": "팀 URL 페이지에 나타날 팀 소개를 해주세요.",
"members": "회원",
"member": "회원",
"number_member_one": "회원 {{count}}명",
"number_member_other": "회원 {{count}}명",
"owner": "소유자",
"admin": "관리",
"administrator_user": "관리자 사용자",
@@ -1014,14 +1009,12 @@
"event_location": "이벤트 위치",
"reschedule_optional": "일정 변경 사유(선택사항)",
"reschedule_placeholder": "일정을 조정해야 하는 사유를 다른 사람들에게 알리십시오",
"event_cancelled": "이 이벤트는 취소되었습니다",
"emailed_information_about_cancelled_event": "귀하와 다른 참석자들에게 이메일로 알려 드렸습니다.",
"this_input_will_shown_booking_this_event": "이 입력은 이 이벤트를 예약할 때 표시됩니다.",
"meeting_url_in_conformation_email": "회의 URL은 확인 이메일에 있습니다",
"url_start_with_https": "URL은 http:// 또는 https://로 시작해야 합니다",
"number_provided": "전화 번호는 제공됩니다",
"before_event_trigger": "이벤트 시작 전",
"event_cancelled_trigger": "이벤트 취소 시",
"new_event_trigger": "새 이벤트 예약 시",
"email_host_action": "호스트에게 이메일 발송",
"email_attendee_action": "참석자들에게 이메일 전송",
@@ -1183,7 +1176,6 @@
"start_of_week": "주의 시작",
"recordings_title": "녹음",
"recording": "녹음",
"happy_scheduling": "즐겁게 일정 관리하세요",
"select_calendars": "중복 예약을 방지하기 위해 충돌을 확인하려는 캘린더를 선택합니다.",
"check_for_conflicts": "충돌 확인",
"view_recordings": "녹음 보기",
@@ -1410,7 +1402,6 @@
"your_team_disbanded_successfully": "귀하의 팀이 성공적으로 해산되었습니다",
"error_creating_team": "팀을 만드는 중 오류 발생",
"you": "귀하",
"send_email": "이메일 보내기",
"member_already_invited": "구성원이 이미 초대되었습니다",
"enter_email_or_username": "이메일 또는 사용자 이름을 입력하세요",
"team_name_taken": "이미 사용 중인 이름입니다",
@@ -1423,7 +1414,7 @@
"attendee_email_info": "예약자 이메일",
"kbar_search_placeholder": "명령어를 입력하거나 검색하세요...",
"invalid_credential": "죄송합니다! 권한이 만료되었거나 취소된 것 같습니다. 다시 설치하십시오.",
"reschedule_reason_success_page": "일정 변경 사유",
"reschedule_reason": "일정 변경 사유",
"choose_common_schedule_team_event": "공통 일정 선택",
"choose_common_schedule_team_event_description": "호스트 간에 공통 일정을 사용하려면 이 옵션을 활성화하세요. 비활성화되면 각 호스트는 기본 일정에 따라 예약됩니다.",
"reason": "사유",
@@ -1578,10 +1569,7 @@
"delete_sso_configuration_confirmation_description": "{{connectionType}} 구성을 삭제하시겠습니까? {{connectionType}} 로그인을 사용하는 팀원은 더 이상 Cal.com에 액세스할 수 없습니다.",
"organizer_timezone": "주최자 시간대",
"email_user_cta": "초대 보기",
"email_no_user_invite_heading": "{{appName}} 팀에 초대되었습니다",
"email_no_user_invite_subheading": "{{invitedBy}} 님이 귀하를 {{appName}}에서 자신의 팀에 초대했습니다. {{appName}} 앱은 귀하와 귀하의 팀이 이메일을 주고 받지 않고 회의 일정을 잡을 수 있게 해주는 이벤트 정리 스케줄러입니다.",
"email_user_invite_subheading": "{{invitedBy}}님이 {{appName}}에서 자신의 `{{teamName}}` 팀에 가입하도록 당신을 초대했습니다. {{appName}}은 유저와 팀이 이메일을 주고 받지 않고도 회의 일정을 잡을 수 있게 하는 이벤트 조율 스케줄러입니다.",
"email_no_user_invite_steps_intro": "안내해 드릴 몇 가지 간단한 단계만 거치면 곧 팀과 함께 스트레스 없이 편리하게 일정을 관리할 수 있게 될 것입니다.",
"email_no_user_step_one": "사용자 이름 선택",
"email_no_user_step_two": "캘린더 계정 연결",
"email_no_user_step_three": "언제 여유가 있는지 설정하세요",
@@ -1602,7 +1590,6 @@
"no_longer_attending": "더 이상 이 이벤트에 참석하지 않고 계십니다",
"attendee_no_longer_attending_subject": "참석자가 더 이상 {{date}} 날짜에 {{title}}에 참석하지 않습니다",
"attendee_no_longer_attending": "참석자가 더 이상 이벤트에 참석하고 있지 않습니다",
"attendee_no_longer_attending_subtitle": "{{name}}이(가) 취소되었습니다. 즉, 이 시간 슬롯에 좌석이 비어 있습니다",
"create_event_on": "이벤트 생성일:",
"default_app_link_title": "기본 앱 링크 설정",
"default_app_link_description": "기본 앱 링크를 설정하면 새로 생성된 모든 이벤트 유형에서 설정된 앱 링크를 사용할 수 있습니다.",
@@ -1623,7 +1610,6 @@
"show_on_booking_page": "예약 페이지에 표시",
"get_started_zapier_templates": "Zapier 템플릿 시작하기",
"team_is_unpublished": "{{team}} 팀은 게시되지 않았습니다",
"team_is_unpublished_description": "이 팀 링크는 현재 사용할 수 없습니다. 팀 소유자에게 연락하거나 게시하라고 요청하십시오.",
"team_member": "팀원",
"a_routing_form": "라우팅 양식",
"form_description_placeholder": "양식 설명",
@@ -1654,7 +1640,6 @@
"spot_popular_event_types_description": "어떤 이벤트 타입이 가장 많은 클릭과 예약을 받고 있는지 확인",
"no_responses_yet": "아직 응답 없음",
"this_will_be_the_placeholder": "이것은 자리 표시자가 됩니다",
"error_booking_event": "이벤트를 예약하는 도중 오류가 발생했습니다. 페이지를 새로고침한 후 다시 시도해주세요.",
"timeslot_missing_title": "시간대가 선택되지 않았습니다",
"timeslot_missing_description": "이벤트를 예약 할 시간대를 선택해주세요.",
"timeslot_missing_cta": "시간대 선택",
@@ -1715,7 +1700,6 @@
"least_booked_members": "예약이 가장 적은 회원",
"events_created": "생성된 이벤트",
"events_completed": "완료된 이벤트",
"events_cancelled": "취소된 이벤트",
"events_rescheduled": "일정이 변경된 이벤트",
"from_last_period": "마지막 기간부터",
"from_to_date_period": "시작일: {{startDate}} 종료일: {{endDate}}",
@@ -1767,7 +1751,6 @@
"book_my_cal": "내 Cal 예약",
"invite_as": "다른 이름으로 초대",
"form_updated_successfully": "양식이 성공적으로 업데이트되었습니다.",
"email_not_cal_member_cta": "팀 합류",
"disable_attendees_confirmation_emails": "참석자에 대한 기본 확인 이메일 비활성화",
"disable_attendees_confirmation_emails_description": "이 이벤트 유형에는 이벤트가 예약되었을 때 참석자들에게 이메일을 보내는 최소한 하나의 워크플로가 활성화되어 있습니다.",
"disable_host_confirmation_emails": "호스트에 대한 기본 확인 이메일 비활성화",
@@ -1777,5 +1760,6 @@
"connect_google_workspace": "Google Workspace 연결",
"google_workspace_admin_tooltip": "이 기능을 사용하려면 Workspace 관리자여야 합니다",
"first_event_type_webhook_description": "이 이벤트 유형에 대한 첫 번째 웹훅 만들기",
"create_for": "작성 대상"
"create_for": "작성 대상",
"organization_url_taken": "이미 사용 중인 URL입니다"
}

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