Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e521bf6f0b | ||
|
|
a91a0f86e0 | ||
|
|
f654003f95 | ||
|
|
4cc8a6fbf4 | ||
|
|
5167608404 | ||
|
|
9c93685431 | ||
|
|
a380087c9b | ||
|
|
3559e0d082 | ||
|
|
4323b0c2d1 | ||
|
|
3a800f7511 | ||
|
|
c203e5a38b | ||
|
|
3f5b3f06a2 | ||
|
|
d52635efbb | ||
|
|
4add4df08e | ||
|
|
df6d7e8df7 | ||
|
|
dc61640118 | ||
|
|
361108246e | ||
|
|
a5e25b9b28 | ||
|
|
ccff528765 | ||
|
|
24a1ef6721 | ||
|
|
b89919129e | ||
|
|
cbf3edefc7 | ||
|
|
909ae5f2fb | ||
|
|
0bbe5173dc | ||
|
|
84ad133077 | ||
|
|
43647a797f | ||
|
|
f469a9c127 | ||
|
|
212f7a374f | ||
|
|
1929d5c7d4 | ||
|
|
8ae54cd7cc | ||
|
|
bb13009e64 | ||
|
|
648dd862f5 | ||
|
|
8eccd3658e | ||
|
|
ed65b2a3ab | ||
|
|
0930121680 | ||
|
|
1068873f27 | ||
|
|
a1ece0be63 | ||
|
|
c550b4c8fc | ||
|
|
e95650637c | ||
|
|
0f3e0a1554 | ||
|
|
761dfac033 | ||
|
|
9fda4acc5b | ||
|
|
0470708aad | ||
|
|
bee392ba1a | ||
|
|
448f57442b | ||
|
|
856b090b4b | ||
|
|
b99661a411 | ||
|
|
d96a26eb3c | ||
|
|
9d08f5c7c8 | ||
|
|
4fe5f6ca6f | ||
|
|
af505935bd | ||
|
|
4a30f60622 | ||
|
|
24ed04e6c7 | ||
|
|
bed3595314 | ||
|
|
74671263bf | ||
|
|
bdc5e9c7e9 | ||
|
|
8fa1c70a97 | ||
|
|
1343c8fa8d | ||
|
|
5c0f9510a1 | ||
|
|
b2801170fa | ||
|
|
6ac19e8307 | ||
|
|
344241cfbf | ||
|
|
66ebf18fa9 | ||
|
|
e6d6f3317e | ||
|
|
55f66e6bcd | ||
|
|
22e2b0a6a9 | ||
|
|
e24f3828cb | ||
|
|
70f5bdc499 | ||
|
|
8731a39c3c | ||
|
|
e2d9e75475 | ||
|
|
55c7707b94 | ||
|
|
98944d4815 | ||
|
|
faba25acbd | ||
|
|
aab5ee344c | ||
|
|
6880f88dbe | ||
|
|
9177fe86dc | ||
|
|
bf3f8acbc0 | ||
|
|
b4fa9826f2 | ||
|
|
955de3133c | ||
|
|
faac3d0f57 | ||
|
|
3fb1ede770 | ||
|
|
53224886e3 | ||
|
|
e513180d7e | ||
|
|
3116d6df1a | ||
|
|
4284a4d16d | ||
|
|
eadca3b2c0 | ||
|
|
68125af29f | ||
|
|
d436e628fe | ||
|
|
c5483c81de | ||
|
|
9db4a04cd9 | ||
|
|
8943e8c2f6 | ||
|
|
f17fa55426 | ||
|
|
9ff83075d6 | ||
|
|
6b6043afdc | ||
|
|
fd9162e70f | ||
|
|
8331059b7c | ||
|
|
f0992b4914 | ||
|
|
e081a4cfc2 | ||
|
|
895b3ca7c9 | ||
|
|
4d30264950 | ||
|
|
3a352a94f6 | ||
|
|
8623175612 | ||
|
|
ea531777c4 | ||
|
|
2639ef7e13 | ||
|
|
0e76a19c96 | ||
|
|
3ec9eb377d | ||
|
|
44b7000509 | ||
|
|
251307f1e6 | ||
|
|
75e638ec4d | ||
|
|
443ccdd6c0 | ||
|
|
dbf11cc04b | ||
|
|
a5c9729f5f | ||
|
|
a6e2983a22 | ||
|
|
a21f0c46c7 | ||
|
|
ed4a81e852 | ||
|
|
9231218350 | ||
|
|
7d1ea4ee2b | ||
|
|
0c68e51930 |
@@ -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
|
||||
@@ -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 }}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
changes:
|
||||
name: Detect changes
|
||||
runs-on: buildjet-4vcpu-ubuntu-2204
|
||||
permissions:
|
||||
pull-requests: read
|
||||
|
||||
@@ -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. ❤️🎉
|
||||
Vendored
+2
-1
@@ -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
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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.
|
||||
@@ -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",
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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: |
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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
@@ -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",
|
||||
|
||||
@@ -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
@@ -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")}{" "}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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" };
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
+1
-1
@@ -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,
|
||||
},
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -86,6 +86,12 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
theme: true,
|
||||
brandColor: true,
|
||||
darkBrandColor: true,
|
||||
parent: {
|
||||
select: {
|
||||
logo: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
users: {
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
@@ -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();
|
||||
|
||||
@@ -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 |
@@ -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 هذا مأخوذ بالفعل"
|
||||
}
|
||||
|
||||
@@ -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á"
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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": "Ή επιστροφή στην αρχική σελίδα",
|
||||
|
||||
@@ -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 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
|
||||
@@ -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}}",
|
||||
|
||||
@@ -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 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ↑"
|
||||
}
|
||||
|
||||
@@ -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 は既に使用されています"
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user