Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f13fc58b9 | ||
|
|
527d1f6c93 | ||
|
|
0ec3c496d8 | ||
|
|
62ec3de0b1 | ||
|
|
2c47cb6a3b | ||
|
|
dc2b145843 | ||
|
|
c958e1578a | ||
|
|
1e857e5c0a | ||
|
|
9bc8d48415 | ||
|
|
f86c6734a7 | ||
|
|
3d5ff82062 | ||
|
|
8b63483e2e | ||
|
|
c97d4288c0 | ||
|
|
ff75364f22 | ||
|
|
7f1b028099 | ||
|
|
9e70a985e4 | ||
|
|
057cf273dd | ||
|
|
9af621294d | ||
|
|
bfb5a31032 | ||
|
|
6308955e89 | ||
|
|
b0c5b629d7 | ||
|
|
10f965570b | ||
|
|
c24f5200f5 | ||
|
|
f922692a1a | ||
|
|
65c137f67d | ||
|
|
585679969a | ||
|
|
893b67b6c4 | ||
|
|
3c296b440e | ||
|
|
f8a59b52f7 | ||
|
|
17d106cfda | ||
|
|
dcf9d30382 | ||
|
|
eafd7f6b77 | ||
|
|
f31165b442 | ||
|
|
40c5d5871e | ||
|
|
2362754356 | ||
|
|
8ccf3b589e | ||
|
|
2dbc73c75b | ||
|
|
87e1ad7115 | ||
|
|
2e9895aceb | ||
|
|
fbbc573f33 | ||
|
|
8bc8a045b6 | ||
|
|
8c049b29b3 | ||
|
|
f1e783f047 | ||
|
|
3baa6c7145 | ||
|
|
dd28bb46db | ||
|
|
c182091fa9 | ||
|
|
d061572ed6 | ||
|
|
3a943fbc81 | ||
|
|
8a58a51a2c | ||
|
|
e92265ceaa | ||
|
|
b7b1fff1c0 | ||
|
|
886f7021f4 | ||
|
|
2b17188087 | ||
|
|
d498988bd4 | ||
|
|
785a08ba2c | ||
|
|
6aa83102e4 | ||
|
|
97fe41f3ba | ||
|
|
b7cecfbb66 | ||
|
|
7f7d80e653 | ||
|
|
64796a96fc | ||
|
|
83cc7dc86e | ||
|
|
75c9145558 | ||
|
|
869f459d98 | ||
|
|
e00008b663 | ||
|
|
175f2482e1 | ||
|
|
9d91d72a72 | ||
|
|
fd9cd1b98b | ||
|
|
2640040359 | ||
|
|
dec8f8e896 | ||
|
|
b4eff25636 | ||
|
|
2a752e5358 | ||
|
|
b2684837c1 | ||
|
|
2fed2133a5 | ||
|
|
7fc0877c26 | ||
|
|
f7ce774ddc | ||
|
|
174c730f1f | ||
|
|
8ad513e4ec | ||
|
|
a0bf5b4067 | ||
|
|
484f603c9e | ||
|
|
94b16fb327 | ||
|
|
55db7bdf76 | ||
|
|
14af241d5f | ||
|
|
4efa90e42f | ||
|
|
581e1759c4 | ||
|
|
61cdac321e | ||
|
|
59a04137a1 | ||
|
|
eba1a1ffff | ||
|
|
df25b179d7 | ||
|
|
ff2d9ad67d | ||
|
|
485b72cd0d | ||
|
|
57eb5a4328 | ||
|
|
2c4954e31c | ||
|
|
748f2b42e8 | ||
|
|
6bc713bc2e | ||
|
|
b1019d6bab | ||
|
|
268f1872e4 | ||
|
|
60d439cc32 | ||
|
|
36d201ac20 | ||
|
|
d6644bc232 | ||
|
|
7a9b893931 | ||
|
|
235c314e68 |
No files matched your search
@@ -106,12 +106,6 @@ LARK_OPEN_APP_ID=""
|
|||||||
LARK_OPEN_APP_SECRET=""
|
LARK_OPEN_APP_SECRET=""
|
||||||
LARK_OPEN_VERIFICATION_TOKEN=""
|
LARK_OPEN_VERIFICATION_TOKEN=""
|
||||||
|
|
||||||
# - WEB3
|
|
||||||
# Used for the Web3 plugin
|
|
||||||
# @see https://github.com/calcom/cal.com/blob/main/packages/app-store/rainbow/README.md
|
|
||||||
ALCHEMY_API_KEY=""
|
|
||||||
INFURA_API_KEY=""
|
|
||||||
|
|
||||||
# - SALESFORCE
|
# - SALESFORCE
|
||||||
# Used for the Salesforce (Sales Cloud) app
|
# Used for the Salesforce (Sales Cloud) app
|
||||||
SALESFORCE_CONSUMER_KEY=""
|
SALESFORCE_CONSUMER_KEY=""
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ Fixes # (issue)
|
|||||||
Loom Video: https://www.loom.com/
|
Loom Video: https://www.loom.com/
|
||||||
-->
|
-->
|
||||||
|
|
||||||
**Environment**: Staging(main branch) / Production
|
|
||||||
|
|
||||||
## Type of change
|
## Type of change
|
||||||
|
|
||||||
<!-- Please delete bullets that are not relevant. -->
|
<!-- Please delete bullets that are not relevant. -->
|
||||||
@@ -27,13 +25,14 @@ Fixes # (issue)
|
|||||||
- [ ] Test A
|
- [ ] Test A
|
||||||
- [ ] Test B
|
- [ ] Test B
|
||||||
|
|
||||||
|
## Mandatory Tasks
|
||||||
|
- [ ] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
<!-- Please remove all the irrelevant bullets to your PR -->
|
<!-- Please remove all the irrelevant bullets to your PR -->
|
||||||
|
|
||||||
- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
|
- I haven't read the [contributing guide](https://github.com/calcom/cal.com/blob/main/CONTRIBUTING.md)
|
||||||
- My code doesn't follow the style guidelines of this project
|
- My code doesn't follow the style guidelines of this project
|
||||||
- I haven't performed a self-review of my own code and corrected any misspellings
|
|
||||||
- I haven't commented my code, particularly in hard-to-understand areas
|
- I haven't commented my code, particularly in hard-to-understand areas
|
||||||
- I haven't checked if my PR needs changes to the documentation
|
- I haven't checked if my PR needs changes to the documentation
|
||||||
- I haven't checked if my changes generate no new warnings
|
- I haven't checked if my changes generate no new warnings
|
||||||
|
|||||||
@@ -1,27 +1,75 @@
|
|||||||
name: "Apply issue labels to PR"
|
name: "Apply issue labels to PR"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request_target:
|
||||||
types: [opened]
|
types:
|
||||||
|
- opened
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
label_on_pr:
|
label_on_pr:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
|
contents: none
|
||||||
|
issues: read
|
||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v2
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
|
|
||||||
- name: Apply labels from linked issue to PR
|
- name: Apply labels from linked issue to PR
|
||||||
env:
|
uses: actions/github-script@v5
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
with:
|
||||||
PR_DATA: ${{ toJson(github.event.pull_request) }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: node ./.github/workflows/scripts/apply-issue-labels-to-pr.ts
|
script: |
|
||||||
|
async function getLinkedIssues(owner, repo, prNumber) {
|
||||||
|
const query = `query GetLinkedIssues($owner: String!, $repo: String!, $prNumber: Int!) {
|
||||||
|
repository(owner: $owner, name: $repo) {
|
||||||
|
pullRequest(number: $prNumber) {
|
||||||
|
closingIssuesReferences(first: 10) {
|
||||||
|
nodes {
|
||||||
|
number
|
||||||
|
labels(first: 10) {
|
||||||
|
nodes {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const variables = {
|
||||||
|
owner: owner,
|
||||||
|
repo: repo,
|
||||||
|
prNumber: prNumber,
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await github.graphql(query, variables);
|
||||||
|
return result.repository.pullRequest.closingIssuesReferences.nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pr = context.payload.pull_request;
|
||||||
|
const linkedIssues = await getLinkedIssues(
|
||||||
|
context.repo.owner,
|
||||||
|
context.repo.repo,
|
||||||
|
pr.number
|
||||||
|
);
|
||||||
|
|
||||||
|
const labelsToAdd = new Set();
|
||||||
|
for (const issue of linkedIssues) {
|
||||||
|
if (issue.labels && issue.labels.nodes) {
|
||||||
|
for (const label of issue.labels.nodes) {
|
||||||
|
labelsToAdd.add(label.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (labelsToAdd.size) {
|
||||||
|
await github.rest.issues.addLabels({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: pr.number,
|
||||||
|
labels: Array.from(labelsToAdd),
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -25,7 +25,9 @@ jobs:
|
|||||||
- uses: ./.github/actions/cache-db
|
- uses: ./.github/actions/cache-db
|
||||||
- uses: ./.github/actions/cache-build
|
- uses: ./.github/actions/cache-build
|
||||||
- name: Run Tests
|
- name: Run Tests
|
||||||
run: yarn test-e2e:embed-react
|
run: |
|
||||||
|
yarn test-e2e:embed-react
|
||||||
|
yarn workspace @calcom/embed-react packaged:tests
|
||||||
env:
|
env:
|
||||||
DEPLOYSENTINEL_API_KEY: ${{ secrets.DEPLOYSENTINEL_API_KEY }}
|
DEPLOYSENTINEL_API_KEY: ${{ secrets.DEPLOYSENTINEL_API_KEY }}
|
||||||
- name: Upload Test Results
|
- name: Upload Test Results
|
||||||
|
|||||||
@@ -1,139 +0,0 @@
|
|||||||
const https = require("https");
|
|
||||||
|
|
||||||
async function applyLabelFromLinkedIssueToPR(pr, token) {
|
|
||||||
// Get the labels from issues linked to the PR
|
|
||||||
const query = `
|
|
||||||
query GetLinkedIssues($owner: String!, $repo: String!, $prNumber: Int!) {
|
|
||||||
repository(owner: $owner, name: $repo) {
|
|
||||||
pullRequest(number: $prNumber) {
|
|
||||||
closingIssuesReferences(first: 10) {
|
|
||||||
nodes {
|
|
||||||
number
|
|
||||||
labels(first: 10) {
|
|
||||||
nodes {
|
|
||||||
name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const graphqlData = JSON.stringify({
|
|
||||||
query,
|
|
||||||
variables: {
|
|
||||||
owner: pr.base.repo.owner.login,
|
|
||||||
repo: pr.base.repo.name,
|
|
||||||
prNumber: pr.number,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const requestOptions = {
|
|
||||||
hostname: "api.github.com",
|
|
||||||
path: "/graphql",
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Content-Length": graphqlData.length,
|
|
||||||
Authorization: "Bearer " + token,
|
|
||||||
"User-Agent": "Node.js",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Use the native Node.js request library to make the request
|
|
||||||
let linkedIssues;
|
|
||||||
linkedIssues = await new Promise((resolve, reject) => {
|
|
||||||
const request = https.request(requestOptions, (response) => {
|
|
||||||
let responseBody = "";
|
|
||||||
response.on("data", (chunk) => {
|
|
||||||
responseBody += chunk;
|
|
||||||
});
|
|
||||||
response.on("end", () => {
|
|
||||||
resolve(JSON.parse(responseBody)?.data?.repository?.pullRequest?.closingIssuesReferences?.nodes);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
request.on("error", (error) => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
request.write(graphqlData);
|
|
||||||
request.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!linkedIssues || linkedIssues.length === 0) {
|
|
||||||
console.log("No issue linked.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Iterate over linked issues and apply labels to PR
|
|
||||||
for (const issue of linkedIssues) {
|
|
||||||
const labels = issue?.labels?.nodes?.map((label) => label.name);
|
|
||||||
|
|
||||||
if (!labels || labels.length === 0) {
|
|
||||||
console.log(`No labels found on the linked issue #${issue.number}.`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const labelsData = JSON.stringify({
|
|
||||||
labels: labels,
|
|
||||||
});
|
|
||||||
|
|
||||||
const requestOptions = {
|
|
||||||
hostname: "api.github.com",
|
|
||||||
path: `/repos/${pr.base.repo.owner.login}/${pr.base.repo.name}/issues/${pr.number}/labels`,
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
"Content-Length": labelsData.length,
|
|
||||||
Authorization: "Bearer " + token,
|
|
||||||
"User-Agent": "Node.js",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let labelResult;
|
|
||||||
labelResult = await new Promise((resolve, reject) => {
|
|
||||||
const request = https.request(requestOptions, (response) => {
|
|
||||||
let responseBody = "";
|
|
||||||
response.on("data", (chunk) => {
|
|
||||||
responseBody += chunk;
|
|
||||||
});
|
|
||||||
response.on("data", () => {});
|
|
||||||
response.on("end", () => {
|
|
||||||
resolve(JSON.parse(responseBody));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
request.on("error", (error) => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
|
|
||||||
request.write(labelsData);
|
|
||||||
request.end();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (labelResult.message) {
|
|
||||||
console.log(`Error labelling PR: ${labelResult.message}`);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
`Applied labels: ${labels.join(", ")} to PR #${pr.number} from linked issue #${issue.number}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass the PR data and GitHub token to the script
|
|
||||||
(async () => {
|
|
||||||
if (!process.env.PR_DATA) {
|
|
||||||
console.log("No PR data found.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const prData = JSON.parse(process.env.PR_DATA);
|
|
||||||
const token = process.env.GITHUB_TOKEN;
|
|
||||||
|
|
||||||
await applyLabelFromLinkedIssueToPR(prData, token);
|
|
||||||
})();
|
|
||||||
@@ -416,7 +416,7 @@ Make sure to complete section "Obtaining the Google API Credentials". After the
|
|||||||
following
|
following
|
||||||
|
|
||||||
1. Add extra redirect URL `<Cal.com URL>/api/auth/callback/google`
|
1. Add extra redirect URL `<Cal.com URL>/api/auth/callback/google`
|
||||||
1. Under 'OAuth concent screen', click "PUBLISH APP"
|
1. Under 'OAuth consent screen', click "PUBLISH APP"
|
||||||
|
|
||||||
### Obtaining Microsoft Graph Client ID and Secret
|
### Obtaining Microsoft Graph Client ID and Secret
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import { schemaQuerySingleOrMultipleUserIds } from "~/lib/validations/shared/que
|
|||||||
* type: integer
|
* type: integer
|
||||||
* example: [2, 3, 4]
|
* example: [2, 3, 4]
|
||||||
* - in: query
|
* - in: query
|
||||||
* name: attendeeEmails
|
* name: attendeeEmail
|
||||||
* required: false
|
* required: false
|
||||||
* schema:
|
* schema:
|
||||||
* oneOf:
|
* oneOf:
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import { defaultResponder } from "@calcom/lib/server";
|
|||||||
* required:
|
* required:
|
||||||
* - eventTypeId
|
* - eventTypeId
|
||||||
* - start
|
* - start
|
||||||
* - end
|
|
||||||
* - name
|
* - name
|
||||||
* - email
|
* - email
|
||||||
* - timeZone
|
* - timeZone
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const SnippedGenerator = {
|
|||||||
// extend some internals to gain information about current path, method and spec in the generator function metioned later
|
// extend some internals to gain information about current path, method and spec in the generator function metioned later
|
||||||
spec: {
|
spec: {
|
||||||
wrapSelectors: {
|
wrapSelectors: {
|
||||||
requestFor: (ori, system) => (state, path, method) => {
|
requestFor: (ori) => (state, path, method) => {
|
||||||
return ori(path, method)
|
return ori(path, method)
|
||||||
?.set("spec", state.get("json", {}))
|
?.set("spec", state.get("json", {}))
|
||||||
?.setIn(["oasPathMethod", "path"], path)
|
?.setIn(["oasPathMethod", "path"], path)
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ export default function AppListCard(props: AppListCardProps) {
|
|||||||
timeoutRef.current = null;
|
timeoutRef.current = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1133,12 +1133,7 @@ export const EmbedDialog = () => {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const embedUrl: string = router.query.embedUrl as string;
|
const embedUrl: string = router.query.embedUrl as string;
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<Dialog name="embed" clearQueryParamsOnClose={queryParamsForDialog}>
|
||||||
name="embed"
|
|
||||||
clearQueryParamsOnClose={queryParamsForDialog}
|
|
||||||
onOpenChange={(open) => {
|
|
||||||
if (!open) window.resetEmbedStatus();
|
|
||||||
}}>
|
|
||||||
{!router.query.embedType ? (
|
{!router.query.embedType ? (
|
||||||
<ChooseEmbedTypesDialogContent />
|
<ChooseEmbedTypesDialogContent />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
import dynamic from "next/dynamic";
|
|
||||||
import type { Dispatch } from "react";
|
|
||||||
import { useState, useEffect } from "react";
|
|
||||||
import type { JSONObject } from "superjson/dist/types";
|
|
||||||
|
|
||||||
export type Gate = undefined | "rainbow"; // Add more like ` | "geolocation" | "payment"`
|
|
||||||
|
|
||||||
export type GateState = {
|
|
||||||
rainbowToken?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type GateProps = {
|
|
||||||
children: React.ReactNode;
|
|
||||||
gates: Gate[];
|
|
||||||
appData: JSONObject;
|
|
||||||
dispatch: Dispatch<Partial<GateState>>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const RainbowGate = dynamic(() => import("@calcom/app-store/rainbow/components/RainbowKit"));
|
|
||||||
|
|
||||||
// To add a new Gate just add the gate logic to the switch statement
|
|
||||||
const Gates: React.FC<GateProps> = ({ children, gates, appData, dispatch }) => {
|
|
||||||
const [rainbowToken, setRainbowToken] = useState<string>();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch({ rainbowToken });
|
|
||||||
}, [rainbowToken, dispatch]);
|
|
||||||
|
|
||||||
let gateWrappers = <>{children}</>;
|
|
||||||
|
|
||||||
// Recursively wraps the `gateWrappers` with new gates allowing for multiple gates
|
|
||||||
for (const gate of gates) {
|
|
||||||
switch (gate) {
|
|
||||||
case "rainbow":
|
|
||||||
if (appData.blockchainId && appData.smartContractAddress && !rainbowToken) {
|
|
||||||
gateWrappers = (
|
|
||||||
<RainbowGate
|
|
||||||
setToken={setRainbowToken}
|
|
||||||
chainId={appData.blockchainId as number}
|
|
||||||
tokenAddress={appData.smartContractAddress as string}>
|
|
||||||
{gateWrappers}
|
|
||||||
</RainbowGate>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return gateWrappers;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Gates;
|
|
||||||
@@ -5,6 +5,8 @@ import Script from "next/script";
|
|||||||
|
|
||||||
import "@calcom/embed-core/src/embed-iframe";
|
import "@calcom/embed-core/src/embed-iframe";
|
||||||
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
|
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
|
||||||
|
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||||
|
import { buildCanonical } from "@calcom/lib/next-seo.config";
|
||||||
|
|
||||||
import type { AppProps } from "@lib/app-providers";
|
import type { AppProps } from "@lib/app-providers";
|
||||||
import AppProviders from "@lib/app-providers";
|
import AppProviders from "@lib/app-providers";
|
||||||
@@ -13,7 +15,7 @@ import { seoConfig } from "@lib/config/next-seo.config";
|
|||||||
import I18nLanguageHandler from "@components/I18nLanguageHandler";
|
import I18nLanguageHandler from "@components/I18nLanguageHandler";
|
||||||
|
|
||||||
export interface CalPageWrapper {
|
export interface CalPageWrapper {
|
||||||
(props?: any): JSX.Element;
|
(props?: AppProps): JSX.Element;
|
||||||
PageWrapper?: AppProps["Component"]["PageWrapper"];
|
PageWrapper?: AppProps["Component"]["PageWrapper"];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,9 +51,24 @@ function PageWrapper(props: AppProps) {
|
|||||||
};
|
};
|
||||||
// Use the layout defined at the page level, if available
|
// Use the layout defined at the page level, if available
|
||||||
const getLayout = Component.getLayout ?? ((page) => page);
|
const getLayout = Component.getLayout ?? ((page) => page);
|
||||||
|
|
||||||
|
// Canonical: Check if the URL is from cal.com so that we set the canonical conditionally
|
||||||
|
const isCalcom =
|
||||||
|
WEBAPP_URL &&
|
||||||
|
(new URL(WEBAPP_URL).hostname.endsWith("cal.com") || new URL(WEBAPP_URL).hostname.endsWith("cal.dev"));
|
||||||
|
const path = router.asPath;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AppProviders {...providerProps}>
|
<AppProviders {...providerProps}>
|
||||||
<DefaultSeo {...seoConfig.defaultNextSeo} />
|
<DefaultSeo
|
||||||
|
// Set canonical to https://cal.com or self-hosted URL
|
||||||
|
canonical={
|
||||||
|
isCalcom
|
||||||
|
? buildCanonical({ path, origin: "https://cal.com" }) // cal.com & .dev
|
||||||
|
: buildCanonical({ path, origin: WEBAPP_URL }) // self-hosted
|
||||||
|
}
|
||||||
|
{...seoConfig.defaultNextSeo}
|
||||||
|
/>
|
||||||
<I18nLanguageHandler />
|
<I18nLanguageHandler />
|
||||||
<Script
|
<Script
|
||||||
nonce={nonce}
|
nonce={nonce}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import type { FunctionComponent, SVGProps } from "react";
|
||||||
|
|
||||||
import { InstallAppButton } from "@calcom/app-store/components";
|
import { InstallAppButton } from "@calcom/app-store/components";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import { trpc } from "@calcom/trpc/react";
|
import { trpc } from "@calcom/trpc/react";
|
||||||
@@ -55,7 +57,7 @@ const AdditionalCalendarSelector = ({ isLoading }: AdditionalCalendarSelectorPro
|
|||||||
<InstallAppButton
|
<InstallAppButton
|
||||||
type={data.type}
|
type={data.type}
|
||||||
render={(installProps) => {
|
render={(installProps) => {
|
||||||
const props = { ...installProps } as any;
|
const props = { ...installProps } as FunctionComponent<SVGProps<SVGSVGElement>>;
|
||||||
return (
|
return (
|
||||||
<DropdownItem {...props} color="minimal" type="button">
|
<DropdownItem {...props} color="minimal" type="button">
|
||||||
<span className="flex items-center gap-x-2">
|
<span className="flex items-center gap-x-2">
|
||||||
|
|||||||
@@ -2,60 +2,12 @@ import type { ComponentProps } from "react";
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import AppCategoryNavigation from "@calcom/app-store/_components/AppCategoryNavigation";
|
import AppCategoryNavigation from "@calcom/app-store/_components/AppCategoryNavigation";
|
||||||
import type { InstalledAppVariants } from "@calcom/app-store/utils";
|
|
||||||
import Shell from "@calcom/features/shell/Shell";
|
import Shell from "@calcom/features/shell/Shell";
|
||||||
import { trpc } from "@calcom/trpc/react";
|
|
||||||
import type { HorizontalTabItemProps, VerticalTabItemProps } from "@calcom/ui";
|
|
||||||
import { BarChart, Calendar, CreditCard, Grid, Share2, Video } from "@calcom/ui/components/icon";
|
|
||||||
|
|
||||||
const tabs: (VerticalTabItemProps | HorizontalTabItemProps)[] = [
|
|
||||||
{
|
|
||||||
name: "calendar",
|
|
||||||
href: "/apps/installed/calendar",
|
|
||||||
icon: Calendar,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "conferencing",
|
|
||||||
href: "/apps/installed/conferencing",
|
|
||||||
icon: Video,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "payment",
|
|
||||||
href: "/apps/installed/payment",
|
|
||||||
icon: CreditCard,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "automation",
|
|
||||||
href: "/apps/installed/automation",
|
|
||||||
icon: Share2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "analytics",
|
|
||||||
href: "/apps/installed/analytics",
|
|
||||||
icon: BarChart,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "other",
|
|
||||||
href: "/apps/installed/other",
|
|
||||||
icon: Grid,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function InstalledAppsLayout({
|
export default function InstalledAppsLayout({
|
||||||
children,
|
children,
|
||||||
...rest
|
...rest
|
||||||
}: { children: React.ReactNode } & ComponentProps<typeof Shell>) {
|
}: { children: React.ReactNode } & ComponentProps<typeof Shell>) {
|
||||||
const variant: (typeof InstalledAppVariants)[number] = "payment";
|
|
||||||
|
|
||||||
const query = trpc.viewer.integrations.useQuery({
|
|
||||||
variant,
|
|
||||||
onlyInstalled: true,
|
|
||||||
});
|
|
||||||
let actualTabs = tabs;
|
|
||||||
if (query.data?.items.length === 0) {
|
|
||||||
actualTabs = tabs.filter((tab) => tab.name !== variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Shell {...rest} hideHeadingOnMobile>
|
<Shell {...rest} hideHeadingOnMobile>
|
||||||
<AppCategoryNavigation baseURL="/apps/installed" containerClassname="min-w-0 w-full">
|
<AppCategoryNavigation baseURL="/apps/installed" containerClassname="min-w-0 w-full">
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ type AvailableTimesProps = {
|
|||||||
bookingAttendees?: number | null;
|
bookingAttendees?: number | null;
|
||||||
slots?: Slot[];
|
slots?: Slot[];
|
||||||
isLoading: boolean;
|
isLoading: boolean;
|
||||||
ethSignature?: string;
|
|
||||||
duration: number;
|
duration: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -43,7 +42,6 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
|
|||||||
onTimeFormatChange,
|
onTimeFormatChange,
|
||||||
seatsPerTimeSlot,
|
seatsPerTimeSlot,
|
||||||
bookingAttendees,
|
bookingAttendees,
|
||||||
ethSignature,
|
|
||||||
duration,
|
duration,
|
||||||
}) => {
|
}) => {
|
||||||
const reserveSlotMutation = trpc.viewer.public.slots.reserveSlot.useMutation();
|
const reserveSlotMutation = trpc.viewer.public.slots.reserveSlot.useMutation();
|
||||||
@@ -119,7 +117,6 @@ const AvailableTimes: FC<AvailableTimesProps> = ({
|
|||||||
timeFormat,
|
timeFormat,
|
||||||
/** Treat as recurring only when a count exist and it's not a rescheduling workflow */
|
/** Treat as recurring only when a count exist and it's not a rescheduling workflow */
|
||||||
count: recurringCount && !rescheduleUid ? recurringCount : undefined,
|
count: recurringCount && !rescheduleUid ? recurringCount : undefined,
|
||||||
...(ethSignature ? { ethSignature } : {}),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ export const SlotPicker = ({
|
|||||||
seatsPerTimeSlot,
|
seatsPerTimeSlot,
|
||||||
bookingAttendees,
|
bookingAttendees,
|
||||||
weekStart = 0,
|
weekStart = 0,
|
||||||
ethSignature,
|
|
||||||
}: {
|
}: {
|
||||||
eventType: Pick<
|
eventType: Pick<
|
||||||
EventType & { metadata: z.infer<typeof EventTypeMetaDataSchema> },
|
EventType & { metadata: z.infer<typeof EventTypeMetaDataSchema> },
|
||||||
@@ -94,7 +93,6 @@ export const SlotPicker = ({
|
|||||||
recurringEventCount?: number;
|
recurringEventCount?: number;
|
||||||
users: string[];
|
users: string[];
|
||||||
weekStart?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
weekStart?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
||||||
ethSignature?: string;
|
|
||||||
}) => {
|
}) => {
|
||||||
const [selectedDate, setSelectedDate] = useState<Dayjs>();
|
const [selectedDate, setSelectedDate] = useState<Dayjs>();
|
||||||
const [browsingDate, setBrowsingDate] = useState<Dayjs>();
|
const [browsingDate, setBrowsingDate] = useState<Dayjs>();
|
||||||
@@ -193,7 +191,6 @@ export const SlotPicker = ({
|
|||||||
seatsPerTimeSlot={seatsPerTimeSlot}
|
seatsPerTimeSlot={seatsPerTimeSlot}
|
||||||
bookingAttendees={bookingAttendees}
|
bookingAttendees={bookingAttendees}
|
||||||
recurringCount={recurringEventCount}
|
recurringCount={recurringEventCount}
|
||||||
ethSignature={ethSignature}
|
|
||||||
duration={parseInt(duration)}
|
duration={parseInt(duration)}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useEffect, useMemo, useReducer, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import BookingPageTagManager from "@calcom/app-store/BookingPageTagManager";
|
import BookingPageTagManager from "@calcom/app-store/BookingPageTagManager";
|
||||||
import { getEventTypeAppData } from "@calcom/app-store/utils";
|
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import {
|
import {
|
||||||
useEmbedNonStylesConfig,
|
useEmbedNonStylesConfig,
|
||||||
@@ -27,8 +26,6 @@ import { CreditCard, User, RefreshCcw } from "@calcom/ui/components/icon";
|
|||||||
|
|
||||||
import { timeZone as localStorageTimeZone } from "@lib/clock";
|
import { timeZone as localStorageTimeZone } from "@lib/clock";
|
||||||
|
|
||||||
import type { Gate, GateState } from "@components/Gates";
|
|
||||||
import Gates from "@components/Gates";
|
|
||||||
import BookingDescription from "@components/booking/BookingDescription";
|
import BookingDescription from "@components/booking/BookingDescription";
|
||||||
import { SlotPicker } from "@components/booking/SlotPicker";
|
import { SlotPicker } from "@components/booking/SlotPicker";
|
||||||
|
|
||||||
@@ -89,14 +86,6 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
|||||||
setIs24hClockInLocalStorage(is24Hours);
|
setIs24hClockInLocalStorage(is24Hours);
|
||||||
};
|
};
|
||||||
|
|
||||||
const [gateState, gateDispatcher] = useReducer(
|
|
||||||
(state: GateState, newState: Partial<GateState>) => ({
|
|
||||||
...state,
|
|
||||||
...newState,
|
|
||||||
}),
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeZone(localStorageTimeZone() || dayjs.tz.guess());
|
setTimeZone(localStorageTimeZone() || dayjs.tz.guess());
|
||||||
}, []);
|
}, []);
|
||||||
@@ -124,20 +113,11 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
|||||||
);
|
);
|
||||||
const paymentAppData = getPaymentAppData(eventType);
|
const paymentAppData = getPaymentAppData(eventType);
|
||||||
|
|
||||||
const rainbowAppData = getEventTypeAppData(eventType, "rainbow") || {};
|
|
||||||
const rawSlug = profile.slug ? profile.slug.split("/") : [];
|
const rawSlug = profile.slug ? profile.slug.split("/") : [];
|
||||||
if (rawSlug.length > 1) rawSlug.pop(); //team events have team name as slug, but user events have [user]/[type] as slug.
|
if (rawSlug.length > 1) rawSlug.pop(); //team events have team name as slug, but user events have [user]/[type] as slug.
|
||||||
|
|
||||||
const showEventTypeDetails = (isEmbed && !embedUiConfig.hideEventTypeDetails) || !isEmbed;
|
const showEventTypeDetails = (isEmbed && !embedUiConfig.hideEventTypeDetails) || !isEmbed;
|
||||||
|
|
||||||
// Define conditional gates here
|
|
||||||
const gates = [
|
|
||||||
// Rainbow gate is only added if the event has both a `blockchainId` and a `smartContractAddress`
|
|
||||||
rainbowAppData && rainbowAppData.blockchainId && rainbowAppData.smartContractAddress
|
|
||||||
? ("rainbow" as Gate)
|
|
||||||
: undefined,
|
|
||||||
];
|
|
||||||
|
|
||||||
const { data: bookingAttendees } = trpc.viewer.bookings.getBookingAttendees.useQuery(
|
const { data: bookingAttendees } = trpc.viewer.bookings.getBookingAttendees.useQuery(
|
||||||
{
|
{
|
||||||
seatReferenceUid: rescheduleUid,
|
seatReferenceUid: rescheduleUid,
|
||||||
@@ -148,7 +128,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Gates gates={gates} appData={rainbowAppData} dispatch={gateDispatcher}>
|
<>
|
||||||
<HeadSeo
|
<HeadSeo
|
||||||
title={`${rescheduleUid ? t("reschedule") : ""} ${eventType.title} | ${profile.name}`}
|
title={`${rescheduleUid ? t("reschedule") : ""} ${eventType.title} | ${profile.name}`}
|
||||||
description={`${rescheduleUid ? t("reschedule") : ""} ${eventType.title}`}
|
description={`${rescheduleUid ? t("reschedule") : ""} ${eventType.title}`}
|
||||||
@@ -296,7 +276,6 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
|||||||
seatsPerTimeSlot={eventType.seatsPerTimeSlot || undefined}
|
seatsPerTimeSlot={eventType.seatsPerTimeSlot || undefined}
|
||||||
bookingAttendees={bookingAttendees || undefined}
|
bookingAttendees={bookingAttendees || undefined}
|
||||||
recurringEventCount={recurringEventCount}
|
recurringEventCount={recurringEventCount}
|
||||||
ethSignature={gateState.rainbowToken}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -306,7 +285,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
<Toaster position="bottom-right" />
|
<Toaster position="bottom-right" />
|
||||||
</Gates>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useSession } from "next-auth/react";
|
|||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { useEffect, useMemo, useReducer, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { useForm, useFormContext } from "react-hook-form";
|
import { useForm, useFormContext } from "react-hook-form";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
@@ -12,7 +12,6 @@ import { z } from "zod";
|
|||||||
import BookingPageTagManager from "@calcom/app-store/BookingPageTagManager";
|
import BookingPageTagManager from "@calcom/app-store/BookingPageTagManager";
|
||||||
import type { EventLocationType } from "@calcom/app-store/locations";
|
import type { EventLocationType } from "@calcom/app-store/locations";
|
||||||
import { createPaymentLink } from "@calcom/app-store/stripepayment/lib/client";
|
import { createPaymentLink } from "@calcom/app-store/stripepayment/lib/client";
|
||||||
import { getEventTypeAppData } from "@calcom/app-store/utils";
|
|
||||||
import type { LocationObject } from "@calcom/core/location";
|
import type { LocationObject } from "@calcom/core/location";
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import {
|
import {
|
||||||
@@ -51,8 +50,6 @@ import { AlertTriangle, Calendar, RefreshCw, User } from "@calcom/ui/components/
|
|||||||
import { timeZone } from "@lib/clock";
|
import { timeZone } from "@lib/clock";
|
||||||
import useRouterQuery from "@lib/hooks/useRouterQuery";
|
import useRouterQuery from "@lib/hooks/useRouterQuery";
|
||||||
|
|
||||||
import type { Gate, GateState } from "@components/Gates";
|
|
||||||
import Gates from "@components/Gates";
|
|
||||||
import BookingDescription from "@components/booking/BookingDescription";
|
import BookingDescription from "@components/booking/BookingDescription";
|
||||||
|
|
||||||
import type { BookPageProps } from "../../../pages/[user]/book";
|
import type { BookPageProps } from "../../../pages/[user]/book";
|
||||||
@@ -224,13 +221,6 @@ const BookingPage = ({
|
|||||||
const { data: session } = useSession();
|
const { data: session } = useSession();
|
||||||
const isBackgroundTransparent = useIsBackgroundTransparent();
|
const isBackgroundTransparent = useIsBackgroundTransparent();
|
||||||
const telemetry = useTelemetry();
|
const telemetry = useTelemetry();
|
||||||
const [gateState, gateDispatcher] = useReducer(
|
|
||||||
(state: GateState, newState: Partial<GateState>) => ({
|
|
||||||
...state,
|
|
||||||
...newState,
|
|
||||||
}),
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
const { timezone } = useTimePreferences();
|
const { timezone } = useTimePreferences();
|
||||||
|
|
||||||
@@ -488,7 +478,6 @@ const BookingPage = ({
|
|||||||
metadata,
|
metadata,
|
||||||
hasHashedBookingLink,
|
hasHashedBookingLink,
|
||||||
hashedLink,
|
hashedLink,
|
||||||
ethSignature: gateState.rainbowToken,
|
|
||||||
}));
|
}));
|
||||||
recurringMutation.mutate(recurringBookings);
|
recurringMutation.mutate(recurringBookings);
|
||||||
} else {
|
} else {
|
||||||
@@ -506,25 +495,15 @@ const BookingPage = ({
|
|||||||
metadata,
|
metadata,
|
||||||
hasHashedBookingLink,
|
hasHashedBookingLink,
|
||||||
hashedLink,
|
hashedLink,
|
||||||
ethSignature: gateState.rainbowToken,
|
|
||||||
seatReferenceUid: router.query.seatReferenceUid as string,
|
seatReferenceUid: router.query.seatReferenceUid as string,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const showEventTypeDetails = (isEmbed && !embedUiConfig.hideEventTypeDetails) || !isEmbed;
|
const showEventTypeDetails = (isEmbed && !embedUiConfig.hideEventTypeDetails) || !isEmbed;
|
||||||
const rainbowAppData = getEventTypeAppData(eventType, "rainbow") || {};
|
|
||||||
|
|
||||||
// Define conditional gates here
|
|
||||||
const gates = [
|
|
||||||
// Rainbow gate is only added if the event has both a `blockchainId` and a `smartContractAddress`
|
|
||||||
rainbowAppData && rainbowAppData.blockchainId && rainbowAppData.smartContractAddress
|
|
||||||
? ("rainbow" as Gate)
|
|
||||||
: undefined,
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Gates gates={gates} appData={rainbowAppData} dispatch={gateDispatcher}>
|
<>
|
||||||
<Head>
|
<Head>
|
||||||
<title>
|
<title>
|
||||||
{rescheduleUid
|
{rescheduleUid
|
||||||
@@ -686,7 +665,7 @@ const BookingPage = ({
|
|||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
<Toaster position="bottom-right" />
|
<Toaster position="bottom-right" />
|
||||||
</Gates>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {
|
|||||||
allowDisablingHostConfirmationEmails,
|
allowDisablingHostConfirmationEmails,
|
||||||
} from "@calcom/features/ee/workflows/lib/allowDisablingStandardEmails";
|
} from "@calcom/features/ee/workflows/lib/allowDisablingStandardEmails";
|
||||||
import { FormBuilder } from "@calcom/features/form-builder/FormBuilder";
|
import { FormBuilder } from "@calcom/features/form-builder/FormBuilder";
|
||||||
|
import { BookerLayoutSelector } from "@calcom/features/settings/BookerLayoutSelector";
|
||||||
import { classNames } from "@calcom/lib";
|
import { classNames } from "@calcom/lib";
|
||||||
import { APP_NAME, CAL_URL } from "@calcom/lib/constants";
|
import { APP_NAME, CAL_URL } from "@calcom/lib/constants";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
@@ -65,7 +66,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
|
|||||||
const [requiresConfirmation, setRequiresConfirmation] = useState(eventType.requiresConfirmation);
|
const [requiresConfirmation, setRequiresConfirmation] = useState(eventType.requiresConfirmation);
|
||||||
const placeholderHashedLink = `${CAL_URL}/d/${hashedUrl}/${eventType.slug}`;
|
const placeholderHashedLink = `${CAL_URL}/d/${hashedUrl}/${eventType.slug}`;
|
||||||
const seatsEnabled = formMethods.watch("seatsPerTimeSlotEnabled");
|
const seatsEnabled = formMethods.watch("seatsPerTimeSlotEnabled");
|
||||||
const noShowFeeEnabled = eventType.metadata.apps?.stripe?.paymentOption === "HOLD";
|
const noShowFeeEnabled = eventType.metadata?.apps?.stripe?.paymentOption === "HOLD";
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
!hashedUrl && setHashedUrl(generateHashedLink(eventType.users[0]?.id ?? team?.id));
|
!hashedUrl && setHashedUrl(generateHashedLink(eventType.users[0]?.id ?? team?.id));
|
||||||
@@ -159,6 +160,10 @@ export const EventAdvancedTab = ({ eventType, team }: Pick<EventTypeSetupProps,
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<hr className="border-subtle [&:has(+div:empty)]:hidden" />
|
||||||
|
<div>
|
||||||
|
<BookerLayoutSelector fallbackToUserSettings />
|
||||||
|
</div>
|
||||||
<hr className="border-subtle" />
|
<hr className="border-subtle" />
|
||||||
<FormBuilder
|
<FormBuilder
|
||||||
title={t("booking_questions_title")}
|
title={t("booking_questions_title")}
|
||||||
|
|||||||
@@ -104,9 +104,9 @@ export const EventAppsTab = ({ eventType }: { eventType: EventType }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{!shouldLockDisableProps("apps").disabled && (
|
{!shouldLockDisableProps("apps").disabled && (
|
||||||
<div>
|
<div className="bg-muted rounded-md p-8">
|
||||||
{!isLoading && notInstalledApps?.length ? (
|
{!isLoading && notInstalledApps?.length ? (
|
||||||
<h2 className="text-emphasis my-2 text-lg font-semibold">{t("available_apps")}</h2>
|
<h2 className="text-emphasis text-lg font-semibold">{t("available_apps")}</h2>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="before:border-0">
|
<div className="before:border-0">
|
||||||
{notInstalledApps?.map((app) => (
|
{notInstalledApps?.map((app) => (
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ export const EventSetupTab = (
|
|||||||
const [showLocationModal, setShowLocationModal] = useState(false);
|
const [showLocationModal, setShowLocationModal] = useState(false);
|
||||||
const [editingLocationType, setEditingLocationType] = useState<string>("");
|
const [editingLocationType, setEditingLocationType] = useState<string>("");
|
||||||
const [selectedLocation, setSelectedLocation] = useState<LocationOption | undefined>(undefined);
|
const [selectedLocation, setSelectedLocation] = useState<LocationOption | undefined>(undefined);
|
||||||
const [multipleDuration, setMultipleDuration] = useState(eventType.metadata.multipleDuration);
|
const [multipleDuration, setMultipleDuration] = useState(eventType.metadata?.multipleDuration);
|
||||||
|
|
||||||
const locationOptions = props.locationOptions.filter((option) => {
|
const locationOptions = props.locationOptions.filter((option) => {
|
||||||
return !team ? option.label !== "Conferencing" : true;
|
return !team ? option.label !== "Conferencing" : true;
|
||||||
|
|||||||
@@ -75,8 +75,7 @@ function getNavigation(props: {
|
|||||||
installedAppsNumber: number;
|
installedAppsNumber: number;
|
||||||
availability: AvailabilityOption | undefined;
|
availability: AvailabilityOption | undefined;
|
||||||
}) {
|
}) {
|
||||||
const { eventType, t, enabledAppsNumber, installedAppsNumber, enabledWorkflowsNumber, availability } =
|
const { eventType, t, enabledAppsNumber, installedAppsNumber, enabledWorkflowsNumber } = props;
|
||||||
props;
|
|
||||||
const duration =
|
const duration =
|
||||||
eventType.metadata?.multipleDuration?.map((duration) => ` ${duration}`) || eventType.length;
|
eventType.metadata?.multipleDuration?.map((duration) => ` ${duration}`) || eventType.length;
|
||||||
|
|
||||||
@@ -178,6 +177,7 @@ function EventTypeSingleLayout({
|
|||||||
enabledWorkflowsNumber,
|
enabledWorkflowsNumber,
|
||||||
availability,
|
availability,
|
||||||
});
|
});
|
||||||
|
|
||||||
navigation.splice(1, 0, {
|
navigation.splice(1, 0, {
|
||||||
name: "availability",
|
name: "availability",
|
||||||
href: `/event-types/${eventType.id}?tabName=availability`,
|
href: `/event-types/${eventType.id}?tabName=availability`,
|
||||||
@@ -185,7 +185,7 @@ function EventTypeSingleLayout({
|
|||||||
info:
|
info:
|
||||||
isManagedEventType || isChildrenManagedEventType
|
isManagedEventType || isChildrenManagedEventType
|
||||||
? eventType.schedule === null
|
? eventType.schedule === null
|
||||||
? "Member's default schedule"
|
? "member_default_schedule"
|
||||||
: isChildrenManagedEventType
|
: isChildrenManagedEventType
|
||||||
? `${
|
? `${
|
||||||
eventType.scheduleName
|
eventType.scheduleName
|
||||||
@@ -193,7 +193,7 @@ function EventTypeSingleLayout({
|
|||||||
: `default_schedule_name`
|
: `default_schedule_name`
|
||||||
}`
|
}`
|
||||||
: eventType.scheduleName ?? `default_schedule_name`
|
: eventType.scheduleName ?? `default_schedule_name`
|
||||||
: `default_schedule_name`,
|
: eventType.scheduleName ?? `default_schedule_name`,
|
||||||
});
|
});
|
||||||
// If there is a team put this navigation item within the tabs
|
// If there is a team put this navigation item within the tabs
|
||||||
if (team) {
|
if (team) {
|
||||||
@@ -220,7 +220,18 @@ function EventTypeSingleLayout({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return navigation;
|
return navigation;
|
||||||
}, [t, eventType, installedAppsNumber, enabledAppsNumber, enabledWorkflowsNumber, team, availability]);
|
}, [
|
||||||
|
t,
|
||||||
|
eventType,
|
||||||
|
enabledAppsNumber,
|
||||||
|
installedAppsNumber,
|
||||||
|
enabledWorkflowsNumber,
|
||||||
|
availability,
|
||||||
|
isManagedEventType,
|
||||||
|
isChildrenManagedEventType,
|
||||||
|
team,
|
||||||
|
formMethods,
|
||||||
|
]);
|
||||||
|
|
||||||
const permalink = `${CAL_URL}/${team ? `team/${team.slug}` : eventType.users[0].username}/${
|
const permalink = `${CAL_URL}/${team ? `team/${team.slug}` : eventType.users[0].username}/${
|
||||||
eventType.slug
|
eventType.slug
|
||||||
@@ -236,7 +247,7 @@ function EventTypeSingleLayout({
|
|||||||
heading={eventType.title}
|
heading={eventType.title}
|
||||||
CTA={
|
CTA={
|
||||||
<div className="flex items-center justify-end">
|
<div className="flex items-center justify-end">
|
||||||
{!eventType.metadata.managedEventConfig && (
|
{!eventType.metadata?.managedEventConfig && (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
@@ -379,7 +390,7 @@ function EventTypeSingleLayout({
|
|||||||
<Button
|
<Button
|
||||||
className="ml-4 lg:ml-0"
|
className="ml-4 lg:ml-0"
|
||||||
type="submit"
|
type="submit"
|
||||||
loading={formMethods.formState.isSubmitting || isUpdateMutationLoading}
|
loading={isUpdateMutationLoading}
|
||||||
data-testid="update-eventtype"
|
data-testid="update-eventtype"
|
||||||
form="event-type-form">
|
form="event-type-form">
|
||||||
{t("save")}
|
{t("save")}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export default function RequiresConfirmationController({
|
|||||||
if (!requiresConfirmation) {
|
if (!requiresConfirmation) {
|
||||||
formMethods.setValue("metadata.requiresConfirmationThreshold", undefined);
|
formMethods.setValue("metadata.requiresConfirmationThreshold", undefined);
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [requiresConfirmation]);
|
}, [requiresConfirmation]);
|
||||||
|
|
||||||
const { shouldLockDisableProps } = useLockedFieldsManager(
|
const { shouldLockDisableProps } = useLockedFieldsManager(
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface IConnectCalendarsProps {
|
|||||||
|
|
||||||
const ConnectedCalendars = (props: IConnectCalendarsProps) => {
|
const ConnectedCalendars = (props: IConnectCalendarsProps) => {
|
||||||
const { nextStep } = props;
|
const { nextStep } = props;
|
||||||
const queryConnectedCalendars = trpc.viewer.connectedCalendars.useQuery();
|
const queryConnectedCalendars = trpc.viewer.connectedCalendars.useQuery({ onboarding: true });
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
const queryIntegrations = trpc.viewer.integrations.useQuery({ variant: "calendar", onlyInstalled: false });
|
const queryIntegrations = trpc.viewer.integrations.useQuery({ variant: "calendar", onlyInstalled: false });
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ interface IUserProfileProps {
|
|||||||
const UserProfile = (props: IUserProfileProps) => {
|
const UserProfile = (props: IUserProfileProps) => {
|
||||||
const { user } = props;
|
const { user } = props;
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
const avatarRef = useRef<HTMLInputElement>(null!);
|
const avatarRef = useRef<HTMLInputElement>(null);
|
||||||
const { setValue, handleSubmit, getValues } = useForm<FormData>({
|
const { setValue, handleSubmit, getValues } = useForm<FormData>({
|
||||||
defaultValues: { bio: user?.bio || "" },
|
defaultValues: { bio: user?.bio || "" },
|
||||||
});
|
});
|
||||||
@@ -76,7 +76,7 @@ const UserProfile = (props: IUserProfileProps) => {
|
|||||||
|
|
||||||
async function updateProfileHandler(event: FormEvent<HTMLFormElement>) {
|
async function updateProfileHandler(event: FormEvent<HTMLFormElement>) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const enteredAvatar = avatarRef.current.value;
|
const enteredAvatar = avatarRef.current?.value;
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
avatar: enteredAvatar,
|
avatar: enteredAvatar,
|
||||||
});
|
});
|
||||||
@@ -127,14 +127,16 @@ const UserProfile = (props: IUserProfileProps) => {
|
|||||||
id="avatar-upload"
|
id="avatar-upload"
|
||||||
buttonMsg={t("add_profile_photo")}
|
buttonMsg={t("add_profile_photo")}
|
||||||
handleAvatarChange={(newAvatar) => {
|
handleAvatarChange={(newAvatar) => {
|
||||||
avatarRef.current.value = newAvatar;
|
if (avatarRef.current) {
|
||||||
|
avatarRef.current.value = newAvatar;
|
||||||
|
}
|
||||||
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
|
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
|
||||||
window.HTMLInputElement.prototype,
|
window.HTMLInputElement.prototype,
|
||||||
"value"
|
"value"
|
||||||
)?.set;
|
)?.set;
|
||||||
nativeInputValueSetter?.call(avatarRef.current, newAvatar);
|
nativeInputValueSetter?.call(avatarRef.current, newAvatar);
|
||||||
const ev2 = new Event("input", { bubbles: true });
|
const ev2 = new Event("input", { bubbles: true });
|
||||||
avatarRef.current.dispatchEvent(ev2);
|
avatarRef.current?.dispatchEvent(ev2);
|
||||||
updateProfileHandler(ev2 as unknown as FormEvent<HTMLFormElement>);
|
updateProfileHandler(ev2 as unknown as FormEvent<HTMLFormElement>);
|
||||||
setImageSrc(newAvatar);
|
setImageSrc(newAvatar);
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
|
|||||||
|
|
||||||
const ActionButtons = () => {
|
const ActionButtons = () => {
|
||||||
return usernameIsAvailable && currentUsername !== inputUsernameValue ? (
|
return usernameIsAvailable && currentUsername !== inputUsernameValue ? (
|
||||||
<div className="ms-2 me-2 mt-px flex flex-row space-x-2">
|
<div className="ms-2 me-2 flex flex-row space-x-2">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setOpenDialogSaveUsername(true)}
|
onClick={() => setOpenDialogSaveUsername(true)}
|
||||||
@@ -142,7 +142,7 @@ const UsernameTextfield = (props: ICustomUsernameProps) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-5 hidden md:inline">
|
<div className="mt-7 hidden md:inline">
|
||||||
<ActionButtons />
|
<ActionButtons />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -26,12 +26,6 @@ export const CheckedSelect = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Select
|
<Select
|
||||||
styles={{
|
|
||||||
option: (styles, { isDisabled }) => ({
|
|
||||||
...styles,
|
|
||||||
backgroundColor: isDisabled ? "#F5F5F5" : "inherit",
|
|
||||||
}),
|
|
||||||
}}
|
|
||||||
name={props.name}
|
name={props.name}
|
||||||
placeholder={props.placeholder || t("select")}
|
placeholder={props.placeholder || t("select")}
|
||||||
isSearchable={false}
|
isSearchable={false}
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ export function QueryCell<TData, TError extends ErrorLike>(
|
|||||||
if ("empty" in opts && (query.data == null || (Array.isArray(query.data) && query.data.length === 0))) {
|
if ("empty" in opts && (query.data == null || (Array.isArray(query.data) && query.data.length === 0))) {
|
||||||
return opts.empty(query);
|
return opts.empty(query);
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
return opts.success(query as any);
|
return opts.success(query as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,9 +89,10 @@ const withQuery = <
|
|||||||
TInput = inferProcedureInput<TQuery>,
|
TInput = inferProcedureInput<TQuery>,
|
||||||
TOutput = inferProcedureOutput<TQuery>
|
TOutput = inferProcedureOutput<TQuery>
|
||||||
>(
|
>(
|
||||||
queryProcedure: DecorateProcedure<TQuery, any, any>,
|
queryProcedure: DecorateProcedure<TQuery, inferProcedureInput<TQuery>, inferProcedureOutput<TQuery>>,
|
||||||
|
|
||||||
input?: TInput,
|
input?: TInput,
|
||||||
params?: UseTRPCQueryOptions<any, TInput, TOutput, TOutput, TError>
|
params?: UseTRPCQueryOptions<TQuery, TInput, TOutput, TOutput, TError>
|
||||||
) => {
|
) => {
|
||||||
return function WithQuery(
|
return function WithQuery(
|
||||||
opts: Omit<
|
opts: Omit<
|
||||||
|
|||||||
@@ -5,7 +5,25 @@ export default function useRouterQuery<T extends string>(name: T) {
|
|||||||
const existingQueryParams = router.asPath.split("?")[1];
|
const existingQueryParams = router.asPath.split("?")[1];
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(existingQueryParams);
|
const urlParams = new URLSearchParams(existingQueryParams);
|
||||||
const query = Object.fromEntries(urlParams);
|
const query: Record<string, string | string[]> = {};
|
||||||
|
// Following error is thrown by Typescript:
|
||||||
|
// 'Type 'URLSearchParams' can only be iterated through when using the '--downlevelIteration' flag or with a '--target' of 'es2015' or higher'
|
||||||
|
// We should change the target to higher ES2019 atleast maybe
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-expect-error
|
||||||
|
for (const [key, value] of urlParams) {
|
||||||
|
if (!query[key]) {
|
||||||
|
query[key] = value;
|
||||||
|
} else {
|
||||||
|
let queryValue = query[key];
|
||||||
|
if (queryValue instanceof Array) {
|
||||||
|
queryValue.push(value);
|
||||||
|
} else {
|
||||||
|
queryValue = query[key] = [queryValue];
|
||||||
|
queryValue.push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const setQuery = (newValue: string | number | null | undefined) => {
|
const setQuery = (newValue: string | number | null | undefined) => {
|
||||||
router.replace({ query: { ...router.query, [name]: newValue } }, undefined, { shallow: true });
|
router.replace({ query: { ...router.query, [name]: newValue } }, undefined, { shallow: true });
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
type GetSSRResult<TProps> =
|
type GetSSRResult<TProps> =
|
||||||
//
|
//
|
||||||
{ props: TProps } | { redirect: any } | { notFound: boolean };
|
{ props: TProps } | { redirect: { destination: string; permanent: boolean } } | { notFound: boolean };
|
||||||
|
|
||||||
type GetSSRFn<TProps> = (...args: any[]) => Promise<GetSSRResult<TProps>>;
|
type GetSSRFn<TProps> = (...args: any[]) => Promise<GetSSRResult<TProps>>;
|
||||||
|
|
||||||
|
|||||||
@@ -215,6 +215,11 @@ const nextConfig = {
|
|||||||
destination: "/new-booker/team/:slug/:type",
|
destination: "/new-booker/team/:slug/:type",
|
||||||
has: [{ type: "cookie", key: "new-booker-enabled" }],
|
has: [{ type: "cookie", key: "new-booker-enabled" }],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
source: "/d/:link/:slug",
|
||||||
|
destination: "/new-booker/d/:link/:slug",
|
||||||
|
has: [{ type: "cookie", key: "new-booker-enabled" }],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
async headers() {
|
async headers() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@calcom/web",
|
"name": "@calcom/web",
|
||||||
"version": "2.9.5",
|
"version": "2.9.7",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"analyze": "ANALYZE=true next build",
|
"analyze": "ANALYZE=true next build",
|
||||||
|
|||||||
@@ -3,18 +3,16 @@
|
|||||||
* caching system that NextJS uses SSG pages.
|
* caching system that NextJS uses SSG pages.
|
||||||
* TODO: Redirect to user profile on browser
|
* TODO: Redirect to user profile on browser
|
||||||
*/
|
*/
|
||||||
import type { GetStaticPaths, GetStaticProps } from "next";
|
import type { GetStaticPaths, GetStaticProps, InferGetStaticPropsType } from "next";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { getCachedResults } from "@calcom/core";
|
import getCalendarsEvents from "@calcom/core/getCalendarsEvents";
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
|
|
||||||
const CalendarCache = () => <div />;
|
|
||||||
|
|
||||||
const paramsSchema = z.object({ user: z.string(), month: z.string() });
|
const paramsSchema = z.object({ user: z.string(), month: z.string() });
|
||||||
export const getStaticProps: GetStaticProps<
|
export const getStaticProps: GetStaticProps<
|
||||||
{ results: Awaited<ReturnType<typeof getCachedResults>> },
|
{ results: Awaited<ReturnType<typeof getCalendarsEvents>> },
|
||||||
{ user: string }
|
{ user: string }
|
||||||
> = async (context) => {
|
> = async (context) => {
|
||||||
const { user: username, month } = paramsSchema.parse(context.params);
|
const { user: username, month } = paramsSchema.parse(context.params);
|
||||||
@@ -29,16 +27,16 @@ export const getStaticProps: GetStaticProps<
|
|||||||
selectedCalendars: true,
|
selectedCalendars: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const startDate = (
|
// Subtract 11 hours from the start date to avoid problems in UTC- time zones.
|
||||||
dayjs(month, "YYYY-MM").isSame(dayjs(), "month") ? dayjs.utc() : dayjs.utc(month, "YYYY-MM")
|
const startDate = dayjs.utc(month, "YYYY-MM").startOf("day").subtract(11, "hours").format();
|
||||||
).startOf("day");
|
// Add 14 hours from the start date to avoid problems in UTC+ time zones.
|
||||||
const endDate = startDate.endOf("month");
|
const endDate = dayjs.utc(month, "YYYY-MM").endOf("month").add(14, "hours").format();
|
||||||
try {
|
try {
|
||||||
const results = userWithCredentials?.credentials
|
const results = userWithCredentials?.credentials
|
||||||
? await getCachedResults(
|
? await getCalendarsEvents(
|
||||||
userWithCredentials?.credentials,
|
userWithCredentials?.credentials,
|
||||||
startDate.format(),
|
startDate,
|
||||||
endDate.format(),
|
endDate,
|
||||||
userWithCredentials?.selectedCalendars
|
userWithCredentials?.selectedCalendars
|
||||||
)
|
)
|
||||||
: [];
|
: [];
|
||||||
@@ -64,5 +62,8 @@ export const getStaticPaths: GetStaticPaths = () => {
|
|||||||
fallback: "blocking",
|
fallback: "blocking",
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
type Props = InferGetStaticPropsType<typeof getStaticProps>;
|
||||||
|
const CalendarCache = (props: Props) =>
|
||||||
|
process.env.NODE_ENV === "development" ? <pre>{JSON.stringify(props, null, " ")}</pre> : <div />;
|
||||||
|
|
||||||
export default CalendarCache;
|
export default CalendarCache;
|
||||||
@@ -48,6 +48,10 @@ class MyDocument extends Document<Props> {
|
|||||||
<meta name="msapplication-TileColor" content="#ff0000" />
|
<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: light)" content="#f9fafb" />
|
||||||
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#1C1C1C" />
|
<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>
|
</Head>
|
||||||
|
|
||||||
<body
|
<body
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from "next";
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
import { hashPassword } from "@calcom/features/auth/lib/hashPassword";
|
import { hashPassword } from "@calcom/features/auth/lib/hashPassword";
|
||||||
|
import { sendEmailVerification } from "@calcom/features/auth/lib/verifyEmail";
|
||||||
import slugify from "@calcom/lib/slugify";
|
import slugify from "@calcom/lib/slugify";
|
||||||
import { closeComUpsertTeamUser } from "@calcom/lib/sync/SyncServiceManager";
|
import { closeComUpsertTeamUser } from "@calcom/lib/sync/SyncServiceManager";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
import { IdentityProvider } from "@calcom/prisma/enums";
|
import { IdentityProvider } from "@calcom/prisma/enums";
|
||||||
|
|
||||||
|
const signupSchema = z.object({
|
||||||
|
username: z.string(),
|
||||||
|
email: z.string().email(),
|
||||||
|
password: z.string().min(7),
|
||||||
|
language: z.string().optional(),
|
||||||
|
});
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
if (req.method !== "POST") {
|
if (req.method !== "POST") {
|
||||||
return;
|
return;
|
||||||
@@ -17,7 +26,8 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = req.body;
|
const data = req.body;
|
||||||
const { email, password } = data;
|
const { email, password, language } = signupSchema.parse(data);
|
||||||
|
|
||||||
const username = slugify(data.username);
|
const username = slugify(data.username);
|
||||||
const userEmail = email.toLowerCase();
|
const userEmail = email.toLowerCase();
|
||||||
|
|
||||||
@@ -26,16 +36,6 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!userEmail || !userEmail.includes("@")) {
|
|
||||||
res.status(422).json({ message: "Invalid email" });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!password || password.trim().length < 7) {
|
|
||||||
res.status(422).json({ message: "Invalid input - password should be at least 7 characters long." });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is an existingUser if the username matches
|
// There is an existingUser if the username matches
|
||||||
// OR if the email matches AND either the email is verified
|
// OR if the email matches AND either the email is verified
|
||||||
// or both username and password are set
|
// or both username and password are set
|
||||||
@@ -106,5 +106,11 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await sendEmailVerification({
|
||||||
|
email: userEmail,
|
||||||
|
username,
|
||||||
|
language,
|
||||||
|
});
|
||||||
|
|
||||||
res.status(201).json({ message: "Created user" });
|
res.status(201).json({ message: "Created user" });
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import type { NextApiRequest, NextApiResponse } from "next";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
import dayjs from "@calcom/dayjs";
|
||||||
|
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||||
|
import { prisma } from "@calcom/prisma";
|
||||||
|
|
||||||
|
const verifySchema = z.object({
|
||||||
|
token: z.string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
|
const { token } = verifySchema.parse(req.query);
|
||||||
|
|
||||||
|
const foundToken = await prisma.verificationToken.findFirst({
|
||||||
|
where: {
|
||||||
|
token,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!foundToken) {
|
||||||
|
return res.status(401).json({ message: "No token found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dayjs(foundToken?.expires).isBefore(dayjs())) {
|
||||||
|
return res.status(401).json({ message: "Token expired" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await prisma.user.update({
|
||||||
|
where: {
|
||||||
|
email: foundToken?.identifier,
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
emailVerified: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete token from DB after it has been used
|
||||||
|
await prisma.verificationToken.delete({
|
||||||
|
where: {
|
||||||
|
id: foundToken?.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const hasCompletedOnboarding = user.completedOnboarding;
|
||||||
|
|
||||||
|
res.redirect(`${WEBAPP_URL}/${hasCompletedOnboarding ? "/event-types" : "/getting-started"}`);
|
||||||
|
}
|
||||||
@@ -60,9 +60,14 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||||||
res.setHeader("Content-Type", "text/html");
|
res.setHeader("Content-Type", "text/html");
|
||||||
res.setHeader("Cache-Control", "no-cache, no-store, private, must-revalidate");
|
res.setHeader("Cache-Control", "no-cache, no-store, private, must-revalidate");
|
||||||
res.write(
|
res.write(
|
||||||
renderEmail("OrganizerRequestEmail", {
|
renderEmail("VerifyAccountEmail", {
|
||||||
calEvent: evt,
|
language: t,
|
||||||
attendee: evt.organizer,
|
user: {
|
||||||
|
name: "Pro Example",
|
||||||
|
email: "pro@example.com",
|
||||||
|
},
|
||||||
|
verificationEmailLink:
|
||||||
|
"http://localhost:3000/api/auth/verify-email?token=b91af0eee5a9a24a8d83a3d3d6a58c1606496e94ced589441649273c66100f5b",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
res.end();
|
res.end();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const decryptedSchema = z.object({
|
|||||||
|
|
||||||
async function handler(req: NextApiRequest, res: NextApiResponse<Response>) {
|
async function handler(req: NextApiRequest, res: NextApiResponse<Response>) {
|
||||||
const { action, token, reason } = querySchema.parse(req.query);
|
const { action, token, reason } = querySchema.parse(req.query);
|
||||||
const { bookingUid } = decryptedSchema.parse(
|
const { bookingUid, userId } = decryptedSchema.parse(
|
||||||
JSON.parse(symmetricDecrypt(decodeURIComponent(token), process.env.CALENDSO_ENCRYPTION_KEY || ""))
|
JSON.parse(symmetricDecrypt(decodeURIComponent(token), process.env.CALENDSO_ENCRYPTION_KEY || ""))
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -34,10 +34,19 @@ async function handler(req: NextApiRequest, res: NextApiResponse<Response>) {
|
|||||||
where: { uid: bookingUid },
|
where: { uid: bookingUid },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const user = await prisma.user.findUniqueOrThrow({
|
||||||
|
where: { id: userId },
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/** @see https://trpc.io/docs/server-side-calls */
|
/** @see https://trpc.io/docs/server-side-calls */
|
||||||
const ctx = await createContext({ req, res });
|
const ctx = await createContext({ req, res });
|
||||||
const caller = viewerRouter.createCaller({ ...ctx, req, res });
|
const caller = viewerRouter.createCaller({
|
||||||
|
...ctx,
|
||||||
|
req,
|
||||||
|
res,
|
||||||
|
user: { ...user, locale: user?.locale ?? "en" },
|
||||||
|
});
|
||||||
await caller.bookings.confirm({
|
await caller.bookings.confirm({
|
||||||
bookingId: booking.id,
|
bookingId: booking.id,
|
||||||
recurringEventId: booking.recurringEventId || undefined,
|
recurringEventId: booking.recurringEventId || undefined,
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
import ethRouter from "@calcom/app-store/rainbow/trpc/router";
|
|
||||||
import { createNextApiHandler } from "@calcom/trpc/server/createNextApiHandler";
|
|
||||||
|
|
||||||
export default createNextApiHandler(ethRouter);
|
|
||||||
@@ -19,6 +19,7 @@ export default function Page() {
|
|||||||
callbackUrl: "/",
|
callbackUrl: "/",
|
||||||
code,
|
code,
|
||||||
});
|
});
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useState } from "react";
|
|||||||
import AdminAppsList from "@calcom/features/apps/AdminAppsList";
|
import AdminAppsList from "@calcom/features/apps/AdminAppsList";
|
||||||
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
|
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
|
||||||
import { getDeploymentKey } from "@calcom/features/ee/deployment/lib/getDeploymentKey";
|
import { getDeploymentKey } from "@calcom/features/ee/deployment/lib/getDeploymentKey";
|
||||||
|
import { APP_NAME } from "@calcom/lib/constants";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import prisma from "@calcom/prisma";
|
import prisma from "@calcom/prisma";
|
||||||
import { UserPermissionRole } from "@calcom/prisma/enums";
|
import { UserPermissionRole } from "@calcom/prisma/enums";
|
||||||
@@ -95,7 +96,7 @@ export function Setup(props: inferSSRProps<typeof getServerSideProps>) {
|
|||||||
|
|
||||||
steps.push({
|
steps.push({
|
||||||
title: t("enable_apps"),
|
title: t("enable_apps"),
|
||||||
description: t("enable_apps_description"),
|
description: t("enable_apps_description", { appName: APP_NAME }),
|
||||||
contentClassname: "!pb-0 mb-[-1px]",
|
contentClassname: "!pb-0 mb-[-1px]",
|
||||||
content: (setIsLoading) => {
|
content: (setIsLoading) => {
|
||||||
const currentStep = isFreeLicense ? 3 : 4;
|
const currentStep = isFreeLicense ? 3 : 4;
|
||||||
|
|||||||
@@ -111,8 +111,10 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
|
|||||||
const ret = await samlTenantProduct(prisma, emailParam);
|
const ret = await samlTenantProduct(prisma, emailParam);
|
||||||
tenant = ret.tenant;
|
tenant = ret.tenant;
|
||||||
product = ret.product;
|
product = ret.product;
|
||||||
} catch (e: any) {
|
} catch (e) {
|
||||||
error = e.message;
|
if (e instanceof Error) {
|
||||||
|
error = e.message;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export default function Page({ samlTenantID, samlProductID }: inferSSRProps<type
|
|||||||
if (HOSTED_CAL_FEATURES) {
|
if (HOSTED_CAL_FEATURES) {
|
||||||
router.push("/auth/login");
|
router.push("/auth/login");
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -29,6 +30,7 @@ export default function Page({ samlTenantID, samlProductID }: inferSSRProps<type
|
|||||||
},
|
},
|
||||||
{ tenant: samlTenantID, product: samlProductID }
|
{ tenant: samlTenantID, product: samlProductID }
|
||||||
);
|
);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
import { MailOpenIcon } from "lucide-react";
|
||||||
|
import { useSession } from "next-auth/react";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
|
||||||
|
import { APP_NAME } from "@calcom/lib/constants";
|
||||||
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
|
import { trpc } from "@calcom/trpc";
|
||||||
|
import useEmailVerifyCheck from "@calcom/trpc/react/hooks/useEmailVerifyCheck";
|
||||||
|
import { Button, EmptyScreen, showToast } from "@calcom/ui";
|
||||||
|
|
||||||
|
import PageWrapper from "@components/PageWrapper";
|
||||||
|
|
||||||
|
function VerifyEmailPage() {
|
||||||
|
const { data } = useEmailVerifyCheck();
|
||||||
|
const { data: session } = useSession();
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useLocale();
|
||||||
|
const mutation = trpc.viewer.auth.resendVerifyEmail.useMutation();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data?.isVerified) {
|
||||||
|
router.replace("/getting-started");
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [data?.isVerified]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="h-[100vh] w-full ">
|
||||||
|
<div className="flex h-full w-full flex-col items-center justify-center">
|
||||||
|
<div className="max-w-3xl">
|
||||||
|
<EmptyScreen
|
||||||
|
border
|
||||||
|
dashedBorder={false}
|
||||||
|
Icon={MailOpenIcon}
|
||||||
|
headline={t("check_your_email")}
|
||||||
|
description={t("verify_email_page_body", { email: session?.user?.email, appName: APP_NAME })}
|
||||||
|
className="bg-default"
|
||||||
|
buttonRaw={
|
||||||
|
<Button
|
||||||
|
color="minimal"
|
||||||
|
className="underline"
|
||||||
|
loading={mutation.isLoading}
|
||||||
|
onClick={() => {
|
||||||
|
showToast("Send email", "success");
|
||||||
|
mutation.mutate();
|
||||||
|
}}>
|
||||||
|
Resend Email
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VerifyEmailPage;
|
||||||
|
|
||||||
|
VerifyEmailPage.PageWrapper = PageWrapper;
|
||||||
@@ -105,7 +105,8 @@ export function AvailabilityList({ schedules }: RouterOutputs["viewer"]["availab
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const WithQuery = withQuery(trpc.viewer.availability.list);
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const WithQuery = withQuery(trpc.viewer.availability.list as any);
|
||||||
|
|
||||||
export default function AvailabilityPage() {
|
export default function AvailabilityPage() {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const AvailabilityView = ({ user }: { user: User }) => {
|
|||||||
|
|
||||||
const { data, isLoading } = trpc.viewer.availability.user.useQuery(
|
const { data, isLoading } = trpc.viewer.availability.user.useQuery(
|
||||||
{
|
{
|
||||||
username: user.username!,
|
username: user.username || "",
|
||||||
dateFrom: selectedDate.startOf("day").utc().format(),
|
dateFrom: selectedDate.startOf("day").utc().format(),
|
||||||
dateTo: selectedDate.endOf("day").utc().format(),
|
dateTo: selectedDate.endOf("day").utc().format(),
|
||||||
withSource: true,
|
withSource: true,
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ export default function Success(props: SuccessProps) {
|
|||||||
allRemainingBookings,
|
allRemainingBookings,
|
||||||
isSuccessBookingPage,
|
isSuccessBookingPage,
|
||||||
cancel: isCancellationMode,
|
cancel: isCancellationMode,
|
||||||
changes,
|
|
||||||
formerTime,
|
formerTime,
|
||||||
email,
|
email,
|
||||||
seatReferenceUid,
|
seatReferenceUid,
|
||||||
@@ -222,6 +221,7 @@ export default function Success(props: SuccessProps) {
|
|||||||
setCalculatedDuration(
|
setCalculatedDuration(
|
||||||
dayjs(props.bookingInfo.endTime).diff(dayjs(props.bookingInfo.startTime), "minutes")
|
dayjs(props.bookingInfo.endTime).diff(dayjs(props.bookingInfo.startTime), "minutes")
|
||||||
);
|
);
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
function eventLink(): string {
|
function eventLink(): string {
|
||||||
@@ -279,9 +279,7 @@ export default function Success(props: SuccessProps) {
|
|||||||
darkBrandColor: props.profile.darkBrandColor,
|
darkBrandColor: props.profile.darkBrandColor,
|
||||||
});
|
});
|
||||||
const title = t(
|
const title = t(
|
||||||
`booking_${needsConfirmation ? "booking_submitted" : "confirmed"}${
|
`booking_${needsConfirmation ? "submitted" : "confirmed"}${props.recurringBookings ? "_recurring" : ""}`
|
||||||
props.recurringBookings ? "_recurring" : ""
|
|
||||||
}`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const locationToDisplay = getSuccessPageLocationMessage(
|
const locationToDisplay = getSuccessPageLocationMessage(
|
||||||
@@ -402,7 +400,7 @@ export default function Success(props: SuccessProps) {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<div className="font-medium">{t("what")}</div>
|
<div className="font-medium">{t("what")}</div>
|
||||||
<div className="col-span-2 mb-6 last:mb-0">{props.bookingInfo.title}</div>
|
<div className="col-span-2 mb-6 last:mb-0">{eventName}</div>
|
||||||
<div className="font-medium">{t("when")}</div>
|
<div className="font-medium">{t("when")}</div>
|
||||||
<div className="col-span-2 mb-6 last:mb-0">
|
<div className="col-span-2 mb-6 last:mb-0">
|
||||||
{reschedule && !!formerTime && (
|
{reschedule && !!formerTime && (
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { useAutoAnimate } from "@formkit/auto-animate/react";
|
|||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import type { GetServerSidePropsContext } from "next";
|
import type { GetServerSidePropsContext } from "next";
|
||||||
import { Trans } from "next-i18next";
|
import { Trans } from "next-i18next";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -17,9 +17,14 @@ import { useLocale } from "@calcom/lib/hooks/useLocale";
|
|||||||
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
|
import { useTypedQuery } from "@calcom/lib/hooks/useTypedQuery";
|
||||||
import { HttpError } from "@calcom/lib/http-error";
|
import { HttpError } from "@calcom/lib/http-error";
|
||||||
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
|
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
|
||||||
|
import { validateBookerLayouts } from "@calcom/lib/validateBookerLayouts";
|
||||||
import type { Prisma } from "@calcom/prisma/client";
|
import type { Prisma } from "@calcom/prisma/client";
|
||||||
import type { PeriodType, SchedulingType } from "@calcom/prisma/enums";
|
import type { PeriodType, SchedulingType } from "@calcom/prisma/enums";
|
||||||
import type { customInputSchema, EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
|
import type {
|
||||||
|
BookerLayoutSettings,
|
||||||
|
customInputSchema,
|
||||||
|
EventTypeMetaDataSchema,
|
||||||
|
} from "@calcom/prisma/zod-utils";
|
||||||
import { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
|
import { eventTypeBookingFields } from "@calcom/prisma/zod-utils";
|
||||||
import type { RouterOutputs } from "@calcom/trpc/react";
|
import type { RouterOutputs } from "@calcom/trpc/react";
|
||||||
import { trpc } from "@calcom/trpc/react";
|
import { trpc } from "@calcom/trpc/react";
|
||||||
@@ -96,6 +101,7 @@ export type FormValues = {
|
|||||||
hosts: { userId: number; isFixed: boolean }[];
|
hosts: { userId: number; isFixed: boolean }[];
|
||||||
bookingFields: z.infer<typeof eventTypeBookingFields>;
|
bookingFields: z.infer<typeof eventTypeBookingFields>;
|
||||||
availability?: AvailabilityOption;
|
availability?: AvailabilityOption;
|
||||||
|
bookerLayouts: BookerLayoutSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CustomInputParsed = typeof customInputSchema._output;
|
export type CustomInputParsed = typeof customInputSchema._output;
|
||||||
@@ -184,17 +190,17 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
|||||||
|
|
||||||
const metadata = eventType.metadata;
|
const metadata = eventType.metadata;
|
||||||
// fallback to !!eventType.schedule when 'useHostSchedulesForTeamEvent' is undefined
|
// fallback to !!eventType.schedule when 'useHostSchedulesForTeamEvent' is undefined
|
||||||
if (!!team) {
|
if (!!team && metadata !== null) {
|
||||||
metadata.config = {
|
metadata.config = {
|
||||||
...metadata.config,
|
...metadata.config,
|
||||||
useHostSchedulesForTeamEvent:
|
useHostSchedulesForTeamEvent:
|
||||||
typeof eventType.metadata.config?.useHostSchedulesForTeamEvent !== "undefined"
|
typeof eventType.metadata?.config?.useHostSchedulesForTeamEvent !== "undefined"
|
||||||
? eventType.metadata.config?.useHostSchedulesForTeamEvent === true
|
? eventType.metadata?.config?.useHostSchedulesForTeamEvent === true
|
||||||
: !!eventType.schedule,
|
: !!eventType.schedule,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
// Make sure non-team events NEVER have this config key;
|
// Make sure non-team events NEVER have this config key;
|
||||||
delete metadata.config?.useHostSchedulesForTeamEvent;
|
delete metadata?.config?.useHostSchedulesForTeamEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bookingFields: Prisma.JsonObject = {};
|
const bookingFields: Prisma.JsonObject = {};
|
||||||
@@ -203,41 +209,43 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
|||||||
bookingFields[name] = name;
|
bookingFields[name] = name;
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultValues = {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
title: eventType.title,
|
const defaultValues: any = useMemo(() => {
|
||||||
locations: eventType.locations || [],
|
return {
|
||||||
recurringEvent: eventType.recurringEvent || null,
|
title: eventType.title,
|
||||||
description: eventType.description ?? undefined,
|
locations: eventType.locations || [],
|
||||||
schedule: eventType.schedule || undefined,
|
recurringEvent: eventType.recurringEvent || null,
|
||||||
bookingLimits: eventType.bookingLimits || undefined,
|
description: eventType.description ?? undefined,
|
||||||
durationLimits: eventType.durationLimits || undefined,
|
schedule: eventType.schedule || undefined,
|
||||||
length: eventType.length,
|
bookingLimits: eventType.bookingLimits || undefined,
|
||||||
offsetStart: eventType.offsetStart,
|
durationLimits: eventType.durationLimits || undefined,
|
||||||
hidden: eventType.hidden,
|
length: eventType.length,
|
||||||
periodDates: {
|
hidden: eventType.hidden,
|
||||||
startDate: periodDates.startDate,
|
periodDates: {
|
||||||
endDate: periodDates.endDate,
|
startDate: periodDates.startDate,
|
||||||
},
|
endDate: periodDates.endDate,
|
||||||
bookingFields: eventType.bookingFields,
|
|
||||||
periodType: eventType.periodType,
|
|
||||||
periodCountCalendarDays: eventType.periodCountCalendarDays ? "1" : "0",
|
|
||||||
schedulingType: eventType.schedulingType,
|
|
||||||
minimumBookingNotice: eventType.minimumBookingNotice,
|
|
||||||
metadata,
|
|
||||||
hosts: eventType.hosts,
|
|
||||||
children: eventType.children.map((ch) => ({
|
|
||||||
...ch,
|
|
||||||
created: true,
|
|
||||||
owner: {
|
|
||||||
...ch.owner,
|
|
||||||
eventTypeSlugs:
|
|
||||||
eventType.team?.members
|
|
||||||
.find((mem) => mem.user.id === ch.owner.id)
|
|
||||||
?.user.eventTypes.map((evTy) => evTy.slug)
|
|
||||||
.filter((slug) => slug !== eventType.slug) ?? [],
|
|
||||||
},
|
},
|
||||||
})),
|
bookingFields: eventType.bookingFields,
|
||||||
} as const;
|
periodType: eventType.periodType,
|
||||||
|
periodCountCalendarDays: eventType.periodCountCalendarDays ? "1" : "0",
|
||||||
|
schedulingType: eventType.schedulingType,
|
||||||
|
minimumBookingNotice: eventType.minimumBookingNotice,
|
||||||
|
metadata,
|
||||||
|
hosts: eventType.hosts,
|
||||||
|
children: eventType.children.map((ch) => ({
|
||||||
|
...ch,
|
||||||
|
created: true,
|
||||||
|
owner: {
|
||||||
|
...ch.owner,
|
||||||
|
eventTypeSlugs:
|
||||||
|
eventType.team?.members
|
||||||
|
.find((mem) => mem.user.id === ch.owner.id)
|
||||||
|
?.user.eventTypes.map((evTy) => evTy.slug)
|
||||||
|
.filter((slug) => slug !== eventType.slug) ?? [],
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
};
|
||||||
|
}, [eventType, periodDates, metadata]);
|
||||||
|
|
||||||
const formMethods = useForm<FormValues>({
|
const formMethods = useForm<FormValues>({
|
||||||
defaultValues,
|
defaultValues,
|
||||||
@@ -270,6 +278,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
|||||||
//TODO: What's the best way to sync the form with backend
|
//TODO: What's the best way to sync the form with backend
|
||||||
formMethods.setValue("bookingFields", defaultValues.bookingFields);
|
formMethods.setValue("bookingFields", defaultValues.bookingFields);
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [defaultValues]);
|
}, [defaultValues]);
|
||||||
|
|
||||||
const appsMetadata = formMethods.getValues("metadata")?.apps;
|
const appsMetadata = formMethods.getValues("metadata")?.apps;
|
||||||
@@ -332,6 +341,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
|||||||
seatsPerTimeSlotEnabled,
|
seatsPerTimeSlotEnabled,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
minimumBookingNoticeInDurationType,
|
minimumBookingNoticeInDurationType,
|
||||||
|
bookerLayouts,
|
||||||
...input
|
...input
|
||||||
} = values;
|
} = values;
|
||||||
|
|
||||||
@@ -345,6 +355,9 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
|||||||
if (!isValid) throw new Error(t("event_setup_duration_limits_error"));
|
if (!isValid) throw new Error(t("event_setup_duration_limits_error"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const layoutError = validateBookerLayouts(metadata?.bookerLayouts || null);
|
||||||
|
if (layoutError) throw new Error(t(layoutError));
|
||||||
|
|
||||||
if (metadata?.multipleDuration !== undefined) {
|
if (metadata?.multipleDuration !== undefined) {
|
||||||
if (metadata?.multipleDuration.length < 1) {
|
if (metadata?.multipleDuration.length < 1) {
|
||||||
throw new Error(t("event_setup_multiple_duration_error"));
|
throw new Error(t("event_setup_multiple_duration_error"));
|
||||||
@@ -415,9 +428,6 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
|||||||
// We don't need to send send these values to the backend
|
// We don't need to send send these values to the backend
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
seatsPerTimeSlotEnabled,
|
seatsPerTimeSlotEnabled,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
minimumBookingNoticeInDurationType,
|
|
||||||
availability,
|
|
||||||
...input
|
...input
|
||||||
} = values;
|
} = values;
|
||||||
|
|
||||||
@@ -431,6 +441,9 @@ const EventTypePage = (props: EventTypeSetupProps) => {
|
|||||||
if (!isValid) throw new Error(t("event_setup_duration_limits_error"));
|
if (!isValid) throw new Error(t("event_setup_duration_limits_error"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const layoutError = validateBookerLayouts(metadata?.bookerLayouts || null);
|
||||||
|
if (layoutError) throw new Error(t(layoutError));
|
||||||
|
|
||||||
if (metadata?.multipleDuration !== undefined) {
|
if (metadata?.multipleDuration !== undefined) {
|
||||||
if (metadata?.multipleDuration.length < 1) {
|
if (metadata?.multipleDuration.length < 1) {
|
||||||
throw new Error(t("event_setup_multiple_duration_error"));
|
throw new Error(t("event_setup_multiple_duration_error"));
|
||||||
|
|||||||
@@ -393,11 +393,13 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
|||||||
className="relative top-1 right-3"
|
className="relative top-1 right-3"
|
||||||
size="sm"
|
size="sm"
|
||||||
truncateAfter={4}
|
truncateAfter={4}
|
||||||
items={type.users.map((organizer: { name: any; username: any }) => ({
|
items={type.users.map(
|
||||||
alt: organizer.name || "",
|
(organizer: { name: string | null; username: string | null }) => ({
|
||||||
image: `${WEBAPP_URL}/${organizer.username}/avatar.png`,
|
alt: organizer.name || "",
|
||||||
title: organizer.name || "",
|
image: `${WEBAPP_URL}/${organizer.username}/avatar.png`,
|
||||||
}))}
|
title: organizer.name || "",
|
||||||
|
})
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isManagedEventType && (
|
{isManagedEventType && (
|
||||||
@@ -780,7 +782,8 @@ const CTA = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const WithQuery = withQuery(trpc.viewer.eventTypes.getByViewer);
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const WithQuery = withQuery(trpc.viewer.eventTypes.getByViewer as any);
|
||||||
|
|
||||||
const EventTypesPage = () => {
|
const EventTypesPage = () => {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
@@ -793,6 +796,7 @@ const EventTypesPage = () => {
|
|||||||
if (query?.openIntercom && query?.openIntercom === "true") {
|
if (query?.openIntercom && query?.openIntercom === "true") {
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -816,7 +820,7 @@ const EventTypesPage = () => {
|
|||||||
{isMobile ? (
|
{isMobile ? (
|
||||||
<MobileTeamsTab eventTypeGroups={data.eventTypeGroups} />
|
<MobileTeamsTab eventTypeGroups={data.eventTypeGroups} />
|
||||||
) : (
|
) : (
|
||||||
data.eventTypeGroups.map((group, index) => (
|
data.eventTypeGroups.map((group: EventTypeGroup, index: number) => (
|
||||||
<div className="flex flex-col" key={group.profile.slug}>
|
<div className="flex flex-col" key={group.profile.slug}>
|
||||||
<EventTypeListHeading
|
<EventTypeListHeading
|
||||||
profile={group.profile}
|
profile={group.profile}
|
||||||
|
|||||||
@@ -117,9 +117,7 @@ const OnboardingPage = (props: IOnboardingPageProps) => {
|
|||||||
}
|
}
|
||||||
key={router.asPath}>
|
key={router.asPath}>
|
||||||
<Head>
|
<Head>
|
||||||
<title>
|
<title>{`${APP_NAME} - ${t("getting_started")}`}</title>
|
||||||
{APP_NAME} - {t("getting_started")}
|
|
||||||
</title>
|
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
import type { GetServerSidePropsContext } from "next";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
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 prisma from "@calcom/prisma";
|
||||||
|
|
||||||
|
import type { inferSSRProps } from "@lib/types/inferSSRProps";
|
||||||
|
|
||||||
|
import PageWrapper from "@components/PageWrapper";
|
||||||
|
|
||||||
|
type PageProps = inferSSRProps<typeof getServerSideProps>;
|
||||||
|
|
||||||
|
export default function Type({ slug, user, booking, away, isBrandingHidden }: PageProps) {
|
||||||
|
return (
|
||||||
|
<main className="flex h-full min-h-[100dvh] items-center justify-center">
|
||||||
|
<BookerSeo
|
||||||
|
username={user}
|
||||||
|
eventSlug={slug}
|
||||||
|
rescheduleUid={booking?.uid}
|
||||||
|
hideBranding={isBrandingHidden}
|
||||||
|
/>
|
||||||
|
<Booker
|
||||||
|
username={user}
|
||||||
|
eventSlug={slug}
|
||||||
|
rescheduleBooking={booking}
|
||||||
|
isAway={away}
|
||||||
|
hideBranding={isBrandingHidden}
|
||||||
|
/>
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Type.PageWrapper = PageWrapper;
|
||||||
|
|
||||||
|
async function getUserPageProps(context: GetServerSidePropsContext) {
|
||||||
|
const { link, slug } = paramsSchema.parse(context.params);
|
||||||
|
const { rescheduleUid } = context.query;
|
||||||
|
|
||||||
|
const { ssrInit } = await import("@server/lib/ssr");
|
||||||
|
const ssr = await ssrInit(context);
|
||||||
|
|
||||||
|
const hashedLink = await prisma.hashedLink.findUnique({
|
||||||
|
where: {
|
||||||
|
link,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
eventTypeId: true,
|
||||||
|
eventType: {
|
||||||
|
select: {
|
||||||
|
users: {
|
||||||
|
select: {
|
||||||
|
username: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const username = hashedLink?.eventType.users[0]?.username;
|
||||||
|
|
||||||
|
if (!hashedLink || !username) {
|
||||||
|
return {
|
||||||
|
notFound: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const user = await prisma.user.findUnique({
|
||||||
|
where: {
|
||||||
|
username,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
away: true,
|
||||||
|
hideBranding: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return {
|
||||||
|
notFound: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let booking: GetBookingType | null = null;
|
||||||
|
if (rescheduleUid) {
|
||||||
|
booking = await getBookingByUidOrRescheduleUid(`${rescheduleUid}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We use this to both prefetch the query on the server,
|
||||||
|
// as well as to check if the event exist, so we c an show a 404 otherwise.
|
||||||
|
const eventData = await ssr.viewer.public.event.fetch({ username, eventSlug: slug });
|
||||||
|
|
||||||
|
if (!eventData) {
|
||||||
|
return {
|
||||||
|
notFound: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
booking,
|
||||||
|
away: user?.away,
|
||||||
|
user: username,
|
||||||
|
slug,
|
||||||
|
trpcState: ssr.dehydrate(),
|
||||||
|
isBrandingHidden: user?.hideBranding,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const paramsSchema = z.object({ link: z.string(), slug: z.string() });
|
||||||
|
|
||||||
|
// Booker page fetches a tiny bit of data server side, to determine early
|
||||||
|
// whether the page should show an away state or dynamic booking not allowed.
|
||||||
|
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
|
||||||
|
return await getUserPageProps(context);
|
||||||
|
};
|
||||||
@@ -1,12 +1,14 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { Controller, useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
|
||||||
|
import { BookerLayoutSelector } from "@calcom/features/settings/BookerLayoutSelector";
|
||||||
import ThemeLabel from "@calcom/features/settings/ThemeLabel";
|
import ThemeLabel from "@calcom/features/settings/ThemeLabel";
|
||||||
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout";
|
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout";
|
||||||
import { APP_NAME } from "@calcom/lib/constants";
|
import { APP_NAME } from "@calcom/lib/constants";
|
||||||
import { checkWCAGContrastColor } from "@calcom/lib/getBrandColours";
|
import { checkWCAGContrastColor } from "@calcom/lib/getBrandColours";
|
||||||
import { useHasPaidPlan } from "@calcom/lib/hooks/useHasPaidPlan";
|
import { useHasPaidPlan } from "@calcom/lib/hooks/useHasPaidPlan";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
|
import { validateBookerLayouts } from "@calcom/lib/validateBookerLayouts";
|
||||||
import { trpc } from "@calcom/trpc/react";
|
import { trpc } from "@calcom/trpc/react";
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert,
|
||||||
@@ -62,6 +64,7 @@ const AppearanceView = () => {
|
|||||||
brandColor: user?.brandColor || "#292929",
|
brandColor: user?.brandColor || "#292929",
|
||||||
darkBrandColor: user?.darkBrandColor || "#fafafa",
|
darkBrandColor: user?.darkBrandColor || "#fafafa",
|
||||||
hideBranding: user?.hideBranding,
|
hideBranding: user?.hideBranding,
|
||||||
|
defaultBookerLayouts: user?.defaultBookerLayouts,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -76,8 +79,12 @@ const AppearanceView = () => {
|
|||||||
showToast(t("settings_updated_successfully"), "success");
|
showToast(t("settings_updated_successfully"), "success");
|
||||||
reset(data);
|
reset(data);
|
||||||
},
|
},
|
||||||
onError: () => {
|
onError: (error) => {
|
||||||
showToast(t("error_updating_settings"), "error");
|
if (error.message) {
|
||||||
|
showToast(error.message, "error");
|
||||||
|
} else {
|
||||||
|
showToast(t("error_updating_settings"), "error");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -92,6 +99,9 @@ const AppearanceView = () => {
|
|||||||
<Form
|
<Form
|
||||||
form={formMethods}
|
form={formMethods}
|
||||||
handleSubmit={(values) => {
|
handleSubmit={(values) => {
|
||||||
|
const layoutError = validateBookerLayouts(values.defaultBookerLayouts || null);
|
||||||
|
if (layoutError) throw new Error(t(layoutError));
|
||||||
|
|
||||||
mutation.mutate({
|
mutation.mutate({
|
||||||
...values,
|
...values,
|
||||||
// Radio values don't support null as values, therefore we convert an empty string
|
// Radio values don't support null as values, therefore we convert an empty string
|
||||||
@@ -130,6 +140,13 @@ const AppearanceView = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<hr className="border-subtle my-8 border [&:has(+hr)]:hidden" />
|
||||||
|
<BookerLayoutSelector
|
||||||
|
name="metadata.defaultBookerLayouts"
|
||||||
|
title={t("bookerlayout_user_settings_title")}
|
||||||
|
description={t("bookerlayout_user_settings_description")}
|
||||||
|
/>
|
||||||
|
|
||||||
<hr className="border-subtle my-8 border" />
|
<hr className="border-subtle my-8 border" />
|
||||||
<div className="mb-6 flex items-center text-sm">
|
<div className="mb-6 flex items-center text-sm">
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -46,7 +46,10 @@ interface GeneralViewProps {
|
|||||||
user: RouterOutputs["viewer"]["me"];
|
user: RouterOutputs["viewer"]["me"];
|
||||||
}
|
}
|
||||||
|
|
||||||
const WithQuery = withQuery(trpc.viewer.public.i18n, undefined, { trpc: { context: { skipBatch: true } } });
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const WithQuery = withQuery(trpc.viewer.public.i18n as any, undefined, {
|
||||||
|
trpc: { context: { skipBatch: true } },
|
||||||
|
});
|
||||||
|
|
||||||
const GeneralQueryView = () => {
|
const GeneralQueryView = () => {
|
||||||
const { t } = useLocale();
|
const { t } = useLocale();
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const PasswordView = () => {
|
|||||||
onSettled: () => {
|
onSettled: () => {
|
||||||
utils.viewer.me.invalidate();
|
utils.viewer.me.invalidate();
|
||||||
},
|
},
|
||||||
onMutate: async ({ metadata }) => {
|
onMutate: async () => {
|
||||||
await utils.viewer.me.cancel();
|
await utils.viewer.me.cancel();
|
||||||
const previousValue = utils.viewer.me.getData();
|
const previousValue = utils.viewer.me.getData();
|
||||||
const previousMetadata = userMetadata.parse(previousValue?.metadata);
|
const previousMetadata = userMetadata.parse(previousValue?.metadata);
|
||||||
|
|||||||
@@ -9,10 +9,11 @@ import { z } from "zod";
|
|||||||
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
|
import LicenseRequired from "@calcom/features/ee/common/components/LicenseRequired";
|
||||||
import { checkPremiumUsername } from "@calcom/features/ee/common/lib/checkPremiumUsername";
|
import { checkPremiumUsername } from "@calcom/features/ee/common/lib/checkPremiumUsername";
|
||||||
import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
|
import { isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
|
||||||
|
import { useFlagMap } from "@calcom/features/flags/context/provider";
|
||||||
|
import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
|
||||||
import { IS_SELF_HOSTED, WEBAPP_URL } from "@calcom/lib/constants";
|
import { IS_SELF_HOSTED, WEBAPP_URL } from "@calcom/lib/constants";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
|
import { collectPageParameters, telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
|
||||||
import prisma from "@calcom/prisma";
|
|
||||||
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
|
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
|
||||||
import { Alert, Button, EmailField, HeadSeo, PasswordField, TextField } from "@calcom/ui";
|
import { Alert, Button, EmailField, HeadSeo, PasswordField, TextField } from "@calcom/ui";
|
||||||
|
|
||||||
@@ -29,10 +30,10 @@ type FormValues = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function Signup({ prepopulateFormValues, token }: inferSSRProps<typeof getServerSideProps>) {
|
export default function Signup({ prepopulateFormValues, token }: inferSSRProps<typeof getServerSideProps>) {
|
||||||
const { t } = useLocale();
|
const { t, i18n } = useLocale();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const flags = useFlagMap();
|
||||||
const telemetry = useTelemetry();
|
const telemetry = useTelemetry();
|
||||||
|
|
||||||
const methods = useForm<FormValues>({
|
const methods = useForm<FormValues>({
|
||||||
defaultValues: prepopulateFormValues,
|
defaultValues: prepopulateFormValues,
|
||||||
});
|
});
|
||||||
@@ -52,6 +53,7 @@ export default function Signup({ prepopulateFormValues, token }: inferSSRProps<t
|
|||||||
await fetch("/api/auth/signup", {
|
await fetch("/api/auth/signup", {
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
...data,
|
...data,
|
||||||
|
language: i18n.language,
|
||||||
}),
|
}),
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
@@ -61,11 +63,12 @@ export default function Signup({ prepopulateFormValues, token }: inferSSRProps<t
|
|||||||
.then(handleErrors)
|
.then(handleErrors)
|
||||||
.then(async () => {
|
.then(async () => {
|
||||||
telemetry.event(telemetryEventTypes.signup, collectPageParameters());
|
telemetry.event(telemetryEventTypes.signup, collectPageParameters());
|
||||||
|
const verifyOrGettingStarted = flags["email-verification"] ? "auth/verify-email" : "getting-started";
|
||||||
await signIn<"credentials">("credentials", {
|
await signIn<"credentials">("credentials", {
|
||||||
...data,
|
...data,
|
||||||
callbackUrl: router.query.callbackUrl
|
callbackUrl: router.query.callbackUrl
|
||||||
? `${WEBAPP_URL}/${router.query.callbackUrl}`
|
? `${WEBAPP_URL}/${router.query.callbackUrl}`
|
||||||
: `${WEBAPP_URL}/getting-started`,
|
: `${WEBAPP_URL}/${verifyOrGettingStarted}`,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
@@ -158,6 +161,8 @@ export default function Signup({ prepopulateFormValues, token }: inferSSRProps<t
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||||
|
const prisma = await import("@calcom/prisma").then((mod) => mod.default);
|
||||||
|
const flags = await getFeatureFlagMap(prisma);
|
||||||
const ssr = await ssrInit(ctx);
|
const ssr = await ssrInit(ctx);
|
||||||
const token = z.string().optional().parse(ctx.query.token);
|
const token = z.string().optional().parse(ctx.query.token);
|
||||||
|
|
||||||
@@ -168,7 +173,9 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
|||||||
prepopulateFormValues: undefined,
|
prepopulateFormValues: undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (process.env.NEXT_PUBLIC_DISABLE_SIGNUP === "true") {
|
if (process.env.NEXT_PUBLIC_DISABLE_SIGNUP === "true" || flags["disable-signup"]) {
|
||||||
|
console.log({ flag: flags["disable-signup"] });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
notFound: true,
|
notFound: true,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ export default function JoinCall(props: JoinCallPageProps) {
|
|||||||
return () => {
|
return () => {
|
||||||
callFrame.destroy();
|
callFrame.destroy();
|
||||||
};
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onRecordingStopped = () => {
|
const onRecordingStopped = () => {
|
||||||
@@ -169,6 +170,7 @@ function ProgressBar(props: ProgressBarProps) {
|
|||||||
intervalRef.current = null;
|
intervalRef.current = null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const prev = startDuration - duration;
|
const prev = startDuration - duration;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ test.afterEach(({ users }) => users.deleteAll());
|
|||||||
test.describe("App Store - Authed", () => {
|
test.describe("App Store - Authed", () => {
|
||||||
test("Browse apple-calendar and try to install", async ({ page, users }) => {
|
test("Browse apple-calendar and try to install", async ({ page, users }) => {
|
||||||
const pro = await users.create();
|
const pro = await users.create();
|
||||||
await pro.login();
|
await pro.apiLogin();
|
||||||
await page.goto("/apps/categories/calendar");
|
await page.goto("/apps/categories/calendar");
|
||||||
await page.click('[data-testid="app-store-app-card-apple-calendar"]');
|
await page.click('[data-testid="app-store-app-card-apple-calendar"]');
|
||||||
await page.waitForURL("/apps/apple-calendar");
|
await page.waitForURL("/apps/apple-calendar");
|
||||||
@@ -19,7 +19,7 @@ test.describe("App Store - Authed", () => {
|
|||||||
|
|
||||||
test("Installed Apps - Navigation", async ({ page, users }) => {
|
test("Installed Apps - Navigation", async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto("/apps/installed");
|
await page.goto("/apps/installed");
|
||||||
await page.waitForSelector('[data-testid="connect-calendar-apps"]');
|
await page.waitForSelector('[data-testid="connect-calendar-apps"]');
|
||||||
await page.click('[data-testid="vertical-tab-payment"]');
|
await page.click('[data-testid="vertical-tab-payment"]');
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { test } from "../lib/fixtures";
|
|||||||
test.describe("Can signup from a team invite", async () => {
|
test.describe("Can signup from a team invite", async () => {
|
||||||
test.beforeEach(async ({ users }) => {
|
test.beforeEach(async ({ users }) => {
|
||||||
const proUser = await users.create();
|
const proUser = await users.create();
|
||||||
await proUser.login();
|
await proUser.apiLogin();
|
||||||
});
|
});
|
||||||
test.afterEach(async ({ users }) => users.deleteAll());
|
test.afterEach(async ({ users }) => users.deleteAll());
|
||||||
|
|
||||||
@@ -33,65 +33,65 @@ test.describe("Can signup from a team invite", async () => {
|
|||||||
// Wait for the invite to be sent
|
// Wait for the invite to be sent
|
||||||
/*await page.waitForSelector(`[data-testid="member-email"][data-email="${testUser.email}"]`);
|
/*await page.waitForSelector(`[data-testid="member-email"][data-email="${testUser.email}"]`);
|
||||||
|
|
||||||
const tokenObj = await prisma.verificationToken.findFirstOrThrow({
|
const tokenObj = await prisma.verificationToken.findFirstOrThrow({
|
||||||
where: { identifier: testUser.email },
|
where: { identifier: testUser.email },
|
||||||
select: { token: true },
|
select: { token: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!proUser.username) throw Error("Test username is null, can't continue");
|
if (!proUser.username) throw Error("Test username is null, can't continue");
|
||||||
|
|
||||||
// Open a new user window to accept the invite
|
// Open a new user window to accept the invite
|
||||||
const newPage = await browser.newPage();
|
const newPage = await browser.newPage();
|
||||||
await newPage.goto(`/auth/signup?token=${tokenObj.token}&callbackUrl=${WEBAPP_URL}/settings/teams`);
|
await newPage.goto(`/auth/signup?token=${tokenObj.token}&callbackUrl=${WEBAPP_URL}/settings/teams`);
|
||||||
|
|
||||||
// Fill in form
|
// Fill in form
|
||||||
await newPage.fill('input[name="username"]', proUser.username); // Invalid username
|
await newPage.fill('input[name="username"]', proUser.username); // Invalid username
|
||||||
await newPage.fill('input[name="email"]', testUser.email);
|
await newPage.fill('input[name="email"]', testUser.email);
|
||||||
await newPage.fill('input[name="password"]', testUser.password);
|
await newPage.fill('input[name="password"]', testUser.password);
|
||||||
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
||||||
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||||
|
|
||||||
await expect(newPage.locator('text="Username already taken"')).toBeVisible();
|
await expect(newPage.locator('text="Username already taken"')).toBeVisible();
|
||||||
|
|
||||||
// Email address is already registered
|
// Email address is already registered
|
||||||
// TODO: Form errors don't disappear when corrected and resubmitted, so we need to refresh
|
// TODO: Form errors don't disappear when corrected and resubmitted, so we need to refresh
|
||||||
await newPage.reload();
|
await newPage.reload();
|
||||||
await newPage.fill('input[name="username"]', testUser.username);
|
await newPage.fill('input[name="username"]', testUser.username);
|
||||||
await newPage.fill('input[name="email"]', `${proUser.username}@example.com`); // Taken email
|
await newPage.fill('input[name="email"]', `${proUser.username}@example.com`); // Taken email
|
||||||
await newPage.fill('input[name="password"]', testUser.password);
|
await newPage.fill('input[name="password"]', testUser.password);
|
||||||
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
||||||
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||||
await expect(newPage.locator('text="Email address is already registered"')).toBeVisible();
|
await expect(newPage.locator('text="Email address is already registered"')).toBeVisible();
|
||||||
|
|
||||||
// Successful signup
|
// Successful signup
|
||||||
// TODO: Form errors don't disappear when corrected and resubmitted, so we need to refresh
|
// TODO: Form errors don't disappear when corrected and resubmitted, so we need to refresh
|
||||||
await newPage.reload();
|
await newPage.reload();
|
||||||
await newPage.fill('input[name="username"]', testUser.username);
|
await newPage.fill('input[name="username"]', testUser.username);
|
||||||
await newPage.fill('input[name="email"]', testUser.email);
|
await newPage.fill('input[name="email"]', testUser.email);
|
||||||
await newPage.fill('input[name="password"]', testUser.password);
|
await newPage.fill('input[name="password"]', testUser.password);
|
||||||
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
await newPage.fill('input[name="passwordcheck"]', testUser.password);
|
||||||
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
await newPage.press('input[name="passwordcheck"]', "Enter"); // Press Enter to submit
|
||||||
await expect(newPage.locator(`[data-testid="login-form"]`)).toBeVisible();
|
await expect(newPage.locator(`[data-testid="login-form"]`)).toBeVisible();
|
||||||
|
|
||||||
// We don't need the new browser anymore
|
// We don't need the new browser anymore
|
||||||
await newPage.close();
|
await newPage.close();
|
||||||
|
|
||||||
const createdUser = await prisma.user.findUniqueOrThrow({
|
const createdUser = await prisma.user.findUniqueOrThrow({
|
||||||
where: { email: testUser.email },
|
where: { email: testUser.email },
|
||||||
include: { teams: { include: { team: true } } },
|
include: { teams: { include: { team: true } } },
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("createdUser", createdUser);
|
console.log("createdUser", createdUser);
|
||||||
|
|
||||||
// Check that the user was created
|
// Check that the user was created
|
||||||
expect(createdUser).not.toBeNull();
|
expect(createdUser).not.toBeNull();
|
||||||
expect(createdUser.username).toBe(testUser.username);
|
expect(createdUser.username).toBe(testUser.username);
|
||||||
expect(createdUser.password).not.toBeNull();
|
expect(createdUser.password).not.toBeNull();
|
||||||
expect(createdUser.emailVerified).not.toBeNull();
|
expect(createdUser.emailVerified).not.toBeNull();
|
||||||
// Check that the user accepted the team invite
|
// Check that the user accepted the team invite
|
||||||
expect(createdUser.teams).toHaveLength(1);
|
expect(createdUser.teams).toHaveLength(1);
|
||||||
expect(createdUser.teams[0].team.name).toBe(teamName);
|
expect(createdUser.teams[0].team.name).toBe(teamName);
|
||||||
expect(createdUser.teams[0].role).toBe("MEMBER");
|
expect(createdUser.teams[0].role).toBe("MEMBER");
|
||||||
expect(createdUser.teams[0].accepted).toBe(true);*/
|
expect(createdUser.teams[0].accepted).toBe(true);*/
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -8,17 +8,16 @@ test("Can delete user account", async ({ page, users }) => {
|
|||||||
const user = await users.create({
|
const user = await users.create({
|
||||||
username: "delete-me",
|
username: "delete-me",
|
||||||
});
|
});
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
|
await page.goto(`/settings/my-account/profile`);
|
||||||
await page.waitForSelector("[data-testid=dashboard-shell]");
|
await page.waitForSelector("[data-testid=dashboard-shell]");
|
||||||
|
|
||||||
await page.goto(`/settings/my-account/profile`);
|
|
||||||
await page.waitForLoadState("networkidle");
|
|
||||||
await page.click("[data-testid=delete-account]");
|
await page.click("[data-testid=delete-account]");
|
||||||
if (!user.username) throw Error(`Test user doesn't have a username`);
|
|
||||||
|
expect(user.username).toBeTruthy();
|
||||||
|
|
||||||
const $passwordField = page.locator("[data-testid=password]");
|
const $passwordField = page.locator("[data-testid=password]");
|
||||||
await $passwordField.fill(user.username);
|
await $passwordField.fill(String(user.username));
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForURL((url) => url.pathname === "/auth/logout"),
|
page.waitForURL((url) => url.pathname === "/auth/logout"),
|
||||||
|
|||||||
@@ -5,9 +5,10 @@ import { test } from "../lib/fixtures";
|
|||||||
test.afterEach(({ users }) => users.deleteAll());
|
test.afterEach(({ users }) => users.deleteAll());
|
||||||
|
|
||||||
test("Can reset forgotten password", async ({ page, users }) => {
|
test("Can reset forgotten password", async ({ page, users }) => {
|
||||||
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip(process.env.NEXT_PUBLIC_IS_E2E !== "1", "It shouldn't if we can't skip email");
|
test.skip(process.env.NEXT_PUBLIC_IS_E2E !== "1", "It shouldn't if we can't skip email");
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
const newPassword = `${user.username!}-123`;
|
const newPassword = `${user.username}-123`;
|
||||||
// Got to reset password flow
|
// Got to reset password flow
|
||||||
await page.goto("/auth/forgot-password");
|
await page.goto("/auth/forgot-password");
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ test("Can reset forgotten password", async ({ page, users }) => {
|
|||||||
|
|
||||||
// Press Enter
|
// Press Enter
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
page.waitForURL((u) => u.pathname.startsWith("/auth/forgot-password/")),
|
page.waitForURL((u) => u.pathname.startsWith("/auth/forgot-password")),
|
||||||
page.press('input[name="email"]', "Enter"),
|
page.press('input[name="email"]', "Enter"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ test.describe.configure({ mode: "parallel" });
|
|||||||
test.describe("Availablity tests", () => {
|
test.describe("Availablity tests", () => {
|
||||||
test.beforeEach(async ({ page, users }) => {
|
test.beforeEach(async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto("/availability");
|
await page.goto("/availability");
|
||||||
// We wait until loading is finished
|
// We wait until loading is finished
|
||||||
await page.waitForSelector('[data-testid="schedules"]');
|
await page.waitForSelector('[data-testid="schedules"]');
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ testBothBookers.describe("pro user", () => {
|
|||||||
const [eventType] = pro.eventTypes;
|
const [eventType] = pro.eventTypes;
|
||||||
await bookings.create(pro.id, pro.username, eventType.id);
|
await bookings.create(pro.id, pro.username, eventType.id);
|
||||||
|
|
||||||
await pro.login();
|
await pro.apiLogin();
|
||||||
await page.goto("/bookings/upcoming");
|
await page.goto("/bookings/upcoming");
|
||||||
await page.waitForSelector('[data-testid="bookings"]');
|
await page.waitForSelector('[data-testid="bookings"]');
|
||||||
await page.locator('[data-testid="edit_booking"]').nth(0).click();
|
await page.locator('[data-testid="edit_booking"]').nth(0).click();
|
||||||
@@ -106,7 +106,7 @@ testBothBookers.describe("pro user", () => {
|
|||||||
await expect(page.locator(`[data-testid="attendee-name-${testName}"]`)).toHaveText(testName);
|
await expect(page.locator(`[data-testid="attendee-name-${testName}"]`)).toHaveText(testName);
|
||||||
|
|
||||||
const [pro] = users.get();
|
const [pro] = users.get();
|
||||||
await pro.login();
|
await pro.apiLogin();
|
||||||
|
|
||||||
await page.goto("/bookings/upcoming");
|
await page.goto("/bookings/upcoming");
|
||||||
await page.locator('[data-testid="cancel"]').first().click();
|
await page.locator('[data-testid="cancel"]').first().click();
|
||||||
@@ -132,7 +132,7 @@ testBothBookers.describe("pro user", () => {
|
|||||||
}) => {
|
}) => {
|
||||||
await bookOptinEvent(page);
|
await bookOptinEvent(page);
|
||||||
const [pro] = users.get();
|
const [pro] = users.get();
|
||||||
await pro.login();
|
await pro.apiLogin();
|
||||||
|
|
||||||
await page.goto("/bookings/unconfirmed");
|
await page.goto("/bookings/unconfirmed");
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
selectFirstAvailableTimeSlotNextMonth,
|
selectFirstAvailableTimeSlotNextMonth,
|
||||||
} from "./lib/testUtils";
|
} from "./lib/testUtils";
|
||||||
|
|
||||||
|
test.describe.configure({ mode: "parallel" });
|
||||||
test.afterEach(({ users }) => users.deleteAll());
|
test.afterEach(({ users }) => users.deleteAll());
|
||||||
|
|
||||||
async function createUserWithSeatedEvent(users: Fixtures["users"]) {
|
async function createUserWithSeatedEvent(users: Fixtures["users"]) {
|
||||||
@@ -50,17 +51,27 @@ async function createUserWithSeatedEventAndAttendees(
|
|||||||
testBothBookers.describe("Booking with Seats", (bookerVariant) => {
|
testBothBookers.describe("Booking with Seats", (bookerVariant) => {
|
||||||
test("User can create a seated event (2 seats as example)", async ({ users, page }) => {
|
test("User can create a seated event (2 seats as example)", async ({ users, page }) => {
|
||||||
const user = await users.create({ name: "Seated event" });
|
const user = await users.create({ name: "Seated event" });
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
|
await page.goto("/event-types");
|
||||||
|
// We wait until loading is finished
|
||||||
|
await page.waitForSelector('[data-testid="event-types"]');
|
||||||
const eventTitle = "My 2-seated event";
|
const eventTitle = "My 2-seated event";
|
||||||
await createNewSeatedEventType(page, { eventTitle });
|
await createNewSeatedEventType(page, { eventTitle });
|
||||||
await expect(page.locator(`text=${eventTitle} event type updated successfully`)).toBeVisible();
|
await expect(page.locator(`text=${eventTitle} event type updated successfully`)).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("Multiple Attendees can book a seated event time slot", async ({ users, page }) => {
|
test("Multiple Attendees can book a seated event time slot", async ({ users, page }) => {
|
||||||
const slug = "my-2-seated-event";
|
const slug = "my-2-seated-event";
|
||||||
const user = await users.create({
|
const user = await users.create({
|
||||||
name: "Seated event user",
|
name: "Seated event user",
|
||||||
eventTypes: [
|
eventTypes: [
|
||||||
{ title: "My 2-seated event", slug, length: 60, seatsPerTimeSlot: 2, seatsShowAttendees: true },
|
{
|
||||||
|
title: "My 2-seated event",
|
||||||
|
slug,
|
||||||
|
length: 60,
|
||||||
|
seatsPerTimeSlot: 2,
|
||||||
|
seatsShowAttendees: true,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
await page.goto(`/${user.username}/${slug}`);
|
await page.goto(`/${user.username}/${slug}`);
|
||||||
@@ -93,6 +104,7 @@ testBothBookers.describe("Booking with Seats", (bookerVariant) => {
|
|||||||
await expect(page.locator("[data-testid=success-page]")).toBeHidden();
|
await expect(page.locator("[data-testid=success-page]")).toBeHidden();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Make E2E test: Attendee #1 should be able to cancel his booking
|
// TODO: Make E2E test: Attendee #1 should be able to cancel his booking
|
||||||
// todo("Attendee #1 should be able to cancel his booking");
|
// todo("Attendee #1 should be able to cancel his booking");
|
||||||
// TODO: Make E2E test: Attendee #1 should be able to reschedule his booking
|
// TODO: Make E2E test: Attendee #1 should be able to reschedule his booking
|
||||||
@@ -222,7 +234,7 @@ testBothBookers.describe("Reschedule for booking with seats", () => {
|
|||||||
{ name: "John First", email: "first+seats@cal.com", timeZone: "Europe/Berlin" },
|
{ name: "John First", email: "first+seats@cal.com", timeZone: "Europe/Berlin" },
|
||||||
{ name: "Jane Second", email: "second+seats@cal.com", timeZone: "Europe/Berlin" },
|
{ name: "Jane Second", email: "second+seats@cal.com", timeZone: "Europe/Berlin" },
|
||||||
]);
|
]);
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
|
|
||||||
const oldBooking = await prisma.booking.findFirst({
|
const oldBooking = await prisma.booking.findFirst({
|
||||||
where: { uid: booking.uid },
|
where: { uid: booking.uid },
|
||||||
@@ -328,7 +340,7 @@ testBothBookers.describe("Reschedule for booking with seats", () => {
|
|||||||
{ name: "John First", email: "first+seats@cal.com", timeZone: "Europe/Berlin" },
|
{ name: "John First", email: "first+seats@cal.com", timeZone: "Europe/Berlin" },
|
||||||
{ name: "Jane Second", email: "second+seats@cal.com", timeZone: "Europe/Berlin" },
|
{ name: "Jane Second", email: "second+seats@cal.com", timeZone: "Europe/Berlin" },
|
||||||
]);
|
]);
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
|
|
||||||
const bookingAttendees = await prisma.attendee.findMany({
|
const bookingAttendees = await prisma.attendee.findMany({
|
||||||
where: { bookingId: booking.id },
|
where: { bookingId: booking.id },
|
||||||
@@ -379,7 +391,7 @@ testBothBookers.describe("Reschedule for booking with seats", () => {
|
|||||||
{ name: "John First", email: "first+seats@cal.com", timeZone: "Europe/Berlin" },
|
{ name: "John First", email: "first+seats@cal.com", timeZone: "Europe/Berlin" },
|
||||||
{ name: "Jane Second", email: "second+seats@cal.com", timeZone: "Europe/Berlin" },
|
{ name: "Jane Second", email: "second+seats@cal.com", timeZone: "Europe/Berlin" },
|
||||||
]);
|
]);
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
const bookingWithEventType = await prisma.booking.findFirst({
|
const bookingWithEventType = await prisma.booking.findFirst({
|
||||||
where: { uid: booking.uid },
|
where: { uid: booking.uid },
|
||||||
select: {
|
select: {
|
||||||
|
|||||||
@@ -7,15 +7,16 @@ test.afterEach(({ users }) => users.deleteAll());
|
|||||||
test.describe("Change Password Test", () => {
|
test.describe("Change Password Test", () => {
|
||||||
test("change password", async ({ page, users }) => {
|
test("change password", async ({ page, users }) => {
|
||||||
const pro = await users.create();
|
const pro = await users.create();
|
||||||
await pro.login();
|
await pro.apiLogin();
|
||||||
// Go to http://localhost:3000/settings/security
|
// Go to http://localhost:3000/settings/security
|
||||||
await page.goto("/settings/security/password");
|
await page.goto("/settings/security/password");
|
||||||
if (!pro.username) throw Error("Test user doesn't have a username");
|
|
||||||
|
expect(pro.username).toBeTruthy();
|
||||||
|
|
||||||
await page.waitForLoadState("networkidle");
|
await page.waitForLoadState("networkidle");
|
||||||
|
|
||||||
// Fill form
|
// Fill form
|
||||||
await page.locator('[name="oldPassword"]').fill(pro.username);
|
await page.locator('[name="oldPassword"]').fill(String(pro.username));
|
||||||
|
|
||||||
const $newPasswordField = page.locator('[name="newPassword"]');
|
const $newPasswordField = page.locator('[name="newPassword"]');
|
||||||
$newPasswordField.fill(`${pro.username}Aa1111`);
|
$newPasswordField.fill(`${pro.username}Aa1111`);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ test.describe("Change username on settings", () => {
|
|||||||
test.fixme("User can change username", async ({ page, users, prisma }) => {
|
test.fixme("User can change username", async ({ page, users, prisma }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
|
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
// Try to go homepage
|
// Try to go homepage
|
||||||
await page.goto("/settings/my-account/profile");
|
await page.goto("/settings/my-account/profile");
|
||||||
// Change username from normal to normal
|
// Change username from normal to normal
|
||||||
@@ -50,12 +50,13 @@ test.describe("Change username on settings", () => {
|
|||||||
test("User can update to PREMIUM username", async ({ page, users }, testInfo) => {
|
test("User can update to PREMIUM username", async ({ page, users }, testInfo) => {
|
||||||
// eslint-disable-next-line playwright/no-skipped-test
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip(!IS_STRIPE_ENABLED, "It should only run if Stripe is installed");
|
test.skip(!IS_STRIPE_ENABLED, "It should only run if Stripe is installed");
|
||||||
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip(IS_SELF_HOSTED, "It shouldn't run on self hosted");
|
test.skip(IS_SELF_HOSTED, "It shouldn't run on self hosted");
|
||||||
|
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await stripe.customers.create({ email: `${user?.username}@example.com` });
|
await stripe.customers.create({ email: `${user?.username}@example.com` });
|
||||||
|
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto("/settings/my-account/profile");
|
await page.goto("/settings/my-account/profile");
|
||||||
|
|
||||||
// Change username from normal to premium
|
// Change username from normal to premium
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ test.afterEach(({ users }) => users.deleteAll());
|
|||||||
|
|
||||||
// Due to some reason for Dynamic booking cancellation, daily video api_key is not set which causes cancellation to fail.
|
// Due to some reason for Dynamic booking cancellation, daily video api_key is not set which causes cancellation to fail.
|
||||||
// This test is skipped until the issue is resolved in GH actions.
|
// This test is skipped until the issue is resolved in GH actions.
|
||||||
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip("dynamic booking", async ({ page, users }) => {
|
test.skip("dynamic booking", async ({ page, users }) => {
|
||||||
const pro = await users.create();
|
const pro = await users.create();
|
||||||
await pro.login();
|
await pro.apiLogin();
|
||||||
|
|
||||||
const free = await users.create({ username: "free" });
|
const free = await users.create({ username: "free" });
|
||||||
await page.goto(`/${pro.username}+${free.username}`);
|
await page.goto(`/${pro.username}+${free.username}`);
|
||||||
|
|||||||
@@ -47,7 +47,15 @@ async function expectToBeNavigatingToEmbedTypesDialog(
|
|||||||
|
|
||||||
async function expectToBeNavigatingToEmbedCodeAndPreviewDialog(
|
async function expectToBeNavigatingToEmbedCodeAndPreviewDialog(
|
||||||
page: Page,
|
page: Page,
|
||||||
{ embedUrl, embedType, basePage }: { embedUrl: string | null; embedType: string; basePage: string }
|
{
|
||||||
|
embedUrl,
|
||||||
|
embedType,
|
||||||
|
basePage,
|
||||||
|
}: {
|
||||||
|
embedUrl: string | null;
|
||||||
|
embedType: string;
|
||||||
|
basePage: string;
|
||||||
|
}
|
||||||
) {
|
) {
|
||||||
if (!embedUrl) {
|
if (!embedUrl) {
|
||||||
throw new Error("Couldn't find embedUrl");
|
throw new Error("Couldn't find embedUrl");
|
||||||
@@ -89,7 +97,7 @@ test.afterEach(({ users }) => users.deleteAll());
|
|||||||
test.describe("Embed Code Generator Tests", () => {
|
test.describe("Embed Code Generator Tests", () => {
|
||||||
test.beforeEach(async ({ users }) => {
|
test.beforeEach(async ({ users }) => {
|
||||||
const pro = await users.create();
|
const pro = await users.create();
|
||||||
await pro.login();
|
await pro.apiLogin();
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe("Event Types Page", () => {
|
test.describe("Event Types Page", () => {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ test.describe("Event Types tests", () => {
|
|||||||
testBothBookers.describe("user", (bookerVariant) => {
|
testBothBookers.describe("user", (bookerVariant) => {
|
||||||
test.beforeEach(async ({ page, users }) => {
|
test.beforeEach(async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto("/event-types");
|
await page.goto("/event-types");
|
||||||
// We wait until loading is finished
|
// We wait until loading is finished
|
||||||
await page.waitForSelector('[data-testid="event-types"]');
|
await page.waitForSelector('[data-testid="event-types"]');
|
||||||
@@ -69,7 +69,7 @@ test.describe("Event Types tests", () => {
|
|||||||
'[data-testid="event-types"] a[href^="/event-types/"] >> nth=0'
|
'[data-testid="event-types"] a[href^="/event-types/"] >> nth=0'
|
||||||
);
|
);
|
||||||
const href = await firstElement.getAttribute("href");
|
const href = await firstElement.getAttribute("href");
|
||||||
if (!href) throw new Error("No href found for event type");
|
expect(href).toBeTruthy();
|
||||||
const [eventTypeId] = new URL(WEBAPP_URL + href).pathname.split("/").reverse();
|
const [eventTypeId] = new URL(WEBAPP_URL + href).pathname.split("/").reverse();
|
||||||
const firstTitle = await page.locator(`[data-testid=event-type-title-${eventTypeId}]`).innerText();
|
const firstTitle = await page.locator(`[data-testid=event-type-title-${eventTypeId}]`).innerText();
|
||||||
const firstFullSlug = await page.locator(`[data-testid=event-type-slug-${eventTypeId}]`).innerText();
|
const firstFullSlug = await page.locator(`[data-testid=event-type-slug-${eventTypeId}]`).innerText();
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export const createBookingsFixture = (page: Page) => {
|
|||||||
status,
|
status,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const bookingFixture = createBookingFixture(booking, store.page!);
|
const bookingFixture = createBookingFixture(booking, store.page);
|
||||||
store.bookings.push(bookingFixture);
|
store.bookings.push(bookingFixture);
|
||||||
return bookingFixture;
|
return bookingFixture;
|
||||||
},
|
},
|
||||||
@@ -80,7 +80,7 @@ const createBookingFixture = (booking: Booking, page: Page) => {
|
|||||||
return {
|
return {
|
||||||
id: store.booking.id,
|
id: store.booking.id,
|
||||||
uid: store.booking.uid,
|
uid: store.booking.uid,
|
||||||
self: async () => (await prisma.booking.findUnique({ where: { id: store.booking.id } }))!,
|
self: async () => await prisma.booking.findUnique({ where: { id: store.booking.id } }),
|
||||||
delete: async () => (await prisma.booking.delete({ where: { id: store.booking.id } }))!,
|
delete: async () => await prisma.booking.delete({ where: { id: store.booking.id } }),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -36,7 +36,7 @@ export const createPaymentsFixture = (page: Page) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const paymentFixture = createPaymentFixture(payment, store.page!);
|
const paymentFixture = createPaymentFixture(payment, store.page);
|
||||||
store.payments.push(paymentFixture);
|
store.payments.push(paymentFixture);
|
||||||
return paymentFixture;
|
return paymentFixture;
|
||||||
},
|
},
|
||||||
@@ -57,7 +57,7 @@ const createPaymentFixture = (payment: Payment, page: Page) => {
|
|||||||
// self is a reflective method that return the Prisma object that references this fixture.
|
// self is a reflective method that return the Prisma object that references this fixture.
|
||||||
return {
|
return {
|
||||||
id: store.payment.id,
|
id: store.payment.id,
|
||||||
self: async () => (await prisma.payment.findUnique({ where: { id: store.payment.id } }))!,
|
self: async () => await prisma.payment.findUnique({ where: { id: store.payment.id } }),
|
||||||
delete: async () => (await prisma.payment.delete({ where: { id: store.payment.id } }))!,
|
delete: async () => await prisma.payment.delete({ where: { id: store.payment.id } }),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -233,7 +233,7 @@ export const createUsersFixture = (page: Page, workerInfo: WorkerInfo) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const userFixture = createUserFixture(user, store.page!);
|
const userFixture = createUserFixture(user, store.page);
|
||||||
store.users.push(userFixture);
|
store.users.push(userFixture);
|
||||||
return userFixture;
|
return userFixture;
|
||||||
},
|
},
|
||||||
@@ -261,13 +261,18 @@ const createUserFixture = (user: UserWithIncludes, page: Page) => {
|
|||||||
|
|
||||||
// self is a reflective method that return the Prisma object that references this fixture.
|
// self is a reflective method that return the Prisma object that references this fixture.
|
||||||
const self = async () =>
|
const self = async () =>
|
||||||
(await prisma.user.findUnique({ where: { id: store.user.id }, include: { eventTypes: true } }))!;
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
(await prisma.user.findUnique({
|
||||||
|
where: { id: store.user.id },
|
||||||
|
include: { eventTypes: true },
|
||||||
|
}))!;
|
||||||
return {
|
return {
|
||||||
id: user.id,
|
id: user.id,
|
||||||
username: user.username,
|
username: user.username,
|
||||||
eventTypes: user.eventTypes,
|
eventTypes: user.eventTypes,
|
||||||
routingForms: user.routingForms,
|
routingForms: user.routingForms,
|
||||||
self,
|
self,
|
||||||
|
apiLogin: async () => apiLogin({ ...(await self()), password: user.username }, store.page),
|
||||||
login: async () => login({ ...(await self()), password: user.username }, store.page),
|
login: async () => login({ ...(await self()), password: user.username }, store.page),
|
||||||
logout: async () => {
|
logout: async () => {
|
||||||
await page.goto("/auth/logout");
|
await page.goto("/auth/logout");
|
||||||
@@ -275,9 +280,12 @@ const createUserFixture = (user: UserWithIncludes, page: Page) => {
|
|||||||
getPaymentCredential: async () => getPaymentCredential(store.page),
|
getPaymentCredential: async () => getPaymentCredential(store.page),
|
||||||
// ths is for developemnt only aimed to inject debugging messages in the metadata field of the user
|
// ths is for developemnt only aimed to inject debugging messages in the metadata field of the user
|
||||||
debug: async (message: string | Record<string, JSONValue>) => {
|
debug: async (message: string | Record<string, JSONValue>) => {
|
||||||
await prisma.user.update({ where: { id: store.user.id }, data: { metadata: { debug: message } } });
|
await prisma.user.update({
|
||||||
|
where: { id: store.user.id },
|
||||||
|
data: { metadata: { debug: message } },
|
||||||
|
});
|
||||||
},
|
},
|
||||||
delete: async () => (await prisma.user.delete({ where: { id: store.user.id } }))!,
|
delete: async () => await prisma.user.delete({ where: { id: store.user.id } }),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -341,6 +349,28 @@ export async function login(
|
|||||||
await page.waitForLoadState("networkidle");
|
await page.waitForLoadState("networkidle");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function apiLogin(
|
||||||
|
user: Pick<Prisma.User, "username"> & Partial<Pick<Prisma.User, "password" | "email">>,
|
||||||
|
page: Page
|
||||||
|
) {
|
||||||
|
const csrfToken = await page
|
||||||
|
.context()
|
||||||
|
.request.get("/api/auth/csrf")
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((json) => json.csrfToken);
|
||||||
|
const data = {
|
||||||
|
email: user.email ?? `${user.username}@example.com`,
|
||||||
|
password: user.password ?? user.username!,
|
||||||
|
callbackURL: "http://localhost:3000/",
|
||||||
|
redirect: "false",
|
||||||
|
json: "true",
|
||||||
|
csrfToken,
|
||||||
|
};
|
||||||
|
return page.context().request.post("/api/auth/callback/credentials", {
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export async function getPaymentCredential(page: Page) {
|
export async function getPaymentCredential(page: Page) {
|
||||||
await page.goto("/apps/stripe");
|
await page.goto("/apps/stripe");
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ test.describe.configure({ mode: "parallel" });
|
|||||||
test.fixme("hash my url", () => {
|
test.fixme("hash my url", () => {
|
||||||
test.beforeEach(async ({ users }) => {
|
test.beforeEach(async ({ users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
});
|
});
|
||||||
test.afterEach(async ({ users }) => {
|
test.afterEach(async ({ users }) => {
|
||||||
await users.deleteAll();
|
await users.deleteAll();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ test.describe("Stripe integration", () => {
|
|||||||
test.describe("Stripe integration dashboard", () => {
|
test.describe("Stripe integration dashboard", () => {
|
||||||
test("Can add Stripe integration", async ({ page, users }) => {
|
test("Can add Stripe integration", async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto("/apps/installed");
|
await page.goto("/apps/installed");
|
||||||
|
|
||||||
await user.getPaymentCredential();
|
await user.getPaymentCredential();
|
||||||
@@ -38,12 +38,12 @@ test.describe("Stripe integration", () => {
|
|||||||
|
|
||||||
test("Can book a paid booking", async ({ page, users }) => {
|
test("Can book a paid booking", async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
const eventType = user.eventTypes.find((e) => e.slug === "paid")!;
|
const eventType = user.eventTypes.find((e) => e.slug === "paid");
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto("/apps/installed");
|
await page.goto("/apps/installed");
|
||||||
await user.getPaymentCredential();
|
await user.getPaymentCredential();
|
||||||
|
|
||||||
await page.goto(`${user.username}/${eventType.slug}`);
|
await page.goto(`${user.username}/${eventType?.slug}`);
|
||||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||||
// --- fill form
|
// --- fill form
|
||||||
await page.fill('[name="name"]', "Stripe Stripeson");
|
await page.fill('[name="name"]', "Stripe Stripeson");
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { Page, Route } from "@playwright/test";
|
import type { Page, Route } from "@playwright/test";
|
||||||
import { expect } from "@playwright/test";
|
import { expect } from "@playwright/test";
|
||||||
|
import type { DefaultBodyType } from "msw";
|
||||||
import { rest } from "msw";
|
import { rest } from "msw";
|
||||||
import { setupServer } from "msw/node";
|
import { setupServer } from "msw/node";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
@@ -42,7 +43,7 @@ const addOauthBasedIntegration = async function ({
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
verify: (config: { requestHeaders: any; params: URLSearchParams; code: string }) => {
|
verify: (config: { requestHeaders: any; params: URLSearchParams; code: string }) => {
|
||||||
status: number;
|
status: number;
|
||||||
body: any;
|
body: DefaultBodyType;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}) {
|
}) {
|
||||||
@@ -213,7 +214,7 @@ test.fixme("Integrations", () => {
|
|||||||
test.describe("Zoom App", () => {
|
test.describe("Zoom App", () => {
|
||||||
test("Can add integration", async ({ page, users }) => {
|
test("Can add integration", async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await addZoomIntegration({ page });
|
await addZoomIntegration({ page });
|
||||||
await page.waitForNavigation({
|
await page.waitForNavigation({
|
||||||
url: (url) => {
|
url: (url) => {
|
||||||
@@ -225,7 +226,7 @@ test.fixme("Integrations", () => {
|
|||||||
|
|
||||||
test("can choose zoom as a location during booking", async ({ page, users }) => {
|
test("can choose zoom as a location during booking", async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
const eventType = await addLocationIntegrationToFirstEvent({ user });
|
const eventType = await addLocationIntegrationToFirstEvent({ user });
|
||||||
await addZoomIntegration({ page });
|
await addZoomIntegration({ page });
|
||||||
await page.waitForNavigation({
|
await page.waitForNavigation({
|
||||||
@@ -240,7 +241,7 @@ test.fixme("Integrations", () => {
|
|||||||
// POST https://api.zoom.us/v2/users/me/meetings
|
// POST https://api.zoom.us/v2/users/me/meetings
|
||||||
// Verify Header-> Authorization: "Bearer " + accessToken,
|
// Verify Header-> Authorization: "Bearer " + accessToken,
|
||||||
/**
|
/**
|
||||||
* {
|
* {
|
||||||
topic: event.title,
|
topic: event.title,
|
||||||
type: 2, // Means that this is a scheduled meeting
|
type: 2, // Means that this is a scheduled meeting
|
||||||
start_time: event.startTime,
|
start_time: event.startTime,
|
||||||
@@ -261,15 +262,15 @@ test.fixme("Integrations", () => {
|
|||||||
approval_type: 2,
|
approval_type: 2,
|
||||||
audio: "both",
|
audio: "both",
|
||||||
auto_recording: "none",
|
auto_recording: "none",
|
||||||
enforce_login: false,
|
enforce_apiLogin: false,
|
||||||
registrants_email_notification: true,
|
registrants_email_notification: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
});
|
});
|
||||||
test("Can disconnect from integration", async ({ page, users }) => {
|
test("Can disconnect from integration", async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await addZoomIntegration({ page });
|
await addZoomIntegration({ page });
|
||||||
await page.waitForNavigation({
|
await page.waitForNavigation({
|
||||||
url: (url) => {
|
url: (url) => {
|
||||||
@@ -298,7 +299,7 @@ test.fixme("Integrations", () => {
|
|||||||
test.describe("Hubspot App", () => {
|
test.describe("Hubspot App", () => {
|
||||||
test("Can add integration", async ({ page, users }) => {
|
test("Can add integration", async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await addOauthBasedIntegration({
|
await addOauthBasedIntegration({
|
||||||
page,
|
page,
|
||||||
slug: "hubspot",
|
slug: "hubspot",
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ declare global {
|
|||||||
* @see https://playwright.dev/docs/test-fixtures
|
* @see https://playwright.dev/docs/test-fixtures
|
||||||
*/
|
*/
|
||||||
export const test = base.extend<Fixtures>({
|
export const test = base.extend<Fixtures>({
|
||||||
users: async ({ page }, use, workerInfo) => {
|
users: async ({ page, context }, use, workerInfo) => {
|
||||||
const usersFixture = createUsersFixture(page, workerInfo);
|
const usersFixture = createUsersFixture(page, workerInfo);
|
||||||
await use(usersFixture);
|
await use(usersFixture);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ export const deleteAllBookingsByEmail = async (
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const deleteEventTypeByTitle = async (title: string) => {
|
export const deleteEventTypeByTitle = async (title: string) => {
|
||||||
const event = (await prisma.eventType.findFirst({
|
const event = await prisma.eventType.findFirst({
|
||||||
select: { id: true },
|
select: { id: true },
|
||||||
where: { title: title },
|
where: { title: title },
|
||||||
}))!;
|
});
|
||||||
await prisma.eventType.delete({ where: { id: event.id } });
|
await prisma.eventType.delete({ where: { id: event?.id } });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const deleteAllWebhooksByEmail = async (email: string) => {
|
export const deleteAllWebhooksByEmail = async (email: string) => {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export function createHttpServer(opts: { requestHandler?: RequestHandler } = {})
|
|||||||
|
|
||||||
// listen on random port
|
// listen on random port
|
||||||
server.listen(0);
|
server.listen(0);
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const port: number = (server.address() as any).port;
|
const port: number = (server.address() as any).port;
|
||||||
const url = `http://localhost:${port}`;
|
const url = `http://localhost:${port}`;
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { expect } from "@playwright/test";
|
||||||
|
|
||||||
|
import { test } from "./lib/fixtures";
|
||||||
|
|
||||||
|
test.describe.configure({ mode: "parallel" });
|
||||||
|
test.afterEach(({ users }) => users.deleteAll());
|
||||||
|
|
||||||
|
test.describe("Login with api request", () => {
|
||||||
|
test("context request will share cookie storage with its browser context", async ({ page, users }) => {
|
||||||
|
const pro = await users.create();
|
||||||
|
await pro.apiLogin();
|
||||||
|
|
||||||
|
const contextCookies = await page.context().cookies();
|
||||||
|
const cookiesMap = new Map(contextCookies.map(({ name, value }) => [name, value]));
|
||||||
|
|
||||||
|
// The browser context will already contain all the cookies from the API response.
|
||||||
|
expect(cookiesMap.has("next-auth.csrf-token")).toBeTruthy();
|
||||||
|
expect(cookiesMap.has("next-auth.callback-url")).toBeTruthy();
|
||||||
|
expect(cookiesMap.has("next-auth.session-token")).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -15,6 +15,7 @@ async function getLabelText(field: Locator) {
|
|||||||
return await field.locator("label").first().locator("span").first().innerText();
|
return await field.locator("label").first().locator("span").first().innerText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test.describe.configure({ mode: "parallel" });
|
||||||
test.describe("Manage Booking Questions", () => {
|
test.describe("Manage Booking Questions", () => {
|
||||||
test.afterEach(async ({ users }) => {
|
test.afterEach(async ({ users }) => {
|
||||||
await users.deleteAll();
|
await users.deleteAll();
|
||||||
@@ -28,7 +29,7 @@ test.describe("Manage Booking Questions", () => {
|
|||||||
}, testInfo) => {
|
}, testInfo) => {
|
||||||
// Considering there are many steps in it, it would need more than default test timeout
|
// Considering there are many steps in it, it would need more than default test timeout
|
||||||
test.setTimeout(testInfo.timeout * 3);
|
test.setTimeout(testInfo.timeout * 3);
|
||||||
const user = await createAndLoginUserWithEventTypes({ users });
|
const user = await createAndLoginUserWithEventTypes({ users, page });
|
||||||
|
|
||||||
const webhookReceiver = await addWebhook(user);
|
const webhookReceiver = await addWebhook(user);
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ test.describe("Manage Booking Questions", () => {
|
|||||||
}, testInfo) => {
|
}, testInfo) => {
|
||||||
// Considering there are many steps in it, it would need more than default test timeout
|
// Considering there are many steps in it, it would need more than default test timeout
|
||||||
test.setTimeout(testInfo.timeout * 3);
|
test.setTimeout(testInfo.timeout * 3);
|
||||||
const user = await createAndLoginUserWithEventTypes({ users });
|
const user = await createAndLoginUserWithEventTypes({ users, page });
|
||||||
const team = await prisma.team.findFirst({
|
const team = await prisma.team.findFirst({
|
||||||
where: {
|
where: {
|
||||||
members: {
|
members: {
|
||||||
@@ -65,7 +66,7 @@ test.describe("Manage Booking Questions", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const teamId = team?.id ?? 0;
|
const teamId = team?.id;
|
||||||
const webhookReceiver = await addWebhook(undefined, teamId);
|
const webhookReceiver = await addWebhook(undefined, teamId);
|
||||||
|
|
||||||
await test.step("Go to First Team Event", async () => {
|
await test.step("Go to First Team Event", async () => {
|
||||||
@@ -86,7 +87,8 @@ async function runTestStepsCommonForTeamAndUserEventType(
|
|||||||
webhookReceiver: {
|
webhookReceiver: {
|
||||||
port: number;
|
port: number;
|
||||||
close: () => import("http").Server;
|
close: () => import("http").Server;
|
||||||
requestList: (import("http").IncomingMessage & { body?: unknown })[];
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
requestList: (import("http").IncomingMessage & { body?: any })[];
|
||||||
url: string;
|
url: string;
|
||||||
},
|
},
|
||||||
bookerVariant: BookerVariants
|
bookerVariant: BookerVariants
|
||||||
@@ -175,7 +177,7 @@ async function runTestStepsCommonForTeamAndUserEventType(
|
|||||||
|
|
||||||
const [request] = webhookReceiver.requestList;
|
const [request] = webhookReceiver.requestList;
|
||||||
|
|
||||||
const payload = (request.body as any).payload as any;
|
const payload = request.body.payload;
|
||||||
|
|
||||||
expect(payload.responses).toMatchObject({
|
expect(payload.responses).toMatchObject({
|
||||||
email: {
|
email: {
|
||||||
@@ -212,7 +214,9 @@ async function runTestStepsCommonForTeamAndUserEventType(
|
|||||||
|
|
||||||
await test.step("Do a reschedule and notice that we can't book without giving a value for rescheduleReason", async () => {
|
await test.step("Do a reschedule and notice that we can't book without giving a value for rescheduleReason", async () => {
|
||||||
const page = previewTabPage;
|
const page = previewTabPage;
|
||||||
await rescheduleFromTheLinkOnPage({ page, bookerVariant });
|
await rescheduleFromTheLinkOnPage({ page });
|
||||||
|
// eslint-disable-next-line playwright/no-page-pause
|
||||||
|
await page.pause();
|
||||||
await expectErrorToBeThereFor({ page, name: "rescheduleReason" });
|
await expectErrorToBeThereFor({ page, name: "rescheduleReason" });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -244,6 +248,7 @@ async function bookTimeSlot({ page, name, email }: { page: Page; name: string; e
|
|||||||
await page.fill('[name="email"]', email);
|
await page.fill('[name="email"]', email);
|
||||||
await page.press('[name="email"]', "Enter");
|
await page.press('[name="email"]', "Enter");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'option' starts from 1
|
* 'option' starts from 1
|
||||||
*/
|
*/
|
||||||
@@ -355,11 +360,20 @@ async function toggleQuestionRequireStatusAndSave({
|
|||||||
await saveEventType(page);
|
await saveEventType(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createAndLoginUserWithEventTypes({ users }: { users: ReturnType<typeof createUsersFixture> }) {
|
async function createAndLoginUserWithEventTypes({
|
||||||
|
users,
|
||||||
|
page,
|
||||||
|
}: {
|
||||||
|
users: ReturnType<typeof createUsersFixture>;
|
||||||
|
page: Page;
|
||||||
|
}) {
|
||||||
const user = await users.create(null, {
|
const user = await users.create(null, {
|
||||||
hasTeam: true,
|
hasTeam: true,
|
||||||
});
|
});
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
|
await page.goto("/event-types");
|
||||||
|
// We wait until loading is finished
|
||||||
|
await page.waitForSelector('[data-testid="event-types"]');
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +382,7 @@ async function rescheduleFromTheLinkOnPage({
|
|||||||
bookerVariant,
|
bookerVariant,
|
||||||
}: {
|
}: {
|
||||||
page: Page;
|
page: Page;
|
||||||
bookerVariant: BookerVariants;
|
bookerVariant?: BookerVariants;
|
||||||
}) {
|
}) {
|
||||||
await page.locator('[data-testid="reschedule-link"]').click();
|
await page.locator('[data-testid="reschedule-link"]').click();
|
||||||
await page.waitForLoadState();
|
await page.waitForLoadState();
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ test.describe("Managed Event Types tests", () => {
|
|||||||
// Creating the member user of the team
|
// Creating the member user of the team
|
||||||
const memberUser = await users.create();
|
const memberUser = await users.create();
|
||||||
// First we work with owner user, logging in
|
// First we work with owner user, logging in
|
||||||
await adminUser.login();
|
await adminUser.apiLogin();
|
||||||
|
await page.goto("/event-types");
|
||||||
// Making sure page loads completely
|
// Making sure page loads completely
|
||||||
await page.waitForLoadState("networkidle");
|
await page.waitForLoadState("networkidle");
|
||||||
// Let's create a team
|
// Let's create a team
|
||||||
@@ -58,7 +59,9 @@ test.describe("Managed Event Types tests", () => {
|
|||||||
// Now we need to accept the invitation as member and come back in as admin to
|
// Now we need to accept the invitation as member and come back in as admin to
|
||||||
// assign the member in the managed event type
|
// assign the member in the managed event type
|
||||||
await adminUser.logout();
|
await adminUser.logout();
|
||||||
await memberUser.login();
|
await memberUser.apiLogin();
|
||||||
|
await page.goto("/event-types");
|
||||||
|
// We wait until loading is finished
|
||||||
await page.waitForSelector('[data-testid="event-types"]');
|
await page.waitForSelector('[data-testid="event-types"]');
|
||||||
await page.goto("/teams");
|
await page.goto("/teams");
|
||||||
await page.waitForLoadState("networkidle");
|
await page.waitForLoadState("networkidle");
|
||||||
@@ -67,7 +70,8 @@ test.describe("Managed Event Types tests", () => {
|
|||||||
await memberUser.logout();
|
await memberUser.logout();
|
||||||
|
|
||||||
// Coming back as team owner to assign member user to managed event
|
// Coming back as team owner to assign member user to managed event
|
||||||
await adminUser.login();
|
await adminUser.apiLogin();
|
||||||
|
await page.goto("/event-types");
|
||||||
await page.waitForLoadState("networkidle");
|
await page.waitForLoadState("networkidle");
|
||||||
await page.locator('[data-testid="event-types"] a[title="managed"]').click();
|
await page.locator('[data-testid="event-types"] a[title="managed"]').click();
|
||||||
await page.locator('[data-testid="vertical-tab-assignment"]').click();
|
await page.locator('[data-testid="vertical-tab-assignment"]').click();
|
||||||
@@ -78,7 +82,8 @@ test.describe("Managed Event Types tests", () => {
|
|||||||
await adminUser.logout();
|
await adminUser.logout();
|
||||||
|
|
||||||
// Coming back as member user to see if there is a managed event present after assignment
|
// Coming back as member user to see if there is a managed event present after assignment
|
||||||
await memberUser.login();
|
await memberUser.apiLogin();
|
||||||
|
await page.goto("/event-types");
|
||||||
await page.waitForLoadState("networkidle");
|
await page.waitForLoadState("networkidle");
|
||||||
await expect(page.locator('[data-testid="event-types"] a[title="managed"]')).toBeVisible();
|
await expect(page.locator('[data-testid="event-types"] a[title="managed"]')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ test.describe("Onboarding", () => {
|
|||||||
test.describe("Onboarding v2", () => {
|
test.describe("Onboarding v2", () => {
|
||||||
test("Onboarding Flow", async ({ page, users }) => {
|
test("Onboarding Flow", async ({ page, users }) => {
|
||||||
const user = await users.create({ completedOnboarding: false, name: null });
|
const user = await users.create({ completedOnboarding: false, name: null });
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
|
await page.goto("/getting-started");
|
||||||
// tests whether the user makes it to /getting-started
|
// tests whether the user makes it to /getting-started
|
||||||
// after login with completedOnboarding false
|
// after login with completedOnboarding false
|
||||||
await page.waitForURL("/getting-started");
|
await page.waitForURL("/getting-started");
|
||||||
@@ -76,9 +76,7 @@ test.describe("Onboarding", () => {
|
|||||||
|
|
||||||
const userComplete = await user.self();
|
const userComplete = await user.self();
|
||||||
|
|
||||||
const userCompleteBio = userComplete.bio ? userComplete.bio : "";
|
expect(userComplete.bio?.replace("<p><br></p>", "").length).toBe(0);
|
||||||
|
|
||||||
expect(userCompleteBio.replace("<p><br></p>", "").length).toBe(0);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ testBothBookers.describe("Reschedule Tests", async () => {
|
|||||||
status: BookingStatus.ACCEPTED,
|
status: BookingStatus.ACCEPTED,
|
||||||
});
|
});
|
||||||
|
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto("/bookings/upcoming");
|
await page.goto("/bookings/upcoming");
|
||||||
|
|
||||||
await page.locator('[data-testid="edit_booking"]').nth(0).click();
|
await page.locator('[data-testid="edit_booking"]').nth(0).click();
|
||||||
@@ -39,9 +39,9 @@ testBothBookers.describe("Reschedule Tests", async () => {
|
|||||||
|
|
||||||
const updatedBooking = await booking.self();
|
const updatedBooking = await booking.self();
|
||||||
|
|
||||||
expect(updatedBooking.rescheduled).toBe(true);
|
expect(updatedBooking?.rescheduled).toBe(true);
|
||||||
expect(updatedBooking.cancellationReason).toBe("I can't longer have it");
|
expect(updatedBooking?.cancellationReason).toBe("I can't longer have it");
|
||||||
expect(updatedBooking.status).toBe(BookingStatus.CANCELLED);
|
expect(updatedBooking?.status).toBe(BookingStatus.CANCELLED);
|
||||||
await booking.delete();
|
await booking.delete();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ testBothBookers.describe("Reschedule Tests", async () => {
|
|||||||
rescheduled: true,
|
rescheduled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto("/bookings/cancelled");
|
await page.goto("/bookings/cancelled");
|
||||||
|
|
||||||
const requestRescheduleSentElement = page.locator('[data-testid="request_reschedule_sent"]').nth(1);
|
const requestRescheduleSentElement = page.locator('[data-testid="request_reschedule_sent"]').nth(1);
|
||||||
@@ -117,7 +117,7 @@ testBothBookers.describe("Reschedule Tests", async () => {
|
|||||||
// eslint-disable-next-line playwright/no-skipped-test
|
// eslint-disable-next-line playwright/no-skipped-test
|
||||||
test.skip(!IS_STRIPE_ENABLED, "Skipped as Stripe is not installed");
|
test.skip(!IS_STRIPE_ENABLED, "Skipped as Stripe is not installed");
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await user.getPaymentCredential();
|
await user.getPaymentCredential();
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
const eventType = user.eventTypes.find((e) => e.slug === "paid")!;
|
const eventType = user.eventTypes.find((e) => e.slug === "paid")!;
|
||||||
@@ -158,7 +158,7 @@ testBothBookers.describe("Reschedule Tests", async () => {
|
|||||||
|
|
||||||
test("Paid rescheduling should go to success page", async ({ page, users, bookings, payments }) => {
|
test("Paid rescheduling should go to success page", async ({ page, users, bookings, payments }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await user.getPaymentCredential();
|
await user.getPaymentCredential();
|
||||||
await users.logout();
|
await users.logout();
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
@@ -207,7 +207,7 @@ testBothBookers.describe("Reschedule Tests", async () => {
|
|||||||
const booking = await bookings.create(user.id, user.username, eventType.id, {
|
const booking = await bookings.create(user.id, user.username, eventType.id, {
|
||||||
status: BookingStatus.ACCEPTED,
|
status: BookingStatus.ACCEPTED,
|
||||||
});
|
});
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
|
|
||||||
await page.goto(`/${user.username}/${eventType.slug}?rescheduleUid=${booking.uid}`);
|
await page.goto(`/${user.username}/${eventType.slug}?rescheduleUid=${booking.uid}`);
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ test.describe("Teams", () => {
|
|||||||
test("Can create teams via Wizard", async ({ page, users }) => {
|
test("Can create teams via Wizard", async ({ page, users }) => {
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
const inviteeEmail = `${user.username}+invitee@example.com`;
|
const inviteeEmail = `${user.username}+invitee@example.com`;
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto("/teams");
|
await page.goto("/teams");
|
||||||
|
|
||||||
await test.step("Can create team", async () => {
|
await test.step("Can create team", async () => {
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ test.describe("BOOKING_CREATED", async () => {
|
|||||||
test("add webhook & test that creating an event triggers a webhook call", async ({
|
test("add webhook & test that creating an event triggers a webhook call", async ({
|
||||||
page,
|
page,
|
||||||
users,
|
users,
|
||||||
}, testInfo) => {
|
}, _testInfo) => {
|
||||||
const webhookReceiver = createHttpServer();
|
const webhookReceiver = createHttpServer();
|
||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
const [eventType] = user.eventTypes;
|
const [eventType] = user.eventTypes;
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
await page.goto(`/settings/developer/webhooks`);
|
await page.goto(`/settings/developer/webhooks`);
|
||||||
|
|
||||||
// --- add webhook
|
// --- add webhook
|
||||||
@@ -51,7 +51,8 @@ test.describe("BOOKING_CREATED", async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const [request] = webhookReceiver.requestList;
|
const [request] = webhookReceiver.requestList;
|
||||||
const body = request.body as any;
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const body: any = request.body;
|
||||||
|
|
||||||
// remove dynamic properties that differs depending on where you run the tests
|
// remove dynamic properties that differs depending on where you run the tests
|
||||||
const dynamic = "[redacted/dynamic]";
|
const dynamic = "[redacted/dynamic]";
|
||||||
@@ -153,7 +154,7 @@ test.describe("BOOKING_REJECTED", async () => {
|
|||||||
await bookOptinEvent(page);
|
await bookOptinEvent(page);
|
||||||
|
|
||||||
// --- login as that user
|
// --- login as that user
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
|
|
||||||
await page.goto(`/settings/developer/webhooks`);
|
await page.goto(`/settings/developer/webhooks`);
|
||||||
|
|
||||||
@@ -274,7 +275,7 @@ test.describe("BOOKING_REQUESTED", async () => {
|
|||||||
const user = await users.create();
|
const user = await users.create();
|
||||||
|
|
||||||
// --- login as that user
|
// --- login as that user
|
||||||
await user.login();
|
await user.apiLogin();
|
||||||
|
|
||||||
await page.goto(`/settings/developer/webhooks`);
|
await page.goto(`/settings/developer/webhooks`);
|
||||||
|
|
||||||
@@ -305,6 +306,7 @@ test.describe("BOOKING_REQUESTED", async () => {
|
|||||||
expect(webhookReceiver.requestList.length).toBe(1);
|
expect(webhookReceiver.requestList.length).toBe(1);
|
||||||
});
|
});
|
||||||
const [request] = webhookReceiver.requestList;
|
const [request] = webhookReceiver.requestList;
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const body = request.body as any;
|
const body = request.body as any;
|
||||||
|
|
||||||
// remove dynamic properties that differs depending on where you run the tests
|
// remove dynamic properties that differs depending on where you run the tests
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ test.describe("Wipe my Cal App Test", () => {
|
|||||||
);
|
);
|
||||||
await bookings.create(pro.id, pro.username, eventType.id, {});
|
await bookings.create(pro.id, pro.username, eventType.id, {});
|
||||||
await bookings.create(pro.id, pro.username, eventType.id, {});
|
await bookings.create(pro.id, pro.username, eventType.id, {});
|
||||||
await pro.login();
|
await pro.apiLogin();
|
||||||
await page.goto("/bookings/upcoming");
|
await page.goto("/bookings/upcoming");
|
||||||
await expect(page.locator("data-testid=wipe-today-button")).toBeVisible();
|
await expect(page.locator("data-testid=wipe-today-button")).toBeVisible();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="250" height="144" fill="none"><rect width="245.667" height="144" x="2.333" fill="url(#a)" rx="6"/><path fill="url(#b)" d="M0 0h249.6v144H0z" opacity=".2"/><rect width="180.557" height="105.342" x="34.888" y="18.829" fill="#fff" rx="6.272"/><circle cx="46.771" cy="30.712" r="3.136" fill="#E5E7EB"/><rect width="33.449" height="2.136" x="43.635" y="38.028" fill="#D1D5DB" rx="1.045"/><rect width="25.087" height="2.091" x="43.635" y="44.345" fill="#E5E7EB" rx="1.045"/><rect width="17.087" height="2.091" x="43.635" y="50.617" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="2.091" x="43.635" y="56.889" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="2.091" x="43.635" y="69.432" fill="#D1D5DB" rx="1.045"/><rect width="6.272" height="2.091" x="51.997" y="69.432" fill="#D1D5DB" rx="1.045"/><rect width="6.272" height="2.091" x="60.359" y="69.432" fill="#D1D5DB" rx="1.045"/><rect width="6.272" height="2.091" x="68.722" y="69.432" fill="#D1D5DB" rx="1.045"/><rect width="6.272" height="2.091" x="77.084" y="69.432" fill="#D1D5DB" rx="1.045"/><rect width="6.272" height="2.091" x="85.446" y="69.432" fill="#D1D5DB" rx="1.045"/><rect width="6.272" height="2.091" x="93.808" y="69.432" fill="#D1D5DB" rx="1.045"/><rect width="6.272" height="6.272" x="60.359" y="75.704" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="68.721" y="75.704" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="77.084" y="75.704" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="85.446" y="75.704" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="93.808" y="75.704" fill="#F3F4F6" rx="1.045"/><rect width="6.272" height="6.272" x="43.635" y="86.157" fill="#F3F4F6" rx="1.045"/><rect width="6.272" height="6.272" x="51.997" y="86.157" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="60.359" y="86.157" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="68.721" y="86.157" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="77.084" y="86.157" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="85.446" y="86.157" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="93.808" y="86.157" fill="#F3F4F6" rx="1.045"/><rect width="6.272" height="6.272" x="43.635" y="96.609" fill="#F3F4F6" rx="1.045"/><rect width="6.272" height="6.272" x="51.997" y="96.609" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="60.359" y="96.609" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="68.721" y="96.609" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="77.084" y="96.609" fill="#9CA3AF" rx="1.045"/><rect width="6.272" height="6.272" x="85.446" y="96.609" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="93.808" y="96.609" fill="#F3F4F6" rx="1.045"/><rect width="6.272" height="6.272" x="43.635" y="107.062" fill="#F3F4F6" rx="1.045"/><rect width="6.272" height="6.272" x="51.997" y="107.062" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="60.359" y="107.062" fill="#E5E7EB" rx="1.045"/><rect width="6.272" height="6.272" x="68.721" y="107.062" fill="#E5E7EB" rx="1.045"/><path fill="#E5E7EB" d="M109.487 23.395v96.211h2.091V23.394h-2.091Z" mask="url(#path-4-inside-1_4870_357380)"/><rect width="25.087" height="4.181" x="114.714" y="27.576" fill="#D1D5DB" rx="1.045"/><rect width="25.087" height="6.272" x="114.714" y="35.938" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="114.714" y="46.391" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="114.714" y="56.843" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="114.714" y="67.296" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="114.714" y="77.749" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="114.714" y="88.202" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="4.181" x="148.163" y="27.576" fill="#D1D5DB" rx="1.045"/><rect width="25.087" height="6.272" x="148.163" y="35.938" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="148.163" y="46.391" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="148.163" y="56.843" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="148.163" y="67.296" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="148.163" y="77.749" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="148.163" y="88.202" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="4.181" x="181.611" y="27.576" fill="#D1D5DB" rx="1.045"/><rect width="25.087" height="6.272" x="181.612" y="35.938" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="181.611" y="46.391" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="181.611" y="56.843" fill="#E5E7EB" rx="1.045"/><rect width="25.087" height="6.272" x="181.611" y="67.296" fill="#E5E7EB" rx="1.045"/><rLine truncated
|
||||||
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,60 @@
|
|||||||
|
<svg width="250" height="144" viewBox="0 0 250 144" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<rect x="2" width="245.667" height="144" rx="6" fill="url(#paint0_radial_4870_357167)"/>
|
||||||
|
<rect opacity="0.2" width="249.6" height="144" fill="url(#pattern0)"/>
|
||||||
|
<rect x="34.9768" y="32.5508" width="179.713" height="78.8984" rx="6.57487" fill="white"/>
|
||||||
|
<circle cx="47.0308" cy="44.6048" r="3.28743" fill="#E5E7EB"/>
|
||||||
|
<rect x="43.7434" y="52.2754" width="26.2995" height="2.28743" rx="1.09581" fill="#D1D5DB"/>
|
||||||
|
<rect x="43.7434" y="58.9463" width="18.2995" height="2.19162" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="43.7434" y="65.521" width="10.2995" height="2.19162" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="43.7434" y="72.0957" width="18.2995" height="2.19162" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<path d="M77.7135 36.9341V107.066H79.9051V36.9341H77.7135Z" fill="#E5E7EB" mask="url(#path-4-inside-1_4870_357167)"/>
|
||||||
|
<rect x="87.5757" y="41.3174" width="26.2995" height="2.19162" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="87.5757" y="47.8921" width="8.76649" height="2.19162" rx="1.09581" fill="#D1D5DB"/>
|
||||||
|
<rect x="98.5339" y="47.8921" width="8.76649" height="2.19162" rx="1.09581" fill="#D1D5DB"/>
|
||||||
|
<rect x="109.492" y="47.8921" width="8.76649" height="2.19162" rx="1.09581" fill="#D1D5DB"/>
|
||||||
|
<rect x="120.45" y="47.8921" width="8.76649" height="2.19162" rx="1.09581" fill="#D1D5DB"/>
|
||||||
|
<rect x="131.408" y="47.8921" width="8.76649" height="2.19162" rx="1.09581" fill="#D1D5DB"/>
|
||||||
|
<rect x="142.366" y="47.8921" width="8.76649" height="2.19162" rx="1.09581" fill="#D1D5DB"/>
|
||||||
|
<rect x="153.324" y="47.8921" width="8.76649" height="2.19162" rx="1.09581" fill="#D1D5DB"/>
|
||||||
|
<rect x="109.492" y="54.4668" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="120.45" y="54.4668" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="131.408" y="54.4668" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="142.366" y="54.4668" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="153.324" y="54.4668" width="8.76649" height="8.76649" rx="1.09581" fill="#F3F4F6"/>
|
||||||
|
<rect x="87.5757" y="67.6167" width="8.76649" height="8.76649" rx="1.09581" fill="#F3F4F6"/>
|
||||||
|
<rect x="98.5339" y="67.6167" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="109.492" y="67.6167" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="120.45" y="67.6167" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="131.408" y="67.6167" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="142.366" y="67.6167" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="153.324" y="67.6167" width="8.76649" height="8.76649" rx="1.09581" fill="#F3F4F6"/>
|
||||||
|
<rect x="87.5757" y="80.7666" width="8.76649" height="8.76649" rx="1.09581" fill="#F3F4F6"/>
|
||||||
|
<rect x="98.5339" y="80.7666" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="109.492" y="80.7666" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="120.45" y="80.7666" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="131.408" y="80.7666" width="8.76649" height="8.76649" rx="1.09581" fill="#9CA3AF"/>
|
||||||
|
<rect x="142.366" y="80.7666" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="153.324" y="80.7666" width="8.76649" height="8.76649" rx="1.09581" fill="#F3F4F6"/>
|
||||||
|
<rect x="87.5757" y="93.916" width="8.76649" height="8.76649" rx="1.09581" fill="#F3F4F6"/>
|
||||||
|
<rect x="98.5339" y="93.916" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="109.492" y="93.916" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="120.45" y="93.916" width="8.76649" height="8.76649" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<path d="M169.762 36.9341V107.066H171.953V36.9341H169.762Z" fill="#E5E7EB" mask="url(#path-11-inside-2_4870_357167)"/>
|
||||||
|
<rect x="179.624" y="41.3174" width="26.2995" height="2.19162" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="179.624" y="47.8921" width="26.2995" height="5.47906" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="179.624" y="57.7544" width="26.2995" height="5.47906" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="179.624" y="67.6167" width="26.2995" height="5.47906" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="179.624" y="77.479" width="26.2995" height="5.47906" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="179.624" y="87.3413" width="26.2995" height="5.47906" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<rect x="179.624" y="97.2036" width="26.2995" height="5.47906" rx="1.09581" fill="#E5E7EB"/>
|
||||||
|
<defs>
|
||||||
|
<pattern id="pattern0" patternContentUnits="objectBoundingBox" width="1" height="1">
|
||||||
|
<use xlink:href="#image0_4870_357167" transform="scale(0.00480769 0.00833333)"/>
|
||||||
|
</pattern>
|
||||||
|
<radialGradient id="paint0_radial_4870_357167" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(457.368 -66) rotate(151.954) scale(454.486 744.445)">
|
||||||
|
<stop stop-color="#A2ABBE"/>
|
||||||
|
<stop offset="1" stop-color="#D4D4D5"/>
|
||||||
|
</radialGradient>
|
||||||
|
<image id="image0_4870_357167" width="208" height="120" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAANAAAAB4CAMAAAC0NYzFAAAAWlBMVEX////4+Pj4+Pj4+Pjw8PDw8PDo6Ojg4ODY2NjY2NjQ0NDIyMjAwMC4uLiwsLC4uLjIyMjIyMjU1NTY2Njc3Nzg4ODg4ODk5OTo6Ojo6Ojs7Ozs7Ozu7u709PT32s2WAAAAHnRSTlNISExKTFBQUFhQWGBgYGhoXFhYVFRUUlBPTk5QTEx67T/AAAAjPElEQVR4AUX6R6IjTW8Gaj7giXgRiUyymvr0yx3V/pfZ7jpM4Ifw4PdYhB95kiuLlTNl3v5s7wsXR1OL5IN+ckY4RfsefToFnPn9RXOVE2e6gOs9qsGjAPx4cbB+7HOGZXjx9KuzB/jBCdfjDVpD5mP4I9TvcLpCRvPKnwPOE9lAZ/qiOj0Ab5wrWGRTnEnqViknwYTAdiL41PXp8Mmet1ztAYHF5SQBXFWrhyhWuNPQ17Xz7tUc0OZxnEMd8OySy41KWN3Bt7C8d+GE9OVnZarLHiPiOjPqjpRInGLGtS9w0m/iRVt+f53kKo+KuszceTEbOeoJ+fPU/0G52ulaqxYSeiY9aN9db+MrCjScCvDvZGIa5GscCLwQp+DTme1pqHwcuX6ndBMsdwD22b6mrg8HL41r55nNvelE4LTR2So2PX0T3PkKLxjom9ly4PRjrbQThxosIv8+bJkOioucXui/TbOvryX13ZjMk6XR/G6LOqWuPm9h9jkGcbEdoGkmHO/LWt/LZ3pPsrztuUU+Bmt7LcDlPR9PXCoLLv+Pts873Dk4W08/Gm6wnBOMi8hfpvmU6Zy3zKFY6aXXkpepqWstHlc0CVcJtbsKhvZ0wKnRgyxPu2L9yAmmvHD58w68UmRvRj+lyy1gNWgsxbbHnT7H/vvXcFqHmu0hcXPz7ldGRl2P5YgHecGRLj5Zbk4rssvLQffjZb+ZzSt0y+HK08Ei4IXrJNWWqdOX7j/93/997c8RXdsBuAZkGpIFxkKmvk7dFF44ZI5ebJ7s/qdr6iJ0H3KFt4XWzTEHvHveF19HymI/m7Nh6YO2oi2db4gvVCypxqqeOnsE/tuYpr1+fuCJyhDpke/wsZiOdYHIja9X9+NUiHNvX/B+2oGTPsP9ULMpYUkTzt+/UKnMbq2Bws5y5wMRy3VBdA/kRizDHejVdStjp02n0oC+pQx6vriyUbcR2oVDL0BaHsJzedjFp/a1H7iOGbdw3YN98bb4SLm+HFvGj8HU3eqgPpUYz6CKXgXSdR4NA1cExPBMpItzGbnDRprbcYGM3mir5l8DlmUtPwiHBWsZ41H78fBtwNTtqNQXai1Oujk7X5Z3Oc8nTtA5+hC9mE2WkZ7ZQzM3C4GimVpQGccPJnN5OOwCZ2+VlcGjTgvjDAzJbSZ5Xy6v/VIsxiC2BQuvvUcn8rRTfbTODQTXnSEvJef3d0/ZXrWsjF7qZXcMU2G/K8LPcp3+PvvpN0YLgG23vohhpd1iep/Co/vBD5OmHWqK6gqpP1wugJjg3uIH2ftNrudMjavqlQcGBNvD7y9CL0hoK/vAnM/ZvISdxwxiw2Tj9NAsPd1q5s11Nte4Gy+FFGElaPuuTI4LOpwNGTuWYz/z7hUCYR53MQBi9ukJ2kighxpNh0yZ9kulLdLUfbzy9YprR2vaORnC7FtrLTJ7RuR//ufWPbvcDUwW7WM4Penibq5xJM6nsqc4t1fg2w0uhKMXIeFTB3nrO4M3VgvwFuj27L/7mF+jWM2cJ+ivWE23x1xblXH27c3bKHj10eeKF8rsSMXDkha2LTrmPLnC3qTNfidaHYk9NNSmndBPBs5MYB4/Cvxwdp2eR3rMhhf2s191nAQmTaf2wz6a1ZxUzmTesHJ74OrJQ3qf6+pPH+i4ppfv7Kg9/3LITIgoZ628cLZV51hLvXeVc/aCnj/nyPhSu5m9zLesTJ9aHd7bz+dpncXdBZl+OHsEPftcnMhXBtiDi5OiOx5PH/aj7nOabA0bAUbrvqvfqZuWxFyyb21YpqQGt/3hXWE2d/4PpjjmtPZSHIgVtjp9A9VY3nt5ZhrGbljy2FYRDTiOrgsJfX1suevN+PQ/0/SHOWkv1e86PqinnDL4wimo96bO769czOy4ihcv/Agw7q3p6TM1RecELpguR6gYhFdbVI3jBkaPB33VrTdX15IWg1Y31BuFR2UYQcUUdKhehohL5BSTYa/WuhHuHNLTfjztxbwBE4J36SOjy8K8I07GtcpqQNG9jxXYLnoJ9dnkj9GnBl5Z4NyfGtRT2jOFqa5hz+a11umHc1rqUPQgplsDn6tf+T9SGTQ97EdXYIN4x8OfATCO9ihw1zZ2Z0G+3W/mEI3mnVi8dmGm743Tp5u2lh0Gr8pyEZHqrLrYm9VV+KQONwme7icXFTjA5RPu9H6uJ/fZ8zRdsJkdbSld6ubQ5Jp9oGng7n/F9qTKsRjMNerQF0/VzAXHuVA3D5m+v081v3ykHwwXQsw5pN5F4Aqqe/Ub227IfeE9UA9M82Sf9hWj+xo7DpYWKzkMVDPlKV2dGofjemzSUkdNiCNQntlYf/8O7z1rmZHWxBfnl+CdGz9ce5pciOfpYVFV+7kixCo18MXPWrInFv2QXsBFBkc75zRps9Hg9aIZrtnHXsb2+5vdfyHtlpob2sdpV1yc0pze0aLnaAQdyDkGAek+R2zmkm2t7IG+6qIvbWgO4DCHaQHNlccp7m1cRvZf15QfdyZkOe9LAJkg6tH5K/Aj5qI9x40lN9KEOnD6JPNPx9tuJ3HGt0o9l7cCdx+HbD0WByf/npsH35pqVGiXFPuJamzPbNrjBshx33+3aDo3FYnuVnvG4wJje5HBwUmpuL+Hq3QeV6Qb2YiVaUPHLXIOK16R6a67pI0hr1yZHQ+Bfxd2ThfP07HYgAG89ht8TmNIA8oVe3Vn37Vx4LzZdFo7GD/Ycgbmec5DHc/24zlHPV/XpBcuj4KfGJbFdnF6j/6wMXla4Cqz2/No2vwzp0/3gxy4rvK+QMMDp8veLEXqXOEKt4zg5DpnhlCcUu1oZZ+AiutQxz1ZGimJUZU8D7RpZ9h+VLm0JbZl4tJPYZnmu0Uu38atZ0fvg/QIxe2TMg762AcDQ/twvKIHh1i27u+59wHKj1BnQF+aZRka2hwsemUGH4OGtbJdnu2hd9isT9Ww/DWe56PDeLuuPj45p84FBNc+Fp+kMo5aYI8Jv7/F1ZrrediBBaOumzviyXA4jbYEbq6+sdDvzQ0dXpgO3wM8Ncy4knGlxp7BLVwPh7+sUkLFh1OiRZ0o5lBWPYkPvBkOAS+d8C4TND49Xq9Axcy5Ls4wuGNQqi7s7SHIQv85gMcPubY0LmtZNHf31DnC2SY1x8U3JDwa5uQlwdDIU1o4lhNOCbxgUg3dTJw52j6h4xzhZXmRW1u5Cm0tkLwlxnkeRIsgh8sXdviiaW6vSL8WR7TKSguocLV9cW1GZogfA3Jf0vRyM3jqM+hzGaiDx2rOxQtv6VMegXNVN7UWM3Imp+lFvEThQQurUQdC15zZXprAHlhddRL57hgpdp2CxReXp3BlBLbVBcpuMNoQVDeEQwHXpSF3mdAWi2WoqWTYAAsvddHASczeIz8/P7+/p/Fnvlyg6JLKS64wmcl9GcvT75/HH6aO1mhMgyDmeyseLZ+HvLAavTFnk1fy+0swv7+xB5+GafED6hJD2YxjhR+rvpzRjMs4fqARN5O5DwZsw8qB2bXP2fPP//7vIgc/TgyewMHm2vPBwvYUi1K8pztPgAGW47jwrPVS1ad3aNOct8z/SbcHjjnZXAvOai+fWnSoyfbCvjhu47LNGFbUVJ1PJb767rk3dc7/QjokYN+8qjUDNxczKFCB4eC5HgnHz3JFvrzxAJRz8Obsi2+pFUtdmvnIjL9/FwFMa+xxh9lcDt3IG/pC0OyHLArsrjM1bQmCVX5/FzpCWKArG72i38y//3vKDGotOsi08YJrQK4rhn2GqekU+AGucpqrumZqX9pKLMt1/HjeA49MaP3fDVSYs8lVbnV7rqs5cz4WuvaME8SJXq3e04t9peai3dGsF2LxclF10fPnAWMu0GhzoZ8dbdkfvBZ+FsxV62+OybArFzOEB3oZXUsj1zOtLpxdTg5HTK5sHdhD80K66XoSGfs/qRfPDjVbDOBoaDFdHmYKNnGGqMsNmDeUk7eurmdYZ1g8xuPvN6XL2WMHh4qt2soMgHHd8s/NDtWei5rnngqvZXHFGXnZ+yFbPCb6P//T4Gwfw4iJHnjQbiN13WZ/vCyI3lNTh9yOFSxdeQjf3RCV6zCX+yQNHU0L2+LM4akHZzhJtuP0RX2Z4Mp+dnPP3nKQPa7KKzNw29x7JOVgpJZTMLn3F2/wzGYwhQ6al/G1Nhq0TyxO6PvE39bkFvZHGZG/f8GL/d09+3Lvu6tOoVGfkQNZdLvPVA/zRD1q7GfsBWnjAR7Tn4zjk+idpbl3o9+DoZPTafpSs/dhWLmYacD2o3Sq9suN9zPy/vsGJ6Ob319mzlD9PFCZZvpoU9cRM0Z/TR1hRcaD9GiDSxy+7eIwmS/BO2Ye+gTnWC7HOyJ9GXcIDTnP3m4ZVx854DRuzG7PGQqN6/57ZeJQ4Tv7xnmPI7G8NIJ5MErb4iqvvuQhlweYpAPFK1P5qv/z6g7MBpdvT2hAnt1q2ezQnp4qWDhyWQupz1YDQJu9tz3aj9lm/lpphfV/1li35yj3x4sxPTlZWPRsXqTAjDO80nt6GW0fhNi8G6JVsiQzpnm25Mm+YzlGXMPTbuopbC50x/KR4ICnHpcVWpxz9t3ZJNBcMve7i2WOo8A0mcebuuTOxkn8/j68izwcfKwCMMrVXkidd16wvOkD28kLoHQK9ui5Wg2LeJ/G8gKzy0trz749HZCl7Line truncated
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 17 KiB |
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="250" height="144" fill="none"><rect width="245.667" height="144" x="1.667" fill="url(#a)" rx="6"/><path fill="url(#b)" d="M0 0h249.6v144H0z" opacity=".2"/><rect width="179.533" height="107.246" x="34.734" y="17.877" fill="#fff" rx="6.384"/><circle cx="46.828" cy="29.972" r="3.192" fill="#E5E7EB"/><rect width="34.048" height="2.192" x="43.636" y="37.42" fill="#D1D5DB" rx="1.064"/><rect width="25.536" height="2.128" x="43.636" y="43.868" fill="#E5E7EB" rx="1.064"/><rect width="25.536" height="2.128" x="43.636" y="50.252" fill="#E5E7EB" rx="1.064"/><rect width="25.536" height="2.128" x="43.636" y="56.636" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="2.128" x="43.636" y="69.404" fill="#D1D5DB" rx="1.064"/><rect width="6.384" height="2.128" x="52.149" y="69.404" fill="#D1D5DB" rx="1.064"/><rect width="6.384" height="2.128" x="60.66" y="69.404" fill="#D1D5DB" rx="1.064"/><rect width="6.384" height="2.128" x="69.172" y="69.404" fill="#D1D5DB" rx="1.064"/><rect width="6.384" height="2.128" x="77.684" y="69.404" fill="#D1D5DB" rx="1.064"/><rect width="6.384" height="2.128" x="86.196" y="69.404" fill="#D1D5DB" rx="1.064"/><rect width="6.384" height="2.128" x="94.708" y="69.404" fill="#D1D5DB" rx="1.064"/><rect width="6.384" height="6.384" x="60.66" y="75.788" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="69.172" y="75.788" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="77.684" y="75.788" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="86.196" y="75.788" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="94.708" y="75.788" fill="#F3F4F6" rx="1.064"/><rect width="6.384" height="6.384" x="43.636" y="86.428" fill="#F3F4F6" rx="1.064"/><rect width="6.384" height="6.384" x="52.149" y="86.428" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="60.66" y="86.428" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="69.172" y="86.428" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="77.684" y="86.428" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="86.196" y="86.428" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="94.708" y="86.428" fill="#F3F4F6" rx="1.064"/><rect width="6.384" height="6.384" x="43.636" y="97.068" fill="#F3F4F6" rx="1.064"/><rect width="6.384" height="6.384" x="52.149" y="97.068" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="60.66" y="97.068" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="69.172" y="97.068" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="77.684" y="97.068" fill="#9CA3AF" rx="1.064"/><rect width="6.384" height="6.384" x="86.196" y="97.068" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="94.708" y="97.068" fill="#F3F4F6" rx="1.064"/><rect width="6.384" height="6.384" x="43.636" y="107.708" fill="#F3F4F6" rx="1.064"/><rect width="6.384" height="6.384" x="52.149" y="107.708" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="60.66" y="107.708" fill="#E5E7EB" rx="1.064"/><rect width="6.384" height="6.384" x="69.172" y="107.708" fill="#E5E7EB" rx="1.064"/><path fill="#E5E7EB" d="M110.668 22.524v97.952h2.128V22.524h-2.128Z" mask="url(#path-4-inside-1_4870_357234)"/><g clip-path="url(#c)"><rect width="12.768" height="2.128" x="120.244" y="26.78" fill="#D1D5DB" rx="1.064"/><rect width="12.768" height="2.128" x="137.268" y="26.78" fill="#D1D5DB" rx="1.064"/><rect width="12.768" height="2.128" x="154.292" y="26.78" fill="#D1D5DB" rx="1.064"/><rect width="12.768" height="2.128" x="171.316" y="26.78" fill="#D1D5DB" rx="1.064"/><rect width="12.768" height="2.128" x="188.34" y="26.78" fill="#D1D5DB" rx="1.064"/><path stroke="#E5E7EB" stroke-width=".532" d="M118.116 35.292c0-1.175.953-2.127 2.128-2.127h14.896v6.383h-17.024v-4.256ZM135.14 33.165h17.024v6.384H135.14zM152.164 33.165h17.024v6.384h-17.024zM169.188 33.165h17.024v6.384h-17.024zM186.212 33.165h14.896c1.175 0 2.128.952 2.128 2.127v4.256h-17.024v-6.383ZM118.116 39.548h17.024v6.384h-17.024z"/><path stroke="#E5E7EB" stroke-width=".532" d="M135.14 39.548h17.024v6.384H135.14zM152.164 39.548h17.024v6.384h-17.024zM169.188 39.548h17.024v6.384h-17.024zM186.212 39.548h17.024v6.384h-17.024zM118.116 45.932h17.024v6.384h-17.024zM135.14 45.932h17.024v6.384H135.14zM152.164 45.932h17.024v6.384h-17.024zM169.188 45.932h17.024v6.384h-17.024zM186.212 45.932h17.024v6.384h-17.024zM118.116 52.316h17.024V58.7h-17.024zM135.14 52.316h17.024V58.7H135.14zM152.164 52.316h17.024V58.7h-17.024zM169.188 52.316h17.024V58.7h-17.024zM186.212 52.316h17.024V58.7h-17.024zM118.116 58.7h17.024v6.384h-17.024zM135.14 58.7h17.024v6.384H135.14zM152.164 58.7h17.024v6.384h-17.024zM169.188 58.7h17.024v6.384h-17.024zM186.212 58.7h17.024v6.384h-17.024zM118.116 65.084h17.024v6.384h-17.024zM135.14 65.084h17.024v6.384H135.14zM152.164 65.084h17.024v6.384h-17.024zM169.188 65.084h1Line truncated
|
||||||
|
After Width: | Height: | Size: 19 KiB |
@@ -11,6 +11,7 @@
|
|||||||
"calcom_explained_new_user": "قم بإنهاء إعداد حسابك في {{appName}}! متبقي بضع خطوات فقط لحل جميع مشاكل الجدولة لديك.",
|
"calcom_explained_new_user": "قم بإنهاء إعداد حسابك في {{appName}}! متبقي بضع خطوات فقط لحل جميع مشاكل الجدولة لديك.",
|
||||||
"have_any_questions": "هل لديك أسئلة؟ نحن هنا للمساعدة.",
|
"have_any_questions": "هل لديك أسئلة؟ نحن هنا للمساعدة.",
|
||||||
"reset_password_subject": "{{appName}}: إرشادات إعادة تعيين كلمة المرور",
|
"reset_password_subject": "{{appName}}: إرشادات إعادة تعيين كلمة المرور",
|
||||||
|
"verify_email_banner_button": "إرسال بريد إلكتروني",
|
||||||
"event_declined_subject": "تم الرفض: {{title}} في {{date}}",
|
"event_declined_subject": "تم الرفض: {{title}} في {{date}}",
|
||||||
"event_cancelled_subject": "تم الإلغاء: {{title}} في {{date}}",
|
"event_cancelled_subject": "تم الإلغاء: {{title}} في {{date}}",
|
||||||
"event_request_declined": "تم رفض طلب الحدث الخاص بك",
|
"event_request_declined": "تم رفض طلب الحدث الخاص بك",
|
||||||
@@ -26,6 +27,8 @@
|
|||||||
"rejection_confirmation": "رفض الحجز",
|
"rejection_confirmation": "رفض الحجز",
|
||||||
"manage_this_event": "قم بإدارة هذا الحدث",
|
"manage_this_event": "قم بإدارة هذا الحدث",
|
||||||
"invite_team_member": "دعوة عضو في الفريق",
|
"invite_team_member": "دعوة عضو في الفريق",
|
||||||
|
"invite_team_individual_segment": "دعوة فرد",
|
||||||
|
"invite_team_bulk_segment": "استيراد بحجم جماعي",
|
||||||
"invite_team_notifcation_badge": "دعوة",
|
"invite_team_notifcation_badge": "دعوة",
|
||||||
"your_event_has_been_scheduled": "تم جدولة الحدث الخاص بك",
|
"your_event_has_been_scheduled": "تم جدولة الحدث الخاص بك",
|
||||||
"your_event_has_been_scheduled_recurring": "تم جدولة الحدث المتكرر الخاص بك",
|
"your_event_has_been_scheduled_recurring": "تم جدولة الحدث المتكرر الخاص بك",
|
||||||
@@ -222,6 +225,7 @@
|
|||||||
"go_back_login": "العودة إلى صفحة تسجيل الدخول",
|
"go_back_login": "العودة إلى صفحة تسجيل الدخول",
|
||||||
"error_during_login": "حدث خطأ ما أثناء تسجيل الدخول. ارجع إلى شاشة تسجيل الدخول وحاول مجددًا.",
|
"error_during_login": "حدث خطأ ما أثناء تسجيل الدخول. ارجع إلى شاشة تسجيل الدخول وحاول مجددًا.",
|
||||||
"request_password_reset": "إرسال بريد إلكتروني لإعادة التعيين",
|
"request_password_reset": "إرسال بريد إلكتروني لإعادة التعيين",
|
||||||
|
"send_invite": "إرسال دعوة",
|
||||||
"forgot_password": "هل نسيت كلمة المرور؟",
|
"forgot_password": "هل نسيت كلمة المرور؟",
|
||||||
"forgot": "هل نسيت؟",
|
"forgot": "هل نسيت؟",
|
||||||
"done": "تم",
|
"done": "تم",
|
||||||
@@ -237,6 +241,8 @@
|
|||||||
"set_availability": "تحديد الوقت الذي تكون فيه متاحًا",
|
"set_availability": "تحديد الوقت الذي تكون فيه متاحًا",
|
||||||
"continue_without_calendar": "المتابعة من دون تقويم",
|
"continue_without_calendar": "المتابعة من دون تقويم",
|
||||||
"connect_your_calendar": "ربط التقويم لديك",
|
"connect_your_calendar": "ربط التقويم لديك",
|
||||||
|
"connect_your_video_app": "اربط تطبيقاتك الفيديو الخاصة بك",
|
||||||
|
"connect_your_video_app_instructions": "قم بتوصيل تطبيقات الفيديو لديك لاستخدامها في أنواع الأحداث الخاصة بك.",
|
||||||
"connect_your_calendar_instructions": "اربط التقويم لديك للتحقق تلقائيًا من الأوقات المشغولة والأحداث الجديدة أثناء جدولتها.",
|
"connect_your_calendar_instructions": "اربط التقويم لديك للتحقق تلقائيًا من الأوقات المشغولة والأحداث الجديدة أثناء جدولتها.",
|
||||||
"set_up_later": "الإعداد لاحقًا",
|
"set_up_later": "الإعداد لاحقًا",
|
||||||
"current_time": "الوقت الحالي",
|
"current_time": "الوقت الحالي",
|
||||||
@@ -366,6 +372,7 @@
|
|||||||
"create_webhook": "إنشاء الويب هوك",
|
"create_webhook": "إنشاء الويب هوك",
|
||||||
"booking_cancelled": "تم إلغاء الحجز",
|
"booking_cancelled": "تم إلغاء الحجز",
|
||||||
"booking_rescheduled": "تمت إعادة جدولة الحجز",
|
"booking_rescheduled": "تمت إعادة جدولة الحجز",
|
||||||
|
"recording_ready": "رابط تنزيل التسجيل جاهز",
|
||||||
"booking_created": "تم إنشاء الحجز",
|
"booking_created": "تم إنشاء الحجز",
|
||||||
"meeting_ended": "انتهى الاجتماع",
|
"meeting_ended": "انتهى الاجتماع",
|
||||||
"form_submitted": "تم إرسال النموذج",
|
"form_submitted": "تم إرسال النموذج",
|
||||||
@@ -464,6 +471,7 @@
|
|||||||
"friday": "الجمعة",
|
"friday": "الجمعة",
|
||||||
"saturday": "السبت",
|
"saturday": "السبت",
|
||||||
"sunday": "الأحد",
|
"sunday": "الأحد",
|
||||||
|
"all_booked_today": "تم حجز الكل.",
|
||||||
"slots_load_fail": "تعذر تحميل الفترات الزمنية المتاحة.",
|
"slots_load_fail": "تعذر تحميل الفترات الزمنية المتاحة.",
|
||||||
"additional_guests": "إضافة ضيوف",
|
"additional_guests": "إضافة ضيوف",
|
||||||
"your_name": "اسمك",
|
"your_name": "اسمك",
|
||||||
@@ -623,8 +631,6 @@
|
|||||||
"event_type_created_successfully": "تم إنشاء نوع الحدث {{eventTypeTitle}} بنجاح",
|
"event_type_created_successfully": "تم إنشاء نوع الحدث {{eventTypeTitle}} بنجاح",
|
||||||
"event_type_updated_successfully": "تم تحديث نوع الحدث {{eventTypeTitle}} بنجاح",
|
"event_type_updated_successfully": "تم تحديث نوع الحدث {{eventTypeTitle}} بنجاح",
|
||||||
"event_type_deleted_successfully": "تم حذف نوع الحدث بنجاح",
|
"event_type_deleted_successfully": "تم حذف نوع الحدث بنجاح",
|
||||||
"web3_metamask_added": "تمت إضافة Metamask بنجاح",
|
|
||||||
"web3_metamask_disconnected": "تم فصل Metamask بنجاح",
|
|
||||||
"hours": "الساعات",
|
"hours": "الساعات",
|
||||||
"your_email": "بريدك الإلكتروني",
|
"your_email": "بريدك الإلكتروني",
|
||||||
"change_avatar": "تغيير الصورة الرمزية",
|
"change_avatar": "تغيير الصورة الرمزية",
|
||||||
@@ -751,6 +757,10 @@
|
|||||||
"new_event_type_to_book_description": "قم بإنشاء نوع حدث جديد ليحجز الأشخاص من خلاله.",
|
"new_event_type_to_book_description": "قم بإنشاء نوع حدث جديد ليحجز الأشخاص من خلاله.",
|
||||||
"length": "الطول",
|
"length": "الطول",
|
||||||
"minimum_booking_notice": "الحد الأدنى من الوقت للحجز",
|
"minimum_booking_notice": "الحد الأدنى من الوقت للحجز",
|
||||||
|
"offset_toggle": "أوقات بدء الإزاحة",
|
||||||
|
"offset_toggle_description": "إزاحة الفتحات الزمنية المعروضة للحاجزين بعدد محدد من الدقائق",
|
||||||
|
"offset_start": "إزاحة بمقدار",
|
||||||
|
"offset_start_description": "على سبيل المثال، هذا سيُظهر فتحات زمنية لمن يقوم بالحجز لديك {{ adjustedTime }} بدلاً من {{ originalTime }}",
|
||||||
"slot_interval": "الفترات الزمنية بين عمليات الحجز",
|
"slot_interval": "الفترات الزمنية بين عمليات الحجز",
|
||||||
"slot_interval_default": "استخدام طول الحدث (الوضع الافتراضي)",
|
"slot_interval_default": "استخدام طول الحدث (الوضع الافتراضي)",
|
||||||
"delete_event_type": "هل تريد حذف نوع الحدث؟",
|
"delete_event_type": "هل تريد حذف نوع الحدث؟",
|
||||||
@@ -861,7 +871,6 @@
|
|||||||
"installed_one": "تم التثبيت",
|
"installed_one": "تم التثبيت",
|
||||||
"installed_other": "{{count}} مثبت",
|
"installed_other": "{{count}} مثبت",
|
||||||
"verify_wallet": "تأكيد المحفظة",
|
"verify_wallet": "تأكيد المحفظة",
|
||||||
"connect_metamask": "توصيل Metamask",
|
|
||||||
"create_events_on": "إنشاء أحداث في",
|
"create_events_on": "إنشاء أحداث في",
|
||||||
"enterprise_license": "هذه هي ميزة للمؤسسات",
|
"enterprise_license": "هذه هي ميزة للمؤسسات",
|
||||||
"enterprise_license_description": "لتمكين هذه الميزة، احصل على مفتاح نشر في وحدة التحكم {{consoleUrl}} وأضفه إلى وحدة التحكم الخاصة بك. nv باسم CALCOM_LICENSE_KEY. إذا كان لدى فريقك بالفعل ترخيص، يرجى الاتصال بـ {{supportMail}} للحصول على المساعدة.",
|
"enterprise_license_description": "لتمكين هذه الميزة، احصل على مفتاح نشر في وحدة التحكم {{consoleUrl}} وأضفه إلى وحدة التحكم الخاصة بك. nv باسم CALCOM_LICENSE_KEY. إذا كان لدى فريقك بالفعل ترخيص، يرجى الاتصال بـ {{supportMail}} للحصول على المساعدة.",
|
||||||
@@ -887,6 +896,7 @@
|
|||||||
"availability_updated_successfully": "تم تحديث جدول {{scheduleName}} بنجاح",
|
"availability_updated_successfully": "تم تحديث جدول {{scheduleName}} بنجاح",
|
||||||
"schedule_deleted_successfully": "تم حذف الجدول بنجاح",
|
"schedule_deleted_successfully": "تم حذف الجدول بنجاح",
|
||||||
"default_schedule_name": "ساعات العمل",
|
"default_schedule_name": "ساعات العمل",
|
||||||
|
"member_default_schedule": "الجدول الزمني الافتراضي للعضو",
|
||||||
"new_schedule_heading": "إنشاء جدول الأوقات المتاحة",
|
"new_schedule_heading": "إنشاء جدول الأوقات المتاحة",
|
||||||
"new_schedule_description": "إن إنشاء جداول الأوقات المتاحة يتيح لك إدارة الأوقات المتاحة عبر أنواع الأحداث. يمكن تطبيقها على نوع أو أكثر من أنواع الأحداث.",
|
"new_schedule_description": "إن إنشاء جداول الأوقات المتاحة يتيح لك إدارة الأوقات المتاحة عبر أنواع الأحداث. يمكن تطبيقها على نوع أو أكثر من أنواع الأحداث.",
|
||||||
"requires_ownership_of_a_token": "يتطلب امتلاك token يخص العنوان التالي:",
|
"requires_ownership_of_a_token": "يتطلب امتلاك token يخص العنوان التالي:",
|
||||||
@@ -903,6 +913,7 @@
|
|||||||
"duplicate": "تكرار",
|
"duplicate": "تكرار",
|
||||||
"offer_seats": "عرض مقاعد",
|
"offer_seats": "عرض مقاعد",
|
||||||
"offer_seats_description": "عرض مقاعد للحجز. هذا يعطل تلقائياً حجز الضيوف وحجز الاشتراك.",
|
"offer_seats_description": "عرض مقاعد للحجز. هذا يعطل تلقائياً حجز الضيوف وحجز الاشتراك.",
|
||||||
|
"seats_available_one": "المقاعد المتاحة",
|
||||||
"seats_available_other": "المقاعد المتاحة",
|
"seats_available_other": "المقاعد المتاحة",
|
||||||
"number_of_seats": "عدد المقاعد لكل حجز",
|
"number_of_seats": "عدد المقاعد لكل حجز",
|
||||||
"enter_number_of_seats": "أدخل عدد المقاعد",
|
"enter_number_of_seats": "أدخل عدد المقاعد",
|
||||||
@@ -1037,7 +1048,7 @@
|
|||||||
"event_cancelled_trigger": "متى تم إلغاء هذا الحدث",
|
"event_cancelled_trigger": "متى تم إلغاء هذا الحدث",
|
||||||
"new_event_trigger": "متى تم حجز الحدث الجديد",
|
"new_event_trigger": "متى تم حجز الحدث الجديد",
|
||||||
"email_host_action": "إرسال رسالة إلكترونية إلى المضيف",
|
"email_host_action": "إرسال رسالة إلكترونية إلى المضيف",
|
||||||
"sms_attendee_action": "إرسال رسالة نصية قصيرة إلى واحد من الحضور",
|
"email_attendee_action": "إرسال رسالة إلكترونية إلى الحضور",
|
||||||
"sms_number_action": "إرسال رسالة نصية قصيرة إلى رقم محدد",
|
"sms_number_action": "إرسال رسالة نصية قصيرة إلى رقم محدد",
|
||||||
"workflows": "سير العمل",
|
"workflows": "سير العمل",
|
||||||
"new_workflow_btn": "سير عمل جديد",
|
"new_workflow_btn": "سير عمل جديد",
|
||||||
@@ -1189,6 +1200,7 @@
|
|||||||
"create_workflow": "إنشاء سير عمل",
|
"create_workflow": "إنشاء سير عمل",
|
||||||
"do_this": "افعل هذا",
|
"do_this": "افعل هذا",
|
||||||
"turn_off": "إيقاف التشغيل",
|
"turn_off": "إيقاف التشغيل",
|
||||||
|
"turn_on": "تشغيل",
|
||||||
"settings_updated_successfully": "تم تحديث الإعدادات بنجاح",
|
"settings_updated_successfully": "تم تحديث الإعدادات بنجاح",
|
||||||
"error_updating_settings": "خطأ في تحديث الإعدادات",
|
"error_updating_settings": "خطأ في تحديث الإعدادات",
|
||||||
"personal_cal_url": "عنوان {{appName}} URL الخاص بي",
|
"personal_cal_url": "عنوان {{appName}} URL الخاص بي",
|
||||||
@@ -1213,11 +1225,6 @@
|
|||||||
"upload": "تحميل",
|
"upload": "تحميل",
|
||||||
"add_profile_photo": "إضافة صورة الملف الشخصي",
|
"add_profile_photo": "إضافة صورة الملف الشخصي",
|
||||||
"web3": "Web3",
|
"web3": "Web3",
|
||||||
"rainbow_token_gated": "يتم فتح هذا النوع من الأحداث برمز مميز.",
|
|
||||||
"rainbow_connect_wallet_gate": "قم بربط محفظتك إذا كنت تملك <1>{{name}}</1> (<3>{{symbol}}</3>).",
|
|
||||||
"rainbow_insufficient_balance": "لا تحتوي محفظتك المربوطة على ما يكفي من <1>{{symbol}}</1>.",
|
|
||||||
"rainbow_sign_message_request": "قم بتوقيع طلب الرسالة على محفظتك.",
|
|
||||||
"rainbow_signature_error": "خطأ في طلب التوقيع من محفظتك.",
|
|
||||||
"token_address": "عنوان الرمز المميز",
|
"token_address": "عنوان الرمز المميز",
|
||||||
"blockchain": "سلسلة الكتل",
|
"blockchain": "سلسلة الكتل",
|
||||||
"old_password": "كلمة مرور قديمة",
|
"old_password": "كلمة مرور قديمة",
|
||||||
@@ -1245,6 +1252,7 @@
|
|||||||
"calendars_description": "قم بتهيئة كيفية تفاعل أنواع الأحداث مع التقويمات الخاصة بك",
|
"calendars_description": "قم بتهيئة كيفية تفاعل أنواع الأحداث مع التقويمات الخاصة بك",
|
||||||
"appearance_description": "إدارة إعدادات مظهر الحجز الخاص بك",
|
"appearance_description": "إدارة إعدادات مظهر الحجز الخاص بك",
|
||||||
"conferencing_description": "أضف تطبيقات مؤتمرات الفيديو المفضلة لديك لاجتماعاتك",
|
"conferencing_description": "أضف تطبيقات مؤتمرات الفيديو المفضلة لديك لاجتماعاتك",
|
||||||
|
"add_conferencing_app": "إضافة تطبيق عقد اجتماعات",
|
||||||
"password_description": "إدارة إعدادات كلمات مرور حسابك",
|
"password_description": "إدارة إعدادات كلمات مرور حسابك",
|
||||||
"2fa_description": "إدارة إعدادات كلمات مرور حسابك",
|
"2fa_description": "إدارة إعدادات كلمات مرور حسابك",
|
||||||
"we_just_need_basic_info": "نحتاج إلى بعض المعلومات الأساسية لإعداد ملفك الشخصي.",
|
"we_just_need_basic_info": "نحتاج إلى بعض المعلومات الأساسية لإعداد ملفك الشخصي.",
|
||||||
@@ -1279,7 +1287,6 @@
|
|||||||
"download_responses_description": "تنزيل جميع الردود إلى النموذج بتنسيق CSV.",
|
"download_responses_description": "تنزيل جميع الردود إلى النموذج بتنسيق CSV.",
|
||||||
"download": "التنزيل",
|
"download": "التنزيل",
|
||||||
"download_recording": "تنزيل التسجيل",
|
"download_recording": "تنزيل التسجيل",
|
||||||
"recording_from_your_recent_call": "تسجيل من مكالمتك الأخيرة على Cal.com جاهز للتنزيل",
|
|
||||||
"create_your_first_form": "إنشاء أول استمارة",
|
"create_your_first_form": "إنشاء أول استمارة",
|
||||||
"create_your_first_form_description": "باستخدام نماذج المسارات، يمكنك طرح أسئلة التأهيل والتوجيه إلى الشخص/نوع الحدث المناسب.",
|
"create_your_first_form_description": "باستخدام نماذج المسارات، يمكنك طرح أسئلة التأهيل والتوجيه إلى الشخص/نوع الحدث المناسب.",
|
||||||
"create_your_first_webhook": "إنشاء أول Webhook",
|
"create_your_first_webhook": "إنشاء أول Webhook",
|
||||||
@@ -1325,7 +1332,7 @@
|
|||||||
"exchange_version_2013_SP1": "2013 SP1",
|
"exchange_version_2013_SP1": "2013 SP1",
|
||||||
"exchange_version_2015": "2015",
|
"exchange_version_2015": "2015",
|
||||||
"exchange_version_2016": "2016",
|
"exchange_version_2016": "2016",
|
||||||
"routing_forms_description": "يمكنك رؤية جميع النماذج والتوجيهات التي أنشأتها هنا.",
|
"routing_forms_description": "أنشئ النماذج لتوجيه الحضور إلى الوجهات الصحيحة",
|
||||||
"routing_forms_send_email_owner": "إرسال رسالة إلكترونية إلى المالك",
|
"routing_forms_send_email_owner": "إرسال رسالة إلكترونية إلى المالك",
|
||||||
"routing_forms_send_email_owner_description": "يرسل رسالة بريد إلكتروني إلى المالك عند إرسال النموذج",
|
"routing_forms_send_email_owner_description": "يرسل رسالة بريد إلكتروني إلى المالك عند إرسال النموذج",
|
||||||
"add_new_form": "إضافة استمارة جديدة",
|
"add_new_form": "إضافة استمارة جديدة",
|
||||||
@@ -1362,7 +1369,6 @@
|
|||||||
"password_updated": "تم تحديث كلمة المرور!",
|
"password_updated": "تم تحديث كلمة المرور!",
|
||||||
"pending_payment": "في انتظار الدفع",
|
"pending_payment": "في انتظار الدفع",
|
||||||
"pending_invites": "دعوات معلقة",
|
"pending_invites": "دعوات معلقة",
|
||||||
"confirmation_page_rainbow": "قم بتعيين رمز مميز لفتح الحدث الخاص بك باستخدام الرموز أو NFTs على Ethereum وPolygon وغيرها.",
|
|
||||||
"not_on_cal": "غير موجود على {{appName}}",
|
"not_on_cal": "غير موجود على {{appName}}",
|
||||||
"no_calendar_installed": "لا يوجد تقويم مثبت",
|
"no_calendar_installed": "لا يوجد تقويم مثبت",
|
||||||
"no_calendar_installed_description": "لم تقم بربط أي من التقويمات الخاصة بك",
|
"no_calendar_installed_description": "لم تقم بربط أي من التقويمات الخاصة بك",
|
||||||
@@ -1476,8 +1482,6 @@
|
|||||||
"find_the_best_person": "ابحث عن أفضل شخص متاح وابحث بالترتيب بين أعضاء فريقك.",
|
"find_the_best_person": "ابحث عن أفضل شخص متاح وابحث بالترتيب بين أعضاء فريقك.",
|
||||||
"fixed_round_robin": "جدولة دوارة",
|
"fixed_round_robin": "جدولة دوارة",
|
||||||
"add_one_fixed_attendee": "أضف حاضرًا ثابتًا وجدولة دوارة عبر عدد من الحاضرين.",
|
"add_one_fixed_attendee": "أضف حاضرًا ثابتًا وجدولة دوارة عبر عدد من الحاضرين.",
|
||||||
"calcom_is_better_with_team": "يعمل Cal.com أفضل مع الفرق",
|
|
||||||
"the_calcom_team": "فريق Cal.com",
|
|
||||||
"add_your_team_members": "أضف أعضاء فريقك إلى أنواع الأحداث الخاصة بك. استخدم الجدولة الجماعية لإدراج الجميع أو العثور على أنسب شخص باستخدام الجدولة الدوارة.",
|
"add_your_team_members": "أضف أعضاء فريقك إلى أنواع الأحداث الخاصة بك. استخدم الجدولة الجماعية لإدراج الجميع أو العثور على أنسب شخص باستخدام الجدولة الدوارة.",
|
||||||
"booking_limit_reached": "تم الوصول إلى الحد الأقصى للحجز لهذا النوع من الأحداث",
|
"booking_limit_reached": "تم الوصول إلى الحد الأقصى للحجز لهذا النوع من الأحداث",
|
||||||
"duration_limit_reached": "تم الوصول إلى الحد الأقصى لمدة الحجز لهذا النوع من الأحداث",
|
"duration_limit_reached": "تم الوصول إلى الحد الأقصى لمدة الحجز لهذا النوع من الأحداث",
|
||||||
@@ -1496,7 +1500,6 @@
|
|||||||
"navigate_installed_apps": "الذهاب إلى التطبيقات المثبتة",
|
"navigate_installed_apps": "الذهاب إلى التطبيقات المثبتة",
|
||||||
"disabled_calendar": "إذا كان لديك تقويم آخر مثبت، ستُضاف الحجوزات الجديدة إليه. إذا لم يكن الأمر كذلك، قم بتوصيل تقويم جديد حتى لا تفوت أي حجوزات جديدة.",
|
"disabled_calendar": "إذا كان لديك تقويم آخر مثبت، ستُضاف الحجوزات الجديدة إليه. إذا لم يكن الأمر كذلك، قم بتوصيل تقويم جديد حتى لا تفوت أي حجوزات جديدة.",
|
||||||
"enable_apps": "تمكين التطبيقات",
|
"enable_apps": "تمكين التطبيقات",
|
||||||
"enable_apps_description": "تمكين التطبيقات التي يمكن للمستخدمين دمجها مع Cal.com",
|
|
||||||
"purchase_license": "شراء ترخيص",
|
"purchase_license": "شراء ترخيص",
|
||||||
"already_have_key": "لدي مفتاح بالفعل:",
|
"already_have_key": "لدي مفتاح بالفعل:",
|
||||||
"already_have_key_suggestion": "يرجى نسخ متغير البيئة الحالي CALCOM_LICENSE_KEY هنا.",
|
"already_have_key_suggestion": "يرجى نسخ متغير البيئة الحالي CALCOM_LICENSE_KEY هنا.",
|
||||||
@@ -1619,6 +1622,7 @@
|
|||||||
"email_user_cta": "عرض الدعوة",
|
"email_user_cta": "عرض الدعوة",
|
||||||
"email_no_user_invite_heading": "لقد تمت دعوتك للانضمام إلى فريق في {{appName}}",
|
"email_no_user_invite_heading": "لقد تمت دعوتك للانضمام إلى فريق في {{appName}}",
|
||||||
"email_no_user_invite_subheading": "دعاك {{invitedBy}} للانضمام إلى فريقه على {{appName}}. إن {{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_invite_steps_intro": "سنرشدك خلال بضع خطوات قصيرة وستستمتع بجدولة خالية من الإجهاد مع فريقك وسريعة.",
|
||||||
"email_no_user_step_one": "اختر اسم المستخدم الخاص بك",
|
"email_no_user_step_one": "اختر اسم المستخدم الخاص بك",
|
||||||
"email_no_user_step_two": "ربط حساب التقويم الخاص بك",
|
"email_no_user_step_two": "ربط حساب التقويم الخاص بك",
|
||||||
@@ -1694,6 +1698,15 @@
|
|||||||
"spot_popular_event_types_description": "تعرف أي أنواع من الأحداث لديك تتلقى أكبر عدد من النقرات والحجوزات",
|
"spot_popular_event_types_description": "تعرف أي أنواع من الأحداث لديك تتلقى أكبر عدد من النقرات والحجوزات",
|
||||||
"no_responses_yet": "لا توجد ردود بعد",
|
"no_responses_yet": "لا توجد ردود بعد",
|
||||||
"this_will_be_the_placeholder": "سيكون هذا هو العنصر النائب",
|
"this_will_be_the_placeholder": "سيكون هذا هو العنصر النائب",
|
||||||
|
"error_booking_event": "حدث خطأ عند حجز الحدث، الرجاء تحديث الصفحة والمحاولة ثانيةً",
|
||||||
|
"timeslot_missing_title": "لم يتم تحديد مساحة زمنية",
|
||||||
|
"timeslot_missing_description": "الرجاء تحديد فترة زمنية لحجز الحدث.",
|
||||||
|
"timeslot_missing_cta": "حدد الوقت",
|
||||||
|
"switch_monthly": "التبديل إلى العرض الشهري",
|
||||||
|
"switch_weekly": "التبديل إلى العرض الأسبوعي",
|
||||||
|
"switch_multiday": "التبديل إلى العرض اليومي",
|
||||||
|
"num_locations": "خيارات الموقع {{num}}",
|
||||||
|
"select_on_next_step": "حدد في الخطوة التالية",
|
||||||
"this_meeting_has_not_started_yet": "لم يبدأ هذا الاجتماع بعد",
|
"this_meeting_has_not_started_yet": "لم يبدأ هذا الاجتماع بعد",
|
||||||
"this_app_requires_connected_account": "{{appName}} يتطلب حساب {{dependencyName}} متصل",
|
"this_app_requires_connected_account": "{{appName}} يتطلب حساب {{dependencyName}} متصل",
|
||||||
"connect_app": "اتصال {{dependencyName}}",
|
"connect_app": "اتصال {{dependencyName}}",
|
||||||
@@ -1723,6 +1736,7 @@
|
|||||||
"locked_apps_description": "سيتمكن الأعضاء من رؤية التطبيقات النشطة، ولكن لن يتمكنوا من تعديل أي إعدادات للتطبيق",
|
"locked_apps_description": "سيتمكن الأعضاء من رؤية التطبيقات النشطة، ولكن لن يتمكنوا من تعديل أي إعدادات للتطبيق",
|
||||||
"locked_webhooks_description": "سيكون الأعضاء قادرين على رؤية webhooks النشطة، ولكن من دون القدرة على تعديل أي إعدادات Webhook",
|
"locked_webhooks_description": "سيكون الأعضاء قادرين على رؤية webhooks النشطة، ولكن من دون القدرة على تعديل أي إعدادات Webhook",
|
||||||
"locked_workflows_description": "سيكون الأعضاء قادرين على رؤية مسارات العمل النشطة، ولكن من دون القدرة على تعديل أي إعدادات لمسار العمل",
|
"locked_workflows_description": "سيكون الأعضاء قادرين على رؤية مسارات العمل النشطة، ولكن من دون القدرة على تعديل أي إعدادات لمسار العمل",
|
||||||
|
"locked_by_admin": "مقفل من قبل المشرف",
|
||||||
"app_not_connected": "أنت غير متصل بحساب {{appName}}.",
|
"app_not_connected": "أنت غير متصل بحساب {{appName}}.",
|
||||||
"connect_now": "اتصل الآن",
|
"connect_now": "اتصل الآن",
|
||||||
"managed_event_dialog_confirm_button_one": "الاستبدال وإخطار {{count}} عضو",
|
"managed_event_dialog_confirm_button_one": "الاستبدال وإخطار {{count}} عضو",
|
||||||
@@ -1780,5 +1794,35 @@
|
|||||||
"seats_and_no_show_fee_error": "لا يمكن حاليًا تمكين المقاعد وفرض رسوم عدم الحضور",
|
"seats_and_no_show_fee_error": "لا يمكن حاليًا تمكين المقاعد وفرض رسوم عدم الحضور",
|
||||||
"complete_your_booking": "أكمل الحجز",
|
"complete_your_booking": "أكمل الحجز",
|
||||||
"complete_your_booking_subject": "أكمل الحجز: {{title}} في {{date}}",
|
"complete_your_booking_subject": "أكمل الحجز: {{title}} في {{date}}",
|
||||||
"email_invite_team": "تم دعوة {{email}}"
|
"confirm_your_details": "تأكيد التفاصيل الخاصة بك",
|
||||||
|
"never_expire": "لا تنتهي الصلاحية أبدًا",
|
||||||
|
"currency_string": "{{amount, currency}}",
|
||||||
|
"charge_card_dialog_body": "أنت على وشك استحصال مبلغ {{amount, currency}} من أحد الحضور. هل أنت متأكد من أنك تريد المتابعة؟",
|
||||||
|
"charge_attendee": "استحصال مبلغ {{amount, currency}} من أحد الحضور",
|
||||||
|
"payment_app_commission": "يتطلب الدفع ({{paymentFeePercentage}}% + {{fee, currency}} عمولة لكل معاملة)",
|
||||||
|
"email_invite_team": "تم دعوة {{email}}",
|
||||||
|
"email_invite_team_bulk": "{{userCount}} مستخدم تم دعوتهم",
|
||||||
|
"error_collecting_card": "خطأ في تحصيل البطاقة",
|
||||||
|
"image_size_limit_exceed": "لا ينبغي أن تتجاوز الصورة التي تم تحميلها الحد الأقصى لحجم 5 ميغابايت",
|
||||||
|
"inline_embed": "Inline Embed",
|
||||||
|
"load_inline_content": "يحمّل نوع الحدث الخاص بك مباشرة مع محتوى موقعك الأخير.",
|
||||||
|
"floating_pop_up_button": "زر منبثق عائم",
|
||||||
|
"floating_button_trigger_modal": "يضع زرًا عائمًا على موقعك يقوم بتشغيل توجيه مع نوع الحدث الخاص بك.",
|
||||||
|
"pop_up_element_click": "ينبثق عبر النقر على العنصر",
|
||||||
|
"open_dialog_with_element_click": "افتح مربع الحوار الخاص بك عندما ينقر شخص على عنصر ما.",
|
||||||
|
"need_help_embedding": "بحاجة إلى مساعدة؟ راجع أدلتنا لإدراج Cal على Wix، Squarespace، أو WordPress، تحقق من أسئلتنا المشتركة، أو استكشف خيارات متقدمة متضمنة.",
|
||||||
|
"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": "تعطيل رسائل التأكيد الافتراضية لمضيف",
|
||||||
|
"disable_host_confirmation_emails_description": "يوجد مسار عمل واحد على الأقل نشط في هذا النوع من الأحداث يقوم بإرسال رسائل إلكترونية إلى المضيف عند حجز الحدث.",
|
||||||
|
"add_an_override": "إضافة تجاوز",
|
||||||
|
"import_from_google_workspace": "استيراد المستخدمين من مساحة عمل Google",
|
||||||
|
"connect_google_workspace": "ربط مساحة عمل Google",
|
||||||
|
"google_workspace_admin_tooltip": "يجب أن تكون مشرفًا على مساحة العمل لاستخدام هذه الميزة",
|
||||||
|
"first_event_type_webhook_description": "قم بإنشاء أول شبكة ويب هوك لهذا النوع من الفعاليات",
|
||||||
|
"create_for": "إنشاء من أجل"
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"awaiting_payment_subject": "Esperant el pagament: {{title}} el {{date}}",
|
||||||
|
"help": "Ajuda",
|
||||||
|
"price": "Preu",
|
||||||
|
"paid": "Pagat",
|
||||||
|
"refunded": "Reembossat",
|
||||||
|
"payment": "Pagament",
|
||||||
|
"missing_card_fields": "Falten camps de la targeta",
|
||||||
|
"pay_now": "Paga ara",
|
||||||
|
"codebase_has_to_stay_opensource": "El codi font ha de seguir com codi obert, tant si s'ha modificat com si no",
|
||||||
|
"cannot_repackage_codebase": "No pots tornar a empaquetar ni vendre el codi font",
|
||||||
|
"acquire_license": "Adquireix una llicència comercial per eliminar aquests termes mitjançant un correu electrònic",
|
||||||
|
"terms_summary": "Resum dels termes",
|
||||||
|
"open_env": "Obre .env i accepta la nostra llicència",
|
||||||
|
"env_changed": "He canviat el meu .env",
|
||||||
|
"accept_license": "Accepta la llicència",
|
||||||
|
"still_waiting_for_approval": "Un esdeveniment encara està pendent d'aprovació",
|
||||||
|
"event_is_still_waiting": "La sol·licitud d'esdeveniment encara està pendent: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||||
|
"no_more_results": "No hi ha més resultats",
|
||||||
|
"no_results": "No hi ha resultats",
|
||||||
|
"load_more_results": "Carrega més resultats",
|
||||||
|
"integration_meeting_id": "{{integrationName}} Identificador de la reunió: {{meetingId}}",
|
||||||
|
"confirmed_event_type_subject": "Confirmat: {{eventType}} amb {{name}} el {{date}}"
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
"calcom_explained_new_user": "Dokončete nastavení svého účtu {{appName}}! Jste jen několik kroků od vyřešení všech svých problémů s plánováním.",
|
"calcom_explained_new_user": "Dokončete nastavení svého účtu {{appName}}! Jste jen několik kroků od vyřešení všech svých problémů s plánováním.",
|
||||||
"have_any_questions": "Máte otázky? Jsme tu, abychom vám pomohli.",
|
"have_any_questions": "Máte otázky? Jsme tu, abychom vám pomohli.",
|
||||||
"reset_password_subject": "{{appName}}: Pokyny pro obnovení hesla",
|
"reset_password_subject": "{{appName}}: Pokyny pro obnovení hesla",
|
||||||
|
"verify_email_banner_button": "Odeslat e-mail",
|
||||||
"event_declined_subject": "Odmítnuto: {{title}} v {{date}}",
|
"event_declined_subject": "Odmítnuto: {{title}} v {{date}}",
|
||||||
"event_cancelled_subject": "Zrušeno: {{title}} v {{date}}",
|
"event_cancelled_subject": "Zrušeno: {{title}} v {{date}}",
|
||||||
"event_request_declined": "Žádost o událost byla zamítnuta",
|
"event_request_declined": "Žádost o událost byla zamítnuta",
|
||||||
@@ -26,6 +27,8 @@
|
|||||||
"rejection_confirmation": "Odmítnout rezervaci",
|
"rejection_confirmation": "Odmítnout rezervaci",
|
||||||
"manage_this_event": "Spravovat tuto událost",
|
"manage_this_event": "Spravovat tuto událost",
|
||||||
"invite_team_member": "Pozvat člena týmu",
|
"invite_team_member": "Pozvat člena týmu",
|
||||||
|
"invite_team_individual_segment": "Pozvat jednotlivce",
|
||||||
|
"invite_team_bulk_segment": "Hromadný import",
|
||||||
"invite_team_notifcation_badge": "Pozv.",
|
"invite_team_notifcation_badge": "Pozv.",
|
||||||
"your_event_has_been_scheduled": "Vaše událost byla naplánována",
|
"your_event_has_been_scheduled": "Vaše událost byla naplánována",
|
||||||
"your_event_has_been_scheduled_recurring": "Opakovaná událost byla naplánována",
|
"your_event_has_been_scheduled_recurring": "Opakovaná událost byla naplánována",
|
||||||
@@ -222,6 +225,7 @@
|
|||||||
"go_back_login": "Zpět na přihlašovací stránku",
|
"go_back_login": "Zpět na přihlašovací stránku",
|
||||||
"error_during_login": "Při přihlašování došlo k chybě. Přejděte zpět na přihlašovací obrazovku a zkuste to znovu.",
|
"error_during_login": "Při přihlašování došlo k chybě. Přejděte zpět na přihlašovací obrazovku a zkuste to znovu.",
|
||||||
"request_password_reset": "Žádost o obnovení hesla",
|
"request_password_reset": "Žádost o obnovení hesla",
|
||||||
|
"send_invite": "Odeslat pozvánku",
|
||||||
"forgot_password": "Zapomenuté heslo",
|
"forgot_password": "Zapomenuté heslo",
|
||||||
"forgot": "Zapomněli jste?",
|
"forgot": "Zapomněli jste?",
|
||||||
"done": "Hotovo",
|
"done": "Hotovo",
|
||||||
@@ -237,6 +241,8 @@
|
|||||||
"set_availability": "Nastavte, jak jste dostupní",
|
"set_availability": "Nastavte, jak jste dostupní",
|
||||||
"continue_without_calendar": "Pokračovat bez kalendáře",
|
"continue_without_calendar": "Pokračovat bez kalendáře",
|
||||||
"connect_your_calendar": "Připojit svůj kalendář",
|
"connect_your_calendar": "Připojit svůj kalendář",
|
||||||
|
"connect_your_video_app": "Propojte své video aplikace",
|
||||||
|
"connect_your_video_app_instructions": "Propojte své video aplikace a používejte je v typech událostí.",
|
||||||
"connect_your_calendar_instructions": "Připojit kalendář pro automatickou kontrolu časů, kdy nejste dostupní, a nově naplánovaných událostí.",
|
"connect_your_calendar_instructions": "Připojit kalendář pro automatickou kontrolu časů, kdy nejste dostupní, a nově naplánovaných událostí.",
|
||||||
"set_up_later": "Zprovoznit později",
|
"set_up_later": "Zprovoznit později",
|
||||||
"current_time": "Aktuální čas",
|
"current_time": "Aktuální čas",
|
||||||
@@ -366,6 +372,7 @@
|
|||||||
"create_webhook": "Vytvořit webhook",
|
"create_webhook": "Vytvořit webhook",
|
||||||
"booking_cancelled": "Rezervace zrušena",
|
"booking_cancelled": "Rezervace zrušena",
|
||||||
"booking_rescheduled": "Rezervace přesunuta",
|
"booking_rescheduled": "Rezervace přesunuta",
|
||||||
|
"recording_ready": "Odkaz ke stažení záznamu je připraven",
|
||||||
"booking_created": "Rezervace vytvořena",
|
"booking_created": "Rezervace vytvořena",
|
||||||
"meeting_ended": "Schůzka skončila",
|
"meeting_ended": "Schůzka skončila",
|
||||||
"form_submitted": "Formulář byl odeslán",
|
"form_submitted": "Formulář byl odeslán",
|
||||||
@@ -464,6 +471,7 @@
|
|||||||
"friday": "pátek",
|
"friday": "pátek",
|
||||||
"saturday": "sobota",
|
"saturday": "sobota",
|
||||||
"sunday": "neděle",
|
"sunday": "neděle",
|
||||||
|
"all_booked_today": "Vše zarezervováno.",
|
||||||
"slots_load_fail": "Nepodařilo se načíst dostupné časové sloty.",
|
"slots_load_fail": "Nepodařilo se načíst dostupné časové sloty.",
|
||||||
"additional_guests": "Přidat hosty",
|
"additional_guests": "Přidat hosty",
|
||||||
"your_name": "Vaše jméno",
|
"your_name": "Vaše jméno",
|
||||||
@@ -623,8 +631,6 @@
|
|||||||
"event_type_created_successfully": "Typ události {{eventTypeTitle}} byl úspěšně vytvořen",
|
"event_type_created_successfully": "Typ události {{eventTypeTitle}} byl úspěšně vytvořen",
|
||||||
"event_type_updated_successfully": "Typ události {{eventTypeTitle}} byl úspěšně aktualizován",
|
"event_type_updated_successfully": "Typ události {{eventTypeTitle}} byl úspěšně aktualizován",
|
||||||
"event_type_deleted_successfully": "Typ události byl úspěšně smazán",
|
"event_type_deleted_successfully": "Typ události byl úspěšně smazán",
|
||||||
"web3_metamask_added": "Metamask úspěšně přidán",
|
|
||||||
"web3_metamask_disconnected": "Metamask úspěšně odpojen",
|
|
||||||
"hours": "Hodiny",
|
"hours": "Hodiny",
|
||||||
"your_email": "Váš e-mail",
|
"your_email": "Váš e-mail",
|
||||||
"change_avatar": "Změnit avatar",
|
"change_avatar": "Změnit avatar",
|
||||||
@@ -751,6 +757,10 @@
|
|||||||
"new_event_type_to_book_description": "Vytvořit nový typ události, ve které si lidé mohou rezervovat časy.",
|
"new_event_type_to_book_description": "Vytvořit nový typ události, ve které si lidé mohou rezervovat časy.",
|
||||||
"length": "Doba trvání",
|
"length": "Doba trvání",
|
||||||
"minimum_booking_notice": "Minimální potřebná doba",
|
"minimum_booking_notice": "Minimální potřebná doba",
|
||||||
|
"offset_toggle": "Posunutí časů začátku",
|
||||||
|
"offset_toggle_description": "Posunutí časových slotů zobrazených rezervujícím osobám o zadaný počet minut",
|
||||||
|
"offset_start": "Posunutí o",
|
||||||
|
"offset_start_description": "například v tomto případě se vašim rezervujícím zobrazí časové sloty v {{ adjustedTime }} namísto {{ originalTime }}",
|
||||||
"slot_interval": "Časové intervaly",
|
"slot_interval": "Časové intervaly",
|
||||||
"slot_interval_default": "Použít délku události (výchozí)",
|
"slot_interval_default": "Použít délku události (výchozí)",
|
||||||
"delete_event_type": "Odstranit typ události?",
|
"delete_event_type": "Odstranit typ události?",
|
||||||
@@ -861,7 +871,6 @@
|
|||||||
"installed_one": "Nainstalováno",
|
"installed_one": "Nainstalováno",
|
||||||
"installed_other": "Nainstalováno: {{count}}",
|
"installed_other": "Nainstalováno: {{count}}",
|
||||||
"verify_wallet": "Ověřit peněženku",
|
"verify_wallet": "Ověřit peněženku",
|
||||||
"connect_metamask": "Připojit Metamask",
|
|
||||||
"create_events_on": "Vytvořit události v:",
|
"create_events_on": "Vytvořit události v:",
|
||||||
"enterprise_license": "Jedná se o firemní funkci",
|
"enterprise_license": "Jedná se o firemní funkci",
|
||||||
"enterprise_license_description": "Pokud chcete povolit tuto funkci, získejte klíč pro nasazení v konzoli {{consoleUrl}} a přidejte ho do souboru .env jako CALCOM_LICENSE_KEY. Pokud váš tým již licenci má, kontaktujte prosím {{supportMail}} a požádejte o pomoc.",
|
"enterprise_license_description": "Pokud chcete povolit tuto funkci, získejte klíč pro nasazení v konzoli {{consoleUrl}} a přidejte ho do souboru .env jako CALCOM_LICENSE_KEY. Pokud váš tým již licenci má, kontaktujte prosím {{supportMail}} a požádejte o pomoc.",
|
||||||
@@ -887,6 +896,7 @@
|
|||||||
"availability_updated_successfully": "Plán {{scheduleName}} byl úspěšně aktualizován",
|
"availability_updated_successfully": "Plán {{scheduleName}} byl úspěšně aktualizován",
|
||||||
"schedule_deleted_successfully": "Plán byl úspěšně odstraněn",
|
"schedule_deleted_successfully": "Plán byl úspěšně odstraněn",
|
||||||
"default_schedule_name": "Pracovní doba",
|
"default_schedule_name": "Pracovní doba",
|
||||||
|
"member_default_schedule": "Výchozí rozvrh člena",
|
||||||
"new_schedule_heading": "Vytvořit plán dostupnosti",
|
"new_schedule_heading": "Vytvořit plán dostupnosti",
|
||||||
"new_schedule_description": "Vytvoření plánů dostupnosti vám umožní spravovat dostupnost mezi typy událostí. Mohou být použity pro jeden nebo více typů událostí.",
|
"new_schedule_description": "Vytvoření plánů dostupnosti vám umožní spravovat dostupnost mezi typy událostí. Mohou být použity pro jeden nebo více typů událostí.",
|
||||||
"requires_ownership_of_a_token": "Vyžaduje vlastnictví tokenu, který patří následující adrese:",
|
"requires_ownership_of_a_token": "Vyžaduje vlastnictví tokenu, který patří následující adrese:",
|
||||||
@@ -903,6 +913,7 @@
|
|||||||
"duplicate": "Duplikovat",
|
"duplicate": "Duplikovat",
|
||||||
"offer_seats": "Nabídka míst",
|
"offer_seats": "Nabídka míst",
|
||||||
"offer_seats_description": "Nabídnout místa k rezervaci. Tím se vypnou rezervace hostů a volitelné rezervace.",
|
"offer_seats_description": "Nabídnout místa k rezervaci. Tím se vypnou rezervace hostů a volitelné rezervace.",
|
||||||
|
"seats_available_one": "Dostupné místo",
|
||||||
"seats_available_other": "Dostupná místa",
|
"seats_available_other": "Dostupná místa",
|
||||||
"number_of_seats": "Počet míst na rezervaci",
|
"number_of_seats": "Počet míst na rezervaci",
|
||||||
"enter_number_of_seats": "Zadejte počet míst",
|
"enter_number_of_seats": "Zadejte počet míst",
|
||||||
@@ -1037,7 +1048,7 @@
|
|||||||
"event_cancelled_trigger": "při zrušení události",
|
"event_cancelled_trigger": "při zrušení události",
|
||||||
"new_event_trigger": "při rezervaci nové události",
|
"new_event_trigger": "při rezervaci nové události",
|
||||||
"email_host_action": "odeslání e-mailu hostiteli",
|
"email_host_action": "odeslání e-mailu hostiteli",
|
||||||
"sms_attendee_action": "odeslání SMS účastníkovi",
|
"email_attendee_action": "odeslat e-mail účastníkům",
|
||||||
"sms_number_action": "odeslání SMS na konkrétní číslo",
|
"sms_number_action": "odeslání SMS na konkrétní číslo",
|
||||||
"workflows": "Pracovní postupy",
|
"workflows": "Pracovní postupy",
|
||||||
"new_workflow_btn": "Nový pracovní postup",
|
"new_workflow_btn": "Nový pracovní postup",
|
||||||
@@ -1189,6 +1200,7 @@
|
|||||||
"create_workflow": "Vytvoření pracovního postupu",
|
"create_workflow": "Vytvoření pracovního postupu",
|
||||||
"do_this": "Provést",
|
"do_this": "Provést",
|
||||||
"turn_off": "Vypnout",
|
"turn_off": "Vypnout",
|
||||||
|
"turn_on": "Zapnout",
|
||||||
"settings_updated_successfully": "Nastavení aktualizováno",
|
"settings_updated_successfully": "Nastavení aktualizováno",
|
||||||
"error_updating_settings": "Chyba při aktualizaci nastavení",
|
"error_updating_settings": "Chyba při aktualizaci nastavení",
|
||||||
"personal_cal_url": "Moje osobní adresa URL {{appName}}",
|
"personal_cal_url": "Moje osobní adresa URL {{appName}}",
|
||||||
@@ -1213,11 +1225,6 @@
|
|||||||
"upload": "Nahrát",
|
"upload": "Nahrát",
|
||||||
"add_profile_photo": "Přidat profilovou fotku",
|
"add_profile_photo": "Přidat profilovou fotku",
|
||||||
"web3": "Web3",
|
"web3": "Web3",
|
||||||
"rainbow_token_gated": "Tento typ události je uzamčený tokenem.",
|
|
||||||
"rainbow_connect_wallet_gate": "Propojte svoji peněženku, pokud vlastníte <1>{{name}}</1> (<3>{{symbol}}</3>).",
|
|
||||||
"rainbow_insufficient_balance": "Vaše propojená peněženka neobsahuje dostatek <1>{{symbol}}</1>.",
|
|
||||||
"rainbow_sign_message_request": "Podepište zprávu s požadavkem ve své peněžence.",
|
|
||||||
"rainbow_signature_error": "Chyba při vyžádání podpisu z vaší peněženky.",
|
|
||||||
"token_address": "Adresa tokenu",
|
"token_address": "Adresa tokenu",
|
||||||
"blockchain": "Blockchain",
|
"blockchain": "Blockchain",
|
||||||
"old_password": "Staré heslo",
|
"old_password": "Staré heslo",
|
||||||
@@ -1245,6 +1252,7 @@
|
|||||||
"calendars_description": "Konfigurace způsobu interakce typů událostí s kalendáři",
|
"calendars_description": "Konfigurace způsobu interakce typů událostí s kalendáři",
|
||||||
"appearance_description": "Správa nastavení vzhledu rezervace",
|
"appearance_description": "Správa nastavení vzhledu rezervace",
|
||||||
"conferencing_description": "Přidejte si oblíbené videokonferenční pro vaše schůzky",
|
"conferencing_description": "Přidejte si oblíbené videokonferenční pro vaše schůzky",
|
||||||
|
"add_conferencing_app": "Přidat videokonferenční aplikaci",
|
||||||
"password_description": "Správa nastavení hesel k vašemu účtu",
|
"password_description": "Správa nastavení hesel k vašemu účtu",
|
||||||
"2fa_description": "Správa nastavení hesel k vašemu účtu",
|
"2fa_description": "Správa nastavení hesel k vašemu účtu",
|
||||||
"we_just_need_basic_info": "K nastavení vašeho profilu potřebujeme jen několik základních informací.",
|
"we_just_need_basic_info": "K nastavení vašeho profilu potřebujeme jen několik základních informací.",
|
||||||
@@ -1279,7 +1287,6 @@
|
|||||||
"download_responses_description": "Stáhněte si všechny odpovědi do formuláře ve formátu CSV.",
|
"download_responses_description": "Stáhněte si všechny odpovědi do formuláře ve formátu CSV.",
|
||||||
"download": "Stáhnout",
|
"download": "Stáhnout",
|
||||||
"download_recording": "Stáhnout nahrávku",
|
"download_recording": "Stáhnout nahrávku",
|
||||||
"recording_from_your_recent_call": "Nahrávka z vašeho nedávného hovoru na Cal.com je připravena ke stažení.",
|
|
||||||
"create_your_first_form": "Vytvořte svůj první formulář",
|
"create_your_first_form": "Vytvořte svůj první formulář",
|
||||||
"create_your_first_form_description": "Pomocí adresných formulářů můžete klást kvalifikační otázky a adresovat je správné osobě nebo typu události.",
|
"create_your_first_form_description": "Pomocí adresných formulářů můžete klást kvalifikační otázky a adresovat je správné osobě nebo typu události.",
|
||||||
"create_your_first_webhook": "Vytvořte svůj první webhook",
|
"create_your_first_webhook": "Vytvořte svůj první webhook",
|
||||||
@@ -1362,7 +1369,6 @@
|
|||||||
"password_updated": "Heslo bylo úspěšně změněno!",
|
"password_updated": "Heslo bylo úspěšně změněno!",
|
||||||
"pending_payment": "Čeká se na platbu",
|
"pending_payment": "Čeká se na platbu",
|
||||||
"pending_invites": "Čekající pozvánky",
|
"pending_invites": "Čekající pozvánky",
|
||||||
"confirmation_page_rainbow": "Zamkněte svoji událost pomocí tokenů nebo NFT na platformách Ethereum, Polygon a dalších.",
|
|
||||||
"not_on_cal": "Nenachází se na {{appName}}",
|
"not_on_cal": "Nenachází se na {{appName}}",
|
||||||
"no_calendar_installed": "Není nainstalován kalendář",
|
"no_calendar_installed": "Není nainstalován kalendář",
|
||||||
"no_calendar_installed_description": "Ještě jste nepropojili žádný ze svých kalendářů",
|
"no_calendar_installed_description": "Ještě jste nepropojili žádný ze svých kalendářů",
|
||||||
@@ -1476,8 +1482,6 @@
|
|||||||
"find_the_best_person": "Najděte nejlepší dostupnou osobu a procházejte tým.",
|
"find_the_best_person": "Najděte nejlepší dostupnou osobu a procházejte tým.",
|
||||||
"fixed_round_robin": "Pevný „round robin“",
|
"fixed_round_robin": "Pevný „round robin“",
|
||||||
"add_one_fixed_attendee": "Přidejte jednoho pevně stanoveného účastníka a „round robin“ přes daný počet účastníků.",
|
"add_one_fixed_attendee": "Přidejte jednoho pevně stanoveného účastníka a „round robin“ přes daný počet účastníků.",
|
||||||
"calcom_is_better_with_team": "Cal.com je s týmy lepší",
|
|
||||||
"the_calcom_team": "Tým Cal.com",
|
|
||||||
"add_your_team_members": "Přidejte členy týmu k typům událostí. Použijte kolektivní plánování, abyste zahrnuli všechny, případně vyhledejte tu nejvhodnější osobu s plánováním „round robin“.",
|
"add_your_team_members": "Přidejte členy týmu k typům událostí. Použijte kolektivní plánování, abyste zahrnuli všechny, případně vyhledejte tu nejvhodnější osobu s plánováním „round robin“.",
|
||||||
"booking_limit_reached": "Byl dosažen limit rezervací pro tento typ události",
|
"booking_limit_reached": "Byl dosažen limit rezervací pro tento typ události",
|
||||||
"duration_limit_reached": "Byl dosažen limit doby trvání pro tento typ události",
|
"duration_limit_reached": "Byl dosažen limit doby trvání pro tento typ události",
|
||||||
@@ -1496,7 +1500,6 @@
|
|||||||
"navigate_installed_apps": "Přejděte na nainstalované aplikace",
|
"navigate_installed_apps": "Přejděte na nainstalované aplikace",
|
||||||
"disabled_calendar": "Pokud máte nainstalovaný jiný kalendář, budou do něj přidány nové rezervace. Pokud ne, připojte nový kalendář, abyste nepřišli o žádné nové rezervace.",
|
"disabled_calendar": "Pokud máte nainstalovaný jiný kalendář, budou do něj přidány nové rezervace. Pokud ne, připojte nový kalendář, abyste nepřišli o žádné nové rezervace.",
|
||||||
"enable_apps": "Povolit aplikace",
|
"enable_apps": "Povolit aplikace",
|
||||||
"enable_apps_description": "Povolte aplikace, které mohou uživatelé integrovat s Cal.com",
|
|
||||||
"purchase_license": "Kupte si licenci",
|
"purchase_license": "Kupte si licenci",
|
||||||
"already_have_key": "Klíč již mám:",
|
"already_have_key": "Klíč již mám:",
|
||||||
"already_have_key_suggestion": "Zkopírujte sem svou stávající proměnnou prostředí CALCOM_LICENSE_KEY.",
|
"already_have_key_suggestion": "Zkopírujte sem svou stávající proměnnou prostředí CALCOM_LICENSE_KEY.",
|
||||||
@@ -1619,6 +1622,7 @@
|
|||||||
"email_user_cta": "Zobrazit pozvánku",
|
"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_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_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_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_one": "Vyberte si uživatelské jméno",
|
||||||
"email_no_user_step_two": "Připojte svůj účet kalendáře",
|
"email_no_user_step_two": "Připojte svůj účet kalendáře",
|
||||||
@@ -1694,6 +1698,15 @@
|
|||||||
"spot_popular_event_types_description": "Zjistěte, které typy vašich událostí získávají nejvíce kliknutí a rezervací",
|
"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",
|
"no_responses_yet": "Zatím žádné odpovědi",
|
||||||
"this_will_be_the_placeholder": "Toto bude zástupný znak",
|
"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",
|
||||||
|
"switch_monthly": "Přepnout na měsíční zobrazení",
|
||||||
|
"switch_weekly": "Přepnout na týdenní zobrazení",
|
||||||
|
"switch_multiday": "Přepnout na denní zobrazení",
|
||||||
|
"num_locations": "Možná místa konání: {{num}}",
|
||||||
|
"select_on_next_step": "Vyberte v dalším kroku",
|
||||||
"this_meeting_has_not_started_yet": "Tato schůzka ještě nezačala",
|
"this_meeting_has_not_started_yet": "Tato schůzka ještě nezačala",
|
||||||
"this_app_requires_connected_account": "{{appName}} vyžaduje připojený účet {{dependencyName}}",
|
"this_app_requires_connected_account": "{{appName}} vyžaduje připojený účet {{dependencyName}}",
|
||||||
"connect_app": "Připojit aplikaci {{dependencyName}}",
|
"connect_app": "Připojit aplikaci {{dependencyName}}",
|
||||||
@@ -1723,6 +1736,7 @@
|
|||||||
"locked_apps_description": "Členové uvidí aktivní aplikace, ale nastavení aplikací upravovat nemohou",
|
"locked_apps_description": "Členové uvidí aktivní aplikace, ale nastavení aplikací upravovat nemohou",
|
||||||
"locked_webhooks_description": "Členové uvidí aktivní webhooky, ale nastavení webhooků upravovat nemohou",
|
"locked_webhooks_description": "Členové uvidí aktivní webhooky, ale nastavení webhooků upravovat nemohou",
|
||||||
"locked_workflows_description": "Členové uvidí aktivní pracovní postupy, ale nastavení pracovních postupů upravovat nemohou",
|
"locked_workflows_description": "Členové uvidí aktivní pracovní postupy, ale nastavení pracovních postupů upravovat nemohou",
|
||||||
|
"locked_by_admin": "Uzamčeno správcem týmu",
|
||||||
"app_not_connected": "Nemáte připojený účet {{appName}}.",
|
"app_not_connected": "Nemáte připojený účet {{appName}}.",
|
||||||
"connect_now": "Připojte se",
|
"connect_now": "Připojte se",
|
||||||
"managed_event_dialog_confirm_button_one": "Nahradit a upozornit {{count}} člena",
|
"managed_event_dialog_confirm_button_one": "Nahradit a upozornit {{count}} člena",
|
||||||
@@ -1780,5 +1794,35 @@
|
|||||||
"seats_and_no_show_fee_error": "V současné době nelze povolit místa a strhnout poplatek za nedostavení se",
|
"seats_and_no_show_fee_error": "V současné době nelze povolit místa a strhnout poplatek za nedostavení se",
|
||||||
"complete_your_booking": "Dokončete svou rezervaci",
|
"complete_your_booking": "Dokončete svou rezervaci",
|
||||||
"complete_your_booking_subject": "Dokončete svou rezervaci: {{title}} dne {{date}}",
|
"complete_your_booking_subject": "Dokončete svou rezervaci: {{title}} dne {{date}}",
|
||||||
"email_invite_team": "Pozvánka pro uživatele {{email}} odeslána"
|
"confirm_your_details": "Potvrďte své údaje",
|
||||||
|
"never_expire": "Platnost nikdy neuplyne",
|
||||||
|
"currency_string": "{{amount, currency}}",
|
||||||
|
"charge_card_dialog_body": "Chystáte se účtovat účastníkovi {{amount, currency}}. Opravdu chcete pokračovat?",
|
||||||
|
"charge_attendee": "Naúčtovat účastníkovi {{amount, currency}}",
|
||||||
|
"payment_app_commission": "Vyžadujte platbu ({{paymentFeePercentage}} % + provizi {{fee, currency}} za transakci)",
|
||||||
|
"email_invite_team": "Pozvánka pro uživatele {{email}} odeslána",
|
||||||
|
"email_invite_team_bulk": "Počet pozvaných uživatelů: {{userCount}}",
|
||||||
|
"error_collecting_card": "Chyba při výběru karty",
|
||||||
|
"image_size_limit_exceed": "Velikost nahraného obrázku by neměla překročit limit 5 MB",
|
||||||
|
"inline_embed": "Embed inline",
|
||||||
|
"load_inline_content": "Načte váš typ události přímo „inline“ s ostatním obsahem webu.",
|
||||||
|
"floating_pop_up_button": "Plovoucí překryvné tlačítko",
|
||||||
|
"floating_button_trigger_modal": "Umístí na váš web plovoucí tlačítko, které spustí modální okno s vaším typem události.",
|
||||||
|
"pop_up_element_click": "Překryvné okno při kliknutí na prvek",
|
||||||
|
"open_dialog_with_element_click": "Otevře dialogové okno Cal, pokud někdo klikne na prvek.",
|
||||||
|
"need_help_embedding": "Potřebujete pomoc? Prohlédněte si naše průvodce pro vložení Cal do Wixu, Squarespace nebo WordPressu, podívejte se na naše nejčastější dotazy nebo prozkoumejte pokročilé možnosti vložení.",
|
||||||
|
"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",
|
||||||
|
"disable_host_confirmation_emails_description": "U tohoto typu události je aktivní alespoň jeden pracovní postup, který po rezervaci události odešle hostiteli e-mail.",
|
||||||
|
"add_an_override": "Přidejte změnu",
|
||||||
|
"import_from_google_workspace": "Importovat uživatele z Google Workspace",
|
||||||
|
"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"
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
"calcom_explained_new_user": "Afslut opsætningen af din {{appName}} konto! Du er kun få skridt fra at løse alle dine planlægningsproblemer.",
|
"calcom_explained_new_user": "Afslut opsætningen af din {{appName}} konto! Du er kun få skridt fra at løse alle dine planlægningsproblemer.",
|
||||||
"have_any_questions": "Har du spørgsmål? Vi er her for at hjælpe.",
|
"have_any_questions": "Har du spørgsmål? Vi er her for at hjælpe.",
|
||||||
"reset_password_subject": "{{appName}}: Nulstil adgangskodeinstruktioner",
|
"reset_password_subject": "{{appName}}: Nulstil adgangskodeinstruktioner",
|
||||||
|
"verify_email_banner_button": "Send e-mail",
|
||||||
"event_declined_subject": "Afvist: {{title}} den {{date}}",
|
"event_declined_subject": "Afvist: {{title}} den {{date}}",
|
||||||
"event_cancelled_subject": "Aflyst: {{title}} den {{date}}",
|
"event_cancelled_subject": "Aflyst: {{title}} den {{date}}",
|
||||||
"event_request_declined": "Din begivenhedsanmodning er blevet afvist",
|
"event_request_declined": "Din begivenhedsanmodning er blevet afvist",
|
||||||
@@ -601,8 +602,6 @@
|
|||||||
"event_type_created_successfully": "{{eventTypeTitle}} begivenhedstype blev oprettet",
|
"event_type_created_successfully": "{{eventTypeTitle}} begivenhedstype blev oprettet",
|
||||||
"event_type_updated_successfully": "{{eventTypeTitle}} begivenhedstype blev opdateret",
|
"event_type_updated_successfully": "{{eventTypeTitle}} begivenhedstype blev opdateret",
|
||||||
"event_type_deleted_successfully": "Begivenhedstypen blev slettet",
|
"event_type_deleted_successfully": "Begivenhedstypen blev slettet",
|
||||||
"web3_metamask_added": "Metamask tilføjet",
|
|
||||||
"web3_metamask_disconnected": "Metamask blev afbrudt",
|
|
||||||
"hours": "Timer",
|
"hours": "Timer",
|
||||||
"your_email": "Din E-Mail",
|
"your_email": "Din E-Mail",
|
||||||
"change_avatar": "Skift Avatar",
|
"change_avatar": "Skift Avatar",
|
||||||
@@ -834,7 +833,6 @@
|
|||||||
"installed_one": "Installeret",
|
"installed_one": "Installeret",
|
||||||
"installed_other": "{{count}} installeret",
|
"installed_other": "{{count}} installeret",
|
||||||
"verify_wallet": "Verificér Wallet",
|
"verify_wallet": "Verificér Wallet",
|
||||||
"connect_metamask": "Forbind Metamask",
|
|
||||||
"create_events_on": "Opret begivenheder på",
|
"create_events_on": "Opret begivenheder på",
|
||||||
"enterprise_license": "Dette er en virksomhedsfunktion",
|
"enterprise_license": "Dette er en virksomhedsfunktion",
|
||||||
"enterprise_license_description": "For at aktivere denne funktion, skal du gå til {{setupUrl}} for at indtaste en licensnøgle. Hvis en licensnøgle allerede er på plads, bedes du kontakte {{supportMail}} for hjælp.",
|
"enterprise_license_description": "For at aktivere denne funktion, skal du gå til {{setupUrl}} for at indtaste en licensnøgle. Hvis en licensnøgle allerede er på plads, bedes du kontakte {{supportMail}} for hjælp.",
|
||||||
@@ -1009,7 +1007,6 @@
|
|||||||
"event_cancelled_trigger": "når begivenheden er aflyst",
|
"event_cancelled_trigger": "når begivenheden er aflyst",
|
||||||
"new_event_trigger": "når ny begivenhed er booket",
|
"new_event_trigger": "når ny begivenhed er booket",
|
||||||
"email_host_action": "send e-mail til vært",
|
"email_host_action": "send e-mail til vært",
|
||||||
"sms_attendee_action": "Send SMS til deltager",
|
|
||||||
"sms_number_action": "send SMS til et specifikt nummer",
|
"sms_number_action": "send SMS til et specifikt nummer",
|
||||||
"workflows": "Workflows",
|
"workflows": "Workflows",
|
||||||
"new_workflow_btn": "Nyt Workflow",
|
"new_workflow_btn": "Nyt Workflow",
|
||||||
@@ -1181,11 +1178,6 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"add_profile_photo": "Tilføj profilbillede",
|
"add_profile_photo": "Tilføj profilbillede",
|
||||||
"web3": "Web3",
|
"web3": "Web3",
|
||||||
"rainbow_token_gated": "Denne begivenhedstype er token gated.",
|
|
||||||
"rainbow_connect_wallet_gate": "Forbind din wallet, hvis du ejer <1>{{name}}</1> (<3>{{symbol}}</3>).",
|
|
||||||
"rainbow_insufficient_balance": "Din tilsluttede wallet indeholder ikke nok <1>{{symbol}}</1>.",
|
|
||||||
"rainbow_sign_message_request": "Signér beskedanmodningen på din wallet.",
|
|
||||||
"rainbow_signature_error": "Fejl ved anmodning om signatur fra din wallet.",
|
|
||||||
"token_address": "Token Adresse",
|
"token_address": "Token Adresse",
|
||||||
"blockchain": "Blockchain",
|
"blockchain": "Blockchain",
|
||||||
"old_password": "Gammel adgangskode",
|
"old_password": "Gammel adgangskode",
|
||||||
@@ -1281,7 +1273,6 @@
|
|||||||
"exchange_authentication_standard": "Grundlæggende autentificering",
|
"exchange_authentication_standard": "Grundlæggende autentificering",
|
||||||
"exchange_authentication_ntlm": "NTLM autentificering",
|
"exchange_authentication_ntlm": "NTLM autentificering",
|
||||||
"exchange_compression": "GZip komprimering",
|
"exchange_compression": "GZip komprimering",
|
||||||
"routing_forms_description": "Du kan se alle former og ruter du har oprettet her.",
|
|
||||||
"routing_forms_send_email_owner": "Send e-mail til Ejer",
|
"routing_forms_send_email_owner": "Send e-mail til Ejer",
|
||||||
"routing_forms_send_email_owner_description": "Sender en e-mail til ejeren når formularen er indsendt",
|
"routing_forms_send_email_owner_description": "Sender en e-mail til ejeren når formularen er indsendt",
|
||||||
"add_new_form": "Tilføj ny formular",
|
"add_new_form": "Tilføj ny formular",
|
||||||
@@ -1318,7 +1309,6 @@
|
|||||||
"password_updated": "Adgangskode opdateret!",
|
"password_updated": "Adgangskode opdateret!",
|
||||||
"pending_payment": "Afventer betaling",
|
"pending_payment": "Afventer betaling",
|
||||||
"pending_invites": "Afventende Invitationer",
|
"pending_invites": "Afventende Invitationer",
|
||||||
"confirmation_page_rainbow": "Token gate din begivenhed med tokens eller NFTs på Ethereum, Polygon og flere.",
|
|
||||||
"not_on_cal": "Ikke på {{appName}}",
|
"not_on_cal": "Ikke på {{appName}}",
|
||||||
"no_calendar_installed": "Ingen kalender installeret",
|
"no_calendar_installed": "Ingen kalender installeret",
|
||||||
"no_calendar_installed_description": "Du har endnu ikke tilsluttet nogen af dine kalendere",
|
"no_calendar_installed_description": "Du har endnu ikke tilsluttet nogen af dine kalendere",
|
||||||
@@ -1428,7 +1418,6 @@
|
|||||||
"find_the_best_person": "Find den bedste person tilgængelig, og cykl gennem dit team.",
|
"find_the_best_person": "Find den bedste person tilgængelig, og cykl gennem dit team.",
|
||||||
"fixed_round_robin": "Fast round robin",
|
"fixed_round_robin": "Fast round robin",
|
||||||
"add_one_fixed_attendee": "Tilføj en fast deltager og round robin gennem en række deltagere.",
|
"add_one_fixed_attendee": "Tilføj en fast deltager og round robin gennem en række deltagere.",
|
||||||
"calcom_is_better_with_team": "Cal.com er bedre med teams",
|
|
||||||
"add_your_team_members": "Føj dine teammedlemmer til dine begivenhedstyper. Brug kollektiv planlægning til at inkludere alle eller finde den bedst egnede person med round robin planlægning.",
|
"add_your_team_members": "Føj dine teammedlemmer til dine begivenhedstyper. Brug kollektiv planlægning til at inkludere alle eller finde den bedst egnede person med round robin planlægning.",
|
||||||
"booking_limit_reached": "Booking Grænse for denne begivenhedstype er nået",
|
"booking_limit_reached": "Booking Grænse for denne begivenhedstype er nået",
|
||||||
"admin_has_disabled": "En administrator har deaktiveret {{appName}}",
|
"admin_has_disabled": "En administrator har deaktiveret {{appName}}",
|
||||||
@@ -1441,7 +1430,6 @@
|
|||||||
"navigate_installed_apps": "Gå til installerede apps",
|
"navigate_installed_apps": "Gå til installerede apps",
|
||||||
"disabled_calendar": "Hvis du har en anden kalender installeret vil nye bookinger blive tilføjet til den. Hvis ikke, så forbind en ny kalender, så du ikke går glip af nye bookinger.",
|
"disabled_calendar": "Hvis du har en anden kalender installeret vil nye bookinger blive tilføjet til den. Hvis ikke, så forbind en ny kalender, så du ikke går glip af nye bookinger.",
|
||||||
"enable_apps": "Aktivér Apps",
|
"enable_apps": "Aktivér Apps",
|
||||||
"enable_apps_description": "Aktivér apps, som brugere kan integrere med Cal.com",
|
|
||||||
"purchase_license": "Køb en licens",
|
"purchase_license": "Køb en licens",
|
||||||
"already_have_key": "Jeg har allerede en nøgle:",
|
"already_have_key": "Jeg har allerede en nøgle:",
|
||||||
"already_have_key_suggestion": "Kopiér venligst din eksisterende CALCOM_LICENSE_KEY environment variabel her.",
|
"already_have_key_suggestion": "Kopiér venligst din eksisterende CALCOM_LICENSE_KEY environment variabel her.",
|
||||||
@@ -1613,5 +1601,6 @@
|
|||||||
"this_will_be_the_placeholder": "Dette vil være pladsholderen",
|
"this_will_be_the_placeholder": "Dette vil være pladsholderen",
|
||||||
"verification_code": "Bekræftelseskode",
|
"verification_code": "Bekræftelseskode",
|
||||||
"verify": "Bekræft",
|
"verify": "Bekræft",
|
||||||
"timezone_variable": "Tidszone"
|
"timezone_variable": "Tidszone",
|
||||||
|
"never_expire": "Udløber aldrig"
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
"calcom_explained_new_user": "Beenden Sie die Einrichtung Ihres {{appName}} -Kontos! Sie sind nur ein paar Schritte von der Lösung aller Probleme in der Zeitplanung entfernt.",
|
"calcom_explained_new_user": "Beenden Sie die Einrichtung Ihres {{appName}} -Kontos! Sie sind nur ein paar Schritte von der Lösung aller Probleme in der Zeitplanung entfernt.",
|
||||||
"have_any_questions": "Haben Sie Fragen? Wir sind hier um Ihnen zu helfen.",
|
"have_any_questions": "Haben Sie Fragen? Wir sind hier um Ihnen zu helfen.",
|
||||||
"reset_password_subject": "{{appName}}: Anleitung zum Zurücksetzen des Passworts",
|
"reset_password_subject": "{{appName}}: Anleitung zum Zurücksetzen des Passworts",
|
||||||
|
"verify_email_banner_button": "E-Mail senden",
|
||||||
"event_declined_subject": "Abgelehnt: {{title}} am {{date}}",
|
"event_declined_subject": "Abgelehnt: {{title}} am {{date}}",
|
||||||
"event_cancelled_subject": "Storniert: {{title}} um {{date}}",
|
"event_cancelled_subject": "Storniert: {{title}} um {{date}}",
|
||||||
"event_request_declined": "Ihre Event-Anfrage wurde abgelehnt",
|
"event_request_declined": "Ihre Event-Anfrage wurde abgelehnt",
|
||||||
@@ -26,6 +27,8 @@
|
|||||||
"rejection_confirmation": "Buchung ablehnen",
|
"rejection_confirmation": "Buchung ablehnen",
|
||||||
"manage_this_event": "Diesen Termin verwalten",
|
"manage_this_event": "Diesen Termin verwalten",
|
||||||
"invite_team_member": "Teammitglied einladen",
|
"invite_team_member": "Teammitglied einladen",
|
||||||
|
"invite_team_individual_segment": "Person einladen",
|
||||||
|
"invite_team_bulk_segment": "Massenimport",
|
||||||
"invite_team_notifcation_badge": "Eing.",
|
"invite_team_notifcation_badge": "Eing.",
|
||||||
"your_event_has_been_scheduled": "Ihr Termin wurde gebucht",
|
"your_event_has_been_scheduled": "Ihr Termin wurde gebucht",
|
||||||
"your_event_has_been_scheduled_recurring": "Ihr wiederkehrender Termin wurde gebucht",
|
"your_event_has_been_scheduled_recurring": "Ihr wiederkehrender Termin wurde gebucht",
|
||||||
@@ -222,6 +225,7 @@
|
|||||||
"go_back_login": "Zurück zur Login-Seite",
|
"go_back_login": "Zurück zur Login-Seite",
|
||||||
"error_during_login": "Beim Anmelden ist ein Fehler aufgetreten. Gehen Sie zurück zum Anmeldebildschirm und versuchen Sie es erneut.",
|
"error_during_login": "Beim Anmelden ist ein Fehler aufgetreten. Gehen Sie zurück zum Anmeldebildschirm und versuchen Sie es erneut.",
|
||||||
"request_password_reset": "Passwort zurücksetzen",
|
"request_password_reset": "Passwort zurücksetzen",
|
||||||
|
"send_invite": "Einladung senden",
|
||||||
"forgot_password": "Passwort vergessen",
|
"forgot_password": "Passwort vergessen",
|
||||||
"forgot": "Vergessen?",
|
"forgot": "Vergessen?",
|
||||||
"done": "Erledigt",
|
"done": "Erledigt",
|
||||||
@@ -237,6 +241,8 @@
|
|||||||
"set_availability": "Verfügbarkeit festlegen",
|
"set_availability": "Verfügbarkeit festlegen",
|
||||||
"continue_without_calendar": "Ohne Kalender fortfahren",
|
"continue_without_calendar": "Ohne Kalender fortfahren",
|
||||||
"connect_your_calendar": "Kalender verbinden",
|
"connect_your_calendar": "Kalender verbinden",
|
||||||
|
"connect_your_video_app": "Verbinden Sie Ihre Video-Apps",
|
||||||
|
"connect_your_video_app_instructions": "Verbinden Sie Ihre Video-Apps, um sie für Ihre Termintypen zu verwenden.",
|
||||||
"connect_your_calendar_instructions": "Verbinden Sie Ihren Kalender, um automatisch zu prüfen, ob Termine verfügbar sind.",
|
"connect_your_calendar_instructions": "Verbinden Sie Ihren Kalender, um automatisch zu prüfen, ob Termine verfügbar sind.",
|
||||||
"set_up_later": "Später einrichten",
|
"set_up_later": "Später einrichten",
|
||||||
"current_time": "Aktuelle Zeit",
|
"current_time": "Aktuelle Zeit",
|
||||||
@@ -366,6 +372,7 @@
|
|||||||
"create_webhook": "Webhook erstellen",
|
"create_webhook": "Webhook erstellen",
|
||||||
"booking_cancelled": "Termin abgesagt",
|
"booking_cancelled": "Termin abgesagt",
|
||||||
"booking_rescheduled": "Termin verlegt",
|
"booking_rescheduled": "Termin verlegt",
|
||||||
|
"recording_ready": "Download-Link der Aufnahme bereit",
|
||||||
"booking_created": "Termin erstellt",
|
"booking_created": "Termin erstellt",
|
||||||
"meeting_ended": "Meeting beendet",
|
"meeting_ended": "Meeting beendet",
|
||||||
"form_submitted": "Formular gesendet",
|
"form_submitted": "Formular gesendet",
|
||||||
@@ -464,6 +471,7 @@
|
|||||||
"friday": "Freitag",
|
"friday": "Freitag",
|
||||||
"saturday": "Samstag",
|
"saturday": "Samstag",
|
||||||
"sunday": "Sonntag",
|
"sunday": "Sonntag",
|
||||||
|
"all_booked_today": "Alle gebucht.",
|
||||||
"slots_load_fail": "Die verfügbaren Zeitfenster konnten nicht geladen werden.",
|
"slots_load_fail": "Die verfügbaren Zeitfenster konnten nicht geladen werden.",
|
||||||
"additional_guests": "+ Weitere Gäste",
|
"additional_guests": "+ Weitere Gäste",
|
||||||
"your_name": "Ihr Name",
|
"your_name": "Ihr Name",
|
||||||
@@ -623,8 +631,6 @@
|
|||||||
"event_type_created_successfully": "{{eventTypeTitle}} Ereignistyp erfolgreich erstellt",
|
"event_type_created_successfully": "{{eventTypeTitle}} Ereignistyp erfolgreich erstellt",
|
||||||
"event_type_updated_successfully": "{{eventTypeTitle}} Ereignistyp erfolgreich aktualisiert",
|
"event_type_updated_successfully": "{{eventTypeTitle}} Ereignistyp erfolgreich aktualisiert",
|
||||||
"event_type_deleted_successfully": "Termintyp erfolgreich gelöscht",
|
"event_type_deleted_successfully": "Termintyp erfolgreich gelöscht",
|
||||||
"web3_metamask_added": "Metamask erfolgreich hinzugefügt",
|
|
||||||
"web3_metamask_disconnected": "Metamask erfolgreich getrennt",
|
|
||||||
"hours": "Stunden",
|
"hours": "Stunden",
|
||||||
"your_email": "Ihre E-Mail-Adresse",
|
"your_email": "Ihre E-Mail-Adresse",
|
||||||
"change_avatar": "Profilbild ändern",
|
"change_avatar": "Profilbild ändern",
|
||||||
@@ -751,6 +757,10 @@
|
|||||||
"new_event_type_to_book_description": "Erstellen Sie einen neuen Termintyp, mit dem Personen Zeiten buchen können.",
|
"new_event_type_to_book_description": "Erstellen Sie einen neuen Termintyp, mit dem Personen Zeiten buchen können.",
|
||||||
"length": "Länge",
|
"length": "Länge",
|
||||||
"minimum_booking_notice": "Mindesvorlaufzeit für eine Buchung",
|
"minimum_booking_notice": "Mindesvorlaufzeit für eine Buchung",
|
||||||
|
"offset_toggle": "Startzeiten versetzen",
|
||||||
|
"offset_toggle_description": "Um eine bestimmte Anzahl an Minuten versetzte Zeitfenster, die Buchern angezeigt werden",
|
||||||
|
"offset_start": "Versetzt um",
|
||||||
|
"offset_start_description": "z.B. wird dies Zeitfenster für Ihre Bucher um {{ adjustedTime }} statt {{ originalTime }} anzeigen",
|
||||||
"slot_interval": "Zeit-Slot-Intervalle",
|
"slot_interval": "Zeit-Slot-Intervalle",
|
||||||
"slot_interval_default": "Verwende Terminlänge (Standard)",
|
"slot_interval_default": "Verwende Terminlänge (Standard)",
|
||||||
"delete_event_type": "Ereignistyp löschen?",
|
"delete_event_type": "Ereignistyp löschen?",
|
||||||
@@ -861,7 +871,6 @@
|
|||||||
"installed_one": "Installiert",
|
"installed_one": "Installiert",
|
||||||
"installed_other": "{{count}} installiert",
|
"installed_other": "{{count}} installiert",
|
||||||
"verify_wallet": "Wallet verifizieren",
|
"verify_wallet": "Wallet verifizieren",
|
||||||
"connect_metamask": "Metamask verbinden",
|
|
||||||
"create_events_on": "Erstelle Termine in:",
|
"create_events_on": "Erstelle Termine in:",
|
||||||
"enterprise_license": "Das ist eine Enterprise-Funktion",
|
"enterprise_license": "Das ist eine Enterprise-Funktion",
|
||||||
"enterprise_license_description": "Um diese Funktion zu aktivieren, holen Sie sich einen Deployment-Schlüssel von der {{consoleUrl}}-Konsole und fügen Sie ihn als CALCOM_LICENSE_KEY zu Ihrer .env hinzu. Wenn Ihr Team bereits eine Lizenz hat, wenden Sie sich bitte an {{supportMail}} für Hilfe.",
|
"enterprise_license_description": "Um diese Funktion zu aktivieren, holen Sie sich einen Deployment-Schlüssel von der {{consoleUrl}}-Konsole und fügen Sie ihn als CALCOM_LICENSE_KEY zu Ihrer .env hinzu. Wenn Ihr Team bereits eine Lizenz hat, wenden Sie sich bitte an {{supportMail}} für Hilfe.",
|
||||||
@@ -887,6 +896,7 @@
|
|||||||
"availability_updated_successfully": "{{scheduleName}} Zeitplan erfolgreich aktualisiert",
|
"availability_updated_successfully": "{{scheduleName}} Zeitplan erfolgreich aktualisiert",
|
||||||
"schedule_deleted_successfully": "Verfügbarkeitsplan erfolgreich gelöscht",
|
"schedule_deleted_successfully": "Verfügbarkeitsplan erfolgreich gelöscht",
|
||||||
"default_schedule_name": "Arbeitszeiten",
|
"default_schedule_name": "Arbeitszeiten",
|
||||||
|
"member_default_schedule": "Standardverfügbarkeitsplan des Mitglieds",
|
||||||
"new_schedule_heading": "Erstelle einen Verfügbarkeitsplan",
|
"new_schedule_heading": "Erstelle einen Verfügbarkeitsplan",
|
||||||
"new_schedule_description": "Das Erstellen eines Verfügbarkeitsplan sorgt dafür, dass Ihre Verfügbarkeit bei mehreren Termintypen genutzt werden kann.",
|
"new_schedule_description": "Das Erstellen eines Verfügbarkeitsplan sorgt dafür, dass Ihre Verfügbarkeit bei mehreren Termintypen genutzt werden kann.",
|
||||||
"requires_ownership_of_a_token": "Erfordert Besitz eines Tokens, das zu der folgenden Adresse gehört:",
|
"requires_ownership_of_a_token": "Erfordert Besitz eines Tokens, das zu der folgenden Adresse gehört:",
|
||||||
@@ -903,6 +913,7 @@
|
|||||||
"duplicate": "Duplizieren",
|
"duplicate": "Duplizieren",
|
||||||
"offer_seats": "Plätze anbieten",
|
"offer_seats": "Plätze anbieten",
|
||||||
"offer_seats_description": "Bieten Sie Plätze für Buchungen an (dies deaktiviert Gäste & Opt-in-Buchungen)",
|
"offer_seats_description": "Bieten Sie Plätze für Buchungen an (dies deaktiviert Gäste & Opt-in-Buchungen)",
|
||||||
|
"seats_available_one": "Verfügbarer Platz",
|
||||||
"seats_available_other": "Verfügbare Plätze",
|
"seats_available_other": "Verfügbare Plätze",
|
||||||
"number_of_seats": "Anzahl der Plätze pro Termin",
|
"number_of_seats": "Anzahl der Plätze pro Termin",
|
||||||
"enter_number_of_seats": "Anzahl der Plätze eingeben",
|
"enter_number_of_seats": "Anzahl der Plätze eingeben",
|
||||||
@@ -1037,7 +1048,7 @@
|
|||||||
"event_cancelled_trigger": "wenn das Ereignis abgesagt wird",
|
"event_cancelled_trigger": "wenn das Ereignis abgesagt wird",
|
||||||
"new_event_trigger": "wenn ein neer Termin gebucht wird",
|
"new_event_trigger": "wenn ein neer Termin gebucht wird",
|
||||||
"email_host_action": "E-Mail an den Veranstalter senden",
|
"email_host_action": "E-Mail an den Veranstalter senden",
|
||||||
"sms_attendee_action": "SMS an Teilnehmende senden",
|
"email_attendee_action": "E-Mail an Teilnehmende senden",
|
||||||
"sms_number_action": "SMS an eine bestimmte Nummer senden",
|
"sms_number_action": "SMS an eine bestimmte Nummer senden",
|
||||||
"workflows": "Workflows",
|
"workflows": "Workflows",
|
||||||
"new_workflow_btn": "Neuer Workflow",
|
"new_workflow_btn": "Neuer Workflow",
|
||||||
@@ -1189,6 +1200,7 @@
|
|||||||
"create_workflow": "Einen Workflow erstellen",
|
"create_workflow": "Einen Workflow erstellen",
|
||||||
"do_this": "Mache dies",
|
"do_this": "Mache dies",
|
||||||
"turn_off": "Abschalten",
|
"turn_off": "Abschalten",
|
||||||
|
"turn_on": "Einschalten",
|
||||||
"settings_updated_successfully": "Einstellungen erfolgreich aktualisiert",
|
"settings_updated_successfully": "Einstellungen erfolgreich aktualisiert",
|
||||||
"error_updating_settings": "Fehler beim Aktualisieren der Einstellungen",
|
"error_updating_settings": "Fehler beim Aktualisieren der Einstellungen",
|
||||||
"personal_cal_url": "Meine persönliche {{appName}}-URL",
|
"personal_cal_url": "Meine persönliche {{appName}}-URL",
|
||||||
@@ -1213,11 +1225,6 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"add_profile_photo": "Profilbild hinzufügen",
|
"add_profile_photo": "Profilbild hinzufügen",
|
||||||
"web3": "Web3",
|
"web3": "Web3",
|
||||||
"rainbow_token_gated": "Dieser Ereignistyp ist durch einen Token geschützt.",
|
|
||||||
"rainbow_connect_wallet_gate": "Verbinden Sie Ihre Wallet, falls Sie <1>{{name}}</1> (<3>{{symbol}}</3>) besitzen.",
|
|
||||||
"rainbow_insufficient_balance": "Ihre verbundene Wallet enthält nicht genug <1>{{symbol}}</1>.",
|
|
||||||
"rainbow_sign_message_request": "Unterschreiben Sie die Nachrichtenanfrage in Ihrem Wallet.",
|
|
||||||
"rainbow_signature_error": "Fehler beim Anfordern der Signatur von Ihrer Wallet.",
|
|
||||||
"token_address": "Adresse des Token",
|
"token_address": "Adresse des Token",
|
||||||
"blockchain": "Blockchain",
|
"blockchain": "Blockchain",
|
||||||
"old_password": "Altes Passwort",
|
"old_password": "Altes Passwort",
|
||||||
@@ -1245,6 +1252,7 @@
|
|||||||
"calendars_description": "Konfigurieren Sie, wie Ihre Event-Typen mit Ihren Kalendern interagieren sollen",
|
"calendars_description": "Konfigurieren Sie, wie Ihre Event-Typen mit Ihren Kalendern interagieren sollen",
|
||||||
"appearance_description": "Einstellungen für Ihre Buchungsdarstellung verwalten",
|
"appearance_description": "Einstellungen für Ihre Buchungsdarstellung verwalten",
|
||||||
"conferencing_description": "Fügen Sie Ihre favorisierten Videokonferenz-Apps für Ihre Meetings hinzu",
|
"conferencing_description": "Fügen Sie Ihre favorisierten Videokonferenz-Apps für Ihre Meetings hinzu",
|
||||||
|
"add_conferencing_app": "Konferenz-App hinzufügen",
|
||||||
"password_description": "Einstellungen für Ihre Konto-Passwörter verwalten",
|
"password_description": "Einstellungen für Ihre Konto-Passwörter verwalten",
|
||||||
"2fa_description": "Einstellungen für Ihre Konto-Passwörter verwalten",
|
"2fa_description": "Einstellungen für Ihre Konto-Passwörter verwalten",
|
||||||
"we_just_need_basic_info": "Wir benötigen nur ein paar grundlegende Informationen, um Ihr Profil einzurichten.",
|
"we_just_need_basic_info": "Wir benötigen nur ein paar grundlegende Informationen, um Ihr Profil einzurichten.",
|
||||||
@@ -1279,7 +1287,6 @@
|
|||||||
"download_responses_description": "Laden Sie alle Antworten zu Ihrem Formular im CSV-Format herunter.",
|
"download_responses_description": "Laden Sie alle Antworten zu Ihrem Formular im CSV-Format herunter.",
|
||||||
"download": "Herunterladen",
|
"download": "Herunterladen",
|
||||||
"download_recording": "Aufnahme herunterladen",
|
"download_recording": "Aufnahme herunterladen",
|
||||||
"recording_from_your_recent_call": "Eine Aufnahme von Ihrem letzten Anruf auf Cal.com steht zum Download bereit",
|
|
||||||
"create_your_first_form": "Erstellen Sie Ihr erstes Formular",
|
"create_your_first_form": "Erstellen Sie Ihr erstes Formular",
|
||||||
"create_your_first_form_description": "Mithilfe von Leitungsformularen können Sie qualifizierende Fragen stellen und zur richtigen Person oder zum richtigen Veranstaltungstyp weiterleiten.",
|
"create_your_first_form_description": "Mithilfe von Leitungsformularen können Sie qualifizierende Fragen stellen und zur richtigen Person oder zum richtigen Veranstaltungstyp weiterleiten.",
|
||||||
"create_your_first_webhook": "Erstellen Sie Ihren ersten Webhook",
|
"create_your_first_webhook": "Erstellen Sie Ihren ersten Webhook",
|
||||||
@@ -1362,7 +1369,6 @@
|
|||||||
"password_updated": "Passwort aktualisiert!",
|
"password_updated": "Passwort aktualisiert!",
|
||||||
"pending_payment": "Zahlung ausstehend",
|
"pending_payment": "Zahlung ausstehend",
|
||||||
"pending_invites": "Offene Einladungen",
|
"pending_invites": "Offene Einladungen",
|
||||||
"confirmation_page_rainbow": "Sperren Sie Ihr Ereignis hinter Tokens oder NFTs auf Ethereum, Polygon und mehr.",
|
|
||||||
"not_on_cal": "Nicht auf {{appName}}",
|
"not_on_cal": "Nicht auf {{appName}}",
|
||||||
"no_calendar_installed": "Kein Kalender installiert",
|
"no_calendar_installed": "Kein Kalender installiert",
|
||||||
"no_calendar_installed_description": "Sie haben noch keinen Ihrer Kalender verbunden",
|
"no_calendar_installed_description": "Sie haben noch keinen Ihrer Kalender verbunden",
|
||||||
@@ -1476,8 +1482,6 @@
|
|||||||
"find_the_best_person": "Finden Sie die beste verfügbare Person und rotieren Sie durch Ihr Team.",
|
"find_the_best_person": "Finden Sie die beste verfügbare Person und rotieren Sie durch Ihr Team.",
|
||||||
"fixed_round_robin": "Festgelegter Round Robin",
|
"fixed_round_robin": "Festgelegter Round Robin",
|
||||||
"add_one_fixed_attendee": "Fügen Sie einen festen Teilnehmer und einen Round Robin mit einer Reihe von Teilnehmern hinzu.",
|
"add_one_fixed_attendee": "Fügen Sie einen festen Teilnehmer und einen Round Robin mit einer Reihe von Teilnehmern hinzu.",
|
||||||
"calcom_is_better_with_team": "Cal.com ist mit Teams besser",
|
|
||||||
"the_calcom_team": "Das Cal.com Team",
|
|
||||||
"add_your_team_members": "Fügen Sie Ihre Teammitglieder zu Ihren Termintypen hinzu. Nutzen Sie kollektive Planung, um alle einzubinden oder finden Sie die geeignetste Person mit der Round Robin Planung.",
|
"add_your_team_members": "Fügen Sie Ihre Teammitglieder zu Ihren Termintypen hinzu. Nutzen Sie kollektive Planung, um alle einzubinden oder finden Sie die geeignetste Person mit der Round Robin Planung.",
|
||||||
"booking_limit_reached": "Das Buchungslimit für diesen Termintyp wurde erreicht",
|
"booking_limit_reached": "Das Buchungslimit für diesen Termintyp wurde erreicht",
|
||||||
"duration_limit_reached": "Das Zeitlimit für diesen Termintyp wurde erreicht",
|
"duration_limit_reached": "Das Zeitlimit für diesen Termintyp wurde erreicht",
|
||||||
@@ -1496,7 +1500,6 @@
|
|||||||
"navigate_installed_apps": "Zu installierten Apps wechseln",
|
"navigate_installed_apps": "Zu installierten Apps wechseln",
|
||||||
"disabled_calendar": "Wenn Sie einen anderen Kalender installiert haben, werden neue Buchungen zu dem Kalender hinzugefügt. Verbinden Sie andernfalls einen neuen Kalender, damit Sie keine neuen Buchungen verpassen.",
|
"disabled_calendar": "Wenn Sie einen anderen Kalender installiert haben, werden neue Buchungen zu dem Kalender hinzugefügt. Verbinden Sie andernfalls einen neuen Kalender, damit Sie keine neuen Buchungen verpassen.",
|
||||||
"enable_apps": "Apps aktivieren",
|
"enable_apps": "Apps aktivieren",
|
||||||
"enable_apps_description": "Apps aktivieren, die Benutzer mit Cal.com integrieren können",
|
|
||||||
"purchase_license": "Lizenz kaufen",
|
"purchase_license": "Lizenz kaufen",
|
||||||
"already_have_key": "Ich habe bereits einen Schlüssel:",
|
"already_have_key": "Ich habe bereits einen Schlüssel:",
|
||||||
"already_have_key_suggestion": "Bitte fügen Sie Ihre vorhandene CALCOM_LICENSE_KEY Umgebungsvariable hier ein.",
|
"already_have_key_suggestion": "Bitte fügen Sie Ihre vorhandene CALCOM_LICENSE_KEY Umgebungsvariable hier ein.",
|
||||||
@@ -1619,6 +1622,7 @@
|
|||||||
"email_user_cta": "Einladung anzeigen",
|
"email_user_cta": "Einladung anzeigen",
|
||||||
"email_no_user_invite_heading": "Sie wurden eingeladen, dem Team in {{appName}} beizutreten",
|
"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_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_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_one": "Wählen Sie Ihren Benutzernamen",
|
||||||
"email_no_user_step_two": "Verbinden Sie Ihr Kalenderkonto",
|
"email_no_user_step_two": "Verbinden Sie Ihr Kalenderkonto",
|
||||||
@@ -1694,6 +1698,15 @@
|
|||||||
"spot_popular_event_types_description": "Sehen Sie, welche Ihrer Ereignistypen die meisten Klicks und Buchungen erhalten",
|
"spot_popular_event_types_description": "Sehen Sie, welche Ihrer Ereignistypen die meisten Klicks und Buchungen erhalten",
|
||||||
"no_responses_yet": "Noch keine Antworten",
|
"no_responses_yet": "Noch keine Antworten",
|
||||||
"this_will_be_the_placeholder": "Dies wird der Platzhalter sein",
|
"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",
|
||||||
|
"switch_monthly": "Zur monatlichen Ansicht wechseln",
|
||||||
|
"switch_weekly": "Zur Wochenansicht wechseln",
|
||||||
|
"switch_multiday": "Zur Tagesansicht wechseln",
|
||||||
|
"num_locations": "{{num}} Standortoptionen",
|
||||||
|
"select_on_next_step": "Im nächsten Schritt auswählen",
|
||||||
"this_meeting_has_not_started_yet": "Dieses Meeting hat noch nicht begonnen",
|
"this_meeting_has_not_started_yet": "Dieses Meeting hat noch nicht begonnen",
|
||||||
"this_app_requires_connected_account": "{{appName}} benötigt ein verbundenes {{dependencyName}}-Konto",
|
"this_app_requires_connected_account": "{{appName}} benötigt ein verbundenes {{dependencyName}}-Konto",
|
||||||
"connect_app": "{{dependencyName}} verbinden",
|
"connect_app": "{{dependencyName}} verbinden",
|
||||||
@@ -1723,6 +1736,7 @@
|
|||||||
"locked_apps_description": "Mitglieder können die aktiven Apps sehen, können aber keine App-Einstellungen anpassen",
|
"locked_apps_description": "Mitglieder können die aktiven Apps sehen, können aber keine App-Einstellungen anpassen",
|
||||||
"locked_webhooks_description": "Mitglieder können die aktiven Webhooks sehen, können aber keine Webhook-Einstellungen anpassen",
|
"locked_webhooks_description": "Mitglieder können die aktiven Webhooks sehen, können aber keine Webhook-Einstellungen anpassen",
|
||||||
"locked_workflows_description": "Mitglieder können die aktiven Workflows sehen, können aber keine Workflow-Einstellungen anpassen",
|
"locked_workflows_description": "Mitglieder können die aktiven Workflows sehen, können aber keine Workflow-Einstellungen anpassen",
|
||||||
|
"locked_by_admin": "Vom Team-Admin gesperrt",
|
||||||
"app_not_connected": "Sie haben kein {{appName}}-Konto verbunden.",
|
"app_not_connected": "Sie haben kein {{appName}}-Konto verbunden.",
|
||||||
"connect_now": "Jetzt verbinden",
|
"connect_now": "Jetzt verbinden",
|
||||||
"managed_event_dialog_confirm_button_one": "{{count}} Mitglied ersetzen & benachrichtigen",
|
"managed_event_dialog_confirm_button_one": "{{count}} Mitglied ersetzen & benachrichtigen",
|
||||||
@@ -1734,7 +1748,7 @@
|
|||||||
"managed_event_dialog_clarification": "Wenn Sie die URL ersetzen, werden wir sie benachrichtigen. Gehen Sie zurück und entfernen Sie sie, wenn Sie sie nicht überschreiben möchten.",
|
"managed_event_dialog_clarification": "Wenn Sie die URL ersetzen, werden wir sie benachrichtigen. Gehen Sie zurück und entfernen Sie sie, wenn Sie sie nicht überschreiben möchten.",
|
||||||
"review_event_type": "Ereignistyp überprüfen",
|
"review_event_type": "Ereignistyp überprüfen",
|
||||||
"looking_for_more_analytics": "Suchen Sie nach weiteren Analysedaten?",
|
"looking_for_more_analytics": "Suchen Sie nach weiteren Analysedaten?",
|
||||||
"looking_for_more_insights": "Suchen Sie nach weiteren Einsichten?",
|
"looking_for_more_insights": "Möchten Sie mehr Insights?",
|
||||||
"add_filter": "Filter hinzufügen",
|
"add_filter": "Filter hinzufügen",
|
||||||
"select_user": "Benutzer auswählen",
|
"select_user": "Benutzer auswählen",
|
||||||
"select_event_type": "Ereignistyp auswählen",
|
"select_event_type": "Ereignistyp auswählen",
|
||||||
@@ -1780,5 +1794,35 @@
|
|||||||
"seats_and_no_show_fee_error": "Aktuell können keine Plätze aktiviert oder eine Gebühr für das Nichterscheinen berechnet werden",
|
"seats_and_no_show_fee_error": "Aktuell können keine Plätze aktiviert oder eine Gebühr für das Nichterscheinen berechnet werden",
|
||||||
"complete_your_booking": "Schließen Sie Ihre Buchung ab",
|
"complete_your_booking": "Schließen Sie Ihre Buchung ab",
|
||||||
"complete_your_booking_subject": "Schließen Sie Ihre Buchung ab: {{title}} am {{date}}",
|
"complete_your_booking_subject": "Schließen Sie Ihre Buchung ab: {{title}} am {{date}}",
|
||||||
"email_invite_team": "{{email}} wurde eingeladen"
|
"confirm_your_details": "Bestätigen Sie Ihre Daten",
|
||||||
|
"never_expire": "Läuft niemals ab",
|
||||||
|
"currency_string": "{{amount, currency}}",
|
||||||
|
"charge_card_dialog_body": "Sie sind im Begriff, den Teilnehmer {{amount, currency}} in Rechnung zu stellen. Sind Sie sicher, dass Sie fortfahren möchten?",
|
||||||
|
"charge_attendee": "Teilnehmer {{amount, currency}} berechnen",
|
||||||
|
"payment_app_commission": "Zahlung erfordern ({{paymentFeePercentage}} % + {{fee, currency}} Provision pro Transaktion)",
|
||||||
|
"email_invite_team": "{{email}} wurde eingeladen",
|
||||||
|
"email_invite_team_bulk": "{{userCount}} Benutzer wurden eingeladen",
|
||||||
|
"error_collecting_card": "Fehler beim Erfassen der Karte",
|
||||||
|
"image_size_limit_exceed": "Das hochgeladene Bild sollte die maximale Größe von 5 MB nicht überschreiten",
|
||||||
|
"inline_embed": "Inline-Einbettung",
|
||||||
|
"load_inline_content": "Laden Sie Ihren Event-Typ direkt inline mit Ihren anderen Website-Inhalten.",
|
||||||
|
"floating_pop_up_button": "Schwebende Pop-Up-Schaltfläche",
|
||||||
|
"floating_button_trigger_modal": "Erstellt einen schwebenden Button auf Ihrer Website, der einen modalen Dialog mit Ihrem Termintypen erstellt.",
|
||||||
|
"pop_up_element_click": "Pop-Up über Element-Klick",
|
||||||
|
"open_dialog_with_element_click": "Öffnet Ihren Cal-Dialog, wenn jemand ein Element anklickt.",
|
||||||
|
"need_help_embedding": "Brauchen Sie Hilfe? Sehen Sie sich unsere Anleitungen zum Einbetten von Cal auf Wix, Squarespace, oder WordPress an, schauen Sie sich unsere häufig gestellten Fragen an oder erkunden Sie erweiterte Einbettungsoptionen.",
|
||||||
|
"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",
|
||||||
|
"disable_host_confirmation_emails_description": "Mindestens ein Workflow ist für diesen Termintyp aktiv, welcher bei Buchung eine E-Mail an den Veranstalter sendet.",
|
||||||
|
"add_an_override": "Eine Überschreibung hinzufügen",
|
||||||
|
"import_from_google_workspace": "Benutzer aus Google Workspace importieren",
|
||||||
|
"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"
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,16 @@
|
|||||||
"calcom_explained_new_user": "Finish setting up your {{appName}} account! You’re just a few steps away from solving all your scheduling problems.",
|
"calcom_explained_new_user": "Finish setting up your {{appName}} account! You’re just a few steps away from solving all your scheduling problems.",
|
||||||
"have_any_questions": "Have questions? We're here to help.",
|
"have_any_questions": "Have questions? We're here to help.",
|
||||||
"reset_password_subject": "{{appName}}: Reset password instructions",
|
"reset_password_subject": "{{appName}}: Reset password instructions",
|
||||||
|
"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_button": "Send email",
|
||||||
|
"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:",
|
||||||
|
"email_sent": "Email sent successfully",
|
||||||
"event_declined_subject": "Declined: {{title}} at {{date}}",
|
"event_declined_subject": "Declined: {{title}} at {{date}}",
|
||||||
"event_cancelled_subject": "Cancelled: {{title}} at {{date}}",
|
"event_cancelled_subject": "Cancelled: {{title}} at {{date}}",
|
||||||
"event_request_declined": "Your event request has been declined",
|
"event_request_declined": "Your event request has been declined",
|
||||||
@@ -294,6 +304,18 @@
|
|||||||
"success": "Success",
|
"success": "Success",
|
||||||
"failed": "Failed",
|
"failed": "Failed",
|
||||||
"password_has_been_reset_login": "Your password has been reset. You can now login with your newly created password.",
|
"password_has_been_reset_login": "Your password has been reset. You can now login with your newly created password.",
|
||||||
|
"bookerlayout_title": "Layout",
|
||||||
|
"bookerlayout_default_title": "Default view",
|
||||||
|
"bookerlayout_description": "You can select multiple and your bookers can switch views.",
|
||||||
|
"bookerlayout_user_settings_title": "Booking layout",
|
||||||
|
"bookerlayout_user_settings_description": "You can select multiple and bookers can switch views. This can be overridden on a per event basis.",
|
||||||
|
"bookerlayout_month_view": "Month",
|
||||||
|
"bookerlayout_week_view": "Weekly",
|
||||||
|
"bookerlayout_column_view": "Column",
|
||||||
|
"bookerlayout_error_min_one_enabled": "At least one layout has to be enabled.",
|
||||||
|
"bookerlayout_error_default_not_enabled": "The layout you selected as the default view is not part of the enabled layouts.",
|
||||||
|
"bookerlayout_error_unknown_layout": "The layout you selected is not a valid layout.",
|
||||||
|
"bookerlayout_override_global_settings": "You can manage this for all your event types in <2>settings / appearance</2> or <6>override for this event only</6>.",
|
||||||
"unexpected_error_try_again": "An unexpected error occurred. Try again.",
|
"unexpected_error_try_again": "An unexpected error occurred. Try again.",
|
||||||
"sunday_time_error": "Invalid time on Sunday",
|
"sunday_time_error": "Invalid time on Sunday",
|
||||||
"monday_time_error": "Invalid time on Monday",
|
"monday_time_error": "Invalid time on Monday",
|
||||||
@@ -634,8 +656,6 @@
|
|||||||
"event_type_created_successfully": "{{eventTypeTitle}} event type created successfully",
|
"event_type_created_successfully": "{{eventTypeTitle}} event type created successfully",
|
||||||
"event_type_updated_successfully": "{{eventTypeTitle}} event type updated successfully",
|
"event_type_updated_successfully": "{{eventTypeTitle}} event type updated successfully",
|
||||||
"event_type_deleted_successfully": "Event type deleted successfully",
|
"event_type_deleted_successfully": "Event type deleted successfully",
|
||||||
"web3_metamask_added": "Metamask added successfully",
|
|
||||||
"web3_metamask_disconnected": "Metamask disconnected successfully",
|
|
||||||
"hours": "Hours",
|
"hours": "Hours",
|
||||||
"your_email": "Your Email",
|
"your_email": "Your Email",
|
||||||
"change_avatar": "Change Avatar",
|
"change_avatar": "Change Avatar",
|
||||||
@@ -876,7 +896,6 @@
|
|||||||
"installed_one": "Installed",
|
"installed_one": "Installed",
|
||||||
"installed_other": "{{count}} installed",
|
"installed_other": "{{count}} installed",
|
||||||
"verify_wallet": "Verify Wallet",
|
"verify_wallet": "Verify Wallet",
|
||||||
"connect_metamask": "Connect Metamask",
|
|
||||||
"create_events_on": "Create events on",
|
"create_events_on": "Create events on",
|
||||||
"enterprise_license": "This is an enterprise feature",
|
"enterprise_license": "This is an enterprise feature",
|
||||||
"enterprise_license_description": "To enable this feature, have an administrator go to {{setupUrl}} to enter a license key. If a license key is already in place, please contact {{supportMail}} for help.",
|
"enterprise_license_description": "To enable this feature, have an administrator go to {{setupUrl}} to enter a license key. If a license key is already in place, please contact {{supportMail}} for help.",
|
||||||
@@ -902,6 +921,7 @@
|
|||||||
"availability_updated_successfully": "{{scheduleName}} schedule updated successfully",
|
"availability_updated_successfully": "{{scheduleName}} schedule updated successfully",
|
||||||
"schedule_deleted_successfully": "Schedule deleted successfully",
|
"schedule_deleted_successfully": "Schedule deleted successfully",
|
||||||
"default_schedule_name": "Working Hours",
|
"default_schedule_name": "Working Hours",
|
||||||
|
"member_default_schedule":"Member's default schedule",
|
||||||
"new_schedule_heading": "Create an availability schedule",
|
"new_schedule_heading": "Create an availability schedule",
|
||||||
"new_schedule_description": "Creating availability schedules allows you to manage availability across event types. They can be applied to one or more event types.",
|
"new_schedule_description": "Creating availability schedules allows you to manage availability across event types. They can be applied to one or more event types.",
|
||||||
"requires_ownership_of_a_token": "Requires ownership of a token belonging to the following address:",
|
"requires_ownership_of_a_token": "Requires ownership of a token belonging to the following address:",
|
||||||
@@ -1054,7 +1074,7 @@
|
|||||||
"new_event_trigger": "when new event is booked",
|
"new_event_trigger": "when new event is booked",
|
||||||
"email_host_action": "send email to host",
|
"email_host_action": "send email to host",
|
||||||
"email_attendee_action": "send email to attendees",
|
"email_attendee_action": "send email to attendees",
|
||||||
"sms_attendee_action": "send SMS to attendee",
|
"sms_attendee_action": "Send SMS to attendee",
|
||||||
"sms_number_action": "send SMS to a specific number",
|
"sms_number_action": "send SMS to a specific number",
|
||||||
"workflows": "Workflows",
|
"workflows": "Workflows",
|
||||||
"new_workflow_btn": "New Workflow",
|
"new_workflow_btn": "New Workflow",
|
||||||
@@ -1231,11 +1251,6 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"add_profile_photo": "Add profile photo",
|
"add_profile_photo": "Add profile photo",
|
||||||
"web3": "Web3",
|
"web3": "Web3",
|
||||||
"rainbow_token_gated": "This event type is token gated.",
|
|
||||||
"rainbow_connect_wallet_gate": "Connect your wallet if you own <1>{{name}}</1> (<3>{{symbol}}</3>).",
|
|
||||||
"rainbow_insufficient_balance": "Your connected wallet doesn't contain enough <1>{{symbol}}</1>.",
|
|
||||||
"rainbow_sign_message_request": "Sign the message request on your wallet.",
|
|
||||||
"rainbow_signature_error": "Error requesting signature from your wallet.",
|
|
||||||
"token_address": "Token Address",
|
"token_address": "Token Address",
|
||||||
"blockchain": "Blockchain",
|
"blockchain": "Blockchain",
|
||||||
"old_password": "Old password",
|
"old_password": "Old password",
|
||||||
@@ -1298,7 +1313,7 @@
|
|||||||
"download_responses_description": "Download all responses to your form in CSV format.",
|
"download_responses_description": "Download all responses to your form in CSV format.",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"download_recording": "Download Recording",
|
"download_recording": "Download Recording",
|
||||||
"recording_from_your_recent_call":"A recording from your recent call on Cal.com 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": "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_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",
|
"create_your_first_webhook": "Create your first Webhook",
|
||||||
@@ -1381,7 +1396,6 @@
|
|||||||
"password_updated": "Password updated!",
|
"password_updated": "Password updated!",
|
||||||
"pending_payment": "Pending payment",
|
"pending_payment": "Pending payment",
|
||||||
"pending_invites": "Pending Invites",
|
"pending_invites": "Pending Invites",
|
||||||
"confirmation_page_rainbow": "Token gate your event with tokens or NFTs on Ethereum, Polygon, and more.",
|
|
||||||
"not_on_cal": "Not on {{appName}}",
|
"not_on_cal": "Not on {{appName}}",
|
||||||
"no_calendar_installed": "No calendar installed",
|
"no_calendar_installed": "No calendar installed",
|
||||||
"no_calendar_installed_description": "You have not yet connected any of your calendars",
|
"no_calendar_installed_description": "You have not yet connected any of your calendars",
|
||||||
@@ -1495,8 +1509,8 @@
|
|||||||
"find_the_best_person": "Find the best person available and cycle through your team.",
|
"find_the_best_person": "Find the best person available and cycle through your team.",
|
||||||
"fixed_round_robin": "Fixed round robin",
|
"fixed_round_robin": "Fixed round robin",
|
||||||
"add_one_fixed_attendee": "Add one fixed attendee and round robin through a number of attendees.",
|
"add_one_fixed_attendee": "Add one fixed attendee and round robin through a number of attendees.",
|
||||||
"calcom_is_better_with_team": "Cal.com is better with teams",
|
"calcom_is_better_with_team": "{{appName}} is better with teams",
|
||||||
"the_calcom_team":"The Cal.com 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.",
|
"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",
|
"booking_limit_reached": "Booking Limit for this event type has been reached",
|
||||||
"duration_limit_reached": "Duration Limit for this event type has been reached",
|
"duration_limit_reached": "Duration Limit for this event type has been reached",
|
||||||
@@ -1515,7 +1529,7 @@
|
|||||||
"navigate_installed_apps": "Go to installed apps",
|
"navigate_installed_apps": "Go to installed apps",
|
||||||
"disabled_calendar": "If you have another calendar installed new bookings will be added to it. If not then connect a new calendar so you do not miss any new bookings.",
|
"disabled_calendar": "If you have another calendar installed new bookings will be added to it. If not then connect a new calendar so you do not miss any new bookings.",
|
||||||
"enable_apps": "Enable Apps",
|
"enable_apps": "Enable Apps",
|
||||||
"enable_apps_description": "Enable apps that users can integrate with Cal.com",
|
"enable_apps_description": "Enable apps that users can integrate with {{appName}}",
|
||||||
"purchase_license": "Purchase a License",
|
"purchase_license": "Purchase a License",
|
||||||
"already_have_key": "I already have a key:",
|
"already_have_key": "I already have a key:",
|
||||||
"already_have_key_suggestion": "Please copy your existing CALCOM_LICENSE_KEY environment variable here.",
|
"already_have_key_suggestion": "Please copy your existing CALCOM_LICENSE_KEY environment variable here.",
|
||||||
@@ -1672,6 +1686,7 @@
|
|||||||
"booking_questions_title": "Booking questions",
|
"booking_questions_title": "Booking questions",
|
||||||
"booking_questions_description": "Customize the questions asked on the booking page",
|
"booking_questions_description": "Customize the questions asked on the booking page",
|
||||||
"add_a_booking_question": "Add a question",
|
"add_a_booking_question": "Add a question",
|
||||||
|
"identifier": "Identifier",
|
||||||
"duplicate_email": "Email is duplicate",
|
"duplicate_email": "Email is duplicate",
|
||||||
"booking_with_payment_cancelled": "Paying for this event is no longer possible",
|
"booking_with_payment_cancelled": "Paying for this event is no longer possible",
|
||||||
"booking_with_payment_cancelled_already_paid": "A refund for this booking payment it's on the way.",
|
"booking_with_payment_cancelled_already_paid": "A refund for this booking payment it's on the way.",
|
||||||
@@ -1680,7 +1695,7 @@
|
|||||||
"not_enough_seats": "Not enough seats",
|
"not_enough_seats": "Not enough seats",
|
||||||
"form_builder_field_already_exists": "A field with this name already exists",
|
"form_builder_field_already_exists": "A field with this name already exists",
|
||||||
"form_builder_field_add_subtitle": "Customize the questions asked on the booking page",
|
"form_builder_field_add_subtitle": "Customize the questions asked on the booking page",
|
||||||
"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",
|
"get_started_zapier_templates": "Get started with Zapier templates",
|
||||||
"team_is_unpublished": "{{team}} is unpublished",
|
"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 team link is currently not available. Please contact the team owner or ask them publish it.",
|
||||||
@@ -1713,6 +1728,7 @@
|
|||||||
"spot_popular_event_types": "Spot popular event types",
|
"spot_popular_event_types": "Spot popular event types",
|
||||||
"spot_popular_event_types_description": "See which of your event types are receiving the most clicks and bookings",
|
"spot_popular_event_types_description": "See which of your event types are receiving the most clicks and bookings",
|
||||||
"no_responses_yet": "No responses yet",
|
"no_responses_yet": "No responses yet",
|
||||||
|
"no_routes_defined": "No routes defined",
|
||||||
"this_will_be_the_placeholder": "This will be the placeholder",
|
"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 occured when booking the event, please refresh the page and try again",
|
||||||
"timeslot_missing_title": "No timeslot selected",
|
"timeslot_missing_title": "No timeslot selected",
|
||||||
@@ -1811,6 +1827,17 @@
|
|||||||
"complete_your_booking": "Complete your booking",
|
"complete_your_booking": "Complete your booking",
|
||||||
"complete_your_booking_subject": "Complete your booking: {{title}} on {{date}}",
|
"complete_your_booking_subject": "Complete your booking: {{title}} on {{date}}",
|
||||||
"confirm_your_details": "Confirm your details",
|
"confirm_your_details": "Confirm your details",
|
||||||
|
"copy_invite_link": "Copy invite link",
|
||||||
|
"edit_invite_link": "Edit link settings",
|
||||||
|
"invite_link_copied": "Invite link copied",
|
||||||
|
"invite_link_deleted": "Invite link deleted",
|
||||||
|
"invite_link_updated": "Invite link settings saved",
|
||||||
|
"link_expires_after": "Links set to expire after...",
|
||||||
|
"one_day": "1 day",
|
||||||
|
"seven_days": "7 days",
|
||||||
|
"thirty_days": "30 days",
|
||||||
|
"never_expire": "Never expires",
|
||||||
|
"team_invite_received": "You have been invited to join {{teamName}}",
|
||||||
"currency_string": "{{amount, currency}}",
|
"currency_string": "{{amount, currency}}",
|
||||||
"charge_card_dialog_body": "You are about to charge the attendee {{amount, currency}}. Are you sure you want to continue?",
|
"charge_card_dialog_body": "You are about to charge the attendee {{amount, currency}}. Are you sure you want to continue?",
|
||||||
"charge_attendee": "Charge attendee {{amount, currency}}",
|
"charge_attendee": "Charge attendee {{amount, currency}}",
|
||||||
@@ -1840,5 +1867,7 @@
|
|||||||
"connect_google_workspace":"Connect Google Workspace",
|
"connect_google_workspace":"Connect Google Workspace",
|
||||||
"google_workspace_admin_tooltip":"You must be a Workspace Admin to use this feature",
|
"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",
|
"first_event_type_webhook_description": "Create your first webhook for this event type",
|
||||||
"create_for": "Create for"
|
"create_for": "Create for",
|
||||||
|
"additional_url_parameters": "Additional URL parameters",
|
||||||
|
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
"calcom_explained_new_user": "¡Termine de configurar su cuenta de {{appName}}! Solo le faltan unos pasos para resolver todos sus problemas de programación.",
|
"calcom_explained_new_user": "¡Termine de configurar su cuenta de {{appName}}! Solo le faltan unos pasos para resolver todos sus problemas de programación.",
|
||||||
"have_any_questions": "¿Tienes preguntas? Estamos aquí para ayudar.",
|
"have_any_questions": "¿Tienes preguntas? Estamos aquí para ayudar.",
|
||||||
"reset_password_subject": "{{appName}}: Instrucciones para restablecer la contraseña",
|
"reset_password_subject": "{{appName}}: Instrucciones para restablecer la contraseña",
|
||||||
|
"verify_email_banner_button": "Enviar correo electrónico",
|
||||||
"event_declined_subject": "Rechazado: {{title}} en {{date}}",
|
"event_declined_subject": "Rechazado: {{title}} en {{date}}",
|
||||||
"event_cancelled_subject": "Cancelado: {{title}} en {{date}}",
|
"event_cancelled_subject": "Cancelado: {{title}} en {{date}}",
|
||||||
"event_request_declined": "Su solicitud de reunión ha sido rechazada",
|
"event_request_declined": "Su solicitud de reunión ha sido rechazada",
|
||||||
@@ -630,8 +631,6 @@
|
|||||||
"event_type_created_successfully": "{{eventTypeTitle}} tipo de evento creado con éxito",
|
"event_type_created_successfully": "{{eventTypeTitle}} tipo de evento creado con éxito",
|
||||||
"event_type_updated_successfully": "{{eventTypeTitle}} tipo de evento actualizado con éxito",
|
"event_type_updated_successfully": "{{eventTypeTitle}} tipo de evento actualizado con éxito",
|
||||||
"event_type_deleted_successfully": "Tipo de evento eliminado con éxito",
|
"event_type_deleted_successfully": "Tipo de evento eliminado con éxito",
|
||||||
"web3_metamask_added": "Metamask ha sido añadido exitosamente",
|
|
||||||
"web3_metamask_disconnected": "Metamask ha sido removido exitosamente",
|
|
||||||
"hours": "Horas",
|
"hours": "Horas",
|
||||||
"your_email": "Tu Email",
|
"your_email": "Tu Email",
|
||||||
"change_avatar": "Cambiar Avatar",
|
"change_avatar": "Cambiar Avatar",
|
||||||
@@ -872,7 +871,6 @@
|
|||||||
"installed_one": "Instalada",
|
"installed_one": "Instalada",
|
||||||
"installed_other": "{{count}} instaladas",
|
"installed_other": "{{count}} instaladas",
|
||||||
"verify_wallet": "Verificar billetera",
|
"verify_wallet": "Verificar billetera",
|
||||||
"connect_metamask": "Conectar Metamask",
|
|
||||||
"create_events_on": "Crear eventos en",
|
"create_events_on": "Crear eventos en",
|
||||||
"enterprise_license": "Esta es una función empresarial",
|
"enterprise_license": "Esta es una función empresarial",
|
||||||
"enterprise_license_description": "Para habilitar esta función, obtenga una clave de despliegue en la consola {{consoleUrl}} y añádala a su .env como CALCOM_LICENSE_KEY. Si su equipo ya tiene una licencia, póngase en contacto con {{supportMail}} para obtener ayuda.",
|
"enterprise_license_description": "Para habilitar esta función, obtenga una clave de despliegue en la consola {{consoleUrl}} y añádala a su .env como CALCOM_LICENSE_KEY. Si su equipo ya tiene una licencia, póngase en contacto con {{supportMail}} para obtener ayuda.",
|
||||||
@@ -898,6 +896,7 @@
|
|||||||
"availability_updated_successfully": "El horario de {{scheduleName}} se actualizó correctamente",
|
"availability_updated_successfully": "El horario de {{scheduleName}} se actualizó correctamente",
|
||||||
"schedule_deleted_successfully": "Programación eliminada exitosamente",
|
"schedule_deleted_successfully": "Programación eliminada exitosamente",
|
||||||
"default_schedule_name": "Horas laborables",
|
"default_schedule_name": "Horas laborables",
|
||||||
|
"member_default_schedule": "Horario predeterminado del miembro",
|
||||||
"new_schedule_heading": "Crear un horario de disponibilidad",
|
"new_schedule_heading": "Crear un horario de disponibilidad",
|
||||||
"new_schedule_description": "Crear horarios de disponibilidad le permite gestionar la disponibilidad a través de tipos de eventos. Pueden aplicarse a uno o más tipos de eventos.",
|
"new_schedule_description": "Crear horarios de disponibilidad le permite gestionar la disponibilidad a través de tipos de eventos. Pueden aplicarse a uno o más tipos de eventos.",
|
||||||
"requires_ownership_of_a_token": "Requiere la propiedad de un token perteneciente a la siguiente dirección:",
|
"requires_ownership_of_a_token": "Requiere la propiedad de un token perteneciente a la siguiente dirección:",
|
||||||
@@ -1050,7 +1049,6 @@
|
|||||||
"new_event_trigger": "cuando se reserva un nuevo evento",
|
"new_event_trigger": "cuando se reserva un nuevo evento",
|
||||||
"email_host_action": "enviar correo electrónico al anfitrión",
|
"email_host_action": "enviar correo electrónico al anfitrión",
|
||||||
"email_attendee_action": "enviar correo electrónico a los asistentes",
|
"email_attendee_action": "enviar correo electrónico a los asistentes",
|
||||||
"sms_attendee_action": "enviar SMS al asistente",
|
|
||||||
"sms_number_action": "enviar SMS a un número específico",
|
"sms_number_action": "enviar SMS a un número específico",
|
||||||
"workflows": "Flujos de trabajo",
|
"workflows": "Flujos de trabajo",
|
||||||
"new_workflow_btn": "Flujo de trabajo nuevo",
|
"new_workflow_btn": "Flujo de trabajo nuevo",
|
||||||
@@ -1227,11 +1225,6 @@
|
|||||||
"upload": "Cargar",
|
"upload": "Cargar",
|
||||||
"add_profile_photo": "Agregar foto de perfil",
|
"add_profile_photo": "Agregar foto de perfil",
|
||||||
"web3": "Web3",
|
"web3": "Web3",
|
||||||
"rainbow_token_gated": "Este tipo de evento tiene acceso cerrado por token.",
|
|
||||||
"rainbow_connect_wallet_gate": "Conecta tu billetera si posees <1>{{name}}</1> (<3>{{symbol}}</3>).",
|
|
||||||
"rainbow_insufficient_balance": "Tu billetera conectada no contiene suficiente <1>{{symbol}}</1>.",
|
|
||||||
"rainbow_sign_message_request": "Firma la solicitud de mensaje en tu billetera.",
|
|
||||||
"rainbow_signature_error": "Error al solicitar la firma desde tu billetera.",
|
|
||||||
"token_address": "Dirección del token",
|
"token_address": "Dirección del token",
|
||||||
"blockchain": "Blockchain",
|
"blockchain": "Blockchain",
|
||||||
"old_password": "Contraseña anterior",
|
"old_password": "Contraseña anterior",
|
||||||
@@ -1294,7 +1287,6 @@
|
|||||||
"download_responses_description": "Descargue todas las respuestas de su formulario en formato CSV.",
|
"download_responses_description": "Descargue todas las respuestas de su formulario en formato CSV.",
|
||||||
"download": "Descargar",
|
"download": "Descargar",
|
||||||
"download_recording": "Descargar grabación",
|
"download_recording": "Descargar grabación",
|
||||||
"recording_from_your_recent_call": "Una grabación de su llamada reciente en Cal.com está lista para su descarga",
|
|
||||||
"create_your_first_form": "Crea tu primer formulario",
|
"create_your_first_form": "Crea tu primer formulario",
|
||||||
"create_your_first_form_description": "Con los formularios de orientación puedes hacer preguntas calificadoras y encaminarte hacia la persona o tipo de evento correctos.",
|
"create_your_first_form_description": "Con los formularios de orientación puedes hacer preguntas calificadoras y encaminarte hacia la persona o tipo de evento correctos.",
|
||||||
"create_your_first_webhook": "Crea tu primer Webhook",
|
"create_your_first_webhook": "Crea tu primer Webhook",
|
||||||
@@ -1377,7 +1369,6 @@
|
|||||||
"password_updated": "¡Contraseña actualizada!",
|
"password_updated": "¡Contraseña actualizada!",
|
||||||
"pending_payment": "Pago pendiente",
|
"pending_payment": "Pago pendiente",
|
||||||
"pending_invites": "Invitaciones pendientes",
|
"pending_invites": "Invitaciones pendientes",
|
||||||
"confirmation_page_rainbow": "Cierra el acceso a tu evento con tokens o NFTs en Ethereum, Polygon, etc.",
|
|
||||||
"not_on_cal": "No estás en {{appName}}",
|
"not_on_cal": "No estás en {{appName}}",
|
||||||
"no_calendar_installed": "No hay ningún calendario instalado",
|
"no_calendar_installed": "No hay ningún calendario instalado",
|
||||||
"no_calendar_installed_description": "Aún no has conectado ninguno de tus calendarios",
|
"no_calendar_installed_description": "Aún no has conectado ninguno de tus calendarios",
|
||||||
@@ -1491,8 +1482,6 @@
|
|||||||
"find_the_best_person": "Encuentre a la mejor persona disponible y haga una rotación en su equipo.",
|
"find_the_best_person": "Encuentre a la mejor persona disponible y haga una rotación en su equipo.",
|
||||||
"fixed_round_robin": "Rotación fija por turnos",
|
"fixed_round_robin": "Rotación fija por turnos",
|
||||||
"add_one_fixed_attendee": "Agregue un asistente fijo y realice rotación por turnos a través de un número de asistentes.",
|
"add_one_fixed_attendee": "Agregue un asistente fijo y realice rotación por turnos a través de un número de asistentes.",
|
||||||
"calcom_is_better_with_team": "Cal.com funciona mejor con equipos",
|
|
||||||
"the_calcom_team": "El equipo de Cal.com",
|
|
||||||
"add_your_team_members": "Añada los miembros de su equipo a sus tipos de eventos. Utilice la programación colectiva para incluir a todos o encuentre a la persona más adecuada con programación de rotación por turnos.",
|
"add_your_team_members": "Añada los miembros de su equipo a sus tipos de eventos. Utilice la programación colectiva para incluir a todos o encuentre a la persona más adecuada con programación de rotación por turnos.",
|
||||||
"booking_limit_reached": "Se ha alcanzado el límite de reserva para este tipo de evento",
|
"booking_limit_reached": "Se ha alcanzado el límite de reserva para este tipo de evento",
|
||||||
"duration_limit_reached": "Se ha alcanzado el límite de duración para este tipo de evento",
|
"duration_limit_reached": "Se ha alcanzado el límite de duración para este tipo de evento",
|
||||||
@@ -1511,7 +1500,6 @@
|
|||||||
"navigate_installed_apps": "Ir a las aplicaciones instaladas",
|
"navigate_installed_apps": "Ir a las aplicaciones instaladas",
|
||||||
"disabled_calendar": "Si tiene otro calendario instalado, las nuevas reservas se añadirán a él. De lo contrario, conecte un nuevo calendario para que no se pierda ninguna reserva nueva.",
|
"disabled_calendar": "Si tiene otro calendario instalado, las nuevas reservas se añadirán a él. De lo contrario, conecte un nuevo calendario para que no se pierda ninguna reserva nueva.",
|
||||||
"enable_apps": "Activar aplicaciones",
|
"enable_apps": "Activar aplicaciones",
|
||||||
"enable_apps_description": "Active aplicaciones que los usuarios puedan integrar con Cal.com",
|
|
||||||
"purchase_license": "Compre una licencia",
|
"purchase_license": "Compre una licencia",
|
||||||
"already_have_key": "Ya tengo una clave:",
|
"already_have_key": "Ya tengo una clave:",
|
||||||
"already_have_key_suggestion": "Copie aquí su variable de entorno CALCOM_LICENSE_KEY existente.",
|
"already_have_key_suggestion": "Copie aquí su variable de entorno CALCOM_LICENSE_KEY existente.",
|
||||||
@@ -1807,6 +1795,7 @@
|
|||||||
"complete_your_booking": "Complete su reserva",
|
"complete_your_booking": "Complete su reserva",
|
||||||
"complete_your_booking_subject": "Complete su reserva: {{title}} el {{date}}",
|
"complete_your_booking_subject": "Complete su reserva: {{title}} el {{date}}",
|
||||||
"confirm_your_details": "Confirme sus datos",
|
"confirm_your_details": "Confirme sus datos",
|
||||||
|
"never_expire": "Nunca caduca",
|
||||||
"currency_string": "{{amount, currency}}",
|
"currency_string": "{{amount, currency}}",
|
||||||
"charge_card_dialog_body": "Está a punto de cobrarle {{amount, currency}} al asistente. ¿Está seguro de que desea continuar?",
|
"charge_card_dialog_body": "Está a punto de cobrarle {{amount, currency}} al asistente. ¿Está seguro de que desea continuar?",
|
||||||
"charge_attendee": "Cobrarle al asistente {{amount, currency}}",
|
"charge_attendee": "Cobrarle al asistente {{amount, currency}}",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"calcom_explained_new_user": "Terminez la configuration de votre compte {{appName}} ! Vous n'êtes qu'à quelques pas de résoudre tous vos problèmes de planification.",
|
"calcom_explained_new_user": "Terminez la configuration de votre compte {{appName}} ! Vous n'êtes qu'à quelques pas de résoudre tous vos problèmes de planification.",
|
||||||
"have_any_questions": "Vous avez des questions ? Nous sommes là pour vous aider.",
|
"have_any_questions": "Vous avez des questions ? Nous sommes là pour vous aider.",
|
||||||
"reset_password_subject": "{{appName}} : Instructions de réinitialisation de mot de passe",
|
"reset_password_subject": "{{appName}} : Instructions de réinitialisation de mot de passe",
|
||||||
|
"verify_email_banner_button": "Envoyer un e-mail",
|
||||||
"event_declined_subject": "Refusé : {{title}} le {{date}}",
|
"event_declined_subject": "Refusé : {{title}} le {{date}}",
|
||||||
"event_cancelled_subject": "Annulé : {{title}} le {{date}}",
|
"event_cancelled_subject": "Annulé : {{title}} le {{date}}",
|
||||||
"event_request_declined": "Votre demande d'événement a été refusée",
|
"event_request_declined": "Votre demande d'événement a été refusée",
|
||||||
@@ -26,6 +27,8 @@
|
|||||||
"rejection_confirmation": "Refuser la réservation",
|
"rejection_confirmation": "Refuser la réservation",
|
||||||
"manage_this_event": "Gérer cet événement",
|
"manage_this_event": "Gérer cet événement",
|
||||||
"invite_team_member": "Inviter un membre d'équipe",
|
"invite_team_member": "Inviter un membre d'équipe",
|
||||||
|
"invite_team_individual_segment": "Inviter une personne",
|
||||||
|
"invite_team_bulk_segment": "Importation multiple",
|
||||||
"invite_team_notifcation_badge": "Inv.",
|
"invite_team_notifcation_badge": "Inv.",
|
||||||
"your_event_has_been_scheduled": "Votre événement a été planifié",
|
"your_event_has_been_scheduled": "Votre événement a été planifié",
|
||||||
"your_event_has_been_scheduled_recurring": "Votre événement récurrent a été planifié",
|
"your_event_has_been_scheduled_recurring": "Votre événement récurrent a été planifié",
|
||||||
@@ -193,6 +196,7 @@
|
|||||||
"page_doesnt_exist": "Cette page n'existe pas.",
|
"page_doesnt_exist": "Cette page n'existe pas.",
|
||||||
"check_spelling_mistakes_or_go_back": "Vérifiez s'il y a des erreurs d'orthographe ou retournez à la page précédente.",
|
"check_spelling_mistakes_or_go_back": "Vérifiez s'il y a des erreurs d'orthographe ou retournez à la page précédente.",
|
||||||
"404_page_not_found": "404 : Cette page est introuvable.",
|
"404_page_not_found": "404 : Cette page est introuvable.",
|
||||||
|
"booker_event_not_found": "Nous n'avons pas pu trouver l'événement que vous essayez de réserver.",
|
||||||
"getting_started": "Commencer",
|
"getting_started": "Commencer",
|
||||||
"15min_meeting": "Rendez-vous de 15 min",
|
"15min_meeting": "Rendez-vous de 15 min",
|
||||||
"30min_meeting": "Rendez-vous de 30 min",
|
"30min_meeting": "Rendez-vous de 30 min",
|
||||||
@@ -222,6 +226,7 @@
|
|||||||
"go_back_login": "Retour à la page de connexion",
|
"go_back_login": "Retour à la page de connexion",
|
||||||
"error_during_login": "Une erreur s'est produite lors de votre connexion. Retournez à l'écran de connexion et réessayez.",
|
"error_during_login": "Une erreur s'est produite lors de votre connexion. Retournez à l'écran de connexion et réessayez.",
|
||||||
"request_password_reset": "Envoyer l'email de réinitialisation",
|
"request_password_reset": "Envoyer l'email de réinitialisation",
|
||||||
|
"send_invite": "Envoyer l'invitation",
|
||||||
"forgot_password": "Mot de passe oublié ?",
|
"forgot_password": "Mot de passe oublié ?",
|
||||||
"forgot": "Oublié ?",
|
"forgot": "Oublié ?",
|
||||||
"done": "Terminé",
|
"done": "Terminé",
|
||||||
@@ -290,6 +295,18 @@
|
|||||||
"success": "Succès",
|
"success": "Succès",
|
||||||
"failed": "Échoué",
|
"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.",
|
"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",
|
||||||
|
"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_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.",
|
||||||
|
"bookerlayout_override_global_settings": "Vous pouvez gérer cela pour tous vos types d'événements dans <2>Paramètres / Apparence</2> ou <6>l'appliquer uniquement à cet événement</6>.",
|
||||||
"unexpected_error_try_again": "Une erreur inattendue s'est produite. Veuillez réessayer.",
|
"unexpected_error_try_again": "Une erreur inattendue s'est produite. Veuillez réessayer.",
|
||||||
"sunday_time_error": "Heure non valide le dimanche",
|
"sunday_time_error": "Heure non valide le dimanche",
|
||||||
"monday_time_error": "Créneau invalide le lundi",
|
"monday_time_error": "Créneau invalide le lundi",
|
||||||
@@ -360,6 +377,7 @@
|
|||||||
"user_dynamic_booking_disabled": "Certains utilisateurs du groupe ont actuellement désactivé les réservations de groupe dynamiques",
|
"user_dynamic_booking_disabled": "Certains utilisateurs du groupe ont actuellement désactivé les réservations de groupe dynamiques",
|
||||||
"allow_dynamic_booking_tooltip": "Les liens de réservation de groupe peuvent être créés dynamiquement en ajoutant plusieurs noms d'utilisateur séparés par un « + ». Exemple : « {{appName}}/bailey+peer ».",
|
"allow_dynamic_booking_tooltip": "Les liens de réservation de groupe peuvent être créés dynamiquement en ajoutant plusieurs noms d'utilisateur séparés par un « + ». Exemple : « {{appName}}/bailey+peer ».",
|
||||||
"allow_dynamic_booking": "Autoriser les participants à prendre rendez-vous avec vous via des réservations de groupe dynamiques",
|
"allow_dynamic_booking": "Autoriser les participants à prendre rendez-vous avec vous via des réservations de groupe dynamiques",
|
||||||
|
"dynamic_booking": "Liens de groupe dynamiques",
|
||||||
"email": "E-mail",
|
"email": "E-mail",
|
||||||
"email_placeholder": "jdoe@exemple.com",
|
"email_placeholder": "jdoe@exemple.com",
|
||||||
"full_name": "Nom complet",
|
"full_name": "Nom complet",
|
||||||
@@ -370,6 +388,8 @@
|
|||||||
"booking_rescheduled": "Réservation replanifié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 d'enregistrement prêt",
|
||||||
"booking_created": "Réservation créée",
|
"booking_created": "Réservation créée",
|
||||||
|
"booking_rejected": "Réservation rejetée",
|
||||||
|
"booking_requested": "Réservation demandée",
|
||||||
"meeting_ended": "Rendez-vous terminé",
|
"meeting_ended": "Rendez-vous terminé",
|
||||||
"form_submitted": "Formulaire envoyé",
|
"form_submitted": "Formulaire envoyé",
|
||||||
"event_triggers": "Déclencheurs d'événement",
|
"event_triggers": "Déclencheurs d'événement",
|
||||||
@@ -503,7 +523,7 @@
|
|||||||
"or": "OU",
|
"or": "OU",
|
||||||
"go_back": "Retour",
|
"go_back": "Retour",
|
||||||
"email_or_username": "Adresse e-mail ou identifiant",
|
"email_or_username": "Adresse e-mail ou identifiant",
|
||||||
"send_invite_email": "Envoyer un e-mail d'invitation",
|
"send_invite_email": "Envoyer une invitation par e-mail",
|
||||||
"role": "Rôle",
|
"role": "Rôle",
|
||||||
"edit_role": "Modifier le rôle",
|
"edit_role": "Modifier le rôle",
|
||||||
"edit_team": "Modifier l'équipe",
|
"edit_team": "Modifier l'équipe",
|
||||||
@@ -627,8 +647,6 @@
|
|||||||
"event_type_created_successfully": "Type d'événement {{eventTypeTitle}} créé avec succès",
|
"event_type_created_successfully": "Type d'événement {{eventTypeTitle}} créé avec succès",
|
||||||
"event_type_updated_successfully": "Type d'événement {{eventTypeTitle}} mis à jour avec succès",
|
"event_type_updated_successfully": "Type d'événement {{eventTypeTitle}} mis à jour avec succès",
|
||||||
"event_type_deleted_successfully": "Type d'événement supprimé avec succès",
|
"event_type_deleted_successfully": "Type d'événement supprimé avec succès",
|
||||||
"web3_metamask_added": "MetaMask ajouté avec succès",
|
|
||||||
"web3_metamask_disconnected": "MetaMask déconnecté avec succès",
|
|
||||||
"hours": "heures",
|
"hours": "heures",
|
||||||
"your_email": "Votre adresse e-mail",
|
"your_email": "Votre adresse e-mail",
|
||||||
"change_avatar": "Changer d'avatar",
|
"change_avatar": "Changer d'avatar",
|
||||||
@@ -755,6 +773,10 @@
|
|||||||
"new_event_type_to_book_description": "Créez un nouveau type d’événement pour que les personnes puissent effectuer des réservations.",
|
"new_event_type_to_book_description": "Créez un nouveau type d’événement pour que les personnes puissent effectuer des réservations.",
|
||||||
"length": "Durée",
|
"length": "Durée",
|
||||||
"minimum_booking_notice": "Préavis minimum",
|
"minimum_booking_notice": "Préavis minimum",
|
||||||
|
"offset_toggle": "Décalage de l'heure de début",
|
||||||
|
"offset_toggle_description": "Appliquez un décalage de durée spécifique aux créneaux horaires affichés aux utilisateurs.",
|
||||||
|
"offset_start": "Décalage de",
|
||||||
|
"offset_start_description": "p. ex. cela affichera les créneaux à vos utilisateurs à {{ adjustedTime }} au lieu de {{ originalTime }}",
|
||||||
"slot_interval": "Fréquence de créneaux horaires",
|
"slot_interval": "Fréquence de créneaux horaires",
|
||||||
"slot_interval_default": "Utiliser la durée de l'événement (par défaut)",
|
"slot_interval_default": "Utiliser la durée de l'événement (par défaut)",
|
||||||
"delete_event_type": "Supprimer le type d'événement ?",
|
"delete_event_type": "Supprimer le type d'événement ?",
|
||||||
@@ -789,7 +811,7 @@
|
|||||||
"connect_your_favourite_apps": "Connectez vos applications favorites.",
|
"connect_your_favourite_apps": "Connectez vos applications favorites.",
|
||||||
"automation": "Automatisation",
|
"automation": "Automatisation",
|
||||||
"configure_how_your_event_types_interact": "Configurez la manière dont vos types d'événements doivent interagir avec vos calendriers.",
|
"configure_how_your_event_types_interact": "Configurez la manière dont vos types d'événements doivent interagir avec vos calendriers.",
|
||||||
"toggle_calendars_conflict": "Activez/désactivez les calendriers pour lesquels vous souhaitez vérifier les conflits afin d'éviter les réservations en double.",
|
"toggle_calendars_conflict": "Activez/désactivez les calendriers pour lesquels vous souhaitez vérifier les conflits afin d'éviter les doubles réservations.",
|
||||||
"select_destination_calendar": "Créer des événements dans :",
|
"select_destination_calendar": "Créer des événements dans :",
|
||||||
"connect_additional_calendar": "Connecter un calendrier supplémentaire",
|
"connect_additional_calendar": "Connecter un calendrier supplémentaire",
|
||||||
"calendar_updated_successfully": "Calendrier mis à jour avec succès",
|
"calendar_updated_successfully": "Calendrier mis à jour avec succès",
|
||||||
@@ -828,14 +850,14 @@
|
|||||||
"installed_apps": "Apps installées",
|
"installed_apps": "Apps installées",
|
||||||
"free_to_use_apps": "Gratuit",
|
"free_to_use_apps": "Gratuit",
|
||||||
"no_category_apps": "Aucune application {{category}}",
|
"no_category_apps": "Aucune application {{category}}",
|
||||||
"no_category_apps_description_calendar": "Ajoutez une application de calendrier pour vérifier les conflits et éviter les réservations en double.",
|
"no_category_apps_description_calendar": "Ajoutez une application de calendrier pour vérifier les conflits et éviter les doubles réservations.",
|
||||||
"no_category_apps_description_conferencing": "Essayez d'ajouter une application de visioconférence pour intégrer les appels vidéo avec vos clients.",
|
"no_category_apps_description_conferencing": "Essayez d'ajouter une application de visioconférence pour intégrer les appels vidéo avec vos clients.",
|
||||||
"no_category_apps_description_payment": "Ajoutez une application de paiement pour faciliter les transactions entre vous et vos clients.",
|
"no_category_apps_description_payment": "Ajoutez une application de paiement pour faciliter les transactions entre vous et vos clients.",
|
||||||
"no_category_apps_description_analytics": "Ajoutez une application d'analyse pour vos pages de réservation.",
|
"no_category_apps_description_analytics": "Ajoutez une application d'analyse pour vos pages de réservation.",
|
||||||
"no_category_apps_description_automation": "Ajoutez une application d'automatisation.",
|
"no_category_apps_description_automation": "Ajoutez une application d'automatisation.",
|
||||||
"no_category_apps_description_other": "Ajoutez n'importe quel autre type d'application pour faire toutes sortes de choses.",
|
"no_category_apps_description_other": "Ajoutez n'importe quel autre type d'application pour faire toutes sortes de choses.",
|
||||||
"no_category_apps_description_web3": "Ajoutez une application Web3 pour vos pages de réservation.",
|
"no_category_apps_description_web3": "Ajoutez une application Web3 pour vos pages de réservation.",
|
||||||
"installed_app_calendar_description": "Définissez les calendriers pour vérifier les conflits afin d'éviter les réservations en double.",
|
"installed_app_calendar_description": "Définissez les calendriers pour vérifier les conflits afin d'éviter les doubles réservations.",
|
||||||
"installed_app_conferencing_description": "Ajoutez vos applications de visioconférence préférées pour vos rendez-vous.",
|
"installed_app_conferencing_description": "Ajoutez vos applications de visioconférence préférées pour vos rendez-vous.",
|
||||||
"installed_app_payment_description": "Configurez les services de traitement de paiement à utiliser lors de la facturation de vos clients.",
|
"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_analytics_description": "Configurez les applications d'analyse à utiliser pour vos pages de réservation.",
|
||||||
@@ -865,7 +887,6 @@
|
|||||||
"installed_one": "Installée",
|
"installed_one": "Installée",
|
||||||
"installed_other": "{{count}} installation(s)",
|
"installed_other": "{{count}} installation(s)",
|
||||||
"verify_wallet": "Vérifier le portefeuille",
|
"verify_wallet": "Vérifier le portefeuille",
|
||||||
"connect_metamask": "Connecter MetaMask",
|
|
||||||
"create_events_on": "Créer des événements dans :",
|
"create_events_on": "Créer des événements dans :",
|
||||||
"enterprise_license": "Il s'agit d'une fonctionnalité d'entreprise",
|
"enterprise_license": "Il s'agit d'une fonctionnalité d'entreprise",
|
||||||
"enterprise_license_description": "Pour activer cette fonctionnalité, demandez à un administrateur d'accéder à {{setupUrl}} pour saisir une clé de licence. Si une clé de licence est déjà en place, veuillez contacter {{supportMail}} pour obtenir de l'aide.",
|
"enterprise_license_description": "Pour activer cette fonctionnalité, demandez à un administrateur d'accéder à {{setupUrl}} pour saisir une clé de licence. Si une clé de licence est déjà en place, veuillez contacter {{supportMail}} pour obtenir de l'aide.",
|
||||||
@@ -891,6 +912,7 @@
|
|||||||
"availability_updated_successfully": "Planning {{scheduleName}} mis à jour avec succès",
|
"availability_updated_successfully": "Planning {{scheduleName}} mis à jour avec succès",
|
||||||
"schedule_deleted_successfully": "Planning supprimé avec succès",
|
"schedule_deleted_successfully": "Planning supprimé avec succès",
|
||||||
"default_schedule_name": "Heures de travail",
|
"default_schedule_name": "Heures de travail",
|
||||||
|
"member_default_schedule": "Planning par défaut du membre",
|
||||||
"new_schedule_heading": "Créer un planning de disponibilité",
|
"new_schedule_heading": "Créer un planning de disponibilité",
|
||||||
"new_schedule_description": "La création de plannings de disponibilité vous permet de gérer la disponibilité pour tous les types d'événements. Ils peuvent être appliqués à un ou plusieurs types d'événements.",
|
"new_schedule_description": "La création de plannings de disponibilité vous permet de gérer la disponibilité pour tous les types d'événements. Ils peuvent être appliqués à un ou plusieurs types d'événements.",
|
||||||
"requires_ownership_of_a_token": "Nécessite la propriété d'un token appartenant à l'adresse suivante :",
|
"requires_ownership_of_a_token": "Nécessite la propriété d'un token appartenant à l'adresse suivante :",
|
||||||
@@ -907,6 +929,7 @@
|
|||||||
"duplicate": "Dupliquer",
|
"duplicate": "Dupliquer",
|
||||||
"offer_seats": "Proposer des places",
|
"offer_seats": "Proposer des places",
|
||||||
"offer_seats_description": "Proposez des places de réservation. Cela désactive automatiquement les réservations d'invités et d'opt-in.",
|
"offer_seats_description": "Proposez des places de réservation. Cela désactive automatiquement les réservations d'invités et d'opt-in.",
|
||||||
|
"seats_available_one": "Place disponible",
|
||||||
"seats_available_other": "places disponibles",
|
"seats_available_other": "places disponibles",
|
||||||
"number_of_seats": "Nombre de places par réservation",
|
"number_of_seats": "Nombre de places par réservation",
|
||||||
"enter_number_of_seats": "Saisir le nombre de sièges",
|
"enter_number_of_seats": "Saisir le nombre de sièges",
|
||||||
@@ -1042,7 +1065,7 @@
|
|||||||
"new_event_trigger": "lorsqu'un nouvel événement est réservé",
|
"new_event_trigger": "lorsqu'un nouvel événement est réservé",
|
||||||
"email_host_action": "envoyer un e-mail à l'hôte",
|
"email_host_action": "envoyer un e-mail à l'hôte",
|
||||||
"email_attendee_action": "envoyer un e-mail aux participants",
|
"email_attendee_action": "envoyer un e-mail aux participants",
|
||||||
"sms_attendee_action": "envoyer un SMS au participant",
|
"sms_attendee_action": "Envoyer un SMS au participant",
|
||||||
"sms_number_action": "envoyer un SMS à un numéro spécifique",
|
"sms_number_action": "envoyer un SMS à un numéro spécifique",
|
||||||
"workflows": "Workflows",
|
"workflows": "Workflows",
|
||||||
"new_workflow_btn": "Nouveau workflow",
|
"new_workflow_btn": "Nouveau workflow",
|
||||||
@@ -1206,7 +1229,7 @@
|
|||||||
"recordings_title": "Enregistrements",
|
"recordings_title": "Enregistrements",
|
||||||
"recording": "Enregistrement",
|
"recording": "Enregistrement",
|
||||||
"happy_scheduling": "Bonne planification",
|
"happy_scheduling": "Bonne planification",
|
||||||
"select_calendars": "Sélectionnez les calendriers dont vous souhaitez vérifier les conflits afin d'éviter les réservations en double.",
|
"select_calendars": "Sélectionnez les calendriers dont vous souhaitez vérifier les conflits afin d'éviter les doubles réservations.",
|
||||||
"check_for_conflicts": "Vérifier les conflits",
|
"check_for_conflicts": "Vérifier les conflits",
|
||||||
"view_recordings": "Voir les enregistrements",
|
"view_recordings": "Voir les enregistrements",
|
||||||
"adding_events_to": "Ajout d'événements",
|
"adding_events_to": "Ajout d'événements",
|
||||||
@@ -1219,11 +1242,6 @@
|
|||||||
"upload": "Télécharger",
|
"upload": "Télécharger",
|
||||||
"add_profile_photo": "Ajouter une photo de profil",
|
"add_profile_photo": "Ajouter une photo de profil",
|
||||||
"web3": "Web3",
|
"web3": "Web3",
|
||||||
"rainbow_token_gated": "Ce type d'événement est protégé par un token.",
|
|
||||||
"rainbow_connect_wallet_gate": "Connectez votre portefeuille si vous possédez <1>{{name}}</1> (<3>{{symbol}}</3>).",
|
|
||||||
"rainbow_insufficient_balance": "Votre portefeuille connecté ne contient pas assez de <1>{{symbol}}</1>.",
|
|
||||||
"rainbow_sign_message_request": "Signez la demande de message sur votre portefeuille.",
|
|
||||||
"rainbow_signature_error": "Erreur lors de la demande de signature de votre portefeuille.",
|
|
||||||
"token_address": "Adresse du token",
|
"token_address": "Adresse du token",
|
||||||
"blockchain": "Blockchain",
|
"blockchain": "Blockchain",
|
||||||
"old_password": "Ancien mot de passe",
|
"old_password": "Ancien mot de passe",
|
||||||
@@ -1266,7 +1284,7 @@
|
|||||||
"connect_automation_apps": "Connecter des applications d'automatisation",
|
"connect_automation_apps": "Connecter des applications d'automatisation",
|
||||||
"connect_analytics_apps": "Connecter des applications analytiques",
|
"connect_analytics_apps": "Connecter des applications analytiques",
|
||||||
"connect_other_apps": "Connecter d'autres applications",
|
"connect_other_apps": "Connecter d'autres applications",
|
||||||
"connect_web3_apps": "Connecter des apps Web3",
|
"connect_web3_apps": "Connecter des applications Web3",
|
||||||
"current_step_of_total": "Étape {{currentStep}} sur {{maxSteps}}",
|
"current_step_of_total": "Étape {{currentStep}} sur {{maxSteps}}",
|
||||||
"add_variable": "Ajouter une variable",
|
"add_variable": "Ajouter une variable",
|
||||||
"custom_phone_number": "Numéro de téléphone personnalisé",
|
"custom_phone_number": "Numéro de téléphone personnalisé",
|
||||||
@@ -1286,7 +1304,7 @@
|
|||||||
"download_responses_description": "Téléchargez toutes les réponses à votre formulaire au format CSV.",
|
"download_responses_description": "Téléchargez toutes les réponses à votre formulaire au format CSV.",
|
||||||
"download": "Télécharger",
|
"download": "Télécharger",
|
||||||
"download_recording": "Télécharger l'enregistrement",
|
"download_recording": "Télécharger l'enregistrement",
|
||||||
"recording_from_your_recent_call": "Un enregistrement de votre appel récent sur Cal.com est prêt à être téléchargé",
|
"recording_from_your_recent_call": "Un enregistrement de votre appel récent sur {{appName}} est prêt à être téléchargé",
|
||||||
"create_your_first_form": "Créez votre premier formulaire",
|
"create_your_first_form": "Créez votre premier formulaire",
|
||||||
"create_your_first_form_description": "Avec les formulaires de routage, vous pouvez poser des questions de qualification et rediriger vers la bonne personne ou le bon type d'événement.",
|
"create_your_first_form_description": "Avec les formulaires de routage, vous pouvez poser des questions de qualification et rediriger vers la bonne personne ou le bon type d'événement.",
|
||||||
"create_your_first_webhook": "Créez votre premier webhook",
|
"create_your_first_webhook": "Créez votre premier webhook",
|
||||||
@@ -1369,7 +1387,6 @@
|
|||||||
"password_updated": "Mot de passe mis à jour !",
|
"password_updated": "Mot de passe mis à jour !",
|
||||||
"pending_payment": "Paiement en attente",
|
"pending_payment": "Paiement en attente",
|
||||||
"pending_invites": "Invitations en attente",
|
"pending_invites": "Invitations en attente",
|
||||||
"confirmation_page_rainbow": "Le token protège votre événement avec des tokens ou des NFT sur Ethereum, Polygon et plus encore.",
|
|
||||||
"not_on_cal": "Pas sur {{appName}}",
|
"not_on_cal": "Pas sur {{appName}}",
|
||||||
"no_calendar_installed": "Aucun calendrier installé",
|
"no_calendar_installed": "Aucun calendrier installé",
|
||||||
"no_calendar_installed_description": "Vous n'avez pas encore connecté vos calendriers.",
|
"no_calendar_installed_description": "Vous n'avez pas encore connecté vos calendriers.",
|
||||||
@@ -1483,8 +1500,8 @@
|
|||||||
"find_the_best_person": "Trouvez la meilleure personne disponible et alternez à travers votre équipe.",
|
"find_the_best_person": "Trouvez la meilleure personne disponible et alternez à travers votre équipe.",
|
||||||
"fixed_round_robin": "Round-Robin fixe",
|
"fixed_round_robin": "Round-Robin fixe",
|
||||||
"add_one_fixed_attendee": "Ajoutez un participant fixe et le Round-Robin via un certain nombre de participants.",
|
"add_one_fixed_attendee": "Ajoutez un participant fixe et le Round-Robin via un certain nombre de participants.",
|
||||||
"calcom_is_better_with_team": "Cal.com est meilleur en équipe",
|
"calcom_is_better_with_team": "{{appName}} est meilleur en équipe",
|
||||||
"the_calcom_team": "L'équipe Cal.com",
|
"the_calcom_team": "L'équipe {{companyName}}",
|
||||||
"add_your_team_members": "Ajoutez les membres de votre équipe à vos types d'événements. Utilisez la planification collective pour inclure tout le monde ou trouvez la personne la plus appropriée avec la planification Round-Robin.",
|
"add_your_team_members": "Ajoutez les membres de votre équipe à vos types d'événements. Utilisez la planification collective pour inclure tout le monde ou trouvez la personne la plus appropriée avec la planification Round-Robin.",
|
||||||
"booking_limit_reached": "La limite de réservation pour ce type d'événement a été atteinte",
|
"booking_limit_reached": "La limite de réservation pour ce type d'événement a été atteinte",
|
||||||
"duration_limit_reached": "La limite de durée pour ce type d'événement a été atteinte",
|
"duration_limit_reached": "La limite de durée pour ce type d'événement a été atteinte",
|
||||||
@@ -1503,7 +1520,7 @@
|
|||||||
"navigate_installed_apps": "Accéder aux applications installées",
|
"navigate_installed_apps": "Accéder aux applications installées",
|
||||||
"disabled_calendar": "Si un autre calendrier est installé, les nouvelles réservations y seront ajoutées. Si ce n'est pas le cas, connectez un nouveau calendrier pour ne pas manquer de nouvelles réservations.",
|
"disabled_calendar": "Si un autre calendrier est installé, les nouvelles réservations y seront ajoutées. Si ce n'est pas le cas, connectez un nouveau calendrier pour ne pas manquer de nouvelles réservations.",
|
||||||
"enable_apps": "Activer les applications",
|
"enable_apps": "Activer les applications",
|
||||||
"enable_apps_description": "Activer les applications que les utilisateurs peuvent intégrer à Cal.com",
|
"enable_apps_description": "Activer les applications que les utilisateurs peuvent intégrer à {{appName}}",
|
||||||
"purchase_license": "Acheter une licence",
|
"purchase_license": "Acheter une licence",
|
||||||
"already_have_key": "J'ai déjà une clé :",
|
"already_have_key": "J'ai déjà une clé :",
|
||||||
"already_have_key_suggestion": "Veuillez copier votre variable d'environnement CALCOM_LICENSE_KEY existante ici.",
|
"already_have_key_suggestion": "Veuillez copier votre variable d'environnement CALCOM_LICENSE_KEY existante ici.",
|
||||||
@@ -1660,6 +1677,7 @@
|
|||||||
"booking_questions_title": "Questions de réservation",
|
"booking_questions_title": "Questions de réservation",
|
||||||
"booking_questions_description": "Personnalisez les questions posées sur la page de réservation.",
|
"booking_questions_description": "Personnalisez les questions posées sur la page de réservation.",
|
||||||
"add_a_booking_question": "Ajouter une question",
|
"add_a_booking_question": "Ajouter une question",
|
||||||
|
"identifier": "Identifiant",
|
||||||
"duplicate_email": "L'adresse e-mail existe déjà",
|
"duplicate_email": "L'adresse e-mail existe déjà",
|
||||||
"booking_with_payment_cancelled": "Payer pour cet événement n'est plus possible",
|
"booking_with_payment_cancelled": "Payer pour cet événement n'est plus possible",
|
||||||
"booking_with_payment_cancelled_already_paid": "Un remboursement pour ce paiement de réservation est en route.",
|
"booking_with_payment_cancelled_already_paid": "Un remboursement pour ce paiement de réservation est en route.",
|
||||||
@@ -1701,6 +1719,7 @@
|
|||||||
"spot_popular_event_types": "Identifiez les types d'événements populaires",
|
"spot_popular_event_types": "Identifiez les types d'événements populaires",
|
||||||
"spot_popular_event_types_description": "Découvrez lesquels de vos types d'événements reçoivent le plus de clics et de réservations.",
|
"spot_popular_event_types_description": "Découvrez lesquels de vos types d'événements reçoivent le plus de clics et de réservations.",
|
||||||
"no_responses_yet": "Aucune réponse pour l'instant",
|
"no_responses_yet": "Aucune réponse pour l'instant",
|
||||||
|
"no_routes_defined": "Aucune route définie",
|
||||||
"this_will_be_the_placeholder": "Ce sera le texte de substitution",
|
"this_will_be_the_placeholder": "Ce sera le texte de substitution",
|
||||||
"error_booking_event": "Une erreur s'est produite lors de la réservation de l'événement, veuillez actualiser la page et réessayer",
|
"error_booking_event": "Une erreur s'est produite lors de la réservation de l'événement, veuillez actualiser la page et réessayer",
|
||||||
"timeslot_missing_title": "Aucun créneau sélectionné",
|
"timeslot_missing_title": "Aucun créneau sélectionné",
|
||||||
@@ -1799,20 +1818,42 @@
|
|||||||
"complete_your_booking": "Terminer votre réservation",
|
"complete_your_booking": "Terminer votre réservation",
|
||||||
"complete_your_booking_subject": "Terminer votre réservation : {{title}} le {{date}}",
|
"complete_your_booking_subject": "Terminer votre réservation : {{title}} le {{date}}",
|
||||||
"confirm_your_details": "Confirmez vos coordonnées",
|
"confirm_your_details": "Confirmez vos coordonnées",
|
||||||
|
"copy_invite_link": "Copier le lien d'invitation",
|
||||||
|
"edit_invite_link": "Modifier les paramètres du lien",
|
||||||
|
"invite_link_copied": "Lien d'invitation copié",
|
||||||
|
"invite_link_deleted": "Lien d'invitation supprimé",
|
||||||
|
"invite_link_updated": "Paramètres de lien d'invitation enregistrés",
|
||||||
|
"link_expires_after": "Les liens ont été définis pour expirer après...",
|
||||||
|
"one_day": "1 jour",
|
||||||
|
"seven_days": "7 jours",
|
||||||
|
"thirty_days": "30 jours",
|
||||||
|
"never_expire": "N'expire jamais",
|
||||||
|
"team_invite_received": "Vous avez été invité(e) à rejoindre {{teamName}}",
|
||||||
"currency_string": "{{amount, currency}}",
|
"currency_string": "{{amount, currency}}",
|
||||||
"charge_card_dialog_body": "Vous êtes sur le point de facturer {{amount, currency}} au participant. Voulez-vous vraiment continuer ?",
|
"charge_card_dialog_body": "Vous êtes sur le point de facturer {{amount, currency}} au participant. Voulez-vous vraiment continuer ?",
|
||||||
"charge_attendee": "Facturer {{amount, currency}} au participant",
|
"charge_attendee": "Facturer {{amount, currency}} au participant",
|
||||||
"payment_app_commission": "Exiger un paiement ({{paymentFeePercentage}} % + {{fee, currency}} de commission par transaction)",
|
"payment_app_commission": "Exiger un paiement ({{paymentFeePercentage}} % + {{fee, currency}} de commission par transaction)",
|
||||||
"email_invite_team": "{{email}} a été invité",
|
"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 collecte de la carte",
|
||||||
"image_size_limit_exceed": "L'image téléchargée ne doit pas dépasser 5 Mo",
|
"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",
|
"unauthorized_workflow_error_message": "{{errorCode}} : Vous n'êtes pas autorisé à activer ou désactiver ce workflow",
|
||||||
"inline_embed": "Intégration en ligne",
|
"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.",
|
"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",
|
"floating_pop_up_button": "Bouton pop-up flottant",
|
||||||
|
"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",
|
"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": "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_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",
|
"disable_host_confirmation_emails": "Désactiver les e-mails de confirmation par défaut pour l'hôte",
|
||||||
"disable_host_confirmation_emails_description": "Au moins un workflow est actif sur ce type d'événement qui envoie un e-mail à l'hôte lorsque l'événement est réservé."
|
"disable_host_confirmation_emails_description": "Au moins un workflow est actif sur ce type d'événement qui envoie un e-mail à l'hôte lorsque l'événement est réservé.",
|
||||||
|
"add_an_override": "Ajouter une superposition",
|
||||||
|
"import_from_google_workspace": "Importer des utilisateurs depuis Google Workspace",
|
||||||
|
"connect_google_workspace": "Connecter Google Workspace",
|
||||||
|
"first_event_type_webhook_description": "Créez votre premier webhook pour ce type d'événement",
|
||||||
|
"create_for": "Créer pour",
|
||||||
|
"additional_url_parameters": "Paramètres d'URL supplémentaires",
|
||||||
|
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Ajoutez vos nouvelles chaînes ci-dessus ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"identity_provider": "ספק זהויות",
|
||||||
"trial_days_left": "נותרו לך $t(day, {\"count\": {{days}} }) לשימוש בגרסת הניסיון של רישוי PRO",
|
"trial_days_left": "נותרו לך $t(day, {\"count\": {{days}} }) לשימוש בגרסת הניסיון של רישוי PRO",
|
||||||
"day_one": "יום {{count}}",
|
"day_one": "יום {{count}}",
|
||||||
"day_other": "{{count}} ימים",
|
"day_other": "{{count}} ימים",
|
||||||
@@ -10,6 +11,16 @@
|
|||||||
"calcom_explained_new_user": "סיים להגדיר את החשבון של {{appName}}! אתה רק מספר צעדים מפתרון כל בעיות התזמון שלך.",
|
"calcom_explained_new_user": "סיים להגדיר את החשבון של {{appName}}! אתה רק מספר צעדים מפתרון כל בעיות התזמון שלך.",
|
||||||
"have_any_questions": "יש לך שאלות? אנחנו כאן כדי לעזור.",
|
"have_any_questions": "יש לך שאלות? אנחנו כאן כדי לעזור.",
|
||||||
"reset_password_subject": "{{appName}}: הנחיות לאיפוס סיסמה",
|
"reset_password_subject": "{{appName}}: הנחיות לאיפוס סיסמה",
|
||||||
|
"verify_email_subject": "{{appName}}: אמת את החשבון",
|
||||||
|
"check_your_email": "בדוק את הדוא״ל שלך",
|
||||||
|
"verify_email_page_body": "שלחנו מייל ל- {{email}}. חשוב שתאמת את כתובת הדוא״ל שלך כדי להבטיח את תעבורת הדוא״ל והיומן מ- {{appName}}.",
|
||||||
|
"verify_email_banner_body": "אנא אמת את חשבון הדוא״ל שלך כדי להבטיח את תעבורת מ- {{appName}}.",
|
||||||
|
"verify_email_banner_button": "שליחת דוא\"ל",
|
||||||
|
"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_declined_subject": "נדחה: {{title}} ב- {{date}}",
|
||||||
"event_cancelled_subject": "בוטל: {{title}} ב- {{date}}",
|
"event_cancelled_subject": "בוטל: {{title}} ב- {{date}}",
|
||||||
"event_request_declined": "בקשת האירוע שלך נדחתה",
|
"event_request_declined": "בקשת האירוע שלך נדחתה",
|
||||||
@@ -25,6 +36,8 @@
|
|||||||
"rejection_confirmation": "לדחות את ההזמנה",
|
"rejection_confirmation": "לדחות את ההזמנה",
|
||||||
"manage_this_event": "נהל את האירוע הזה",
|
"manage_this_event": "נהל את האירוע הזה",
|
||||||
"invite_team_member": "הזמן חבר צוות",
|
"invite_team_member": "הזמן חבר צוות",
|
||||||
|
"invite_team_individual_segment": "הזמנת אדם אחד",
|
||||||
|
"invite_team_bulk_segment": "ייבוא בכמות גדולה",
|
||||||
"invite_team_notifcation_badge": "הזמנה",
|
"invite_team_notifcation_badge": "הזמנה",
|
||||||
"your_event_has_been_scheduled": "נקבע מועד לאירוע שלך",
|
"your_event_has_been_scheduled": "נקבע מועד לאירוע שלך",
|
||||||
"your_event_has_been_scheduled_recurring": "נקבע מועד לאירוע החוזר שלך",
|
"your_event_has_been_scheduled_recurring": "נקבע מועד לאירוע החוזר שלך",
|
||||||
@@ -69,6 +82,8 @@
|
|||||||
"event_awaiting_approval_subject": "ממתין לאישור: {{title}} ב- {{date}}",
|
"event_awaiting_approval_subject": "ממתין לאישור: {{title}} ב- {{date}}",
|
||||||
"event_still_awaiting_approval": "אירוע עדיין ממתין לאישורך",
|
"event_still_awaiting_approval": "אירוע עדיין ממתין לאישורך",
|
||||||
"booking_submitted_subject": "ההזמנה נשלחה: {{title}} ב- {{date}}",
|
"booking_submitted_subject": "ההזמנה נשלחה: {{title}} ב- {{date}}",
|
||||||
|
"download_recording_subject": "הורדת ההקלטה: {{title}} בתאריך {{date}}",
|
||||||
|
"download_your_recording": "הורד/י את ההקלטה שלך",
|
||||||
"your_meeting_has_been_booked": "הפגישה שלך הוזמנה",
|
"your_meeting_has_been_booked": "הפגישה שלך הוזמנה",
|
||||||
"event_type_has_been_rescheduled_on_time_date": "{{title}} תוזמן מחדש לתאריך {{date}}.",
|
"event_type_has_been_rescheduled_on_time_date": "{{title}} תוזמן מחדש לתאריך {{date}}.",
|
||||||
"event_has_been_rescheduled": "עודכן – מועד האירוע שלך השתנה",
|
"event_has_been_rescheduled": "עודכן – מועד האירוע שלך השתנה",
|
||||||
@@ -190,6 +205,7 @@
|
|||||||
"page_doesnt_exist": "דף זה אינו קיים.",
|
"page_doesnt_exist": "דף זה אינו קיים.",
|
||||||
"check_spelling_mistakes_or_go_back": "ודא כי שאין שגיאות איות או חזור/י לדף הקודם.",
|
"check_spelling_mistakes_or_go_back": "ודא כי שאין שגיאות איות או חזור/י לדף הקודם.",
|
||||||
"404_page_not_found": "404: לא ניתן למצוא את הדף הזה.",
|
"404_page_not_found": "404: לא ניתן למצוא את הדף הזה.",
|
||||||
|
"booker_event_not_found": "לא מצאנו את הארוע שניסית להזמין.",
|
||||||
"getting_started": "תחילת העבודה",
|
"getting_started": "תחילת העבודה",
|
||||||
"15min_meeting": "פגישה של 15 דקות",
|
"15min_meeting": "פגישה של 15 דקות",
|
||||||
"30min_meeting": "פגישה של 30 דקות",
|
"30min_meeting": "פגישה של 30 דקות",
|
||||||
@@ -219,11 +235,13 @@
|
|||||||
"go_back_login": "חזרה לדף הכניסה",
|
"go_back_login": "חזרה לדף הכניסה",
|
||||||
"error_during_login": "אירעה שגיאה בעת הכניסה. נא לחזור אל מסך הכניסה ולנסות שוב.",
|
"error_during_login": "אירעה שגיאה בעת הכניסה. נא לחזור אל מסך הכניסה ולנסות שוב.",
|
||||||
"request_password_reset": "לשלוח בקשת איפוס",
|
"request_password_reset": "לשלוח בקשת איפוס",
|
||||||
|
"send_invite": "שליחת הזמנה",
|
||||||
"forgot_password": "שכחת את הסיסמה?",
|
"forgot_password": "שכחת את הסיסמה?",
|
||||||
"forgot": "שכחת?",
|
"forgot": "שכחת?",
|
||||||
"done": "בוצע",
|
"done": "בוצע",
|
||||||
"all_done": "זהו, סיימת!",
|
"all_done": "זהו, סיימת!",
|
||||||
"all_apps": "כל האפליקציות",
|
"all_apps": "כל האפליקציות",
|
||||||
|
"available_apps": "אפליקציות זמינות",
|
||||||
"check_email_reset_password": "בדוק/י בתיבת הדוא\"ל – שלחנו לך קישור לאיפוס הסיסמה.",
|
"check_email_reset_password": "בדוק/י בתיבת הדוא\"ל – שלחנו לך קישור לאיפוס הסיסמה.",
|
||||||
"finish": "סיום",
|
"finish": "סיום",
|
||||||
"few_sentences_about_yourself": "מספר משפטים אודותיך. המידע הזה יופיע בדף ה-URL האישי שלך.",
|
"few_sentences_about_yourself": "מספר משפטים אודותיך. המידע הזה יופיע בדף ה-URL האישי שלך.",
|
||||||
@@ -233,6 +251,8 @@
|
|||||||
"set_availability": "ציין את הזמינות שלך",
|
"set_availability": "ציין את הזמינות שלך",
|
||||||
"continue_without_calendar": "להמשיך בלי לוח שנה",
|
"continue_without_calendar": "להמשיך בלי לוח שנה",
|
||||||
"connect_your_calendar": "קשר את לוח השנה שלך",
|
"connect_your_calendar": "קשר את לוח השנה שלך",
|
||||||
|
"connect_your_video_app": "חיבור אפליקציות הווידאו שלך",
|
||||||
|
"connect_your_video_app_instructions": "חבר/י את אפליקציות הווידאו שלך כדי להשתמש בהן עבור סוגי האירועים שלך.",
|
||||||
"connect_your_calendar_instructions": "קשר את לוח השנה שלך לצפייה בזמנים עמוסים ובאירועים חדשים באופן אוטומטי ברגע שנקבע מועד עבורם.",
|
"connect_your_calendar_instructions": "קשר את לוח השנה שלך לצפייה בזמנים עמוסים ובאירועים חדשים באופן אוטומטי ברגע שנקבע מועד עבורם.",
|
||||||
"set_up_later": "להגדיר מאוחר יותר",
|
"set_up_later": "להגדיר מאוחר יותר",
|
||||||
"current_time": "השעה הנוכחית",
|
"current_time": "השעה הנוכחית",
|
||||||
@@ -284,6 +304,10 @@
|
|||||||
"success": "הפעולה בוצעה בהצלחה",
|
"success": "הפעולה בוצעה בהצלחה",
|
||||||
"failed": "הפעולה נכשלה",
|
"failed": "הפעולה נכשלה",
|
||||||
"password_has_been_reset_login": "הסיסמה שלך אופסה. עכשיו ניתן להיכנס עם הסיסמה החדשה.",
|
"password_has_been_reset_login": "הסיסמה שלך אופסה. עכשיו ניתן להיכנס עם הסיסמה החדשה.",
|
||||||
|
"bookerlayout_title": "פריסה",
|
||||||
|
"bookerlayout_default_title": "תצוגת ברירת מחדל",
|
||||||
|
"bookerlayout_description": "אתה יכול לבחור כמה והמתזמנים שלך יכולים לשנות תצוגות.",
|
||||||
|
"bookerlayout_user_settings_title": "פריסת תזמון",
|
||||||
"unexpected_error_try_again": "אירעה שגיאה בלתי צפויה. נא לנסות שוב.",
|
"unexpected_error_try_again": "אירעה שגיאה בלתי צפויה. נא לנסות שוב.",
|
||||||
"sunday_time_error": "שעה לא תקפה ביום ראשון",
|
"sunday_time_error": "שעה לא תקפה ביום ראשון",
|
||||||
"monday_time_error": "שעה לא תקפה ביום שני",
|
"monday_time_error": "שעה לא תקפה ביום שני",
|
||||||
@@ -362,6 +386,7 @@
|
|||||||
"create_webhook": "יצירת Webhook",
|
"create_webhook": "יצירת Webhook",
|
||||||
"booking_cancelled": "ההזמנה בוטלה",
|
"booking_cancelled": "ההזמנה בוטלה",
|
||||||
"booking_rescheduled": "מועד ההזמנה השתנה",
|
"booking_rescheduled": "מועד ההזמנה השתנה",
|
||||||
|
"recording_ready": "הקישור להורדת ההקלטה מוכן",
|
||||||
"booking_created": "ההזמנה נוצרה",
|
"booking_created": "ההזמנה נוצרה",
|
||||||
"meeting_ended": "הפגישה הסתיימה",
|
"meeting_ended": "הפגישה הסתיימה",
|
||||||
"form_submitted": "הטופס נשלח",
|
"form_submitted": "הטופס נשלח",
|
||||||
@@ -403,6 +428,7 @@
|
|||||||
"add_time_availability": "הוספת חלון זמן חדש",
|
"add_time_availability": "הוספת חלון זמן חדש",
|
||||||
"add_an_extra_layer_of_security": "כדאי להוסיף רמת אבטחה נוספת לחשבון, למקרה שהסיסמה שלך תיגנב.",
|
"add_an_extra_layer_of_security": "כדאי להוסיף רמת אבטחה נוספת לחשבון, למקרה שהסיסמה שלך תיגנב.",
|
||||||
"2fa": "אימות דו-גורמי",
|
"2fa": "אימות דו-גורמי",
|
||||||
|
"2fa_disabled": "ניתן להפעיל אימות דו-גורמי רק לאימות בדוא\"ל ובאמצעות סיסמה",
|
||||||
"enable_2fa": "הפעלת אימות דו-גורמי",
|
"enable_2fa": "הפעלת אימות דו-גורמי",
|
||||||
"disable_2fa": "השבתת אימות דו-גורמי",
|
"disable_2fa": "השבתת אימות דו-גורמי",
|
||||||
"disable_2fa_recommendation": "אם עליך להשבית את האימות הדו-גורמי, מומלץ להפעיל אותו שוב בהקדם האפשרי.",
|
"disable_2fa_recommendation": "אם עליך להשבית את האימות הדו-גורמי, מומלץ להפעיל אותו שוב בהקדם האפשרי.",
|
||||||
@@ -459,6 +485,7 @@
|
|||||||
"friday": "יום שישי",
|
"friday": "יום שישי",
|
||||||
"saturday": "יום שבת",
|
"saturday": "יום שבת",
|
||||||
"sunday": "יום ראשון",
|
"sunday": "יום ראשון",
|
||||||
|
"all_booked_today": "כל מה שהוזמן.",
|
||||||
"slots_load_fail": "לא ניתן לטעון את חלונות הזמן הזמינים.",
|
"slots_load_fail": "לא ניתן לטעון את חלונות הזמן הזמינים.",
|
||||||
"additional_guests": "הוספת אורחים",
|
"additional_guests": "הוספת אורחים",
|
||||||
"your_name": "שמך",
|
"your_name": "שמך",
|
||||||
@@ -583,6 +610,20 @@
|
|||||||
"minutes": "דקות",
|
"minutes": "דקות",
|
||||||
"round_robin": "לפי תורות",
|
"round_robin": "לפי תורות",
|
||||||
"round_robin_description": "פגישות מחזוריות בין חברי צוות מרובים.",
|
"round_robin_description": "פגישות מחזוריות בין חברי צוות מרובים.",
|
||||||
|
"managed_event": "אירוע מנוהל",
|
||||||
|
"username_placeholder": "שם משתמש",
|
||||||
|
"managed_event_description": "יצירה והפצה של סוגי אירועים בכמות גדולה לחברי צוות",
|
||||||
|
"managed": "מנוהל",
|
||||||
|
"managed_event_url_clarification": "יש למלא את שדה \"username\" בשמות המשתמשים של החברים שהוקצו",
|
||||||
|
"assign_to": "הקצאה ל",
|
||||||
|
"add_members": "הוספת חברים...",
|
||||||
|
"count_members_one": "חבר {{count}}",
|
||||||
|
"count_members_other": "{{count}} חברים",
|
||||||
|
"no_assigned_members": "לא הוקצה אף חבר",
|
||||||
|
"assigned_to": "הוקצה ל",
|
||||||
|
"start_assigning_members_above": "התחל/י להקצות חברים למעלה",
|
||||||
|
"locked_fields_admin_description": "חברים לא יוכלו לערוך את זה",
|
||||||
|
"locked_fields_member_description": "האפשרות הזו ננעלה על ידי מנהל הצוות",
|
||||||
"url": "כתובת URL",
|
"url": "כתובת URL",
|
||||||
"hidden": "מוסתר",
|
"hidden": "מוסתר",
|
||||||
"readonly": "לקריאה בלבד",
|
"readonly": "לקריאה בלבד",
|
||||||
@@ -604,8 +645,6 @@
|
|||||||
"event_type_created_successfully": "יצירת האירוע מסוג {{eventTypeTitle}} בוצעה בהצלחה",
|
"event_type_created_successfully": "יצירת האירוע מסוג {{eventTypeTitle}} בוצעה בהצלחה",
|
||||||
"event_type_updated_successfully": "עדכון האירוע מסוג {{eventTypeTitle}} בוצע בהצלחה",
|
"event_type_updated_successfully": "עדכון האירוע מסוג {{eventTypeTitle}} בוצע בהצלחה",
|
||||||
"event_type_deleted_successfully": "מחיקת סוג האירוע בוצעה בהצלחה",
|
"event_type_deleted_successfully": "מחיקת סוג האירוע בוצעה בהצלחה",
|
||||||
"web3_metamask_added": "הוספת ה-Metamask בוצעה בהצלחה",
|
|
||||||
"web3_metamask_disconnected": "ניתוק ה-Metamask בוצע בהצלחה",
|
|
||||||
"hours": "שעות",
|
"hours": "שעות",
|
||||||
"your_email": "הדוא\"ל שלך",
|
"your_email": "הדוא\"ל שלך",
|
||||||
"change_avatar": "שינוי אווטאר",
|
"change_avatar": "שינוי אווטאר",
|
||||||
@@ -732,8 +771,17 @@
|
|||||||
"new_event_type_to_book_description": "צור סוג אירוע חדש שאנשים יוכלו לקבוע מועדים באמצעותו.",
|
"new_event_type_to_book_description": "צור סוג אירוע חדש שאנשים יוכלו לקבוע מועדים באמצעותו.",
|
||||||
"length": "משך זמן",
|
"length": "משך זמן",
|
||||||
"minimum_booking_notice": "משך הזמן המינימלי לפני ביצוע הזמנה",
|
"minimum_booking_notice": "משך הזמן המינימלי לפני ביצוע הזמנה",
|
||||||
|
"offset_toggle": "הזזת זמני ההתחלה",
|
||||||
|
"offset_toggle_description": "הזזת חלונות הזמן שמוצגים למזמינים במספר מוגדר של דקות",
|
||||||
|
"offset_start": "הזזה של",
|
||||||
|
"offset_start_description": "לדוגמה, הבחירה באפשרות זו תציג למזמינים את חלונות הזמן כ-{{ adjustedTime }} במקום כ-{{ originalTime }}",
|
||||||
"slot_interval": "מרווחי חלונות זמן",
|
"slot_interval": "מרווחי חלונות זמן",
|
||||||
"slot_interval_default": "השתמש במשך האירוע (ברירת מחדל)",
|
"slot_interval_default": "השתמש במשך האירוע (ברירת מחדל)",
|
||||||
|
"delete_event_type": "למחוק את סוג האירוע?",
|
||||||
|
"delete_managed_event_type": "למחוק את סוג האירוע המנוהל?",
|
||||||
|
"delete_event_type_description": "כל מי ששיתפת איתו את הקישור הזה כבר לא יוכל להזמין באמצעותו.",
|
||||||
|
"delete_managed_event_type_description": "<ul><li>סוגי האירועים האלה יימחקו גם אצל חברים שהוקצו לסוגי אירועים אלה.</li><li>כל מי שהם שיתפו איתו את הקישור שלהם כבר לא יוכל להזמין באמצעותו.</li></ul>",
|
||||||
|
"confirm_delete_event_type": "כן, למחוק",
|
||||||
"delete_account": "מחיקת חשבון",
|
"delete_account": "מחיקת חשבון",
|
||||||
"confirm_delete_account": "כן, למחוק את החשבון",
|
"confirm_delete_account": "כן, למחוק את החשבון",
|
||||||
"delete_account_confirmation_message": "בטוח שברצונך למחוק את חשבון {{appName}} שלך? כל מי ששיתפת איתו את הקישור לחשבון לא יוכל יותר להזמין באמצעותו, וכל ההעדפות ששמרת יאבדו.",
|
"delete_account_confirmation_message": "בטוח שברצונך למחוק את חשבון {{appName}} שלך? כל מי ששיתפת איתו את הקישור לחשבון לא יוכל יותר להזמין באמצעותו, וכל ההעדפות ששמרת יאבדו.",
|
||||||
@@ -837,7 +885,6 @@
|
|||||||
"installed_one": "מותקן",
|
"installed_one": "מותקן",
|
||||||
"installed_other": "{{count}} התקנות",
|
"installed_other": "{{count}} התקנות",
|
||||||
"verify_wallet": "אימות הארנק",
|
"verify_wallet": "אימות הארנק",
|
||||||
"connect_metamask": "קישור Metamask",
|
|
||||||
"create_events_on": "ליצור אירועים ב-",
|
"create_events_on": "ליצור אירועים ב-",
|
||||||
"enterprise_license": "תכונה זו זמינה רק במינוי Enterprise",
|
"enterprise_license": "תכונה זו זמינה רק במינוי Enterprise",
|
||||||
"enterprise_license_description": "כדי להפעיל את יכולת זו, בקש ממנהל לגשת אל הקישור {{setupUrl}} והקלדת הרישיון. אם כבר יש רישיון מוגדר, צור קשר עם {{supportMail}} לעזרה.",
|
"enterprise_license_description": "כדי להפעיל את יכולת זו, בקש ממנהל לגשת אל הקישור {{setupUrl}} והקלדת הרישיון. אם כבר יש רישיון מוגדר, צור קשר עם {{supportMail}} לעזרה.",
|
||||||
@@ -863,6 +910,7 @@
|
|||||||
"availability_updated_successfully": "עדכון התזמון {{scheduleName}} בוצע בהצלחה",
|
"availability_updated_successfully": "עדכון התזמון {{scheduleName}} בוצע בהצלחה",
|
||||||
"schedule_deleted_successfully": "מחיקת התזמון בוצעה בהצלחה",
|
"schedule_deleted_successfully": "מחיקת התזמון בוצעה בהצלחה",
|
||||||
"default_schedule_name": "שעות עבודה",
|
"default_schedule_name": "שעות עבודה",
|
||||||
|
"member_default_schedule": "לוח הזמנים שמוגדר כברירת מחדל עבור החבר/ה",
|
||||||
"new_schedule_heading": "יצירת לוח זמנים של מועדים פנויים",
|
"new_schedule_heading": "יצירת לוח זמנים של מועדים פנויים",
|
||||||
"new_schedule_description": "יצירת לוחות זמנים להצגת זמינות מאפשרת לנהל את הזמינות של סוגי אירועים שונים. ניתן להחיל אותם על סוג אירוע אחד או יותר.",
|
"new_schedule_description": "יצירת לוחות זמנים להצגת זמינות מאפשרת לנהל את הזמינות של סוגי אירועים שונים. ניתן להחיל אותם על סוג אירוע אחד או יותר.",
|
||||||
"requires_ownership_of_a_token": "מחייב בעלות על טוקן ששייך לכתובת הבאה:",
|
"requires_ownership_of_a_token": "מחייב בעלות על טוקן ששייך לכתובת הבאה:",
|
||||||
@@ -879,6 +927,7 @@
|
|||||||
"duplicate": "כפילות",
|
"duplicate": "כפילות",
|
||||||
"offer_seats": "הצעת מקומות",
|
"offer_seats": "הצעת מקומות",
|
||||||
"offer_seats_description": "הצעת מקומות להזמנות (אפשרות זו משביתה באופן אוטומטי אישורי הזמנות ואורחים).",
|
"offer_seats_description": "הצעת מקומות להזמנות (אפשרות זו משביתה באופן אוטומטי אישורי הזמנות ואורחים).",
|
||||||
|
"seats_available_one": "מקום זמין",
|
||||||
"seats_available_other": "מקומות זמינים",
|
"seats_available_other": "מקומות זמינים",
|
||||||
"number_of_seats": "מספר המקומות לכל הזמנה",
|
"number_of_seats": "מספר המקומות לכל הזמנה",
|
||||||
"enter_number_of_seats": "יש להזין את מספר המקומות",
|
"enter_number_of_seats": "יש להזין את מספר המקומות",
|
||||||
@@ -1013,7 +1062,7 @@
|
|||||||
"event_cancelled_trigger": "כאשר אירוע מבוטל",
|
"event_cancelled_trigger": "כאשר אירוע מבוטל",
|
||||||
"new_event_trigger": "כאשר אירוע חדש מוזמן",
|
"new_event_trigger": "כאשר אירוע חדש מוזמן",
|
||||||
"email_host_action": "שלח מייל למארח",
|
"email_host_action": "שלח מייל למארח",
|
||||||
"sms_attendee_action": "שלח SMS למשתתף",
|
"email_attendee_action": "שליחת דוא\"ל למשתתפים",
|
||||||
"sms_number_action": "שלח SMS למספר מסוים",
|
"sms_number_action": "שלח SMS למספר מסוים",
|
||||||
"workflows": "תהליכים",
|
"workflows": "תהליכים",
|
||||||
"new_workflow_btn": "תהליך עבודה חדש",
|
"new_workflow_btn": "תהליך עבודה חדש",
|
||||||
@@ -1123,11 +1172,13 @@
|
|||||||
"current_username": "שם משתמש נוכחי",
|
"current_username": "שם משתמש נוכחי",
|
||||||
"example_1": "דוגמה 1",
|
"example_1": "דוגמה 1",
|
||||||
"example_2": "דוגמה 2",
|
"example_2": "דוגמה 2",
|
||||||
|
"booking_question_identifier": "מזהה שאלת הזמנה",
|
||||||
"company_size": "גודל החברה",
|
"company_size": "גודל החברה",
|
||||||
"what_help_needed": "במה דרושה לך עזרה?",
|
"what_help_needed": "במה דרושה לך עזרה?",
|
||||||
"variable_format": "הפורמט של המשתנה",
|
"variable_format": "הפורמט של המשתנה",
|
||||||
"webhook_subscriber_url_reserved": "כתובת ה-URL של מנוי Webhook כבר מוגדרת",
|
"webhook_subscriber_url_reserved": "כתובת ה-URL של מנוי Webhook כבר מוגדרת",
|
||||||
"custom_input_as_variable_info": "התעלמות מכל התווים המיוחדים של תווית הקלט הנוספת (שימוש באותיות ובספרות בלבד), שימוש באותיות רישיות עבור כל האותיות והחלפת רווחים במקפים תחתונים.",
|
"custom_input_as_variable_info": "התעלמות מכל התווים המיוחדים של תווית הקלט הנוספת (שימוש באותיות ובספרות בלבד), שימוש באותיות רישיות עבור כל האותיות והחלפת רווחים במקפים תחתונים.",
|
||||||
|
"using_booking_questions_as_variables": "איך משתמשים בשאלות הזמנה בתור משתנים?",
|
||||||
"download_desktop_app": "הורדת האפליקציה למחשבים שולחניים",
|
"download_desktop_app": "הורדת האפליקציה למחשבים שולחניים",
|
||||||
"set_ping_link": "הגדרת קישור Ping",
|
"set_ping_link": "הגדרת קישור Ping",
|
||||||
"rate_limit_exceeded": "חריגה מהגבלת קצב",
|
"rate_limit_exceeded": "חריגה מהגבלת קצב",
|
||||||
@@ -1163,6 +1214,7 @@
|
|||||||
"create_workflow": "יצירת תהליך עבודה",
|
"create_workflow": "יצירת תהליך עבודה",
|
||||||
"do_this": "עשה את זה",
|
"do_this": "עשה את זה",
|
||||||
"turn_off": "כבה",
|
"turn_off": "כבה",
|
||||||
|
"turn_on": "הפעלה",
|
||||||
"settings_updated_successfully": "עדכון ההגדרות בוצע בהצלחה",
|
"settings_updated_successfully": "עדכון ההגדרות בוצע בהצלחה",
|
||||||
"error_updating_settings": "שגיאה בעדכון ההגדרות",
|
"error_updating_settings": "שגיאה בעדכון ההגדרות",
|
||||||
"personal_cal_url": "כתובת ה-URL האישית שלי של {{appName}}",
|
"personal_cal_url": "כתובת ה-URL האישית שלי של {{appName}}",
|
||||||
@@ -1173,6 +1225,7 @@
|
|||||||
"start_of_week": "תחילת השבוע",
|
"start_of_week": "תחילת השבוע",
|
||||||
"recordings_title": "הקלטות",
|
"recordings_title": "הקלטות",
|
||||||
"recording": "הקלטה",
|
"recording": "הקלטה",
|
||||||
|
"happy_scheduling": "תזמון נעים!",
|
||||||
"select_calendars": "בחר את לוחות השנה שבהם ברצונך לבדוק אם יש התנגשויות, כדי למנוע כפל הזמנות.",
|
"select_calendars": "בחר את לוחות השנה שבהם ברצונך לבדוק אם יש התנגשויות, כדי למנוע כפל הזמנות.",
|
||||||
"check_for_conflicts": "בדיקת התנגשויות",
|
"check_for_conflicts": "בדיקת התנגשויות",
|
||||||
"view_recordings": "צפייה בהקלטות",
|
"view_recordings": "צפייה בהקלטות",
|
||||||
@@ -1186,11 +1239,6 @@
|
|||||||
"upload": "העלאה",
|
"upload": "העלאה",
|
||||||
"add_profile_photo": "הוספת תמונת פרופיל",
|
"add_profile_photo": "הוספת תמונת פרופיל",
|
||||||
"web3": "Web3",
|
"web3": "Web3",
|
||||||
"rainbow_token_gated": "סוג אירוע זה מוגן באמצעות טוקן.",
|
|
||||||
"rainbow_connect_wallet_gate": "קשר/י את הארנק שלך אם בבעלותך <1>{{name}}</1> (<3>{{symbol}}</3>).",
|
|
||||||
"rainbow_insufficient_balance": "אין בארנק שלך מספיק <1>{{symbol}}</1>.",
|
|
||||||
"rainbow_sign_message_request": "חתום/י על בקשת ההודעה בארנק.",
|
|
||||||
"rainbow_signature_error": "שגיאה בעת בקשת חתימה מהארנק.",
|
|
||||||
"token_address": "כתובת הטוקן",
|
"token_address": "כתובת הטוקן",
|
||||||
"blockchain": "בלוקצ'יין",
|
"blockchain": "בלוקצ'יין",
|
||||||
"old_password": "סיסמה ישנה",
|
"old_password": "סיסמה ישנה",
|
||||||
@@ -1210,6 +1258,7 @@
|
|||||||
"impersonation": "התחזות",
|
"impersonation": "התחזות",
|
||||||
"impersonation_description": "הגדרות לניהול התחזות למשתמשים",
|
"impersonation_description": "הגדרות לניהול התחזות למשתמשים",
|
||||||
"users": "משתמשים",
|
"users": "משתמשים",
|
||||||
|
"user": "משתמש",
|
||||||
"profile_description": "ניהול הגדרות עבור פרופיל {{appName}} שלך",
|
"profile_description": "ניהול הגדרות עבור פרופיל {{appName}} שלך",
|
||||||
"users_description": "כאן אפשר למצוא רשימה של כל המשתמשים",
|
"users_description": "כאן אפשר למצוא רשימה של כל המשתמשים",
|
||||||
"users_listing": "רשימת משתמשים",
|
"users_listing": "רשימת משתמשים",
|
||||||
@@ -1217,6 +1266,7 @@
|
|||||||
"calendars_description": "הגדרת האינטראקציה בין סוגי האירועים שלך לבין לוחות השנה שלך",
|
"calendars_description": "הגדרת האינטראקציה בין סוגי האירועים שלך לבין לוחות השנה שלך",
|
||||||
"appearance_description": "ניהול ההגדרות של מראה ההזמנות שלך",
|
"appearance_description": "ניהול ההגדרות של מראה ההזמנות שלך",
|
||||||
"conferencing_description": "הוסף/הוסיפי את האפליקציות האהובות עליך/ייך לשיחות ועידה לשימוש בפגישות",
|
"conferencing_description": "הוסף/הוסיפי את האפליקציות האהובות עליך/ייך לשיחות ועידה לשימוש בפגישות",
|
||||||
|
"add_conferencing_app": "הוספת אפליקציה לשיחות ועידה",
|
||||||
"password_description": "נהל/י את ההגדרות של סיסמאות החשבון שלך",
|
"password_description": "נהל/י את ההגדרות של סיסמאות החשבון שלך",
|
||||||
"2fa_description": "נהל/י את ההגדרות של סיסמאות החשבון שלך",
|
"2fa_description": "נהל/י את ההגדרות של סיסמאות החשבון שלך",
|
||||||
"we_just_need_basic_info": "אנחנו זקוקים רק לפרטים בסיסיים כדי להגדיר את הפרופיל שלך.",
|
"we_just_need_basic_info": "אנחנו זקוקים רק לפרטים בסיסיים כדי להגדיר את הפרופיל שלך.",
|
||||||
@@ -1250,6 +1300,7 @@
|
|||||||
"download_responses": "הורד תגובות",
|
"download_responses": "הורד תגובות",
|
||||||
"download_responses_description": "הורד את כל התגובות לטופס שלך בפורמט CSV.",
|
"download_responses_description": "הורד את כל התגובות לטופס שלך בפורמט CSV.",
|
||||||
"download": "הורדה",
|
"download": "הורדה",
|
||||||
|
"download_recording": "הורדת ההקלטה",
|
||||||
"create_your_first_form": "צור/צרי את הטופס הראשון שלך",
|
"create_your_first_form": "צור/צרי את הטופס הראשון שלך",
|
||||||
"create_your_first_form_description": "באמצעות טפסי ניתוב ניתן לשאול שאלות סיווג ולנתב אל האדם או אל סוג האירוע המתאימים.",
|
"create_your_first_form_description": "באמצעות טפסי ניתוב ניתן לשאול שאלות סיווג ולנתב אל האדם או אל סוג האירוע המתאימים.",
|
||||||
"create_your_first_webhook": "יצירת ה-Webhook הראשון שלך",
|
"create_your_first_webhook": "יצירת ה-Webhook הראשון שלך",
|
||||||
@@ -1286,6 +1337,15 @@
|
|||||||
"exchange_authentication_standard": "אימות בסיסי",
|
"exchange_authentication_standard": "אימות בסיסי",
|
||||||
"exchange_authentication_ntlm": "אימות NTLM",
|
"exchange_authentication_ntlm": "אימות NTLM",
|
||||||
"exchange_compression": "דחיסת GZip",
|
"exchange_compression": "דחיסת GZip",
|
||||||
|
"exchange_version": "גרסת Exchange",
|
||||||
|
"exchange_version_2007_SP1": "2007 SP1",
|
||||||
|
"exchange_version_2010": "2010",
|
||||||
|
"exchange_version_2010_SP1": "2010 SP1",
|
||||||
|
"exchange_version_2010_SP2": "2010 SP2",
|
||||||
|
"exchange_version_2013": "2013",
|
||||||
|
"exchange_version_2013_SP1": "2013 SP1",
|
||||||
|
"exchange_version_2015": "2015",
|
||||||
|
"exchange_version_2016": "2016",
|
||||||
"routing_forms_description": "צור טפסים להפניית משתתפים ליעדים הנכונים",
|
"routing_forms_description": "צור טפסים להפניית משתתפים ליעדים הנכונים",
|
||||||
"routing_forms_send_email_owner": "שליחת דוא\"ל לבעלים",
|
"routing_forms_send_email_owner": "שליחת דוא\"ל לבעלים",
|
||||||
"routing_forms_send_email_owner_description": "דוא\"ל נשלח לבעלים לאחר שליחת הטופס",
|
"routing_forms_send_email_owner_description": "דוא\"ל נשלח לבעלים לאחר שליחת הטופס",
|
||||||
@@ -1323,7 +1383,6 @@
|
|||||||
"password_updated": "הסיסמה עודכנה!",
|
"password_updated": "הסיסמה עודכנה!",
|
||||||
"pending_payment": "המתנה לתשלום",
|
"pending_payment": "המתנה לתשלום",
|
||||||
"pending_invites": "הזמנות ממתינות",
|
"pending_invites": "הזמנות ממתינות",
|
||||||
"confirmation_page_rainbow": "הגן/י על האירוע שלך באמצעות טוקנים או אסימוני NFT במטבע Ethereum, Polygon ועוד.",
|
|
||||||
"not_on_cal": "לא ב-{{appName}}",
|
"not_on_cal": "לא ב-{{appName}}",
|
||||||
"no_calendar_installed": "לא מותקן לוח שנה",
|
"no_calendar_installed": "לא מותקן לוח שנה",
|
||||||
"no_calendar_installed_description": "לא קישרת אף אחד מלוחות השנה שלך",
|
"no_calendar_installed_description": "לא קישרת אף אחד מלוחות השנה שלך",
|
||||||
@@ -1340,6 +1399,7 @@
|
|||||||
"add_limit": "הוספת הגבלה",
|
"add_limit": "הוספת הגבלה",
|
||||||
"team_name_required": "נדרש שם צוות",
|
"team_name_required": "נדרש שם צוות",
|
||||||
"show_attendees": "שיתוף האורחים בפרטי המשתתפים",
|
"show_attendees": "שיתוף האורחים בפרטי המשתתפים",
|
||||||
|
"how_booking_questions_as_variables": "איך משתמשים בשאלות הזמנה בתור משתנים?",
|
||||||
"format": "פורמט",
|
"format": "פורמט",
|
||||||
"uppercase_for_letters": "שימוש באותיות רישיות עבור כל האותיות",
|
"uppercase_for_letters": "שימוש באותיות רישיות עבור כל האותיות",
|
||||||
"replace_whitespaces_underscores": "החלפת רווחים במקפים תחתונים",
|
"replace_whitespaces_underscores": "החלפת רווחים במקפים תחתונים",
|
||||||
@@ -1354,6 +1414,7 @@
|
|||||||
"billing_help_title": "צריך/ה משהו נוסף?",
|
"billing_help_title": "צריך/ה משהו נוסף?",
|
||||||
"billing_help_description": "אם דרוש לך סיוע נוסף בענייני חיוב, צוות התמיכה שלנו כאן כדי לעזור.",
|
"billing_help_description": "אם דרוש לך סיוע נוסף בענייני חיוב, צוות התמיכה שלנו כאן כדי לעזור.",
|
||||||
"billing_help_cta": "פנייה לתמיכה",
|
"billing_help_cta": "פנייה לתמיכה",
|
||||||
|
"ignore_special_characters_booking_questions": "להתעלם מתווים מיוחדים במזהה שאלת ההזמנה, להשתמש באותיות ובספרות בלבד",
|
||||||
"retry": "ניסיון נוסף",
|
"retry": "ניסיון נוסף",
|
||||||
"fetching_calendars_error": "אירעה בעיה בטעינת לוחות השנה שלך. <1>נסה/י שוב</1> או פנה/י למחלקת תמיכת הלקוחות.",
|
"fetching_calendars_error": "אירעה בעיה בטעינת לוחות השנה שלך. <1>נסה/י שוב</1> או פנה/י למחלקת תמיכת הלקוחות.",
|
||||||
"calendar_connection_fail": "החיבור ללוח השנה נכשל",
|
"calendar_connection_fail": "החיבור ללוח השנה נכשל",
|
||||||
@@ -1435,12 +1496,16 @@
|
|||||||
"find_the_best_person": "למצוא את האדם הכי מתאים שגם זמין לפגישה, ולעבור בסבב דרך כל חברי הצוות.",
|
"find_the_best_person": "למצוא את האדם הכי מתאים שגם זמין לפגישה, ולעבור בסבב דרך כל חברי הצוות.",
|
||||||
"fixed_round_robin": "סבב קבוע",
|
"fixed_round_robin": "סבב קבוע",
|
||||||
"add_one_fixed_attendee": "הוסף/י משתתף/ת קבוע/ה אחד/ת ועבור/י בסבב בין מספר משתתפים.",
|
"add_one_fixed_attendee": "הוסף/י משתתף/ת קבוע/ה אחד/ת ועבור/י בסבב בין מספר משתתפים.",
|
||||||
"calcom_is_better_with_team": "Cal.com טוב יותר לשימוש עם צוותים",
|
|
||||||
"add_your_team_members": "הוסף/י את חברי הצוות לסוגי האירועים שלך. השתמש/י בתזמון שיתופי כדי לכלול את כולם או מצא/י את האדם הכי מתאים בעזרת תזמון בסבב.",
|
"add_your_team_members": "הוסף/י את חברי הצוות לסוגי האירועים שלך. השתמש/י בתזמון שיתופי כדי לכלול את כולם או מצא/י את האדם הכי מתאים בעזרת תזמון בסבב.",
|
||||||
"booking_limit_reached": "הגעת להגבלת ההזמנות עבור סוג אירוע זה",
|
"booking_limit_reached": "הגעת להגבלת ההזמנות עבור סוג אירוע זה",
|
||||||
"duration_limit_reached": "מגבלת הזמן לארוע זה עבר",
|
"duration_limit_reached": "מגבלת הזמן לארוע זה עבר",
|
||||||
"admin_has_disabled": "מנהל/ת מערכת השבית/ה את {{appName}}",
|
"admin_has_disabled": "מנהל/ת מערכת השבית/ה את {{appName}}",
|
||||||
"disabled_app_affects_event_type": "מנהל/ת מערכת השבית/ה את {{appName}}, ויש לכך השפעה על האירוע שלך מסוג {{eventType}}",
|
"disabled_app_affects_event_type": "מנהל/ת מערכת השבית/ה את {{appName}}, ויש לכך השפעה על האירוע שלך מסוג {{eventType}}",
|
||||||
|
"event_replaced_notice": "מנהל/ת מערכת החליף/ה אחד מסוגי האירועים שלך",
|
||||||
|
"email_subject_slug_replacement": "מנהל/ת צוות החליף/ה את האירוע שלך /{{slug}}",
|
||||||
|
"email_body_slug_replacement_notice": "מנהל/ת בצוות <strong>{{teamName}}</strong> החליף/ה את סוג האירוע שלך, <strong>/{{slug}}</strong>, בסוג של אירוע מנוהל שתהיה לו/ה אפשרות לשלוט בו.",
|
||||||
|
"email_body_slug_replacement_info": "הקישור שלך ימשיך לעבוד, אבל ייתכן שחלק מההגדרות עבורו השתנו. ניתן לבדוק אותו בסוגי האירועים.",
|
||||||
|
"email_body_slug_replacement_suggestion": "אם יש לך שאלות לגבי סוג האירוע, פנה/י אל מנהל/ת המערכת.<br /><br />שיהיה תזמון נעים, <br />הצוות של Cal.com",
|
||||||
"disable_payment_app": "מנהל/ת המערכת השבית/ה את {{appName}}, ויש לכך השפעה על סוג האירוע שלך בשם {{title}}. המשתתפים עדיין יוכלו להזמין אירוע מסוג זה, אבל לא תוצג להם בקשה לביצוע תשלום. ניתן להסתיר את סוג האירוע הזה על מנת למנוע מצב זה עד שמנהל/ת המערכת יפעיל/תפעיל שוב את שיטת התשלום.",
|
"disable_payment_app": "מנהל/ת המערכת השבית/ה את {{appName}}, ויש לכך השפעה על סוג האירוע שלך בשם {{title}}. המשתתפים עדיין יוכלו להזמין אירוע מסוג זה, אבל לא תוצג להם בקשה לביצוע תשלום. ניתן להסתיר את סוג האירוע הזה על מנת למנוע מצב זה עד שמנהל/ת המערכת יפעיל/תפעיל שוב את שיטת התשלום.",
|
||||||
"payment_disabled_still_able_to_book": "המשתתפים עדיין יוכלו להזמין אירוע מסוג זה, אבל לא תוצג להם בקשה לביצוע תשלום. ניתן להסתיר את סוג האירוע הזה על מנת למנוע מצב זה עד שמנהל/ת המערכת יפעיל/תפעיל שוב את שיטת התשלום.",
|
"payment_disabled_still_able_to_book": "המשתתפים עדיין יוכלו להזמין אירוע מסוג זה, אבל לא תוצג להם בקשה לביצוע תשלום. ניתן להסתיר את סוג האירוע הזה על מנת למנוע מצב זה עד שמנהל/ת המערכת יפעיל/תפעיל שוב את שיטת התשלום.",
|
||||||
"app_disabled_with_event_type": "מנהל/ת המערכת השבית/ה את {{appName}}, ויש לכך השפעה על האירוע שלך מסוג {{title}}.",
|
"app_disabled_with_event_type": "מנהל/ת המערכת השבית/ה את {{appName}}, ויש לכך השפעה על האירוע שלך מסוג {{title}}.",
|
||||||
@@ -1449,7 +1514,6 @@
|
|||||||
"navigate_installed_apps": "מעבר לאפליקציות המותקנות",
|
"navigate_installed_apps": "מעבר לאפליקציות המותקנות",
|
||||||
"disabled_calendar": "אם התקנת לוח שנה אחר, ההזמנות החדשות יתווספו אליו. אם לא, קשר/י לוח שנה חדש כדי לא להחמיץ הזמנות חדשות.",
|
"disabled_calendar": "אם התקנת לוח שנה אחר, ההזמנות החדשות יתווספו אליו. אם לא, קשר/י לוח שנה חדש כדי לא להחמיץ הזמנות חדשות.",
|
||||||
"enable_apps": "הפעלת אפליקציות",
|
"enable_apps": "הפעלת אפליקציות",
|
||||||
"enable_apps_description": "להפעיל אפליקציות שמשתמשים יכולים לשלב עם Cal.com",
|
|
||||||
"purchase_license": "רכוש רישיון",
|
"purchase_license": "רכוש רישיון",
|
||||||
"already_have_key": "כבר יש לי מפתח:",
|
"already_have_key": "כבר יש לי מפתח:",
|
||||||
"already_have_key_suggestion": "אנא העתק את משתנה הסביבה CALCOM_LICENSE_KEY הקיים שלך לכאן.",
|
"already_have_key_suggestion": "אנא העתק את משתנה הסביבה CALCOM_LICENSE_KEY הקיים שלך לכאן.",
|
||||||
@@ -1489,6 +1553,7 @@
|
|||||||
"date_overrides_update_btn": "עדכון מעקף",
|
"date_overrides_update_btn": "עדכון מעקף",
|
||||||
"event_type_duplicate_copy_text": "{{slug}}-עותק",
|
"event_type_duplicate_copy_text": "{{slug}}-עותק",
|
||||||
"set_as_default": "להגדיר כברירת מחדל",
|
"set_as_default": "להגדיר כברירת מחדל",
|
||||||
|
"hide_eventtype_details": "הסתרת פרטי סוג האירוע",
|
||||||
"show_navigation": "הצגת הניווט",
|
"show_navigation": "הצגת הניווט",
|
||||||
"hide_navigation": "הסתרת הניווט",
|
"hide_navigation": "הסתרת הניווט",
|
||||||
"verification_code_sent": "הקוד לאימות נשלח",
|
"verification_code_sent": "הקוד לאימות נשלח",
|
||||||
@@ -1502,6 +1567,7 @@
|
|||||||
"create_your_first_team_webhook_description": "צור/צרי את ה-Webhook הראשון שלך עבור סוג זה של אירוע צוות",
|
"create_your_first_team_webhook_description": "צור/צרי את ה-Webhook הראשון שלך עבור סוג זה של אירוע צוות",
|
||||||
"create_webhook_team_event_type": "צור/צרי Webhook עבור סוג זה של אירוע צוות",
|
"create_webhook_team_event_type": "צור/צרי Webhook עבור סוג זה של אירוע צוות",
|
||||||
"disable_success_page": "השבתת דף 'הפעולה הצליחה' (עובד רק אם יש לך כתובת URL להפניה אוטומטית)",
|
"disable_success_page": "השבתת דף 'הפעולה הצליחה' (עובד רק אם יש לך כתובת URL להפניה אוטומטית)",
|
||||||
|
"invalid_admin_password": "את/ה מנהל/ת מערכת, אבל הסיסמה שלך לא כוללת את האורך המינימלי של 15 תווים או שלא הגדרת עדיין אימות דו-גורמי",
|
||||||
"change_password_admin": "שנה/י את הסיסמה כדי לקבל גישה של מנהל/ת מערכת",
|
"change_password_admin": "שנה/י את הסיסמה כדי לקבל גישה של מנהל/ת מערכת",
|
||||||
"username_already_taken": "שם המשתמש הזה כבר תפוס",
|
"username_already_taken": "שם המשתמש הזה כבר תפוס",
|
||||||
"assignment": "הקצאה",
|
"assignment": "הקצאה",
|
||||||
@@ -1534,6 +1600,7 @@
|
|||||||
"ee_enterprise_license": "\"ee/\" רישיון Enterprise",
|
"ee_enterprise_license": "\"ee/\" רישיון Enterprise",
|
||||||
"enterprise_booking_fee": "החל מ- {{enterprise_booking_fee}}/לחודש",
|
"enterprise_booking_fee": "החל מ- {{enterprise_booking_fee}}/לחודש",
|
||||||
"enterprise_license_includes": "הכל לשימוש מסחרי",
|
"enterprise_license_includes": "הכל לשימוש מסחרי",
|
||||||
|
"no_need_to_keep_your_code_open_source": "אין צורך לשמור את הקוד שלך כקוד פתוח",
|
||||||
"repackage_rebrand_resell": "אריזה מחדש, מיתוג מחדש ומכירה בקלות",
|
"repackage_rebrand_resell": "אריזה מחדש, מיתוג מחדש ומכירה בקלות",
|
||||||
"a_vast_suite_of_enterprise_features": "מגוון יכולות Enterprise עצום",
|
"a_vast_suite_of_enterprise_features": "מגוון יכולות Enterprise עצום",
|
||||||
"free_license_fee": "$0.00/לחודש",
|
"free_license_fee": "$0.00/לחודש",
|
||||||
@@ -1569,6 +1636,7 @@
|
|||||||
"email_user_cta": "צפה בהזמנה",
|
"email_user_cta": "צפה בהזמנה",
|
||||||
"email_no_user_invite_heading": "הוזמנת להצטרף לצוות ב- {{appName}}",
|
"email_no_user_invite_heading": "הוזמנת להצטרף לצוות ב- {{appName}}",
|
||||||
"email_no_user_invite_subheading": "{{invitedBy}} הזמין אותך להצטרף לצוות שלו ב- {{appName}}. {{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_invite_steps_intro": "אנחנו נדריך אותך במספר צעדים קצרים ואתה תהנה תזמון נטול מתח עם הצוות שלך כהרף עין.",
|
||||||
"email_no_user_step_one": "בחר שם משתמש",
|
"email_no_user_step_one": "בחר שם משתמש",
|
||||||
"email_no_user_step_two": "קשר את לוח השנה שלך",
|
"email_no_user_step_two": "קשר את לוח השנה שלך",
|
||||||
@@ -1595,6 +1663,7 @@
|
|||||||
"default_app_link_title": "צור קישור אפליקציה ברירת מחדל",
|
"default_app_link_title": "צור קישור אפליקציה ברירת מחדל",
|
||||||
"default_app_link_description": "הגדרת קישור אפליקציה ברירת מחדל מאפשר לכל הארועים החדשים להשתמש בקישור שהגדרת.",
|
"default_app_link_description": "הגדרת קישור אפליקציה ברירת מחדל מאפשר לכל הארועים החדשים להשתמש בקישור שהגדרת.",
|
||||||
"change_default_conferencing_app": "להגדיר כברירת מחדל",
|
"change_default_conferencing_app": "להגדיר כברירת מחדל",
|
||||||
|
"organizer_default_conferencing_app": "אפליקציית ברירת המחדל של המארגן/ת",
|
||||||
"under_maintenance": "אינו זמין עקב תחזוקה",
|
"under_maintenance": "אינו זמין עקב תחזוקה",
|
||||||
"under_maintenance_description": "צוות {{appName}} מבצע עבודות תחזוקה שתוכננו מראש. אם יש לך שאלות, נא צור קשר עם התמיכה.",
|
"under_maintenance_description": "צוות {{appName}} מבצע עבודות תחזוקה שתוכננו מראש. אם יש לך שאלות, נא צור קשר עם התמיכה.",
|
||||||
"event_type_seats": "{{numberOfSeats}} מושבים",
|
"event_type_seats": "{{numberOfSeats}} מושבים",
|
||||||
@@ -1609,6 +1678,7 @@
|
|||||||
"not_enough_seats": "אין מספיק מושבים",
|
"not_enough_seats": "אין מספיק מושבים",
|
||||||
"form_builder_field_already_exists": "שדה עם שם זה כבר קיים",
|
"form_builder_field_already_exists": "שדה עם שם זה כבר קיים",
|
||||||
"form_builder_field_add_subtitle": "התאמת השאלות שנשאלות בדף התזמון",
|
"form_builder_field_add_subtitle": "התאמת השאלות שנשאלות בדף התזמון",
|
||||||
|
"show_on_booking_page": "להציג בדף ההזמנות",
|
||||||
"get_started_zapier_templates": "התחל עם תבניות Zapier",
|
"get_started_zapier_templates": "התחל עם תבניות Zapier",
|
||||||
"team_is_unpublished": "צוות {{team}} אינו מפורסם",
|
"team_is_unpublished": "צוות {{team}} אינו מפורסם",
|
||||||
"team_is_unpublished_description": "קישור הצוות הזה אינו זמין כעת. אנא צור קשר עם הבעלים של הצוות או בקש מהם לפרסם אותו.",
|
"team_is_unpublished_description": "קישור הצוות הזה אינו זמין כעת. אנא צור קשר עם הבעלים של הצוות או בקש מהם לפרסם אותו.",
|
||||||
@@ -1642,6 +1712,15 @@
|
|||||||
"spot_popular_event_types_description": "צפה איזה ארועים מקבלים הכי הרבה גישות ותזמונים",
|
"spot_popular_event_types_description": "צפה איזה ארועים מקבלים הכי הרבה גישות ותזמונים",
|
||||||
"no_responses_yet": "אין עדיין תגובות",
|
"no_responses_yet": "אין עדיין תגובות",
|
||||||
"this_will_be_the_placeholder": "זה יהיה הממלא מקום",
|
"this_will_be_the_placeholder": "זה יהיה הממלא מקום",
|
||||||
|
"error_booking_event": "אירעה שגיאה בעת הזמנת האירוע, רענן/י את הדף ונסה/י שוב",
|
||||||
|
"timeslot_missing_title": "לא נבחר חלון זמן",
|
||||||
|
"timeslot_missing_description": "כדי להזמין את האירוע, יש לבחור חלון זמן.",
|
||||||
|
"timeslot_missing_cta": "חלון הזמן שנבחר",
|
||||||
|
"switch_monthly": "מעבר לתצוגת חודש",
|
||||||
|
"switch_weekly": "מעבר לתצוגת שבוע",
|
||||||
|
"switch_multiday": "מעבר לתצוגת יום",
|
||||||
|
"num_locations": "{{num}} אפשרויות מיקום",
|
||||||
|
"select_on_next_step": "בחר/י בשלב הבא",
|
||||||
"this_meeting_has_not_started_yet": "פגישה זו עוד לא התחילה",
|
"this_meeting_has_not_started_yet": "פגישה זו עוד לא התחילה",
|
||||||
"this_app_requires_connected_account": "{{appName}} דורש חשבון {{dependencyName}} מחובר",
|
"this_app_requires_connected_account": "{{appName}} דורש חשבון {{dependencyName}} מחובר",
|
||||||
"connect_app": "חבר את {{dependencyName}}",
|
"connect_app": "חבר את {{dependencyName}}",
|
||||||
@@ -1651,12 +1730,39 @@
|
|||||||
"can_you_try_again": "אתה יכול לנסות שוב עם שעה אחרת?",
|
"can_you_try_again": "אתה יכול לנסות שוב עם שעה אחרת?",
|
||||||
"verify": "אמת",
|
"verify": "אמת",
|
||||||
"timezone_variable": "אזור זמן",
|
"timezone_variable": "אזור זמן",
|
||||||
|
"timezone_info": "אזור הזמן של האדם שיקבל את ההזמנה",
|
||||||
|
"event_end_time_variable": "שעת סיום האירוע",
|
||||||
|
"event_end_time_info": "שעת סיום האירוע",
|
||||||
|
"cancel_url_variable": "ה-URL לביטול",
|
||||||
|
"cancel_url_info": "כתובת ה-URL לביטול ההזמנה",
|
||||||
|
"reschedule_url_variable": "ה-URL לתזמון מחדש",
|
||||||
|
"reschedule_url_info": "כתובת ה-URL לקביעת מועד חדש להזמנה",
|
||||||
"invalid_event_name_variables": "יש משתנה שגוי בשם הארוע שלך",
|
"invalid_event_name_variables": "יש משתנה שגוי בשם הארוע שלך",
|
||||||
"select_all": "בחר הכל",
|
"select_all": "בחר הכל",
|
||||||
"default_conferencing_bulk_title": "בצע עדכון אצווה של סוגי הארועים הקיימים",
|
"default_conferencing_bulk_title": "בצע עדכון אצווה של סוגי הארועים הקיימים",
|
||||||
|
"members_default_schedule": "לוח הזמנים שמוגדר כברירת מחדל עבור החבר/ה",
|
||||||
|
"set_by_admin": "הגדרה לפי מנהל/ת הצוות",
|
||||||
|
"members_default_location": "מיקום ברירת המחדל של החבר/ה",
|
||||||
|
"members_default_schedule_description": "אנחנו נשתמש בלוח הזמנים לזמינות שמוגדר כברירת מחדל עבור כל חבר/ה. החברים יוכלו לערוך את הנתונים.",
|
||||||
"requires_at_least_one_schedule": "אתה חייב שיהיה לך לפחות לוח זמנים אחד",
|
"requires_at_least_one_schedule": "אתה חייב שיהיה לך לפחות לוח זמנים אחד",
|
||||||
"default_conferencing_bulk_description": "עדכן את המיקומים עבור סוגי הארועים שנבחרו",
|
"default_conferencing_bulk_description": "עדכן את המיקומים עבור סוגי הארועים שנבחרו",
|
||||||
|
"locked_for_members": "נעול לחברים",
|
||||||
|
"locked_apps_description": "החברים יוכלו לראות את האפליקציות הפעילות, אבל לא יוכלו לערוך הגדרות של האפליקציה",
|
||||||
|
"locked_webhooks_description": "החברים יוכלו לראות את רכיבי ה-Webhook הפעילים, אבל לא יוכלו לערוך הגדרות של רכיבי Webhook",
|
||||||
|
"locked_workflows_description": "החברים יוכלו לראות את תהליכי העבודה הפעילים, אבל לא יוכלו לערוך הגדרות של תהליכי עבודה",
|
||||||
|
"locked_by_admin": "נעול על ידי מנהל/ת הצוות",
|
||||||
|
"app_not_connected": "לא קישרת חשבון {{appName}}.",
|
||||||
|
"connect_now": "להתחבר עכשיו",
|
||||||
|
"managed_event_dialog_confirm_button_one": "החלפה ועדכון של חבר/ה {{count}}",
|
||||||
|
"managed_event_dialog_confirm_button_other": "החלפה ועדכון של {{count}} חברים",
|
||||||
|
"managed_event_dialog_title_one": "כתובת ה-URL /{{slug}} כבר קיימת עבור חבר/ה {{count}}. האם ברצונך להחליף אותה?",
|
||||||
|
"managed_event_dialog_title_other": "כתובת ה-URL /{{slug}} כבר קיימת עבור {{count}} חברים. האם ברצונך להחליף אותה?",
|
||||||
|
"managed_event_dialog_information_one": "<strong>{{names}}</strong> כבר משתמש/ת בכתובת ה-URL <strong>/{{slug}}</strong>.",
|
||||||
|
"managed_event_dialog_information_other": "<strong>{{names}}</strong> כבר משתמשים בכתובת ה-URL <string>/{{slug}}</strong>.",
|
||||||
|
"managed_event_dialog_clarification": "אם תבחר/י להחליף את כתובת ה-URL, נודיע לחברים. אם אינך רוצה להחליף אותה, חזור/י אחורה והסר/י את החברים.",
|
||||||
|
"review_event_type": "בדיקת סוג האירוע",
|
||||||
"looking_for_more_analytics": "מחפש עוד מידע אנליטי?",
|
"looking_for_more_analytics": "מחפש עוד מידע אנליטי?",
|
||||||
|
"looking_for_more_insights": "רצית עוד Insights?",
|
||||||
"add_filter": "הוסף סנן",
|
"add_filter": "הוסף סנן",
|
||||||
"select_user": "בחר משתמש",
|
"select_user": "בחר משתמש",
|
||||||
"select_event_type": "בחר סוג ארוע",
|
"select_event_type": "בחר סוג ארוע",
|
||||||
@@ -1672,5 +1778,65 @@
|
|||||||
"events_rescheduled": "ארועים שתוזמנו מחדש",
|
"events_rescheduled": "ארועים שתוזמנו מחדש",
|
||||||
"from_last_period": "מפרק הזמן האחרון",
|
"from_last_period": "מפרק הזמן האחרון",
|
||||||
"from_to_date_period": "מ: {{startDate}} עד: {{endDate}}",
|
"from_to_date_period": "מ: {{startDate}} עד: {{endDate}}",
|
||||||
"event_trends": "מגמות ארוע"
|
"analytics_for_organisation": "Insights",
|
||||||
|
"subtitle_analytics": "קבל/י מידע נוסף על הפעילות של הצוות שלך",
|
||||||
|
"redirect_url_warning": "הוספת כתובת URL להפניה אוטומטית תגרום להשבתת דף 'הפעולה הצליחה'. חשוב להוסיף את ההודעה 'ההזמנה אושרה בהצלחה' בדף המותאם אישית לציון שהפעולה הצליחה.",
|
||||||
|
"event_trends": "מגמות ארוע",
|
||||||
|
"clear_filters": "ניקוי המסננים",
|
||||||
|
"hold": "החזקה",
|
||||||
|
"on_booking_option": "גביית תשלום בעת ההזמנה",
|
||||||
|
"hold_option": "חיוב דמי אי-הגעה",
|
||||||
|
"card_held": "החזקת הסכום בכרטיס",
|
||||||
|
"charge_card": "חיוב הכרטיס",
|
||||||
|
"card_charged": "הכרטיס חויב",
|
||||||
|
"no_show_fee_amount": "דמי אי-הגעה בסך {{amount, currency}}",
|
||||||
|
"no_show_fee": "דמי אי-הגעה",
|
||||||
|
"submit_card": "מסירת כרטיס",
|
||||||
|
"submit_payment_information": "מסירת פרטי כרטיס",
|
||||||
|
"meeting_awaiting_payment_method": "עוד לא צוין אמצעי תשלום עבור הפגישה",
|
||||||
|
"no_show_fee_charged_email_subject": "דמי אי-הגעה בסך {{amount, currency}} חויבו עבור {{title}} ב-{{date}}",
|
||||||
|
"no_show_fee_charged_text_body": "דמי אי-הגעה חויבו",
|
||||||
|
"no_show_fee_charged_subtitle": "דמי אי-הגעה בסך {{amount, currency}} חויבו עבור האירוע הבא",
|
||||||
|
"error_charging_card": "משהו השתבש בעת גביית התשלום על אי-הגעה. אפשר לנסות שוב מאוחר יותר.",
|
||||||
|
"collect_no_show_fee": "גביית דמי אי-הגעה",
|
||||||
|
"no_show_fee_charged": "דמי אי-הגעה חויבו",
|
||||||
|
"insights": "Insights",
|
||||||
|
"testing_workflow_info_message": "במהלך בדיקת תהליך העבודה הזה, קח/י בחשבון שהודעות דוא\"ל ו-SMS ניתנות לתזמון לפחות שעה מראש",
|
||||||
|
"insights_no_data_found_for_filter": "לא נמצאו נתונים עבור המסנן שנבחר או התאריכים שנבחרו.",
|
||||||
|
"acknowledge_booking_no_show_fee": "מובן לי שאם לא אשתתף באירוע הזה, דמי אי-הגעה בסך {{amount, currency}} ינוכו מהכרטיס שלי.",
|
||||||
|
"card_details": "פרטי כרטיס",
|
||||||
|
"seats_and_no_show_fee_error": "נכון לעכשיו, אי אפשר להפעיל מקומות ולחייב דמי אי-הגעה",
|
||||||
|
"complete_your_booking": "יש להשלים את ההזמנה",
|
||||||
|
"complete_your_booking_subject": "יש להשלים את ההזמנה: {{title}} ב-{{date}}",
|
||||||
|
"confirm_your_details": "אישור הפרטים שלך",
|
||||||
|
"never_expire": "התוקף לעולם לא יפוג",
|
||||||
|
"currency_string": "{{amount, currency}}",
|
||||||
|
"charge_card_dialog_body": "את/ה עומד/ת לחייב את המשתתף/ת בסכום של {{amount, currency}}. בטוח שברצונך להמשיך?",
|
||||||
|
"charge_attendee": "לחייב את המשתתף/ת ב-{{amount, currency}}",
|
||||||
|
"payment_app_commission": "דרישת תשלום ({{paymentFeePercentage}}% + {{fee, currency}} עמלה על העסקה)",
|
||||||
|
"email_invite_team": "נשלחה הזמנה ל-{{email}}",
|
||||||
|
"email_invite_team_bulk": "{{userCount}} משתמשים הוזמנו",
|
||||||
|
"error_collecting_card": "שגיאה בחיוב הכרטיס",
|
||||||
|
"image_size_limit_exceed": "התמונה שתעלה/י יכולה להיות בנפח של מקסימום 5MB",
|
||||||
|
"inline_embed": "הטמעה מוטבעת",
|
||||||
|
"load_inline_content": "סוג האירוע נטען ישירות בתוך שאר תוכן האתר שלך.",
|
||||||
|
"floating_pop_up_button": "לחצן קופץ צף",
|
||||||
|
"floating_button_trigger_modal": "אפשרות זו מציבה באתר שלך לחצן צף שמפעיל חלון מודאלי עם סוג האירוע שלך.",
|
||||||
|
"pop_up_element_click": "קופץ בעקבות לחיצה על הרכיב",
|
||||||
|
"open_dialog_with_element_click": "פתיחת תיבת הדו-שיח ב-Cal כשמישהו לוחץ על רכיב.",
|
||||||
|
"need_help_embedding": "זקוק/ה לעזרה? ניתן לעיין במדריכים שלנו בנושא הטמעת Cal ב-Wix, ב-Squarespace או ב-WordPress, לקרוא את דף השאלות הנפוצות או לסקור אפשרויות הטמעה מתקדמות.",
|
||||||
|
"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": "השבתת הודעות דוא\"ל לאישור שנשלחות כברירת מחדל עבור המארח/ת",
|
||||||
|
"disable_host_confirmation_emails_description": "בסוג האירוע הזה פעיל לפחות תהליך עבודה אחד ששולח דוא\"ל למארח/ת כשהאירוע מוזמן.",
|
||||||
|
"add_an_override": "הוספת מעקף",
|
||||||
|
"import_from_google_workspace": "ייבוא משתמשים מ-Google Workspace",
|
||||||
|
"connect_google_workspace": "חיבור Google Workspace",
|
||||||
|
"google_workspace_admin_tooltip": "עליך להיות אדמין/ית ב-Workspace כדי להשתמש בתכונה הזו",
|
||||||
|
"first_event_type_webhook_description": "צור/צרי את ה-Webhook הראשון שלך עבור סוג זה של אירוע",
|
||||||
|
"create_for": "צור/צרי עבור"
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,6 @@
|
|||||||
"remove": "Ektávolítás",
|
"remove": "Ektávolítás",
|
||||||
"add": "Hozzáadás",
|
"add": "Hozzáadás",
|
||||||
"installed_one": "Telepített",
|
"installed_one": "Telepített",
|
||||||
"connect_metamask": "Metamask csatlakoztatása",
|
|
||||||
"error_404": "404-es hiba",
|
"error_404": "404-es hiba",
|
||||||
"default": "Alapértelmezett",
|
"default": "Alapértelmezett",
|
||||||
"24_hour_short": "0-24",
|
"24_hour_short": "0-24",
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
"calcom_explained_new_user": "Completa la configurazione del tuo account {{appName}}! Mancano solo pochi passi per risolvere tutti i problemi di pianificazione.",
|
"calcom_explained_new_user": "Completa la configurazione del tuo account {{appName}}! Mancano solo pochi passi per risolvere tutti i problemi di pianificazione.",
|
||||||
"have_any_questions": "Hai domande? Siamo qui per aiutare.",
|
"have_any_questions": "Hai domande? Siamo qui per aiutare.",
|
||||||
"reset_password_subject": "{{appName}}: istruzioni per reimpostare la password",
|
"reset_password_subject": "{{appName}}: istruzioni per reimpostare la password",
|
||||||
|
"verify_email_banner_button": "Invia e-mail",
|
||||||
"event_declined_subject": "Rifiutato: {{title}} il {{date}}",
|
"event_declined_subject": "Rifiutato: {{title}} il {{date}}",
|
||||||
"event_cancelled_subject": "Cancellato: {{title}} il {{date}}",
|
"event_cancelled_subject": "Cancellato: {{title}} il {{date}}",
|
||||||
"event_request_declined": "La tua richiesta per l'evento è stata rifiutata",
|
"event_request_declined": "La tua richiesta per l'evento è stata rifiutata",
|
||||||
@@ -630,8 +631,6 @@
|
|||||||
"event_type_created_successfully": "{{eventTypeTitle}} tipo di evento creato con successo",
|
"event_type_created_successfully": "{{eventTypeTitle}} tipo di evento creato con successo",
|
||||||
"event_type_updated_successfully": "{{eventTypeTitle}} tipo di evento aggiornato con successo",
|
"event_type_updated_successfully": "{{eventTypeTitle}} tipo di evento aggiornato con successo",
|
||||||
"event_type_deleted_successfully": "Tipo di evento eliminato con successo",
|
"event_type_deleted_successfully": "Tipo di evento eliminato con successo",
|
||||||
"web3_metamask_added": "Metamask aggiunto",
|
|
||||||
"web3_metamask_disconnected": "Metamask disconnesso",
|
|
||||||
"hours": "Ore",
|
"hours": "Ore",
|
||||||
"your_email": "La Tua Email",
|
"your_email": "La Tua Email",
|
||||||
"change_avatar": "Cambia Avatar",
|
"change_avatar": "Cambia Avatar",
|
||||||
@@ -872,7 +871,6 @@
|
|||||||
"installed_one": "Installata",
|
"installed_one": "Installata",
|
||||||
"installed_other": "{{count}} installate",
|
"installed_other": "{{count}} installate",
|
||||||
"verify_wallet": "Verifica Wallet",
|
"verify_wallet": "Verifica Wallet",
|
||||||
"connect_metamask": "Connetti Metamask",
|
|
||||||
"create_events_on": "Crea eventi su:",
|
"create_events_on": "Crea eventi su:",
|
||||||
"enterprise_license": "Questa è una funzione Enterprise",
|
"enterprise_license": "Questa è una funzione Enterprise",
|
||||||
"enterprise_license_description": "Per abilitare questa funzione, ottenere una chiave di distribuzione presso la console {{consoleUrl}} e aggiungerla al proprio .env come CALCOM_LICENSE_KEY. Nel caso il team possieda già una licenza, contattare {{supportMail}} per assistenza.",
|
"enterprise_license_description": "Per abilitare questa funzione, ottenere una chiave di distribuzione presso la console {{consoleUrl}} e aggiungerla al proprio .env come CALCOM_LICENSE_KEY. Nel caso il team possieda già una licenza, contattare {{supportMail}} per assistenza.",
|
||||||
@@ -898,6 +896,7 @@
|
|||||||
"availability_updated_successfully": "Disponibilità aggiornata con successo",
|
"availability_updated_successfully": "Disponibilità aggiornata con successo",
|
||||||
"schedule_deleted_successfully": "Programma eliminato",
|
"schedule_deleted_successfully": "Programma eliminato",
|
||||||
"default_schedule_name": "Orario lavorativo",
|
"default_schedule_name": "Orario lavorativo",
|
||||||
|
"member_default_schedule": "Pianificazione predefinita membro",
|
||||||
"new_schedule_heading": "Crea un programma di disponibilità",
|
"new_schedule_heading": "Crea un programma di disponibilità",
|
||||||
"new_schedule_description": "La creazione di programmi di disponibilità consente di gestire la disponibilità per i diversi tipi di eventi. I programmi possono essere applicati a uno o più tipi di evento.",
|
"new_schedule_description": "La creazione di programmi di disponibilità consente di gestire la disponibilità per i diversi tipi di eventi. I programmi possono essere applicati a uno o più tipi di evento.",
|
||||||
"requires_ownership_of_a_token": "Richiede il possesso di un token appartenente al seguente indirizzo:",
|
"requires_ownership_of_a_token": "Richiede il possesso di un token appartenente al seguente indirizzo:",
|
||||||
@@ -1050,7 +1049,6 @@
|
|||||||
"new_event_trigger": "quando viene prenotato un nuovo evento",
|
"new_event_trigger": "quando viene prenotato un nuovo evento",
|
||||||
"email_host_action": "invia e-mail all'organizzatore",
|
"email_host_action": "invia e-mail all'organizzatore",
|
||||||
"email_attendee_action": "invia e-mail ai partecipanti",
|
"email_attendee_action": "invia e-mail ai partecipanti",
|
||||||
"sms_attendee_action": "invia SMS al partecipante",
|
|
||||||
"sms_number_action": "invia SMS a un numero specifico",
|
"sms_number_action": "invia SMS a un numero specifico",
|
||||||
"workflows": "Flussi di lavoro",
|
"workflows": "Flussi di lavoro",
|
||||||
"new_workflow_btn": "Nuovo flusso di lavoro",
|
"new_workflow_btn": "Nuovo flusso di lavoro",
|
||||||
@@ -1227,11 +1225,6 @@
|
|||||||
"upload": "Carica",
|
"upload": "Carica",
|
||||||
"add_profile_photo": "Aggiungi foto del profilo",
|
"add_profile_photo": "Aggiungi foto del profilo",
|
||||||
"web3": "Web3",
|
"web3": "Web3",
|
||||||
"rainbow_token_gated": "Questo tipo di evento è protetto da token.",
|
|
||||||
"rainbow_connect_wallet_gate": "Collega il tuo portafoglio se possiedi <1>{{name}}</1> (<3>{{symbol}}</3>).",
|
|
||||||
"rainbow_insufficient_balance": "Il portafoglio collegato non contiene abbastanza <1>{{symbol}}</1>.",
|
|
||||||
"rainbow_sign_message_request": "Firma la richiesta di messaggio sul tuo portafoglio.",
|
|
||||||
"rainbow_signature_error": "Errore durante la richiesta di firma al tuo portafoglio.",
|
|
||||||
"token_address": "Indirizzo token",
|
"token_address": "Indirizzo token",
|
||||||
"blockchain": "Blockchain",
|
"blockchain": "Blockchain",
|
||||||
"old_password": "Vecchia password",
|
"old_password": "Vecchia password",
|
||||||
@@ -1294,7 +1287,6 @@
|
|||||||
"download_responses_description": "Scarica tutte le risposte al tuo modulo in formato CSV.",
|
"download_responses_description": "Scarica tutte le risposte al tuo modulo in formato CSV.",
|
||||||
"download": "Scarica",
|
"download": "Scarica",
|
||||||
"download_recording": "Scarica registrazione",
|
"download_recording": "Scarica registrazione",
|
||||||
"recording_from_your_recent_call": "Una registrazione della tua recente chiamata su Cal.com è pronta per il download",
|
|
||||||
"create_your_first_form": "Crea il tuo primo modulo",
|
"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_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",
|
"create_your_first_webhook": "Crea il tuo primo Webhook",
|
||||||
@@ -1377,7 +1369,6 @@
|
|||||||
"password_updated": "Password aggiornata!",
|
"password_updated": "Password aggiornata!",
|
||||||
"pending_payment": "Pagamento in sospeso",
|
"pending_payment": "Pagamento in sospeso",
|
||||||
"pending_invites": "Inviti in sospeso",
|
"pending_invites": "Inviti in sospeso",
|
||||||
"confirmation_page_rainbow": "Proteggi i tuoi eventi con token o NFT su Ethereum, Polygon e altri.",
|
|
||||||
"not_on_cal": "Non presente su {{appName}}",
|
"not_on_cal": "Non presente su {{appName}}",
|
||||||
"no_calendar_installed": "Nessun calendario installato",
|
"no_calendar_installed": "Nessun calendario installato",
|
||||||
"no_calendar_installed_description": "Non hai ancora collegato alcun calendario",
|
"no_calendar_installed_description": "Non hai ancora collegato alcun calendario",
|
||||||
@@ -1491,8 +1482,6 @@
|
|||||||
"find_the_best_person": "Trova la persona più adatta disponibile e fai ruotare i membri del team.",
|
"find_the_best_person": "Trova la persona più adatta disponibile e fai ruotare i membri del team.",
|
||||||
"fixed_round_robin": "Round robin fisso",
|
"fixed_round_robin": "Round robin fisso",
|
||||||
"add_one_fixed_attendee": "Aggiungi un partecipante fisso e fai intervenire a turno altri partecipanti.",
|
"add_one_fixed_attendee": "Aggiungi un partecipante fisso e fai intervenire a turno altri partecipanti.",
|
||||||
"calcom_is_better_with_team": "Cal.com funziona meglio in team",
|
|
||||||
"the_calcom_team": "Il team Cal.com",
|
|
||||||
"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.",
|
"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",
|
"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",
|
"duration_limit_reached": "È stato raggiunto il limite di durata per questo tipo di evento",
|
||||||
@@ -1511,7 +1500,6 @@
|
|||||||
"navigate_installed_apps": "Vai alle app installate",
|
"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.",
|
"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": "Abilita app",
|
||||||
"enable_apps_description": "Abilita le app che gli utenti possono integrare con Cal.com",
|
|
||||||
"purchase_license": "Acquista una licenza",
|
"purchase_license": "Acquista una licenza",
|
||||||
"already_have_key": "Ho già una chiave:",
|
"already_have_key": "Ho già una chiave:",
|
||||||
"already_have_key_suggestion": "Copia qui la variabile di ambiente CALCOM_LICENSE_KEY esistente.",
|
"already_have_key_suggestion": "Copia qui la variabile di ambiente CALCOM_LICENSE_KEY esistente.",
|
||||||
@@ -1634,7 +1622,7 @@
|
|||||||
"email_user_cta": "Visualizza invito",
|
"email_user_cta": "Visualizza invito",
|
||||||
"email_no_user_invite_heading": "Sei stato invitato a unirti a un team su {{appName}}",
|
"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_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 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_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_one": "Scegli il tuo nome utente",
|
||||||
"email_no_user_step_two": "Collega il tuo account di calendario",
|
"email_no_user_step_two": "Collega il tuo account di calendario",
|
||||||
@@ -1760,7 +1748,7 @@
|
|||||||
"managed_event_dialog_clarification": "Se decidi di sostituirlo, i membri ne saranno avvisati. Torna indietro e rimuovili se non desideri sovrascriverlo.",
|
"managed_event_dialog_clarification": "Se decidi di sostituirlo, i membri ne saranno avvisati. Torna indietro e rimuovili se non desideri sovrascriverlo.",
|
||||||
"review_event_type": "Rivedi tipo di evento",
|
"review_event_type": "Rivedi tipo di evento",
|
||||||
"looking_for_more_analytics": "Hai bisogno di più dati analitici?",
|
"looking_for_more_analytics": "Hai bisogno di più dati analitici?",
|
||||||
"looking_for_more_insights": "Hai bisogno di maggiori approfondimenti?",
|
"looking_for_more_insights": "Ti servono più Insights?",
|
||||||
"add_filter": "Aggiungi filtro",
|
"add_filter": "Aggiungi filtro",
|
||||||
"select_user": "Seleziona utente",
|
"select_user": "Seleziona utente",
|
||||||
"select_event_type": "Seleziona tipo di evento",
|
"select_event_type": "Seleziona tipo di evento",
|
||||||
@@ -1807,6 +1795,7 @@
|
|||||||
"complete_your_booking": "Completa la prenotazione",
|
"complete_your_booking": "Completa la prenotazione",
|
||||||
"complete_your_booking_subject": "Completa la prenotazione: {{title}} del {{date}}",
|
"complete_your_booking_subject": "Completa la prenotazione: {{title}} del {{date}}",
|
||||||
"confirm_your_details": "Conferma i tuoi dati",
|
"confirm_your_details": "Conferma i tuoi dati",
|
||||||
|
"never_expire": "Nessuna scadenza",
|
||||||
"currency_string": "{{amount, currency}}",
|
"currency_string": "{{amount, currency}}",
|
||||||
"charge_card_dialog_body": "Stai per addebitare {{amount, currency}} al partecipante. Continuare?",
|
"charge_card_dialog_body": "Stai per addebitare {{amount, currency}} al partecipante. Continuare?",
|
||||||
"charge_attendee": "Addebita {{amount, currency}} al partecipante",
|
"charge_attendee": "Addebita {{amount, currency}} al partecipante",
|
||||||
@@ -1821,7 +1810,7 @@
|
|||||||
"floating_button_trigger_modal": "Inserisce nel sito un pulsante mobile che attiva una finestra modale con il tuo tipo di evento.",
|
"floating_button_trigger_modal": "Inserisce nel sito un pulsante mobile che attiva una finestra modale con il tuo tipo di evento.",
|
||||||
"pop_up_element_click": "Finestra popup tramite clic su un elemento",
|
"pop_up_element_click": "Finestra popup tramite clic su un elemento",
|
||||||
"open_dialog_with_element_click": "Apre la finestra di dialogo di Cal quando un utente clicca su un elemento.",
|
"open_dialog_with_element_click": "Apre la finestra di dialogo di Cal quando un utente clicca su un elemento.",
|
||||||
"need_help_embedding": "Hai bisogno di aiuto? Consulta le nostre guide per integrare Cal su Wix, Squarespace o WordPress, legge le risposte alle domande più frequenti o esplora le opzioni di icorporamento avanzate.",
|
"need_help_embedding": "Hai bisogno di aiuto? Consulta le nostre guide per integrare Cal su Wix, Squarespace o WordPress, leggi le risposte alle domande più frequenti o esplora le opzioni di incorporamento avanzate.",
|
||||||
"book_my_cal": "Prenota il mio Cal",
|
"book_my_cal": "Prenota il mio Cal",
|
||||||
"invite_as": "Invita come",
|
"invite_as": "Invita come",
|
||||||
"form_updated_successfully": "Modulo aggiornato correttamente.",
|
"form_updated_successfully": "Modulo aggiornato correttamente.",
|
||||||
|
|||||||
Loaded 100 of 347 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user