Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b896bee5c | ||
|
|
cc1985442e | ||
|
|
630f438b32 | ||
|
|
6fae01d45a | ||
|
|
7009373b11 | ||
|
|
c2f150dbab | ||
|
|
688541923b | ||
|
|
20402ac26c | ||
|
|
a54952b41a | ||
|
|
987756c4d4 | ||
|
|
3ee294ffc5 | ||
|
|
a638708871 | ||
|
|
3456cc5521 | ||
|
|
546f0c3881 | ||
|
|
7b18272d60 | ||
|
|
cf6efabdbb | ||
|
|
92d15a00f5 | ||
|
|
2f2b72dd54 | ||
|
|
8fd5d6b5b5 | ||
|
|
2078f12a85 | ||
|
|
77b8eb8a7f | ||
|
|
463787b607 | ||
|
|
1f4e7ca695 | ||
|
|
9eb52bbfb2 | ||
|
|
61e6f76bc6 | ||
|
|
2e6c3a6068 | ||
|
|
8f48ecafec | ||
|
|
8849d1148c | ||
|
|
98a4684a2b | ||
|
|
da0bdfacae | ||
|
|
68c7425922 | ||
|
|
c3418cbe1f | ||
|
|
3a641e0bc1 | ||
|
|
b7fcf6ade1 | ||
|
|
53d160e495 | ||
|
|
df4df6846b | ||
|
|
c1bbb9b139 | ||
|
|
56c07ec351 | ||
|
|
3080b47aec | ||
|
|
c1e23bfdc6 | ||
|
|
e7ff5508d7 | ||
|
|
5850d227ee | ||
|
|
ede987ba19 | ||
|
|
bc0d83164c | ||
|
|
30f0b080c5 | ||
|
|
ee39ea316f | ||
|
|
fbc2708259 | ||
|
|
9bb83aba7e |
@@ -7,14 +7,13 @@
|
||||
# - E-MAIL SETTINGS
|
||||
|
||||
# - LICENSE *************************************************************************************************
|
||||
# Set this value to 'agree' to accept our license:
|
||||
# LICENSE: https://github.com/calendso/calendso/blob/main/LICENSE
|
||||
# https://github.com/calendso/calendso/blob/main/LICENSE
|
||||
#
|
||||
# Summary of terms:
|
||||
# - The codebase has to stay open source, whether it was modified or not
|
||||
# - You can not repackage or sell the codebase
|
||||
# - Acquire a commercial license to remove these terms by visiting: cal.com/sales
|
||||
NEXT_PUBLIC_LICENSE_CONSENT=''
|
||||
#
|
||||
# To enable enterprise-only features, fill your license key in here.
|
||||
# @see https://console.cal.com
|
||||
CALCOM_LICENSE_KEY=
|
||||
@@ -86,6 +85,9 @@ SENDGRID_EMAIL=
|
||||
TWILIO_SID=
|
||||
TWILIO_TOKEN=
|
||||
TWILIO_MESSAGING_SID=
|
||||
TWILIO_PHONE_NUMBER=
|
||||
NEXT_PUBLIC_SENDER_ID=
|
||||
TWILIO_VERIFY_SID=
|
||||
|
||||
# This is used so we can bypass emails in auth flows for E2E testing
|
||||
# Set it to "1" if you need to run E2E tests locally
|
||||
|
||||
@@ -292,7 +292,7 @@ You can deploy Cal on [Railway](https://railway.app/) using the button above. Th
|
||||
|
||||
Currently Vercel Pro Plan is required to be able to Deploy this application with Vercel, due to limitations on the number of serverless functions on the free plan.
|
||||
|
||||
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fcalcom%2Fcal.com&env=DATABASE_URL,NEXT_PUBLIC_WEBAPP_URL,NEXTAUTH_URL,NEXTAUTH_SECRET,CRON_API_KEY,CALENDSO_ENCRYPTION_KEY,NEXT_PUBLIC_LICENSE_CONSENT&envDescription=See%20all%20available%20env%20vars&envLink=https%3A%2F%2Fgithub.com%2Fcalcom%2Fcal.com%2Fblob%2Fmain%2F.env.example&project-name=cal&repo-name=cal.com&build-command=cd%20../..%20%26%26%20yarn%20build&root-directory=apps%2Fweb%2F)
|
||||
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fcalcom%2Fcal.com&env=DATABASE_URL,NEXT_PUBLIC_WEBAPP_URL,NEXTAUTH_URL,NEXTAUTH_SECRET,CRON_API_KEY,CALENDSO_ENCRYPTION_KEY&envDescription=See%20all%20available%20env%20vars&envLink=https%3A%2F%2Fgithub.com%2Fcalcom%2Fcal.com%2Fblob%2Fmain%2F.env.example&project-name=cal&repo-name=cal.com&build-command=cd%20../..%20%26%26%20yarn%20build&root-directory=apps%2Fweb%2F)
|
||||
|
||||
<!-- ROADMAP -->
|
||||
|
||||
@@ -419,14 +419,18 @@ following
|
||||
2. Click ‘Get a Twilio phone number’
|
||||
3. Copy Account SID to your .env file into the TWILIO_SID field
|
||||
4. Copy Auth Token to your .env file into the TWILIO_TOKEN field
|
||||
5. Create a messaging service (Develop -> Messaging -> Services)
|
||||
6. Choose any name for the messaging service
|
||||
7. Click 'Add Senders'
|
||||
8. Choose phone number as sender type
|
||||
9. Add the listed phone number
|
||||
10. Leave all other fields as they are
|
||||
11. Complete setup and click ‘View my new Messaging Service’
|
||||
12. Copy Messaging Service SID to your .env file into the TWILIO_MESSAGING_SID field
|
||||
5. Copy your Twilio phone number to your .env file into the TWILIO_PHONE_NUMBER field
|
||||
6. Add your own sender id to the .env file into the NEXT_PUBLIC_SENDER_ID field (fallback is Cal)
|
||||
7. Create a messaging service (Develop -> Messaging -> Services)
|
||||
8. Choose any name for the messaging service
|
||||
9. Click 'Add Senders'
|
||||
10. Choose phone number as sender type
|
||||
11. Add the listed phone number
|
||||
12. Leave all other fields as they are
|
||||
13. Complete setup and click ‘View my new Messaging Service’
|
||||
14. Copy Messaging Service SID to your .env file into the TWILIO_MESSAGING_SID field
|
||||
15. Create a verify service
|
||||
16. Copy Verify Service SID to your .env file into the TWILIO_VERIFY_SID field
|
||||
|
||||
<!-- LICENSE -->
|
||||
|
||||
|
||||
@@ -33,11 +33,6 @@
|
||||
"generator": "secret",
|
||||
"required": "true"
|
||||
},
|
||||
"NEXT_PUBLIC_LICENSE_CONSENT": {
|
||||
"description": "License consent",
|
||||
"value": "true",
|
||||
"required": "true"
|
||||
},
|
||||
"CRON_API_KEY": {
|
||||
"description": "ApiKey for cronjobs",
|
||||
"value": ""
|
||||
|
||||
@@ -4,6 +4,7 @@ module.exports = {
|
||||
stories: [
|
||||
"../intro.stories.mdx",
|
||||
"../../../packages/ui/components/**/*.stories.mdx",
|
||||
"../../../packages/features/**/*.stories.mdx",
|
||||
"../../../packages/ui/components/**/*.stories.@(js|jsx|ts|tsx)",
|
||||
],
|
||||
addons: [
|
||||
@@ -50,6 +51,21 @@ module.exports = {
|
||||
vm: false,
|
||||
zlib: false,
|
||||
};
|
||||
|
||||
config.module.rules.push({
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
"style-loader",
|
||||
{
|
||||
loader: "css-loader",
|
||||
options: {
|
||||
modules: true, // Enable modules to help you using className
|
||||
},
|
||||
},
|
||||
],
|
||||
include: path.resolve(__dirname, "../src"),
|
||||
});
|
||||
|
||||
return config;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -15,7 +15,11 @@ export const parameters = {
|
||||
},
|
||||
};
|
||||
|
||||
addDecorator((storyFn) => <I18nextProvider i18n={i18n}>{storyFn()}</I18nextProvider>);
|
||||
addDecorator((storyFn) => (
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<div style={{ margin: "2rem" }}>{storyFn()}</div>
|
||||
</I18nextProvider>
|
||||
));
|
||||
|
||||
window.getEmbedNamespace = () => {
|
||||
const url = new URL(document.URL);
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@import "../../../packages/ui/styles/shared-globals.css"
|
||||
@import "../../../packages/ui/styles/shared-globals.css"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
@import url("../../../packages/features/calendars/weeklyview/styles/styles.css");
|
||||
|
||||
.sbdocs {
|
||||
font-family: 'Inter var' !important;
|
||||
padding: 0!important;
|
||||
@@ -36,7 +38,7 @@
|
||||
|
||||
/** Docs table **/
|
||||
.custom-args-wrapper{
|
||||
max-height: 600px;
|
||||
max-height: 400px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
@@ -44,6 +44,7 @@ type PreviewState = {
|
||||
palette: {
|
||||
brandColor: string;
|
||||
};
|
||||
hideEventTypeDetails: boolean;
|
||||
};
|
||||
const queryParamsForDialog = ["embedType", "embedTabName", "embedUrl"];
|
||||
|
||||
@@ -125,10 +126,12 @@ const getEmbedUIInstructionString = ({
|
||||
apiName,
|
||||
theme,
|
||||
brandColor,
|
||||
hideEventTypeDetails,
|
||||
}: {
|
||||
apiName: string;
|
||||
theme?: string;
|
||||
brandColor: string;
|
||||
hideEventTypeDetails: boolean;
|
||||
}) => {
|
||||
theme = theme !== "auto" ? theme : undefined;
|
||||
return getInstructionString({
|
||||
@@ -141,6 +144,7 @@ const getEmbedUIInstructionString = ({
|
||||
brandColor,
|
||||
},
|
||||
},
|
||||
hideEventTypeDetails: hideEventTypeDetails,
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -253,18 +257,21 @@ const getEmbedTypeSpecificString = ({
|
||||
apiName: string;
|
||||
theme: PreviewState["theme"];
|
||||
brandColor: string;
|
||||
hideEventTypeDetails: boolean;
|
||||
};
|
||||
if (embedFramework === "react") {
|
||||
uiInstructionStringArg = {
|
||||
apiName: "cal",
|
||||
theme: previewState.theme,
|
||||
brandColor: previewState.palette.brandColor,
|
||||
hideEventTypeDetails: previewState.hideEventTypeDetails,
|
||||
};
|
||||
} else {
|
||||
uiInstructionStringArg = {
|
||||
apiName: "Cal",
|
||||
theme: previewState.theme,
|
||||
brandColor: previewState.palette.brandColor,
|
||||
hideEventTypeDetails: previewState.hideEventTypeDetails,
|
||||
};
|
||||
}
|
||||
if (!frameworkCodes[embedType]) {
|
||||
@@ -689,6 +696,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
theme: Theme.auto,
|
||||
floatingPopup: {},
|
||||
elementClick: {},
|
||||
hideEventTypeDetails: false,
|
||||
palette: {
|
||||
brandColor: "#000000",
|
||||
},
|
||||
@@ -753,6 +761,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
name: "ui",
|
||||
arg: {
|
||||
theme: previewState.theme,
|
||||
hideEventTypeDetails: previewState.hideEventTypeDetails,
|
||||
styles: {
|
||||
branding: {
|
||||
...previewState.palette,
|
||||
@@ -811,7 +820,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
{embed.title}
|
||||
</h3>
|
||||
<hr className={classNames("mt-4", embedType === "element-click" ? "hidden" : "")} />
|
||||
<div className="max-h-97 flex flex-col overflow-y-auto">
|
||||
<div className="flex flex-col overflow-y-auto">
|
||||
<div className={classNames("mt-4 font-medium", embedType === "element-click" ? "hidden" : "")}>
|
||||
<Collapsible
|
||||
open={isEmbedCustomizationOpen}
|
||||
@@ -838,7 +847,6 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
<div className="text-sm">Embed Window Sizing</div>
|
||||
<div className="justify-left flex items-center">
|
||||
<TextField
|
||||
name="width"
|
||||
labelProps={{ className: "hidden" }}
|
||||
required
|
||||
value={previewState.inline.width}
|
||||
@@ -860,7 +868,6 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
<span className="p-2">×</span>
|
||||
<TextField
|
||||
labelProps={{ className: "hidden" }}
|
||||
name="height"
|
||||
value={previewState.inline.height}
|
||||
required
|
||||
onChange={(e) => {
|
||||
@@ -888,7 +895,6 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
<div className="mb-2 text-sm">Button Text</div>
|
||||
{/* Default Values should come from preview iframe */}
|
||||
<TextField
|
||||
name="buttonText"
|
||||
labelProps={{ className: "hidden" }}
|
||||
onChange={(e) => {
|
||||
setPreviewState((previewState) => {
|
||||
@@ -1004,6 +1010,20 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<div className="mt-6 text-sm">
|
||||
<div className="mb-4 flex items-center justify-start space-x-2">
|
||||
<Switch
|
||||
checked={previewState.hideEventTypeDetails}
|
||||
onCheckedChange={(checked) => {
|
||||
setPreviewState((previewState) => {
|
||||
return {
|
||||
...previewState,
|
||||
hideEventTypeDetails: checked,
|
||||
};
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<div className="text-sm">{t("hide_eventtype_details")}</div>
|
||||
</div>
|
||||
<Label className="">
|
||||
<div className="mb-2">Theme</div>
|
||||
<Select
|
||||
|
||||
@@ -66,7 +66,9 @@ const Component = ({
|
||||
}
|
||||
);
|
||||
|
||||
const allowedMultipleInstalls = categories.indexOf("calendar") > -1;
|
||||
// variant not other allows, an app to be shown in calendar category without requiring an actual calendar connection e.g. vimcal
|
||||
// Such apps, can only be installed once.
|
||||
const allowedMultipleInstalls = categories.indexOf("calendar") > -1 && variant !== "other";
|
||||
|
||||
return (
|
||||
<div className="relative flex-1 flex-col items-start justify-start px-4 md:flex md:px-8 lg:flex-row lg:px-0">
|
||||
|
||||
@@ -44,7 +44,7 @@ function IntegrationListItem(props: {
|
||||
expanded={!!props.children}
|
||||
className={classNames(
|
||||
props.separate ? "rounded-md" : "first:rounded-t-md last:rounded-b-md",
|
||||
"my-0 flex-col border transition-colors duration-500 ",
|
||||
"my-0 flex-col border transition-colors duration-500",
|
||||
highlight ? "bg-yellow-100" : ""
|
||||
)}>
|
||||
<div className={classNames("flex w-full flex-1 items-center space-x-2 p-4 rtl:space-x-reverse")}>
|
||||
|
||||
@@ -13,6 +13,7 @@ import dayjs, { Dayjs } from "@calcom/dayjs";
|
||||
import {
|
||||
useEmbedNonStylesConfig,
|
||||
useEmbedStyles,
|
||||
useEmbedUiConfig,
|
||||
useIsBackgroundTransparent,
|
||||
useIsEmbed,
|
||||
} from "@calcom/embed-core/embed-iframe";
|
||||
@@ -253,6 +254,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
||||
useTheme(profile.theme);
|
||||
const { t } = useLocale();
|
||||
const availabilityDatePickerEmbedStyles = useEmbedStyles("availabilityDatePicker");
|
||||
//TODO: Plan to remove shouldAlignCentrallyInEmbed config
|
||||
const shouldAlignCentrallyInEmbed = useEmbedNonStylesConfig("align") !== "left";
|
||||
const shouldAlignCentrally = !isEmbed || shouldAlignCentrallyInEmbed;
|
||||
const isBackgroundTransparent = useIsBackgroundTransparent();
|
||||
@@ -289,7 +291,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
||||
);
|
||||
}
|
||||
}, [telemetry]);
|
||||
|
||||
const embedUiConfig = useEmbedUiConfig();
|
||||
// get dynamic user list here
|
||||
const userList = eventType.users ? eventType.users.map((user) => user.username).filter(notEmpty) : [];
|
||||
|
||||
@@ -302,6 +304,8 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
||||
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.
|
||||
|
||||
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`
|
||||
@@ -335,7 +339,7 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
||||
<div>
|
||||
<main
|
||||
className={classNames(
|
||||
"flex-col md:mx-4 lg:flex",
|
||||
"flex flex-col md:mx-4",
|
||||
shouldAlignCentrally ? "items-center" : "items-start",
|
||||
!isEmbed && classNames("mx-auto my-0 ease-in-out md:my-24")
|
||||
)}>
|
||||
@@ -350,54 +354,55 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
||||
isEmbed && "mx-auto"
|
||||
)}>
|
||||
<div className="overflow-hidden md:flex">
|
||||
<div
|
||||
className={classNames(
|
||||
"sm:dark:border-darkgray-200 flex flex-col border-gray-200 p-5 sm:border-r",
|
||||
"min-w-full md:w-[230px] md:min-w-[230px]",
|
||||
recurringEventCount && "xl:w-[380px] xl:min-w-[380px]"
|
||||
)}>
|
||||
<BookingDescription profile={profile} eventType={eventType} rescheduleUid={rescheduleUid}>
|
||||
{!rescheduleUid && eventType.recurringEvent && (
|
||||
<div className="flex items-start text-sm font-medium">
|
||||
<Icon.FiRefreshCcw className="float-left mr-[10px] mt-[7px] ml-[2px] inline-block h-4 w-4 " />
|
||||
<div>
|
||||
<p className="mb-1 -ml-2 inline px-2 py-1">
|
||||
{getRecurringFreq({ t, recurringEvent: eventType.recurringEvent })}
|
||||
</p>
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
max={eventType.recurringEvent.count}
|
||||
className="w-15 dark:bg-darkgray-200 h-7 rounded-sm border-gray-300 bg-white text-sm font-medium [appearance:textfield] ltr:mr-2 rtl:ml-2 dark:border-gray-500"
|
||||
defaultValue={eventType.recurringEvent.count}
|
||||
onChange={(event) => {
|
||||
setRecurringEventCount(parseInt(event?.target.value));
|
||||
}}
|
||||
/>
|
||||
<p className="inline">
|
||||
{t("occurrence", {
|
||||
count: recurringEventCount,
|
||||
})}
|
||||
</p>
|
||||
{showEventTypeDetails && (
|
||||
<div
|
||||
className={classNames(
|
||||
"sm:dark:border-darkgray-200 flex flex-col border-gray-200 p-5 sm:border-r",
|
||||
"min-w-full md:w-[230px] md:min-w-[230px]",
|
||||
recurringEventCount && "xl:w-[380px] xl:min-w-[380px]"
|
||||
)}>
|
||||
<BookingDescription profile={profile} eventType={eventType} rescheduleUid={rescheduleUid}>
|
||||
{!rescheduleUid && eventType.recurringEvent && (
|
||||
<div className="flex items-start text-sm font-medium">
|
||||
<Icon.FiRefreshCcw className="float-left mr-[10px] mt-[7px] ml-[2px] inline-block h-4 w-4 " />
|
||||
<div>
|
||||
<p className="mb-1 -ml-2 inline px-2 py-1">
|
||||
{getRecurringFreq({ t, recurringEvent: eventType.recurringEvent })}
|
||||
</p>
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
max={eventType.recurringEvent.count}
|
||||
className="w-15 dark:bg-darkgray-200 h-7 rounded-sm border-gray-300 bg-white text-sm font-medium [appearance:textfield] ltr:mr-2 rtl:ml-2 dark:border-gray-500"
|
||||
defaultValue={eventType.recurringEvent.count}
|
||||
onChange={(event) => {
|
||||
setRecurringEventCount(parseInt(event?.target.value));
|
||||
}}
|
||||
/>
|
||||
<p className="inline">
|
||||
{t("occurrence", {
|
||||
count: recurringEventCount,
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{stripeAppData.price > 0 && (
|
||||
<p className="-ml-2 px-2 text-sm font-medium">
|
||||
<Icon.FiCreditCard className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
|
||||
<IntlProvider locale="en">
|
||||
<FormattedNumber
|
||||
value={stripeAppData.price / 100.0}
|
||||
style="currency"
|
||||
currency={stripeAppData.currency.toUpperCase()}
|
||||
/>
|
||||
</IntlProvider>
|
||||
</p>
|
||||
)}
|
||||
{timezoneDropdown}
|
||||
</BookingDescription>
|
||||
)}
|
||||
{stripeAppData.price > 0 && (
|
||||
<p className="-ml-2 px-2 text-sm font-medium">
|
||||
<Icon.FiCreditCard className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
|
||||
<IntlProvider locale="en">
|
||||
<FormattedNumber
|
||||
value={stripeAppData.price / 100.0}
|
||||
style="currency"
|
||||
currency={stripeAppData.currency.toUpperCase()}
|
||||
/>
|
||||
</IntlProvider>
|
||||
</p>
|
||||
)}
|
||||
{timezoneDropdown}
|
||||
</BookingDescription>
|
||||
|
||||
{/* Temporarily disabled - booking?.startTime && rescheduleUid && (
|
||||
{/* Temporarily disabled - booking?.startTime && rescheduleUid && (
|
||||
<div>
|
||||
<p
|
||||
className="mt-4 mb-3 text-gray-600 dark:text-darkgray-600"
|
||||
@@ -410,7 +415,8 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
||||
</p>
|
||||
</div>
|
||||
)*/}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<SlotPicker
|
||||
weekStart={
|
||||
typeof profile.weekStart === "string"
|
||||
@@ -436,7 +442,8 @@ const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{(!restProps.isBrandingHidden || isEmbed) && <PoweredByCal />}
|
||||
{/* FIXME: We don't show branding in Embed yet because we need to place branding on top of the main content. Keeping it outside the main content would have visibility issues because outside main content background is transparent */}
|
||||
{!restProps.isBrandingHidden && !isEmbed && <PoweredByCal />}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -26,6 +26,7 @@ import { LocationObject, LocationType } from "@calcom/core/location";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import {
|
||||
useEmbedNonStylesConfig,
|
||||
useEmbedUiConfig,
|
||||
useIsBackgroundTransparent,
|
||||
useIsEmbed,
|
||||
} from "@calcom/embed-core/embed-iframe";
|
||||
@@ -89,6 +90,7 @@ const BookingPage = ({
|
||||
const { t, i18n } = useLocale();
|
||||
const { duration: queryDuration } = useRouterQuery("duration");
|
||||
const isEmbed = useIsEmbed(restProps.isEmbed);
|
||||
const embedUiConfig = useEmbedUiConfig();
|
||||
const shouldAlignCentrallyInEmbed = useEmbedNonStylesConfig("align") !== "left";
|
||||
const shouldAlignCentrally = !isEmbed || shouldAlignCentrallyInEmbed;
|
||||
const router = useRouter();
|
||||
@@ -315,6 +317,22 @@ const BookingPage = ({
|
||||
{}
|
||||
);
|
||||
|
||||
if (eventType.customInputs.length > 0) {
|
||||
// find all required custom inputs and ensure they are filled out in the booking form
|
||||
const requiredCustomInputs = eventType.customInputs.filter((input) => input.required);
|
||||
const missingRequiredCustomInputs = requiredCustomInputs.filter(
|
||||
(input) => !booking?.customInputs?.[input.id]
|
||||
);
|
||||
if (missingRequiredCustomInputs.length > 0) {
|
||||
missingRequiredCustomInputs.forEach((input) => {
|
||||
bookingForm.setError(`customInputs.${input.id}`, {
|
||||
type: "required",
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (recurringDates.length) {
|
||||
// Identify set of bookings to one intance of recurring event to support batch changes
|
||||
const recurringEventId = uuidv4();
|
||||
@@ -406,6 +424,7 @@ const BookingPage = ({
|
||||
}
|
||||
});
|
||||
}
|
||||
const showEventTypeDetails = (isEmbed && !embedUiConfig.hideEventTypeDetails) || !isEmbed;
|
||||
const rainbowAppData = getEventTypeAppData(eventType, "rainbow") || {};
|
||||
|
||||
// Define conditional gates here
|
||||
@@ -439,7 +458,7 @@ const BookingPage = ({
|
||||
className={classNames(
|
||||
shouldAlignCentrally ? "mx-auto" : "",
|
||||
isEmbed ? "" : "sm:my-24",
|
||||
"my-0 max-w-3xl "
|
||||
"my-0 max-w-3xl"
|
||||
)}>
|
||||
<div
|
||||
className={classNames(
|
||||
@@ -448,95 +467,97 @@ const BookingPage = ({
|
||||
"dark:border-darkgray-300 rounded-md sm:border"
|
||||
)}>
|
||||
<div className="sm:flex">
|
||||
<div className="sm:dark:border-darkgray-300 dark:text-darkgray-600 flex flex-col px-6 pt-6 pb-0 text-gray-600 sm:w-1/2 sm:border-r sm:pb-6">
|
||||
<BookingDescription isBookingPage profile={profile} eventType={eventType}>
|
||||
{stripeAppData.price > 0 && (
|
||||
<p className="text-bookinglight -ml-2 px-2 text-sm ">
|
||||
<Icon.FiCreditCard className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
|
||||
<IntlProvider locale="en">
|
||||
<FormattedNumber
|
||||
value={stripeAppData.price / 100.0}
|
||||
style="currency"
|
||||
currency={stripeAppData.currency.toUpperCase()}
|
||||
/>
|
||||
</IntlProvider>
|
||||
</p>
|
||||
)}
|
||||
{!rescheduleUid && eventType.recurringEvent?.freq && recurringEventCount && (
|
||||
<div className="items-start text-sm font-medium text-gray-600 dark:text-white">
|
||||
<Icon.FiRefreshCw className="mr-[10px] ml-[2px] inline-block h-4 w-4" />
|
||||
<p className="-ml-2 inline-block items-center px-2">
|
||||
{getEveryFreqFor({
|
||||
t,
|
||||
recurringEvent: eventType.recurringEvent,
|
||||
recurringCount: recurringEventCount,
|
||||
})}
|
||||
{showEventTypeDetails && (
|
||||
<div className="sm:dark:border-darkgray-300 dark:text-darkgray-600 flex flex-col px-6 pt-6 pb-0 text-gray-600 sm:w-1/2 sm:border-r sm:pb-6">
|
||||
<BookingDescription isBookingPage profile={profile} eventType={eventType}>
|
||||
{stripeAppData.price > 0 && (
|
||||
<p className="text-bookinglight -ml-2 px-2 text-sm ">
|
||||
<Icon.FiCreditCard className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
|
||||
<IntlProvider locale="en">
|
||||
<FormattedNumber
|
||||
value={stripeAppData.price / 100.0}
|
||||
style="currency"
|
||||
currency={stripeAppData.currency.toUpperCase()}
|
||||
/>
|
||||
</IntlProvider>
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="text-bookinghighlight flex items-start text-sm">
|
||||
<Icon.FiCalendar className="mr-[10px] ml-[2px] mt-[2px] inline-block h-4 w-4" />
|
||||
<div className="text-sm font-medium">
|
||||
{(rescheduleUid || !eventType.recurringEvent?.freq) && `${parseDate(date, i18n)}`}
|
||||
{!rescheduleUid &&
|
||||
eventType.recurringEvent?.freq &&
|
||||
recurringStrings.slice(0, 5).map((timeFormatted, key) => {
|
||||
return <p key={key}>{timeFormatted}</p>;
|
||||
})}
|
||||
{!rescheduleUid && eventType.recurringEvent?.freq && recurringStrings.length > 5 && (
|
||||
<div className="flex">
|
||||
<Tooltip
|
||||
content={recurringStrings.slice(5).map((timeFormatted, key) => (
|
||||
<p key={key}>{timeFormatted}</p>
|
||||
))}>
|
||||
<p className="dark:text-darkgray-600 text-sm">
|
||||
+ {t("plus_more", { count: recurringStrings.length - 5 })}
|
||||
</p>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{booking?.startTime && rescheduleUid && (
|
||||
<div>
|
||||
<p className="mt-8 mb-2 text-sm " data-testid="former_time_p">
|
||||
{t("former_time")}
|
||||
</p>
|
||||
<p className="line-through ">
|
||||
<Icon.FiCalendar className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
|
||||
{typeof booking.startTime === "string" && parseDate(dayjs(booking.startTime), i18n)}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{!!eventType.seatsPerTimeSlot && (
|
||||
)}
|
||||
{!rescheduleUid && eventType.recurringEvent?.freq && recurringEventCount && (
|
||||
<div className="items-start text-sm font-medium text-gray-600 dark:text-white">
|
||||
<Icon.FiRefreshCw className="mr-[10px] ml-[2px] inline-block h-4 w-4" />
|
||||
<p className="-ml-2 inline-block items-center px-2">
|
||||
{getEveryFreqFor({
|
||||
t,
|
||||
recurringEvent: eventType.recurringEvent,
|
||||
recurringCount: recurringEventCount,
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="text-bookinghighlight flex items-start text-sm">
|
||||
<Icon.FiUser
|
||||
className={`mr-[10px] ml-[2px] mt-[2px] inline-block h-4 w-4 ${
|
||||
booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.5
|
||||
? "text-rose-600"
|
||||
: booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.33
|
||||
? "text-yellow-500"
|
||||
: "text-bookinghighlight"
|
||||
}`}
|
||||
/>
|
||||
<p
|
||||
className={`${
|
||||
booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.5
|
||||
? "text-rose-600"
|
||||
: booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.33
|
||||
? "text-yellow-500"
|
||||
: "text-bookinghighlight"
|
||||
} mb-2 font-medium`}>
|
||||
{booking
|
||||
? eventType.seatsPerTimeSlot - booking.attendees.length
|
||||
: eventType.seatsPerTimeSlot}{" "}
|
||||
/ {eventType.seatsPerTimeSlot} {t("seats_available")}
|
||||
</p>
|
||||
<Icon.FiCalendar className="mr-[10px] ml-[2px] mt-[2px] inline-block h-4 w-4" />
|
||||
<div className="text-sm font-medium">
|
||||
{(rescheduleUid || !eventType.recurringEvent?.freq) && `${parseDate(date, i18n)}`}
|
||||
{!rescheduleUid &&
|
||||
eventType.recurringEvent?.freq &&
|
||||
recurringStrings.slice(0, 5).map((timeFormatted, key) => {
|
||||
return <p key={key}>{timeFormatted}</p>;
|
||||
})}
|
||||
{!rescheduleUid && eventType.recurringEvent?.freq && recurringStrings.length > 5 && (
|
||||
<div className="flex">
|
||||
<Tooltip
|
||||
content={recurringStrings.slice(5).map((timeFormatted, key) => (
|
||||
<p key={key}>{timeFormatted}</p>
|
||||
))}>
|
||||
<p className="dark:text-darkgray-600 text-sm">
|
||||
+ {t("plus_more", { count: recurringStrings.length - 5 })}
|
||||
</p>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</BookingDescription>
|
||||
</div>
|
||||
<div className="p-6 sm:w-1/2">
|
||||
{booking?.startTime && rescheduleUid && (
|
||||
<div>
|
||||
<p className="mt-8 mb-2 text-sm " data-testid="former_time_p">
|
||||
{t("former_time")}
|
||||
</p>
|
||||
<p className="line-through ">
|
||||
<Icon.FiCalendar className="mr-[10px] ml-[2px] -mt-1 inline-block h-4 w-4" />
|
||||
{typeof booking.startTime === "string" && parseDate(dayjs(booking.startTime), i18n)}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{!!eventType.seatsPerTimeSlot && (
|
||||
<div className="text-bookinghighlight flex items-start text-sm">
|
||||
<Icon.FiUser
|
||||
className={`mr-[10px] ml-[2px] mt-[2px] inline-block h-4 w-4 ${
|
||||
booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.5
|
||||
? "text-rose-600"
|
||||
: booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.33
|
||||
? "text-yellow-500"
|
||||
: "text-bookinghighlight"
|
||||
}`}
|
||||
/>
|
||||
<p
|
||||
className={`${
|
||||
booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.5
|
||||
? "text-rose-600"
|
||||
: booking && booking.attendees.length / eventType.seatsPerTimeSlot >= 0.33
|
||||
? "text-yellow-500"
|
||||
: "text-bookinghighlight"
|
||||
} mb-2 font-medium`}>
|
||||
{booking
|
||||
? eventType.seatsPerTimeSlot - booking.attendees.length
|
||||
: eventType.seatsPerTimeSlot}{" "}
|
||||
/ {eventType.seatsPerTimeSlot} {t("seats_available")}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</BookingDescription>
|
||||
</div>
|
||||
)}
|
||||
<div className={classNames("p-6", showEventTypeDetails ? "sm:w-1/2" : "w-full")}>
|
||||
<Form form={bookingForm} handleSubmit={bookEvent}>
|
||||
<div className="mb-4">
|
||||
<label htmlFor="name" className="block text-sm font-medium text-gray-700 dark:text-white">
|
||||
@@ -679,8 +700,11 @@ const BookingPage = ({
|
||||
{input.type !== EventTypeCustomInputType.BOOL && (
|
||||
<label
|
||||
htmlFor={"custom_" + input.id}
|
||||
className="mb-1 block text-sm font-medium text-gray-700 dark:text-white">
|
||||
{input.label}
|
||||
className={classNames(
|
||||
"mb-1 block text-sm font-medium text-gray-700 transition-colors dark:text-white",
|
||||
bookingForm.formState.errors.customInputs?.[input.id] && "!text-red-700"
|
||||
)}>
|
||||
{input.label} {input.required && <span className="text-red-700">*</span>}
|
||||
</label>
|
||||
)}
|
||||
{input.type === EventTypeCustomInputType.TEXTLONG && (
|
||||
@@ -745,24 +769,28 @@ const BookingPage = ({
|
||||
</div>
|
||||
)}
|
||||
{input.options && input.type === EventTypeCustomInputType.RADIO && (
|
||||
<div className="">
|
||||
<div className="flex">
|
||||
<Group
|
||||
onValueChange={(e) => {
|
||||
bookingForm.setValue(`customInputs.${input.id}`, e);
|
||||
}}>
|
||||
<>
|
||||
{input.options.map((option, i) => (
|
||||
<RadioField
|
||||
label={option.label}
|
||||
key={`option.${i}.radio`}
|
||||
value={option.label}
|
||||
id={`option.${i}.radio`}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
</Group>
|
||||
</div>
|
||||
<div className="flex">
|
||||
<Group
|
||||
required={input.required}
|
||||
onValueChange={(e) => {
|
||||
bookingForm.setValue(`customInputs.${input.id}`, e);
|
||||
}}>
|
||||
<>
|
||||
{input.options.map((option, i) => (
|
||||
<RadioField
|
||||
label={option.label}
|
||||
key={`option.${i}.radio`}
|
||||
value={option.label}
|
||||
id={`option.${i}.radio`}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
{bookingForm.formState.errors.customInputs?.[input.id] && (
|
||||
<div className="mt-px flex items-center text-xs text-red-700 ">
|
||||
<p>{t("required")}</p>
|
||||
</div>
|
||||
)}
|
||||
</Group>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@calcom/web",
|
||||
"version": "2.3.7",
|
||||
"version": "2.4.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"analyze": "ANALYZE=true next build",
|
||||
@@ -61,7 +61,7 @@
|
||||
"@stripe/stripe-js": "^1.35.0",
|
||||
"@tanstack/react-query": "^4.3.9",
|
||||
"@vercel/edge-functions-ui": "^0.2.1",
|
||||
"@vercel/og": "^0.0.19",
|
||||
"@vercel/og": "^0.0.21",
|
||||
"accept-language-parser": "^1.5.0",
|
||||
"async": "^3.2.4",
|
||||
"bcryptjs": "^2.4.3",
|
||||
@@ -121,7 +121,7 @@
|
||||
"tailwindcss-radix": "^2.6.0",
|
||||
"uuid": "^8.3.2",
|
||||
"web3": "^1.7.5",
|
||||
"zod": "^3.19.1"
|
||||
"zod": "^3.20.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.6",
|
||||
|
||||
@@ -1,32 +1,48 @@
|
||||
import Head from "next/head";
|
||||
import { useRouter } from "next/router";
|
||||
|
||||
import { APP_NAME, WEBSITE_URL } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { Button } from "@calcom/ui";
|
||||
import { Button, Icon, showToast } from "@calcom/ui";
|
||||
|
||||
export default function Error500() {
|
||||
const { t } = useLocale();
|
||||
const router = useRouter();
|
||||
|
||||
return (
|
||||
<div className="flex h-screen">
|
||||
<div className="flex h-screen bg-gray-100">
|
||||
<Head>
|
||||
<title>Something unexpected occurred | {APP_NAME}</title>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
<div className="m-auto text-center">
|
||||
<h1 className="font-cal text-[250px] text-gray-900">
|
||||
5
|
||||
{
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img src="/error.svg" className="-mt-10 inline w-60" alt="0" />
|
||||
}
|
||||
0
|
||||
</h1>
|
||||
<h2 className="mb-2 -mt-16 text-3xl text-gray-600">It's not you, it's us.</h2>
|
||||
<p className="mb-4 max-w-2xl text-gray-500">
|
||||
<div className="rtl: m-auto rounded-md bg-white p-10 text-right ltr:text-left">
|
||||
<h1 className="font-cal text-6xl text-black">500</h1>
|
||||
<h2 className="mt-6 text-2xl font-medium text-black">It's not you, it's us.</h2>
|
||||
<p className="mt-4 mb-6 max-w-2xl text-sm text-gray-600">
|
||||
Something went wrong on our end. Get in touch with our support team, and we’ll get it fixed right
|
||||
away for you.
|
||||
</p>
|
||||
{router.query.error && (
|
||||
<div className="mb-8 flex flex-col">
|
||||
<p className="mb-4 max-w-2xl text-sm text-gray-600">
|
||||
Please provide the following text when contacting support to better help you:
|
||||
</p>
|
||||
<pre className="w-full max-w-2xl whitespace-normal break-words rounded-md bg-gray-200 p-4 text-gray-900">
|
||||
{router.query.error}
|
||||
<br />
|
||||
<Button
|
||||
color="secondary"
|
||||
className="mt-2 border-0 font-sans font-normal hover:bg-gray-300"
|
||||
StartIcon={Icon.FiCopy}
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(router.query.error as string);
|
||||
showToast("Link copied!", "success");
|
||||
}}>
|
||||
{t("copy")}
|
||||
</Button>
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
<Button href={`${WEBSITE_URL}/support`}>{t("contact_support")}</Button>
|
||||
<Button color="secondary" href="javascript:history.back()" className="ml-2">
|
||||
Go back
|
||||
|
||||
@@ -4,7 +4,7 @@ import { JSONObject } from "superjson/dist/types";
|
||||
import { z } from "zod";
|
||||
|
||||
import { privacyFilteredLocations, LocationObject } from "@calcom/app-store/locations";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { getDefaultEvent, getGroupName, getUsernameList } from "@calcom/lib/defaultEvents";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent";
|
||||
@@ -157,9 +157,10 @@ async function getUserPageProps(context: GetStaticPropsContext) {
|
||||
// Check if the user you are logging into has any active teams
|
||||
const hasActiveTeam =
|
||||
user.teams.filter((m) => {
|
||||
if (!IS_TEAM_BILLING_ENABLED) return true;
|
||||
const metadata = teamMetadataSchema.safeParse(m.team.metadata);
|
||||
if (metadata.success && metadata.data?.subscriptionId) return false;
|
||||
return true;
|
||||
if (metadata.success && metadata.data?.subscriptionId) return true;
|
||||
return false;
|
||||
}).length > 0;
|
||||
|
||||
return {
|
||||
|
||||
@@ -14,7 +14,7 @@ import checkLicense from "@calcom/features/ee/common/server/checkLicense";
|
||||
import ImpersonationProvider from "@calcom/features/ee/impersonation/lib/ImpersonationProvider";
|
||||
import { hostedCal, isSAMLLoginEnabled } from "@calcom/features/ee/sso/lib/saml";
|
||||
import { ErrorCode, isPasswordValid, verifyPassword } from "@calcom/lib/auth";
|
||||
import { APP_NAME, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { APP_NAME, IS_TEAM_BILLING_ENABLED, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { symmetricDecrypt } from "@calcom/lib/crypto";
|
||||
import { defaultCookies } from "@calcom/lib/default-cookies";
|
||||
import rateLimit from "@calcom/lib/rateLimit";
|
||||
@@ -125,9 +125,10 @@ const providers: Provider[] = [
|
||||
// Check if the user you are logging into has any active teams
|
||||
const hasActiveTeams =
|
||||
user.teams.filter((m) => {
|
||||
if (!IS_TEAM_BILLING_ENABLED) return true;
|
||||
const metadata = teamMetadataSchema.safeParse(m.team.metadata);
|
||||
if (metadata.success && metadata.data?.subscriptionId) return false;
|
||||
return true;
|
||||
if (metadata.success && metadata.data?.subscriptionId) return true;
|
||||
return false;
|
||||
}).length > 0;
|
||||
|
||||
// authentication success- but does it meet the minimum password requirements?
|
||||
|
||||
@@ -13,10 +13,6 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
title: "30min between Pro Example and pro@example.com",
|
||||
description: null,
|
||||
additionalNotes: "asdasdas",
|
||||
customInputs: {
|
||||
"Custom input 01": "sadasdasdsadasd",
|
||||
"Custom input 02": "asdasdasd",
|
||||
},
|
||||
startTime: "2022-06-03T09:00:00-06:00",
|
||||
endTime: "2022-06-03T09:30:00-06:00",
|
||||
organizer: {
|
||||
@@ -32,26 +28,12 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
timeZone: "America/Chihuahua",
|
||||
language,
|
||||
},
|
||||
{
|
||||
email: "pro@example.com",
|
||||
name: "pro@example.com",
|
||||
timeZone: "America/Chihuahua",
|
||||
language,
|
||||
},
|
||||
{
|
||||
email: "pro@example.com",
|
||||
name: "pro@example.com",
|
||||
timeZone: "America/Chihuahua",
|
||||
language,
|
||||
},
|
||||
],
|
||||
location: "Zoom video",
|
||||
destinationCalendar: null,
|
||||
hideCalendarNotes: false,
|
||||
uid: "bwPWLpjYrx4rZf6MCZdKgE",
|
||||
uid: "xxyPr4cg2xx4XoS2KeMEQy",
|
||||
metadata: {},
|
||||
cancellationReason: "It got late",
|
||||
paymentInfo: { id: "pi_12312", link: "https://cal.com", reason: "no reason" },
|
||||
recurringEvent: null,
|
||||
};
|
||||
|
||||
@@ -60,10 +42,9 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
res.setHeader("Content-Type", "text/html");
|
||||
res.setHeader("Cache-Control", "no-cache, no-store, private, must-revalidate");
|
||||
res.write(
|
||||
renderEmail("DisabledAppEmail", {
|
||||
appName: "Stripe",
|
||||
appType: ["payment"],
|
||||
t,
|
||||
renderEmail("OrganizerRequestEmail", {
|
||||
attendee: evt.attendees[0],
|
||||
calEvent: evt,
|
||||
})
|
||||
);
|
||||
res.end();
|
||||
|
||||
@@ -53,6 +53,8 @@ export default async function handler(req: NextApiRequest) {
|
||||
interFontMedium,
|
||||
]);
|
||||
const ogConfig = {
|
||||
width: 1200,
|
||||
height: 630,
|
||||
fonts: [
|
||||
{ name: "inter", data: interFontData, weight: 400 },
|
||||
{ name: "inter", data: interFontMediumData, weight: 500 },
|
||||
@@ -71,7 +73,7 @@ export default async function handler(req: NextApiRequest) {
|
||||
meetingImage: searchParams.get("meetingImage"),
|
||||
imageType,
|
||||
});
|
||||
return new ImageResponse(
|
||||
const img = new ImageResponse(
|
||||
(
|
||||
<Meeting
|
||||
title={title}
|
||||
@@ -80,7 +82,9 @@ export default async function handler(req: NextApiRequest) {
|
||||
/>
|
||||
),
|
||||
ogConfig
|
||||
);
|
||||
) as { body: Buffer };
|
||||
|
||||
return new Response(img.body, { status: 200 });
|
||||
}
|
||||
case "app": {
|
||||
const { name, description, slug } = appSchema.parse({
|
||||
@@ -89,7 +93,11 @@ export default async function handler(req: NextApiRequest) {
|
||||
slug: searchParams.get("slug"),
|
||||
imageType,
|
||||
});
|
||||
return new ImageResponse(<App name={name} description={description} slug={slug} />, ogConfig);
|
||||
const img = new ImageResponse(<App name={name} description={description} slug={slug} />, ogConfig) as {
|
||||
body: Buffer;
|
||||
};
|
||||
|
||||
return new Response(img.body, { status: 200 });
|
||||
}
|
||||
|
||||
case "generic": {
|
||||
@@ -99,7 +107,11 @@ export default async function handler(req: NextApiRequest) {
|
||||
imageType,
|
||||
});
|
||||
|
||||
return new ImageResponse(<Generic title={title} description={description} />, ogConfig);
|
||||
const img = new ImageResponse(<Generic title={title} description={description} />, ogConfig) as {
|
||||
body: Buffer;
|
||||
};
|
||||
|
||||
return new Response(img.body, { status: 200 });
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { GetStaticPaths, GetStaticProps } from "next";
|
||||
import { useEffect } from "react";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { GetServerSidePropsContext } from "next";
|
||||
import { Controller, useFieldArray, useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
|
||||
import { DateOverrideInputDialog, DateOverrideList } from "@calcom/features/schedules";
|
||||
import Schedule from "@calcom/features/schedules/components/Schedule";
|
||||
import { availabilityAsString } from "@calcom/lib/availability";
|
||||
import { yyyymmdd } from "@calcom/lib/date-fns";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { stringOrNumber } from "@calcom/prisma/zod-utils";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery";
|
||||
import type { Schedule as ScheduleType } from "@calcom/types/schedule";
|
||||
import type { Schedule as ScheduleType, TimeRange, WorkingHours } from "@calcom/types/schedule";
|
||||
import {
|
||||
Button,
|
||||
Form,
|
||||
@@ -21,6 +22,7 @@ import {
|
||||
SkeletonText,
|
||||
Switch,
|
||||
TimezoneSelect,
|
||||
Tooltip,
|
||||
VerticalDivider,
|
||||
} from "@calcom/ui";
|
||||
|
||||
@@ -29,7 +31,7 @@ import { HttpError } from "@lib/core/http/error";
|
||||
import { SelectSkeletonLoader } from "@components/availability/SkeletonLoader";
|
||||
import EditableHeading from "@components/ui/EditableHeading";
|
||||
|
||||
import { ssgInit } from "@server/lib/ssg";
|
||||
import { ssrInit } from "@server/lib/ssr";
|
||||
|
||||
const querySchema = z.object({
|
||||
schedule: stringOrNumber,
|
||||
@@ -38,31 +40,59 @@ const querySchema = z.object({
|
||||
type AvailabilityFormValues = {
|
||||
name: string;
|
||||
schedule: ScheduleType;
|
||||
dateOverrides: { ranges: TimeRange[] }[];
|
||||
timeZone: string;
|
||||
isDefault: boolean;
|
||||
};
|
||||
|
||||
const DateOverride = ({ workingHours }: { workingHours: WorkingHours[] }) => {
|
||||
const { remove, append, update, fields } = useFieldArray<AvailabilityFormValues, "dateOverrides">({
|
||||
name: "dateOverrides",
|
||||
});
|
||||
const { t } = useLocale();
|
||||
return (
|
||||
<div className="px-4 py-5 sm:p-6">
|
||||
<h3 className="font-medium leading-6 text-gray-900">
|
||||
{t("date_overrides")}{" "}
|
||||
<Tooltip content={t("date_overrides_info")}>
|
||||
<span className="inline-block">
|
||||
<Icon.FiInfo />
|
||||
</span>
|
||||
</Tooltip>
|
||||
</h3>
|
||||
<p className="mb-4 text-sm text-neutral-500 ltr:mr-4 rtl:ml-4">{t("date_overrides_subtitle")}</p>
|
||||
<div className="mt-1 space-y-2">
|
||||
<DateOverrideList
|
||||
excludedDates={fields.map((field) => yyyymmdd(field.ranges[0].start))}
|
||||
remove={remove}
|
||||
update={update}
|
||||
items={fields}
|
||||
workingHours={workingHours}
|
||||
/>
|
||||
<DateOverrideInputDialog
|
||||
workingHours={workingHours}
|
||||
excludedDates={fields.map((field) => yyyymmdd(field.ranges[0].start))}
|
||||
onChange={(ranges) => append({ ranges })}
|
||||
Trigger={
|
||||
<Button color="secondary" StartIcon={Icon.FiPlus} data-testid="add-override">
|
||||
Add an override
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default function Availability({ schedule }: { schedule: number }) {
|
||||
const { t, i18n } = useLocale();
|
||||
const utils = trpc.useContext();
|
||||
const me = useMeQuery();
|
||||
const { timeFormat } = me.data || { timeFormat: null };
|
||||
const { data, isLoading } = trpc.viewer.availability.schedule.get.useQuery({ scheduleId: schedule });
|
||||
|
||||
const form = useForm<AvailabilityFormValues>();
|
||||
const { control, reset } = form;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoading && data) {
|
||||
reset({
|
||||
name: data?.schedule?.name,
|
||||
schedule: data.availability,
|
||||
timeZone: data.timeZone,
|
||||
isDefault: data.isDefault,
|
||||
});
|
||||
}
|
||||
}, [data, isLoading, reset]);
|
||||
|
||||
const { data: defaultValues } = trpc.viewer.availability.defaultValues.useQuery({ scheduleId: schedule });
|
||||
const form = useForm<AvailabilityFormValues>({ defaultValues });
|
||||
const { control } = form;
|
||||
const updateMutation = trpc.viewer.availability.schedule.update.useMutation({
|
||||
onSuccess: async ({ prevDefaultId, currentDefaultId, ...data }) => {
|
||||
if (prevDefaultId && currentDefaultId) {
|
||||
@@ -73,7 +103,7 @@ export default function Availability({ schedule }: { schedule: number }) {
|
||||
utils.viewer.availability.schedule.get.refetch({ scheduleId: prevDefaultId });
|
||||
}
|
||||
}
|
||||
utils.viewer.availability.schedule.get.setData({ scheduleId: data.schedule.id }, data);
|
||||
utils.viewer.availability.schedule.get.invalidate({ scheduleId: data.schedule.id });
|
||||
utils.viewer.availability.list.invalidate();
|
||||
showToast(
|
||||
t("availability_updated_successfully", {
|
||||
@@ -98,17 +128,21 @@ export default function Availability({ schedule }: { schedule: number }) {
|
||||
<Controller
|
||||
control={form.control}
|
||||
name="name"
|
||||
render={({ field }) => <EditableHeading isReady={!isLoading} {...field} />}
|
||||
render={({ field }) => (
|
||||
<EditableHeading isReady={!isLoading} {...field} data-testid="availablity-title" />
|
||||
)}
|
||||
/>
|
||||
}
|
||||
subtitle={
|
||||
data ? (
|
||||
data.schedule.availability.map((availability) => (
|
||||
<span key={availability.id}>
|
||||
{availabilityAsString(availability, { locale: i18n.language, hour12: timeFormat === 12 })}
|
||||
<br />
|
||||
</span>
|
||||
))
|
||||
data.schedule.availability
|
||||
.filter((availability) => !!availability.days.length)
|
||||
.map((availability) => (
|
||||
<span key={availability.id}>
|
||||
{availabilityAsString(availability, { locale: i18n.language, hour12: timeFormat === 12 })}
|
||||
<br />
|
||||
</span>
|
||||
))
|
||||
) : (
|
||||
<SkeletonText className="h-4 w-48" />
|
||||
)
|
||||
@@ -147,15 +181,16 @@ export default function Availability({ schedule }: { schedule: number }) {
|
||||
<Form
|
||||
form={form}
|
||||
id="availability-form"
|
||||
handleSubmit={async (values) => {
|
||||
handleSubmit={async ({ dateOverrides, ...values }) => {
|
||||
updateMutation.mutate({
|
||||
scheduleId: schedule,
|
||||
dateOverrides: dateOverrides.flatMap((override) => override.ranges),
|
||||
...values,
|
||||
});
|
||||
}}
|
||||
className="-mx-4 flex flex-col pb-16 sm:mx-0 xl:flex-row xl:space-x-6">
|
||||
<div className="flex-1">
|
||||
<div className="rounded-md border-gray-200 bg-white py-5 pr-4 sm:border sm:p-6">
|
||||
<div className="flex-1 divide-y divide-neutral-200 rounded-md border">
|
||||
<div className=" py-5 pr-4 sm:p-6">
|
||||
<h3 className="mb-5 text-base font-medium leading-6 text-gray-900">
|
||||
{t("change_start_end")}
|
||||
</h3>
|
||||
@@ -171,6 +206,7 @@ export default function Availability({ schedule }: { schedule: number }) {
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
{data?.workingHours && <DateOverride workingHours={data.workingHours} />}
|
||||
</div>
|
||||
<div className="min-w-40 col-span-3 space-y-2 lg:col-span-1">
|
||||
<div className="xl:max-w-80 mt-4 w-full pr-4 sm:p-0">
|
||||
@@ -211,24 +247,19 @@ export default function Availability({ schedule }: { schedule: number }) {
|
||||
);
|
||||
}
|
||||
|
||||
export const getStaticProps: GetStaticProps = async (ctx) => {
|
||||
export const getServerSideProps = async (ctx: GetServerSidePropsContext) => {
|
||||
const params = querySchema.safeParse(ctx.params);
|
||||
const ssg = await ssgInit(ctx);
|
||||
const ssr = await ssrInit(ctx);
|
||||
|
||||
if (!params.success) return { notFound: true };
|
||||
|
||||
const scheduleId = params.data.schedule;
|
||||
await ssr.viewer.availability.schedule.get.fetch({ scheduleId });
|
||||
await ssr.viewer.availability.defaultValues.fetch({ scheduleId });
|
||||
return {
|
||||
props: {
|
||||
schedule: params.data.schedule,
|
||||
trpcState: ssg.dehydrate(),
|
||||
schedule: scheduleId,
|
||||
trpcState: ssr.dehydrate(),
|
||||
},
|
||||
revalidate: 10, // seconds
|
||||
};
|
||||
};
|
||||
|
||||
export const getStaticPaths: GetStaticPaths = () => {
|
||||
return {
|
||||
paths: [],
|
||||
fallback: "blocking",
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useState } from "react";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { RouterOutputs, trpc } from "@calcom/trpc/react";
|
||||
import { Shell, SkeletonText } from "@calcom/ui";
|
||||
|
||||
import useRouterQuery from "@lib/hooks/useRouterQuery";
|
||||
|
||||
type User = RouterOutputs["viewer"]["me"];
|
||||
|
||||
export interface IBusySlot {
|
||||
@@ -16,7 +16,9 @@ export interface IBusySlot {
|
||||
|
||||
const AvailabilityView = ({ user }: { user: User }) => {
|
||||
const { t } = useLocale();
|
||||
const [selectedDate, setSelectedDate] = useState(dayjs());
|
||||
const { date, setQuery: setSelectedDate } = useRouterQuery("date");
|
||||
const selectedDate = dayjs(date);
|
||||
const formattedSelectedDate = selectedDate.format("YYYY-MM-DD");
|
||||
|
||||
const { data, isLoading } = trpc.viewer.availability.user.useQuery(
|
||||
{
|
||||
@@ -30,6 +32,17 @@ const AvailabilityView = ({ user }: { user: User }) => {
|
||||
}
|
||||
);
|
||||
|
||||
const overrides =
|
||||
data?.dateOverrides.reduce((acc, override) => {
|
||||
if (
|
||||
formattedSelectedDate !== dayjs(override.start).format("YYYY-MM-DD") &&
|
||||
formattedSelectedDate !== dayjs(override.end).format("YYYY-MM-DD")
|
||||
)
|
||||
return acc;
|
||||
acc.push({ ...override, source: "Date override" });
|
||||
return acc;
|
||||
}, [] as IBusySlot[]) || [];
|
||||
|
||||
return (
|
||||
<div className="max-w-xl overflow-hidden rounded-md bg-white shadow">
|
||||
<div className="px-4 py-5 sm:p-6">
|
||||
@@ -37,9 +50,9 @@ const AvailabilityView = ({ user }: { user: User }) => {
|
||||
<input
|
||||
type="date"
|
||||
className="inline h-8 border-none p-0"
|
||||
defaultValue={selectedDate.format("YYYY-MM-DD")}
|
||||
defaultValue={formattedSelectedDate}
|
||||
onChange={(e) => {
|
||||
if (e.target.value) setSelectedDate(dayjs(e.target.value));
|
||||
if (e.target.value) setSelectedDate(e.target.value);
|
||||
}}
|
||||
/>
|
||||
<small className="block text-neutral-400">{t("hover_over_bold_times_tip")}</small>
|
||||
@@ -49,39 +62,47 @@ const AvailabilityView = ({ user }: { user: User }) => {
|
||||
{t("your_day_starts_at")} {convertMinsToHrsMins(user.startTime)}
|
||||
</div>
|
||||
</div>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<SkeletonText className="block h-16 w-full" />
|
||||
<SkeletonText className="block h-16 w-full" />
|
||||
</>
|
||||
) : data && data.busy.length > 0 ? (
|
||||
data.busy
|
||||
.sort((a: IBusySlot, b: IBusySlot) => (a.start > b.start ? -1 : 1))
|
||||
.map((slot: IBusySlot) => (
|
||||
<div
|
||||
key={dayjs(slot.start).format("HH:mm")}
|
||||
className="overflow-hidden rounded-md bg-neutral-100">
|
||||
<div className="px-4 py-5 text-black sm:p-6">
|
||||
{t("calendar_shows_busy_between")}{" "}
|
||||
<span className="font-medium text-neutral-800" title={dayjs(slot.start).format("HH:mm")}>
|
||||
{dayjs(slot.start).format("HH:mm")}
|
||||
</span>{" "}
|
||||
{t("and")}{" "}
|
||||
<span className="font-medium text-neutral-800" title={dayjs(slot.end).format("HH:mm")}>
|
||||
{dayjs(slot.end).format("HH:mm")}
|
||||
</span>{" "}
|
||||
{t("on")} {dayjs(slot.start).format("D")}{" "}
|
||||
{t(dayjs(slot.start).format("MMMM").toLowerCase())} {dayjs(slot.start).format("YYYY")}
|
||||
{slot.title && ` - (${slot.title})`}
|
||||
{slot.source && <small>{` - (source: ${slot.source})`}</small>}
|
||||
{(() => {
|
||||
if (isLoading)
|
||||
return (
|
||||
<>
|
||||
<SkeletonText className="block h-16 w-full" />
|
||||
<SkeletonText className="block h-16 w-full" />
|
||||
</>
|
||||
);
|
||||
|
||||
if (data && (data.busy.length > 0 || overrides.length > 0))
|
||||
return [...data.busy, ...overrides]
|
||||
.sort((a: IBusySlot, b: IBusySlot) => (a.start > b.start ? -1 : 1))
|
||||
.map((slot: IBusySlot) => (
|
||||
<div
|
||||
key={dayjs(slot.start).format("HH:mm")}
|
||||
className="overflow-hidden rounded-md bg-neutral-100"
|
||||
data-testid="troubleshooter-busy-time">
|
||||
<div className="px-4 py-5 text-black sm:p-6">
|
||||
{t("calendar_shows_busy_between")}{" "}
|
||||
<span
|
||||
className="font-medium text-neutral-800"
|
||||
title={dayjs(slot.start).format("HH:mm")}>
|
||||
{dayjs(slot.start).format("HH:mm")}
|
||||
</span>{" "}
|
||||
{t("and")}{" "}
|
||||
<span className="font-medium text-neutral-800" title={dayjs(slot.end).format("HH:mm")}>
|
||||
{dayjs(slot.end).format("HH:mm")}
|
||||
</span>{" "}
|
||||
{t("on")} {dayjs(slot.start).format("D")}{" "}
|
||||
{t(dayjs(slot.start).format("MMMM").toLowerCase())} {dayjs(slot.start).format("YYYY")}
|
||||
{slot.title && ` - (${slot.title})`}
|
||||
{slot.source && <small>{` - (source: ${slot.source})`}</small>}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className="overflow-hidden rounded-md bg-neutral-100">
|
||||
<div className="px-4 py-5 text-black sm:p-6">{t("calendar_no_busy_slots")}</div>
|
||||
</div>
|
||||
)}
|
||||
));
|
||||
return (
|
||||
<div className="overflow-hidden rounded-md bg-neutral-100">
|
||||
<div className="px-4 py-5 text-black sm:p-6">{t("calendar_no_busy_slots")}</div>
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
|
||||
<div className="bg-brand dark:bg-darkmodebrand overflow-hidden rounded-md">
|
||||
<div className="text-brandcontrast dark:text-darkmodebrandcontrast px-4 py-2 sm:px-6">
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
import { BookingStatus } from "@prisma/client";
|
||||
import { createHmac } from "crypto";
|
||||
import { instance } from "gaxios";
|
||||
import { GetServerSidePropsContext } from "next";
|
||||
import { useRouter } from "next/router";
|
||||
import { useState } from "react";
|
||||
import z from "zod";
|
||||
|
||||
import { getEventLocationValue, getSuccessPageLocationMessage } from "@calcom/app-store/locations";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { getRecurringWhen } from "@calcom/emails/src/components/WhenInfo";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { parseRecurringEvent } from "@calcom/lib/isRecurringEvent";
|
||||
import { processBookingConfirmation } from "@calcom/lib/server/queries/bookings/confirm";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { TRPCError } from "@calcom/trpc/server";
|
||||
import { inferSSRProps } from "@calcom/types/inferSSRProps";
|
||||
import { Button, Icon, TextArea } from "@calcom/ui";
|
||||
|
||||
import { HeadSeo } from "@components/seo/head-seo";
|
||||
|
||||
enum DirectAction {
|
||||
"accept" = "accept",
|
||||
"reject" = "reject",
|
||||
}
|
||||
const actionSchema = z.nativeEnum(DirectAction);
|
||||
|
||||
const refineParse = (result: z.SafeParseReturnType<any, any>, context: z.RefinementCtx) => {
|
||||
if (result.success === false) {
|
||||
result.error.issues.map((issue) => context.addIssue(issue));
|
||||
}
|
||||
};
|
||||
|
||||
const CALENDSO_ENCRYPTION_KEY = process.env.CALENDSO_ENCRYPTION_KEY || "";
|
||||
|
||||
const pageErrors = {
|
||||
signature_mismatch: "Direct link signature doesn't match signed data",
|
||||
booking_not_found: "Direct link booking not found",
|
||||
user_not_found: "Direct link booking user not found",
|
||||
};
|
||||
|
||||
const requestSchema = z.object({
|
||||
link: z
|
||||
.array(z.string())
|
||||
.max(4)
|
||||
.superRefine((data, ctx) => {
|
||||
refineParse(actionSchema.safeParse(data[0]), ctx);
|
||||
const signedData = `${data[1]}/${data[2]}`;
|
||||
const sig = createHmac("sha1", CALENDSO_ENCRYPTION_KEY).update(signedData).digest("base64");
|
||||
if (data[3] !== sig) {
|
||||
ctx.addIssue({
|
||||
message: pageErrors.signature_mismatch,
|
||||
code: "custom",
|
||||
});
|
||||
console.log(signedData, data, data[3], "==", sig);
|
||||
}
|
||||
}),
|
||||
reason: z.string().optional(),
|
||||
});
|
||||
|
||||
function bookingContent(status: BookingStatus | undefined | null) {
|
||||
switch (status) {
|
||||
case BookingStatus.PENDING:
|
||||
// Trying to reject booking without reason
|
||||
return {
|
||||
iconColor: "gray",
|
||||
Icon: Icon.FiCalendar,
|
||||
titleKey: "event_awaiting_approval",
|
||||
subtitleKey: "someone_requested_an_event",
|
||||
};
|
||||
case BookingStatus.ACCEPTED:
|
||||
// Booking was acepted successfully
|
||||
return {
|
||||
iconColor: "green",
|
||||
Icon: Icon.FiCheck,
|
||||
titleKey: "booking_confirmed",
|
||||
subtitleKey: "emailed_you_and_any_other_attendees",
|
||||
};
|
||||
case BookingStatus.REJECTED:
|
||||
// Booking was rejected successfully
|
||||
return {
|
||||
iconColor: "red",
|
||||
Icon: Icon.FiX,
|
||||
titleKey: "booking_rejection_success",
|
||||
subtitleKey: "emailed_you_and_any_other_attendees",
|
||||
};
|
||||
default:
|
||||
// Booking was already accepted or rejected
|
||||
return {
|
||||
iconColor: "yellow",
|
||||
Icon: Icon.FiAlertTriangle,
|
||||
titleKey: "booking_already_accepted_rejected",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default function Directlink({ booking, reason, status }: inferSSRProps<typeof getServerSideProps>) {
|
||||
const { t } = useLocale();
|
||||
const router = useRouter();
|
||||
const acceptPath = router.asPath.replace("reject", "accept");
|
||||
const rejectPath = router.asPath.replace("accept", "reject");
|
||||
const [cancellationReason, setCancellationReason] = useState("");
|
||||
function getRecipientStart(format: string) {
|
||||
return dayjs(booking.startTime).tz(booking?.user?.timeZone).format(format);
|
||||
}
|
||||
|
||||
function getRecipientEnd(format: string) {
|
||||
return dayjs(booking.endTime).tz(booking?.user?.timeZone).format(format);
|
||||
}
|
||||
const organizer = {
|
||||
...booking.attendees[0],
|
||||
language: {
|
||||
translate: t,
|
||||
locale: booking.attendees[0].locale ?? "en",
|
||||
},
|
||||
};
|
||||
const location: ReturnType<typeof getEventLocationValue> = Array.isArray(booking.location)
|
||||
? booking.location[0]
|
||||
: // If there is no location set then we default to Cal Video
|
||||
"integrations:daily";
|
||||
const locationToDisplay = getSuccessPageLocationMessage(location, t);
|
||||
const content = bookingContent(status);
|
||||
const recurringInfo = getRecurringWhen({
|
||||
recurringEvent: booking.eventType?.recurringEvent,
|
||||
attendee: organizer,
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<HeadSeo
|
||||
title={t(content.titleKey)}
|
||||
description=""
|
||||
nextSeoProps={{
|
||||
nofollow: true,
|
||||
noindex: true,
|
||||
}}
|
||||
/>
|
||||
<div className="dark:bg-darkgray-50 desktop-transparent min-h-screen bg-gray-100 px-4">
|
||||
<main className="mx-auto max-w-3xl">
|
||||
<div className="z-50 overflow-y-auto ">
|
||||
<div className="flex items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
|
||||
<div className="inset-0 my-4 transition-opacity sm:my-0" aria-hidden="true">
|
||||
<div
|
||||
className="main dark:bg-darkgray-100 inline-block transform overflow-hidden rounded-lg border bg-white px-8 pt-5 pb-4 text-left align-bottom transition-all dark:border-neutral-700 sm:my-[68px] sm:w-full sm:max-w-xl sm:py-8 sm:align-middle"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="modal-headline">
|
||||
<div
|
||||
className={`flex h-12 w-12 items-center justify-center rounded-full sm:mx-auto bg-${content.iconColor}-100`}>
|
||||
<content.Icon className={`h-5 w-5 text-${content.iconColor}-600`} />
|
||||
</div>
|
||||
<div className="mt-6 mb-8 last:mb-0 sm:text-center">
|
||||
<h3
|
||||
className="text-2xl font-semibold leading-6 text-neutral-900 dark:text-white"
|
||||
id="modal-headline">
|
||||
{t(content.titleKey)}
|
||||
</h3>
|
||||
{content.subtitleKey && (
|
||||
<div className="mt-3">
|
||||
<p className="text-neutral-600 dark:text-gray-300">{t(content.subtitleKey)}</p>
|
||||
</div>
|
||||
)}
|
||||
<div className="dark:border-darkgray-300 mt-8 grid grid-cols-3 border-t border-[#e1e1e1] pt-8 text-left text-[#313131] dark:text-gray-300">
|
||||
<div className="col-span-3 font-medium sm:col-span-1">{t("what")}</div>
|
||||
<div className="col-span-3 mb-6 last:mb-0 sm:col-span-2">{booking.title}</div>
|
||||
<div className="col-span-3 font-medium sm:col-span-1">{t("when")}</div>
|
||||
<div className="col-span-3 mb-6 last:mb-0 sm:col-span-2">
|
||||
{recurringInfo !== "" && (
|
||||
<>
|
||||
{recurringInfo}
|
||||
<br />
|
||||
</>
|
||||
)}
|
||||
{booking.eventType.recurringEvent?.count ? `${t("starting")} ` : ""}
|
||||
{t(getRecipientStart("dddd").toLowerCase())},{" "}
|
||||
{t(getRecipientStart("MMMM").toLowerCase())} {getRecipientStart("D, YYYY")}
|
||||
<br />
|
||||
{getRecipientStart("h:mma")} - {getRecipientEnd("h:mma")}{" "}
|
||||
<span style={{ color: "#888888" }}>({booking.attendees[0].timeZone})</span>
|
||||
</div>
|
||||
{(booking?.user || booking?.attendees) && (
|
||||
<>
|
||||
<div className="col-span-3 font-medium sm:col-span-1">{t("who")}</div>
|
||||
<div className="col-span-3 last:mb-0 sm:col-span-2">
|
||||
<>
|
||||
{booking?.user && (
|
||||
<div className="mb-3">
|
||||
<p>{booking.user.name}</p>
|
||||
<p className="text-[#888888]">{booking.user.email}</p>
|
||||
</div>
|
||||
)}
|
||||
{booking?.attendees.map((attendee) => (
|
||||
<div key={attendee.name} className="mb-3 last:mb-0">
|
||||
{attendee.name && <p>{attendee.name}</p>}
|
||||
<p className="text-[#888888]">{attendee.email}</p>
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{locationToDisplay && (
|
||||
<>
|
||||
<div className="col-span-3 mt-6 font-medium sm:col-span-1">{t("where")}</div>
|
||||
<div className="col-span-3 mt-6 sm:col-span-2">
|
||||
{locationToDisplay.startsWith("http") ? (
|
||||
<a title="Meeting Link" href={locationToDisplay}>
|
||||
{locationToDisplay}
|
||||
</a>
|
||||
) : (
|
||||
locationToDisplay
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{booking?.description && (
|
||||
<>
|
||||
<div className="col-span-3 mt-9 font-medium sm:col-span-1">
|
||||
{t("additional_notes")}
|
||||
</div>
|
||||
<div className="col-span-3 mb-2 mt-9 sm:col-span-2">
|
||||
<p>{booking.description}</p>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{status === BookingStatus.REJECTED && reason && (
|
||||
<>
|
||||
<div className="col-span-3 mt-9 font-medium sm:col-span-1">
|
||||
{t("rejection_reason")}
|
||||
</div>
|
||||
<div className="col-span-3 mb-2 mt-9 sm:col-span-2">
|
||||
<p>{reason}</p>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
{status === BookingStatus.PENDING && reason === undefined && (
|
||||
<>
|
||||
<hr className="mt-6" />
|
||||
<div className="mt-5 text-left sm:mt-6">
|
||||
<label className="font-medium text-[#313131] dark:text-white">
|
||||
{`${t("rejection_reason")} (${t("optional").toLowerCase()})`}
|
||||
</label>
|
||||
<TextArea
|
||||
value={cancellationReason}
|
||||
onChange={(e) => setCancellationReason(e.target.value)}
|
||||
className="mt-2 mb-4 w-full dark:border-gray-900 dark:bg-gray-700 dark:text-white "
|
||||
rows={3}
|
||||
/>
|
||||
<div className="flex flex-col-reverse rtl:space-x-reverse">
|
||||
<div className="ml-auto flex w-full justify-end space-x-4">
|
||||
<Button
|
||||
color="secondary"
|
||||
className="hidden text-center sm:block"
|
||||
href={acceptPath}>
|
||||
{t("booking_accept_intent")}
|
||||
</Button>
|
||||
<Button
|
||||
className="hidden sm:block"
|
||||
onClick={async () => {
|
||||
router.push(
|
||||
`${rejectPath}?reason=${encodeURIComponent(cancellationReason)}`
|
||||
);
|
||||
}}>
|
||||
{t("rejection_confirmation")}
|
||||
</Button>
|
||||
<Button
|
||||
color="secondary"
|
||||
className="block text-center sm:hidden"
|
||||
href={acceptPath}>
|
||||
{t("accept")}
|
||||
</Button>
|
||||
<Button
|
||||
className="block sm:hidden"
|
||||
onClick={async () => {
|
||||
router.push(
|
||||
`${rejectPath}?reason=${encodeURIComponent(cancellationReason)}`
|
||||
);
|
||||
}}>
|
||||
{t("reject")}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
const parsedQuery = requestSchema.safeParse(context.query);
|
||||
|
||||
// Parsing error, showing error 500 with message
|
||||
if (parsedQuery.success === false) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/500?error=${parsedQuery.error.errors[0].message.concat(
|
||||
" accessing " + context.resolvedUrl
|
||||
)}`,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const {
|
||||
link: [action, email, bookingUid],
|
||||
reason,
|
||||
} = parsedQuery.data;
|
||||
|
||||
const isAccept = action === DirectAction.accept;
|
||||
|
||||
const bookingRaw = await prisma?.booking.findFirst({
|
||||
where: {
|
||||
uid: bookingUid,
|
||||
user: {
|
||||
email,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
location: true,
|
||||
description: true,
|
||||
id: true,
|
||||
recurringEventId: true,
|
||||
status: true,
|
||||
title: true,
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
eventType: {
|
||||
select: {
|
||||
recurringEvent: true,
|
||||
},
|
||||
},
|
||||
attendees: {
|
||||
select: {
|
||||
locale: true,
|
||||
name: true,
|
||||
email: true,
|
||||
timeZone: true,
|
||||
},
|
||||
},
|
||||
user: {
|
||||
select: {
|
||||
id: true,
|
||||
email: true,
|
||||
name: true,
|
||||
timeZone: true,
|
||||
locale: true,
|
||||
destinationCalendar: true,
|
||||
credentials: true,
|
||||
username: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Booking not found, showing error 500 with message
|
||||
if (!bookingRaw) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/500?error=${pageErrors.booking_not_found.concat(" accessing " + context.resolvedUrl)}`,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const booking = {
|
||||
...bookingRaw,
|
||||
startTime: bookingRaw.startTime.toString(),
|
||||
endTime: bookingRaw.endTime.toString(),
|
||||
eventType: {
|
||||
...bookingRaw.eventType,
|
||||
recurringEvent: parseRecurringEvent(bookingRaw?.eventType?.recurringEvent),
|
||||
},
|
||||
attendees: bookingRaw?.attendees.map((att) => ({
|
||||
...att,
|
||||
language: {
|
||||
locale: att.locale ?? "en",
|
||||
},
|
||||
})),
|
||||
};
|
||||
|
||||
// Booking user not found, showing error 500 with message
|
||||
if (booking.user === null) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/500?error=${pageErrors.user_not_found.concat(" accessing " + context.resolvedUrl)}`,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Booking already accepted or rejected
|
||||
if (booking.status !== BookingStatus.PENDING) {
|
||||
return {
|
||||
props: {
|
||||
booking,
|
||||
status: null,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Trying to reject booking without reason
|
||||
if (!isAccept && reason === undefined) {
|
||||
return {
|
||||
props: {
|
||||
booking,
|
||||
status: BookingStatus.PENDING,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Booking good to be accepted or rejected, proceeding to mark it
|
||||
let result: { status: BookingStatus | undefined } = { status: undefined };
|
||||
try {
|
||||
result = await processBookingConfirmation(
|
||||
{
|
||||
bookingId: booking.id,
|
||||
user: booking.user,
|
||||
recurringEventId: booking.recurringEventId,
|
||||
confirmed: action === DirectAction.accept,
|
||||
rejectionReason: reason,
|
||||
},
|
||||
prisma
|
||||
);
|
||||
} catch (e) {
|
||||
if (e instanceof TRPCError) {
|
||||
return {
|
||||
redirect: {
|
||||
destination: `/500?error=${e.message.concat(" accessing " + context.resolvedUrl)}`,
|
||||
permanent: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
booking,
|
||||
status: result.status,
|
||||
reason: context.query.reason ?? null,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import React, { Fragment, useEffect, useState } from "react";
|
||||
import CreateEventTypeButton from "@calcom/features/eventtypes/components/CreateEventTypeButton";
|
||||
import { APP_NAME, CAL_URL, WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import isCalcom from "@calcom/lib/isCalcom";
|
||||
import { RouterOutputs, trpc, TRPCClientError } from "@calcom/trpc/react";
|
||||
import {
|
||||
Badge,
|
||||
@@ -28,6 +29,7 @@ import {
|
||||
showToast,
|
||||
Switch,
|
||||
Tooltip,
|
||||
TipBanner,
|
||||
} from "@calcom/ui";
|
||||
|
||||
import { withQuery } from "@lib/QueryCell";
|
||||
@@ -177,22 +179,17 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
||||
}
|
||||
|
||||
// inject selection data into url for correct router history
|
||||
const openModal = (group: EventTypeGroup, type: EventType) => {
|
||||
const openDuplicateModal = (eventType: EventType) => {
|
||||
const query = {
|
||||
...router.query,
|
||||
dialog: "new-eventtype",
|
||||
eventPage: group.profile.slug,
|
||||
title: type.title,
|
||||
slug: type.slug,
|
||||
description: type.description,
|
||||
length: type.length,
|
||||
type: type.schedulingType,
|
||||
teamId: group.teamId,
|
||||
locations: encodeURIComponent(JSON.stringify(type.locations)),
|
||||
dialog: "duplicate-event-type",
|
||||
title: eventType.title,
|
||||
description: eventType.description,
|
||||
slug: eventType.slug,
|
||||
id: eventType.id,
|
||||
length: eventType.length,
|
||||
};
|
||||
if (!group.teamId) {
|
||||
delete query.teamId;
|
||||
}
|
||||
|
||||
router.push(
|
||||
{
|
||||
pathname: router.pathname,
|
||||
@@ -361,7 +358,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
||||
type="button"
|
||||
data-testid={"event-type-duplicate-" + type.id}
|
||||
StartIcon={Icon.FiCopy}
|
||||
onClick={() => openModal(group, type)}>
|
||||
onClick={() => openDuplicateModal(type)}>
|
||||
{t("duplicate") as string}
|
||||
</DropdownItem>
|
||||
</DropdownMenuItem>
|
||||
@@ -469,7 +466,7 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
|
||||
className="w-full rounded-none"
|
||||
data-testid={"event-type-duplicate-" + type.id}
|
||||
StartIcon={Icon.FiCopy}
|
||||
onClick={() => openModal(group, type)}>
|
||||
onClick={() => openDuplicateModal(type)}>
|
||||
{t("duplicate") as string}
|
||||
</Button>
|
||||
</DropdownMenuItem>
|
||||
@@ -592,6 +589,7 @@ const EventTypesPage = () => {
|
||||
customLoader={<SkeletonLoader />}
|
||||
success={({ data }) => (
|
||||
<>
|
||||
{isCalcom && <TipBanner />}
|
||||
{data.eventTypeGroups.map((group, index) => (
|
||||
<Fragment key={group.profile.slug}>
|
||||
{/* hide list heading when there is only one (current user) */}
|
||||
@@ -610,7 +608,6 @@ const EventTypesPage = () => {
|
||||
/>
|
||||
</Fragment>
|
||||
))}
|
||||
|
||||
{data.eventTypeGroups.length === 0 && <CreateFirstEventTypeView />}
|
||||
<EmbedDialog />
|
||||
</>
|
||||
|
||||
@@ -10,7 +10,7 @@ function AdminAppsView() {
|
||||
const { t } = useLocale();
|
||||
return (
|
||||
<>
|
||||
<Meta title={t("apps")} description={t("apps_description")} />
|
||||
<Meta title={t("apps")} description={t("admin_apps_description")} />
|
||||
<AdminAppsList baseURL="/settings/admin/apps" className="w-0" />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -189,7 +189,7 @@ const AppearanceView = () => {
|
||||
onCheckedChange={(checked) =>
|
||||
formMethods.setValue("hideBranding", checked, { shouldDirty: true })
|
||||
}
|
||||
checked={value}
|
||||
checked={!session.data?.user.belongsToActiveTeam ? false : value}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import { expect } from "@playwright/test";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
|
||||
import { test } from "./lib/fixtures";
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.describe("Availablity tests", () => {
|
||||
test.beforeEach(async ({ page, users }) => {
|
||||
const user = await users.create();
|
||||
await user.login();
|
||||
await page.goto("/availability");
|
||||
// We wait until loading is finished
|
||||
await page.waitForSelector('[data-testid="schedules"]');
|
||||
});
|
||||
|
||||
test.afterEach(async ({ users }) => {
|
||||
await users.deleteAll();
|
||||
});
|
||||
|
||||
test("Date Overrides", async ({ page }) => {
|
||||
await test.step("Can add a date override", async () => {
|
||||
await page.locator('[data-testid="schedules"] > li a').click();
|
||||
await page.locator('[data-testid="add-override"]').click();
|
||||
await page.locator('[id="modal-title"]').waitFor();
|
||||
await page.locator('[data-testid="incrementMonth"]').click();
|
||||
await page.locator('[data-testid="day"][data-disabled="false"]').nth(0).click();
|
||||
await page.locator('[data-testid="date-override-mark-unavailable"]').click();
|
||||
await page.locator('[data-testid="add-override-submit-btn"]').click();
|
||||
await expect(page.locator('[data-testid="date-overrides-list"] > li')).toHaveCount(1);
|
||||
await page.locator('[form="availability-form"][type="submit"]').click();
|
||||
});
|
||||
|
||||
await test.step("Date override is displayed in troubleshooter", async () => {
|
||||
const response = await page.waitForResponse("**/api/trpc/viewer.availability.schedule.update?batch=1");
|
||||
const json = await response.json();
|
||||
// @ts-expect-error trust me bro
|
||||
const date = json[0].result.data.json.schedule.availability.find((a) => !!a.date);
|
||||
const troubleshooterURL = `/availability/troubleshoot?date=${dayjs(date.date).format("YYYY-MM-DD")}`;
|
||||
await page.goto(troubleshooterURL);
|
||||
await expect(page.locator('[data-testid="troubleshooter-busy-time"]')).toHaveCount(1);
|
||||
});
|
||||
});
|
||||
|
||||
test("Availablity pages", async ({ page }) => {
|
||||
await test.step("Can add a new schedule", async () => {
|
||||
await page.locator('[data-testid="new-schedule"]').click();
|
||||
await page.locator('[id="name"]').fill("More working hours");
|
||||
page.locator('[type="submit"]').click();
|
||||
await expect(page.locator("[data-testid=availablity-title]")).toHaveValue("More working hours");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8,10 +8,10 @@ import { test } from "./lib/fixtures";
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
test.describe("Event Types tests", () => {
|
||||
test.describe("pro user", () => {
|
||||
test.describe("user", () => {
|
||||
test.beforeEach(async ({ page, users }) => {
|
||||
const proUser = await users.create();
|
||||
await proUser.login();
|
||||
const user = await users.create();
|
||||
await user.login();
|
||||
await page.goto("/event-types");
|
||||
// We wait until loading is finished
|
||||
await page.waitForSelector('[data-testid="event-types"]');
|
||||
@@ -101,13 +101,13 @@ test.describe("Event Types tests", () => {
|
||||
const params = new URLSearchParams(url);
|
||||
|
||||
expect(params.get("title")).toBe(firstTitle);
|
||||
expect(params.get("slug")).toBe(firstSlug);
|
||||
expect(params.get("slug")).toContain(firstSlug);
|
||||
|
||||
const formTitle = await page.inputValue("[name=title]");
|
||||
const formSlug = await page.inputValue("[name=slug]");
|
||||
|
||||
expect(formTitle).toBe(firstTitle);
|
||||
expect(formSlug).toBe(firstSlug);
|
||||
expect(formSlug).toContain(firstSlug);
|
||||
});
|
||||
test("edit first event", async ({ page }) => {
|
||||
const $eventTypes = page.locator("[data-testid=event-types] > li a");
|
||||
|
||||
@@ -247,7 +247,7 @@ const createUser = async (
|
||||
opts?: CustomUserOpts | null
|
||||
): Promise<PrismaType.UserCreateInput> => {
|
||||
// build a unique name for our user
|
||||
const uname = `${opts?.username}-${workerInfo.workerIndex}-${Date.now()}`;
|
||||
const uname = `${opts?.username || "user"}-${workerInfo.workerIndex}-${Date.now()}`;
|
||||
return {
|
||||
username: uname,
|
||||
name: opts?.name,
|
||||
|
||||
@@ -67,6 +67,7 @@ test("add webhook & test that creating an event triggers a webhook call", async
|
||||
body.payload.eventTypeId = dynamic;
|
||||
body.payload.videoCallData = dynamic;
|
||||
body.payload.appsStatus = dynamic;
|
||||
body.payload.metadata.videoCallUrl = dynamic;
|
||||
|
||||
// if we change the shape of our webhooks, we can simply update this by clicking `u`
|
||||
// console.log("BODY", body);
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"triggerEvent":"BOOKING_CREATED","createdAt":"[redacted/dynamic]","payload":{"type":"30 min","title":"30 min between Nameless and Test Testson","description":"","additionalNotes":"","customInputs":{},"startTime":"[redacted/dynamic]","endTime":"[redacted/dynamic]","organizer":{"name":"Nameless","email":"[redacted/dynamic]","timeZone":"[redacted/dynamic]","language":"[redacted/dynamic]"},"attendees":[{"email":"test@example.com","name":"Test Testson","timeZone":"[redacted/dynamic]","language":"[redacted/dynamic]"}],"location":"[redacted/dynamic]","destinationCalendar":null,"hideCalendarNotes":false,"requiresConfirmation":"[redacted/dynamic]","eventTypeId":"[redacted/dynamic]","seatsShowAttendees":false,"uid":"[redacted/dynamic]","videoCallData":"[redacted/dynamic]","appsStatus":"[redacted/dynamic]","eventTitle":"30 min","eventDescription":null,"price":0,"currency":"usd","length":30,"bookingId":"[redacted/dynamic]","metadata":{},"status":"ACCEPTED","additionalInformation":"[redacted/dynamic]"}}
|
||||
{"triggerEvent":"BOOKING_CREATED","createdAt":"[redacted/dynamic]","payload":{"type":"30 min","title":"30 min between Nameless and Test Testson","description":"","additionalNotes":"","customInputs":{},"startTime":"[redacted/dynamic]","endTime":"[redacted/dynamic]","organizer":{"name":"Nameless","email":"[redacted/dynamic]","timeZone":"[redacted/dynamic]","language":"[redacted/dynamic]"},"attendees":[{"email":"test@example.com","name":"Test Testson","timeZone":"[redacted/dynamic]","language":"[redacted/dynamic]"}],"location":"[redacted/dynamic]","destinationCalendar":null,"hideCalendarNotes":false,"requiresConfirmation":"[redacted/dynamic]","eventTypeId":"[redacted/dynamic]","seatsShowAttendees":false,"uid":"[redacted/dynamic]","videoCallData":"[redacted/dynamic]","appsStatus":"[redacted/dynamic]","eventTitle":"30 min","eventDescription":null,"price":0,"currency":"usd","length":30,"bookingId":"[redacted/dynamic]","metadata":{"videoCallUrl":"[redacted/dynamic]"},"status":"ACCEPTED","additionalInformation":"[redacted/dynamic]"}}
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg stroke="#888888" fill="none" stroke-width="2.5" viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
|
||||
<polyline points="15 3 21 3 21 9"></polyline>
|
||||
<line x1="10" y1="14" x2="21" y2="3"></line>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 360 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 197 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 35 KiB |
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "يوجد حدث لا يزال في انتظار الموافقة",
|
||||
"event_is_still_waiting": "لا يزال طلب الحدث في الانتظار: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "لا يوجد مزيد من النتائج",
|
||||
"no_results": "لا نتائج",
|
||||
"load_more_results": "تحميل المزيد من النتائج",
|
||||
"integration_meeting_id": "مُعرّف اجتماع {{integrationName}}: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "تم التأكيد: {{eventType}} مع {{name}} في {{date}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "إضافة إلى التقويم",
|
||||
"add_another_calendar": "إضافة تقويم آخر",
|
||||
"other": "آخر",
|
||||
"email_sign_in_subject": "رابط تسجيل الدخول بك لـ{{appName}}",
|
||||
"emailed_you_and_attendees": "لقد أرسلنا إليك وإلى الحضور الآخرين دعوة للتقويم عبر البريد الإلكتروني تتضمن كل التفاصيل.",
|
||||
"emailed_you_and_attendees_recurring": "لقد أرسلنا إليك وإلى الحضور الآخرين دعوة تقويم عبر البريد الإلكتروني لأول هذه الأحداث المتكررة.",
|
||||
"emailed_you_and_any_other_attendees": "تم إرسال هذه المعلومات إليك وإلى الحضور الآخرين عبر البريد الإلكتروني.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "انتقل إلى بوابة الفوترة",
|
||||
"need_anything_else": "هل تحتاج إلى أي شيء آخر؟",
|
||||
"further_billing_help": "إذا كنت تحتاج إلى أي مساعدة إضافية بخصوص الفوترة، فإن فريق الدعم لدينا في انتظارك لتقديم المساعدة.",
|
||||
"contact_our_support_team": "الاتصال بفريق الدعم لدينا",
|
||||
"uh_oh": "عذرًا!",
|
||||
"no_event_types_have_been_setup": "لم يقم هذا المستخدم بإعداد أي أنواع للحدث حتى الآن.",
|
||||
"edit_logo": "تعديل الشعار",
|
||||
@@ -420,6 +421,7 @@
|
||||
"current_incorrect_password": "كلمة المرور الحالية غير صحيحة",
|
||||
"password_hint_caplow": "مزيج من الحروف الكبيرة والحروف الصغيرة",
|
||||
"password_hint_min": "8 أحرف كحد أدنى",
|
||||
"password_hint_admin_min": "15 محرفًا كحد أدنى",
|
||||
"password_hint_num": "يحتوي على رقم واحد على الأقل",
|
||||
"invalid_password_hint": "يجب أن تتألف كلمة المرور على الأقل من 7 أحرف، ورقم واحد على الأقل، ومزيج من الحروف الكبيرة والصغيرة",
|
||||
"incorrect_password": "كلمة المرور غير صحيحة.",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "قم بتأكيد {{eventTypeTitle}} مع {{profileName}}",
|
||||
"booking_reschedule_confirmation": "أعد جدولة {{eventTypeTitle}} مع {{profileName}}",
|
||||
"in_person_meeting": "الرابط أو الاجتماع الشخصي",
|
||||
"attendeeInPerson": "شخصيًا (عنوان من سيحضر)",
|
||||
"inPerson": "شخصيًا (عنوان المنظم)",
|
||||
"link_meeting": "رابط الاجتماع",
|
||||
"phone_call": "رقم هاتف الحضور",
|
||||
"your_number": "رقم هاتفك",
|
||||
"phone_number": "رقم الهاتف",
|
||||
"attendee_phone_number": "رقم هاتف الحضور",
|
||||
"organizer_phone_number": "رقم هاتف المنظم",
|
||||
"host_phone_number": "رقم هاتفك",
|
||||
"enter_phone_number": "أدخل رقم الهاتف",
|
||||
"reschedule": "إعادة الجدولة",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "جماعي",
|
||||
"collective_description": "جدولة الاجتماعات عندما يكون جميع أعضاء الفريق المحددين متاحين.",
|
||||
"duration": "المدة",
|
||||
"available_durations": "المدد المتاحة",
|
||||
"default_duration": "المدة الافتراضية",
|
||||
"default_duration_no_options": "يرجى اختيار المدد المتاحة أولاً",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "الدقائق",
|
||||
"round_robin": "الترتيب الدوري",
|
||||
"round_robin_description": "نقل الاجتماعات بشكل دوري بين أعضاء الفريق المتعددين.",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "الفرق",
|
||||
"team": "فريق",
|
||||
"team_billing": "الفوترة الخاصة بالفريق",
|
||||
"team_billing_description": "إدارة الفواتير لفريقك",
|
||||
"upgrade_to_flexible_pro_title": "لقد قمنا بتغيير الفوترة الخاصة بالفرق",
|
||||
"upgrade_to_flexible_pro_message": "يوجد أعضاء في فريقك من دون مقاعد. قم بترقية خطة Pro خاصتك لتوفير المقاعد الناقصة.",
|
||||
"changed_team_billing_info": "بدءًا من يناير 2022، أصبحنا نفرض الرسوم على مقاعد أعضاء الفريق بشكل منفرد. حاليًا، أعضاء فريقك الذين كانت لديهم خطة Pro مجانية أصبحوا في فترة تجريبية مدتها 14 يومًا. وبمجرد انتهاء الفترة التجريبية الخاصة بهم، سيجري إخفاء هؤلاء الأعضاء من فريقك ما لم تقم بالترقية الآن.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "إخفاء نوع الحدث",
|
||||
"edit_location": "تعديل الموقع",
|
||||
"into_the_future": "في المستقبل",
|
||||
"when_booked_with_less_than_notice": "عند الحجز بأقل من إشعار <time></time>",
|
||||
"within_date_range": "خلال فترة زمنية",
|
||||
"indefinitely_into_future": "إلى أجل غير مسمى في المستقبل",
|
||||
"add_new_custom_input_field": "إضافة خانة إدخال مخصص جديدة",
|
||||
@@ -713,6 +724,8 @@
|
||||
"delete_account_confirmation_message": "هل تريد بالتأكيد حذف حسابك على {{appName}}؟ أي شخص شاركت رابط حسابك معه لن يستطيع بعد الآن الحجز باستخدامه، وستفقد أي تفضيلات حفظتها.",
|
||||
"integrations": "التكاملات",
|
||||
"apps": "التطبيقات",
|
||||
"apps_description": "تمكين تطبيقات مثيل Cal الخاص بك",
|
||||
"apps_listing": "قائمة التطبيقات",
|
||||
"category_apps": "تطبيقات {{category}}",
|
||||
"app_store": "متجر التطبيقات",
|
||||
"app_store_description": "الربط بين الناس، والتكنولوجيا، ومكان العمل.",
|
||||
@@ -736,6 +749,7 @@
|
||||
"toggle_calendars_conflict": "قم بتبديل التقويمات التي تريد التحقق من وجود تضاربات فيها لمنع حدوث حجز مزدوج.",
|
||||
"select_destination_calendar": "إنشاء أحداث في",
|
||||
"connect_additional_calendar": "ربط رزنامة إضافية",
|
||||
"calendar_updated_successfully": "تم تحديث الرزنامة بنجاح",
|
||||
"conferencing": "المؤتمرات عبر الفيديو",
|
||||
"calendar": "التقويم",
|
||||
"payments": "المدفوعات",
|
||||
@@ -768,6 +782,7 @@
|
||||
"trending_apps": "التطبيقات الرائجة",
|
||||
"explore_apps": "تطبيقات {{category}}",
|
||||
"installed_apps": "التطبيقات المثبتة",
|
||||
"free_to_use_apps": "متاح",
|
||||
"no_category_apps": "لا توجد تطبيقات {{category}}",
|
||||
"no_category_apps_description_calendar": "إضافة تطبيق تقويم للتحقق من أي تضارب لمنع أي حجوزات مزدوجة",
|
||||
"no_category_apps_description_conferencing": "جرب إضافة تطبيق مؤتمرات لإنشاء مكالمات فيديو مع عملائك",
|
||||
@@ -806,6 +821,8 @@
|
||||
"verify_wallet": "تأكيد المحفظة",
|
||||
"connect_metamask": "توصيل Metamask",
|
||||
"create_events_on": "إنشاء أحداث في",
|
||||
"enterprise_license": "هذه هي ميزة للمؤسسات",
|
||||
"enterprise_license_description": "لتمكين هذه الميزة، احصل على مفتاح نشر في وحدة التحكم {{consoleUrl}} وأضفه إلى وحدة التحكم الخاصة بك. nv باسم CALCOM_LICENSE_KEY. إذا كان لدى فريقك بالفعل ترخيص، يرجى الاتصال بـ {{supportMail}} للحصول على المساعدة.",
|
||||
"missing_license": "الترخيص مفقود",
|
||||
"signup_requires": "يلزم ترخيص تجاري",
|
||||
"signup_requires_description": "لا تقدم شركة {{companyName}} حاليًا إصدارًا مجانيًا مفتوح المصدر لصفحة التسجيل. للحصول على حق الوصول الكامل إلى مكونات التسجيل، يجب أن تحصل على ترخيص تجاري. للاستخدام الشخصي، نوصي باستخدام منصة Prisma Data أو أي واجهة أخرى من واجهات Postgres لإنشاء الحسابات.",
|
||||
@@ -897,6 +914,7 @@
|
||||
"user_impersonation_heading": "انتحال شخصية مستخدم",
|
||||
"user_impersonation_description": "يسمح لفريق الدعم الخاص بنا بتسجيل الدخول مؤقتًا نيابة عنك لمساعدتنا على حل أي مشاكل تبلغ عنها بسرعة.",
|
||||
"team_impersonation_description": "يسمح لأعضاء فريقك بتسجيل الدخول نيابة عنك مؤقتًا.",
|
||||
"allow_booker_to_select_duration": "السماح لمن يقوم بالحجز بتحديد المدة",
|
||||
"impersonate_user_tip": "يتم مراجعة جميع استخدامات هذه الميزة.",
|
||||
"impersonating_user_warning": "انتحال اسم مستخدم \"{{user}}\".",
|
||||
"impersonating_stop_instructions": "<0>انقر هنا لإيقاف </0>.",
|
||||
@@ -1014,6 +1032,9 @@
|
||||
"error_removing_app": "خطأ في إزالة التطبيق",
|
||||
"web_conference": "مؤتمر عبر الإنترنت",
|
||||
"requires_confirmation": "يتطلب التأكيد",
|
||||
"always_requires_confirmation": "دائمًا",
|
||||
"requires_confirmation_threshold": "يتطلب تأكيد إذا تم حجزه مع إشعار $t({{unit}}_timeUnit){{time}}",
|
||||
"may_require_confirmation": "قد يتطلب التأكيد",
|
||||
"nr_event_type_one": "{{count}} نوع حدث",
|
||||
"nr_event_type_other": "{{count}} من أنواع الحدث",
|
||||
"add_action": "إضافة إجراء",
|
||||
@@ -1101,6 +1122,9 @@
|
||||
"event_limit_tab_description": "ما تواتر مرات الحجز",
|
||||
"event_advanced_tab_description": "إعدادات الرزنامة والمزيد...",
|
||||
"event_advanced_tab_title": "متقدم",
|
||||
"event_setup_multiple_duration_error": "إعداد الحدث: تستلزم فترات متعددة خيارًا واحدًا على الأقل.",
|
||||
"event_setup_multiple_duration_default_error": "إعداد الحدث: الرجاء تحديد مدة افتراضية صالحة.",
|
||||
"event_setup_booking_limits_error": "يجب أن تكون حدود الحجز بترتيب تصاعدي. [يوم،أسبوع،شهر،سنة]",
|
||||
"select_which_cal": "اختر أي رزنامة تريد إضافة الحجز إليها",
|
||||
"custom_event_name": "اسم حدث مخصص",
|
||||
"custom_event_name_description": "إنشاء أسماء أحداث مخصصة لعرضها في حدث الرزنامة",
|
||||
@@ -1154,8 +1178,11 @@
|
||||
"invoices": "الفواتير",
|
||||
"embeds": "التضمينات",
|
||||
"impersonation": "انتحال الشخصية",
|
||||
"impersonation_description": "إعدادات إدارة انتحال شخصية مستخدم",
|
||||
"users": "المستخدمون",
|
||||
"profile_description": "إدارة الإعدادات لملفك الشخصي على {{appName}}",
|
||||
"users_description": "يمكنك هنا العثور على قائمة بجميع المستخدمين",
|
||||
"users_listing": "قائمة المستخدمين",
|
||||
"general_description": "إدارة الإعدادات للغة والمنطقة الزمنية الخاصة بك",
|
||||
"calendars_description": "قم بتهيئة كيفية تفاعل أنواع الأحداث مع التقويمات الخاصة بك",
|
||||
"appearance_description": "إدارة إعدادات مظهر الحجز الخاص بك",
|
||||
@@ -1360,6 +1387,7 @@
|
||||
"number_sms_notifications": "رقم الهاتف (إشعارات الرسائل النصية)",
|
||||
"attendee_email_workflow": "اسم الحاضر",
|
||||
"attendee_email_info": "البريد الإلكتروني للشخص الحجز",
|
||||
"kbar_search_placeholder": "اكتب أمرًا أو بحثًا...",
|
||||
"invalid_credential": "لا! يبدو أن الصلاحية انتهت أو تم إلغاؤها. يرجى إعادة التثبيت مرة أخرى.",
|
||||
"choose_common_schedule_team_event": "اختر جدولاً زمنياً مشتركاً",
|
||||
"choose_common_schedule_team_event_description": "قم بتمكين هذا الخيار إذا كنت ترغب في استخدام جدول زمني مشترك بين المضيفين. عند تعطيل هذا الخيار، سيتم حجز كل مضيف على أساس جدوله الافتراضي.",
|
||||
@@ -1370,5 +1398,44 @@
|
||||
"test_preview": "اختبار المعاينة",
|
||||
"route_to": "التوجيه إلى",
|
||||
"test_preview_description": "اختبار نموذج التوجيه الخاص بك دون تقديم أي بيانات",
|
||||
"test_routing": "اختبار التوجيه"
|
||||
"test_routing": "اختبار التوجيه",
|
||||
"payment_app_disabled": "قام المشرف بتعطيل تطبيق دفع",
|
||||
"edit_event_type": "تعديل نوع الحدث",
|
||||
"collective_scheduling": "جدولة جماعية",
|
||||
"make_it_easy_to_book": "سهّل على فريقك الحجز عندما يكون الجميع متاحين.",
|
||||
"find_the_best_person": "ابحث عن أفضل شخص متوفر، وقم بالتدوير بين أعضاء فريقك.",
|
||||
"fixed_round_robin": "روبين دائري ثابت",
|
||||
"add_one_fixed_attendee": "أضف حاضرًا ثابتًا وروبين مستدير من خلال عدد من الحاضرين.",
|
||||
"calcom_is_better_with_team": "Cal.com أفضل مع الفرق",
|
||||
"add_your_team_members": "أضف أعضاء فريقك إلى أنواع الأحداث الخاصة بك. استخدم الجدولة الجماعية لإدراج الجميع أو العثور على أنسب شخص مع جدولة روبن الدائرية.",
|
||||
"booking_limit_reached": "تم الوصول إلى الحد الأقصى للحجز لهذا النوع من الأحداث",
|
||||
"admin_has_disabled": "قام المشرف بتعطيل {{appName}}",
|
||||
"disabled_app_affects_event_type": "قام المشرف بتعطيل {{appName}} مما يؤثر على نوع الحدث {{eventType}} لديك",
|
||||
"disable_payment_app": "قام المشرف بتعطيل {{appName}} الذي يؤثر على نوع الحدث {{title}} لديك. ولا يزال بإمكان الحاضرين حجز هذا النوع من الأحداث، ولكن لن يُطالبوا بالدفع. يمكنك إخفاء نوع الحدث لمنع حدوث هذا إلى أن يقوم المشرف بتغيير طريقة الدفع لك.",
|
||||
"payment_disabled_still_able_to_book": "لا يزال بإمكان الحاضرين حجز هذا النوع من الأحداث، ولكن لن يُطالبوا بالدفع. يمكنك إخفاء نوع الحدث لمنع حدوث هذا إلى أن يقوم المشرف بتغيير طريقة الدفع لك.",
|
||||
"app_disabled_with_event_type": "عطّل المشرف {{appName}} مما يؤثر على نوع الحدث {{title}} لديك.",
|
||||
"app_disabled_video": "عطّل المشرف {{appName}} الذي قد يؤثر على أنواع الأحداث لديك. إذا كان لديك أنواع من الأحداث مع {{appName}} كموقع، سيكون افتراضيًا من أجل فيديو Cal.",
|
||||
"app_disabled_subject": "تم تعطيل {{appName}}",
|
||||
"navigate_installed_apps": "الذهاب إلى التطبيقات المثبتة",
|
||||
"disabled_calendar": "إذا كان لديك تقويم آخر مثبت، ستُضاف الحجوزات الجديدة إليه. إذا لم يكن الأمر كذلك، قم إذن بتوصيل تقويم جديد لكيلا تفوت أي حجوزات جديدة.",
|
||||
"enable_apps": "تمكين التطبيقات",
|
||||
"enable_apps_description": "تمكين التطبيقات التي يمكن للمستخدمين دمجها مع Cal.com",
|
||||
"app_is_enabled": "تم تمكين {{appName}}",
|
||||
"app_is_disabled": "تم تعطيل {{appName}}",
|
||||
"keys_have_been_saved": "تم حفظ المفاتيح",
|
||||
"disable_app": "تعطيل التطبيق",
|
||||
"disable_app_description": "يمكن لتعطيل هذا التطبيق أن يسبب مشاكل مع كيفية تفاعل المستخدمين مع Cal",
|
||||
"edit_keys": "تحرير المفاتيح",
|
||||
"admin_apps_description": "تمكين تطبيقات مثيل Cal الخاص بك",
|
||||
"no_available_apps": "لا توجد تطبيقات متاحة",
|
||||
"no_available_apps_description": "الرجاء التأكد من وجود تطبيقات في نشرك تحت 'حزم/متجر تطبيقات'",
|
||||
"no_apps": "لا توجد تطبيقات مفعلة في هذا المظهر من Cal",
|
||||
"apps_settings": "إعدادات التطبيقات",
|
||||
"fill_this_field": "يرجى ملء هذا الحقل",
|
||||
"options": "خيارات",
|
||||
"enter_option": "أدخل خيار {{index}}",
|
||||
"add_an_option": "إضافة خيار",
|
||||
"radio": "الراديو",
|
||||
"event_type_duplicate_copy_text": "{{slug}}-نسخ",
|
||||
"set_as_default": "تعيين كافتراضي"
|
||||
}
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "Přejít na fakturační portál",
|
||||
"need_anything_else": "Potřebujete ještě něco?",
|
||||
"further_billing_help": "Pokud potřebujete další pomoc s fakturací, náš tým podpory je zde, aby vám pomohl.",
|
||||
"contact_our_support_team": "Kontaktovat tým podpory",
|
||||
"uh_oh": "Ale ne!",
|
||||
"no_event_types_have_been_setup": "Tento uživatel zatím nezaložil žádné typy událostí.",
|
||||
"edit_logo": "Upravit logo",
|
||||
|
||||
@@ -370,7 +370,6 @@
|
||||
"go_to_billing_portal": "Zum Rechnungsportal gehen",
|
||||
"need_anything_else": "Brauchen Sie etwas anderes?",
|
||||
"further_billing_help": "Wenn Sie weitere Hilfe bei der Rechnungsstellung benötigen, hilft Ihnen unser Support-Team gerne weiter.",
|
||||
"contact_our_support_team": "Kontaktieren Sie unser Support-Team",
|
||||
"uh_oh": "Uh oh!",
|
||||
"no_event_types_have_been_setup": "Dieser Benutzer hat noch keine Termintypen eingerichtet.",
|
||||
"edit_logo": "Logo bearbeiten",
|
||||
@@ -1338,5 +1337,6 @@
|
||||
"test_preview": "Vorschau testen",
|
||||
"route_to": "Weiterleiten zu",
|
||||
"test_preview_description": "Testen Sie Ihr Weiterleitungsformular, ohne Daten zu senden",
|
||||
"test_routing": "Testweiterleitung"
|
||||
"test_routing": "Testweiterleitung",
|
||||
"admin_apps_description": "Hier findest du eine Auflistung deiner Apps"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
{
|
||||
"day_one": "{{count}} ημέρα",
|
||||
"day_other": "{{count}} ημέρες",
|
||||
"second_one": "{{count}} δευτερόλεπτο",
|
||||
"second_other": "{{count}} δευτερόλεπτα",
|
||||
"upgrade_now": "Αναβαθμίστε τώρα",
|
||||
"accept_invitation": "Αποδοχή Πρόσκλησης",
|
||||
"have_any_questions": "Έχετε ερωτήσεις? Είμαστε εδώ για να βοηθήσουμε.",
|
||||
"reset_password_subject": "{{appName}}: Οδηγίες επαναφοράς κωδικού πρόσβασης",
|
||||
"event_declined_subject": "Απορρίφθηκε: {{eventType}} με {{name}} στις {{date}}",
|
||||
"event_cancelled_subject": "Ακύρωση: {{eventType}} με {{name}} στις {{date}}",
|
||||
"need_to_reschedule_or_cancel": "Χρειάζεται να επαναπρογραμματίσετε ή να ακυρώσετε;",
|
||||
"cancellation_reason": "Λόγος ακύρωσης (προαιρετικό)",
|
||||
"rejection_reason": "Λόγος απόρριψης",
|
||||
"rejection_reason_title": "Απόρριψη του αιτήματος κράτησης;",
|
||||
"rejection_confirmation": "Απόρριψη κράτησης",
|
||||
"error_message": "Το μήνυμα σφάλματος ήταν: '{{errorMessage}}'",
|
||||
"refund_failed_subject": "Η επιστροφή χρημάτων απέτυχε: {{name}} - {{date}} - {{eventType}}",
|
||||
"refund_failed": "Η επιστροφή χρημάτων για την εκδήλωση {{eventType}} με {{userName}} στις {{date}} απέτυχε.",
|
||||
"a_refund_failed": "Αποτυχία επιστροφής χρημάτων",
|
||||
"awaiting_payment_subject": "Σε αναμονή Πληρωμής: {{eventType}} με {{name}} στις {{date}}",
|
||||
"meeting_awaiting_payment": "Η πληρωμή της συνάντησής σας εκκρεμεί",
|
||||
"help": "Βοήθεια",
|
||||
"price": "Τιμή",
|
||||
"payment": "Πληρωμή",
|
||||
"missing_card_fields": "Λείπουν τα πεδία της κάρτας",
|
||||
"pay_now": "Πληρωμή τώρα",
|
||||
"terms_summary": "Περίληψη όρων",
|
||||
"open_env": "Ανοίξτε το .env και συμφωνήστε με την Άδεια χρήσης μας",
|
||||
"env_changed": "Έχω αλλάξει το .env μου",
|
||||
"accept_license": "Αποδοχή Άδειας",
|
||||
"no_more_results": "Δεν υπάρχουν άλλα αποτελέσματα",
|
||||
"no_results": "Δεν υπάρχουν αποτελέσματα",
|
||||
"load_more_results": "Φόρτωση περισσότερων αποτελεσμάτων",
|
||||
"integration_meeting_id": "ID συνάντησης {{integrationName}} : {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Επιβεβαίωση: {{eventType}} με {{name}} στις {{date}}",
|
||||
"new_event_request": "Νέο αίτημα εκδήλωσης: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"confirm_or_reject_request": "Επιβεβαιώστε ή απορρίψτε το αίτημα",
|
||||
"check_bookings_page_to_confirm_or_reject": "Ελέγξτε τη σελίδα κρατήσεων για να επιβεβαιώσετε ή να απορρίψετε την κράτηση.",
|
||||
"event_awaiting_approval": "Ένα γεγονός περιμένει την έγκρισή σας",
|
||||
"event_type": "Τύπος Συμβάντος",
|
||||
"meeting_password": "Συνθηματικό Συνάντησης",
|
||||
"meeting_url": "URL Συνάντησης",
|
||||
"meeting_request_rejected": "Το αίτημα συνάντησής σας απορρίφθηκε",
|
||||
"hi": "Γεια",
|
||||
"manage_this_team": "Διαχείριση αυτής της ομάδας",
|
||||
"team_info": "Πληροφορίες Ομάδας",
|
||||
"hidden_team_member_title": "Είστε κρυμμένοι σε αυτήν την ομάδα",
|
||||
"edit_webhook": "Επεξεργασία Webhook",
|
||||
"delete_webhook": "Διαγραφή Webhook",
|
||||
"webhook_enabled": "Ενεργοποιημένο Webhook",
|
||||
"webhook_disabled": "Απενεργοποιημένο Webhook",
|
||||
"webhook_response": "Απάντηση Webhook",
|
||||
"webhook_test": "Έλεγχος Webhook",
|
||||
"webhook_created_successfully": "Το Webhook δημιουργήθηκε επιτυχώς!",
|
||||
"webhook_updated_successfully": "Το Webhook ενημερώθηκε επιτυχώς!",
|
||||
"webhook_removed_successfully": "Το Webhook αφαιρέθηκε επιτυχώς!",
|
||||
"dismiss": "Παράβλεψη",
|
||||
"no_data_yet": "Δεν υπάρχουν δεδομένα ακόμη",
|
||||
"upcoming": "Επερχόμενα",
|
||||
"recurring": "Επαναλαμβανόμενα",
|
||||
"past": "Παρελθοντικά",
|
||||
"choose_a_file": "Επιλογή αρχείου...",
|
||||
"upload_image": "Μεταφόρτωση εικόνας",
|
||||
"username": "Όνομα χρήστη",
|
||||
"is_still_available": "είναι ακόμα διαθέσιμο.",
|
||||
"documentation": "Τεκμηρίωση",
|
||||
"blog": "Ιστολόγιο",
|
||||
"blog_description": "Διαβάστε τα τελευταία μας νέα και άρθρα",
|
||||
"popular_pages": "Δημοφιλείς σελίδες",
|
||||
"register_now": "Εγγραφή τώρα",
|
||||
"register": "Εγγραφή",
|
||||
"page_doesnt_exist": "Η σελίδα δεν υπάρχει.",
|
||||
"check_spelling_mistakes_or_go_back": "Έλεγχος για ορθογραφικά λάθη ή επιστροφή στην προηγούμενη σελίδα.",
|
||||
"404_page_not_found": "404: Η σελίδα δεν βρέθηκε.",
|
||||
"getting_started": "Ξεκινήστε",
|
||||
"already_have_an_account": "Έχετε ήδη λογαριασμό;",
|
||||
"create_account": "Δημιουργία Λογαριασμού",
|
||||
"confirm_password": "Επιβεβαίωση κωδικού πρόσβασης",
|
||||
"create_your_account": "Δημιουργία λογαριασμού",
|
||||
"sign_up": "Εγγραφή",
|
||||
"youve_been_logged_out": "Έχετε αποσυνδεθεί",
|
||||
"hope_to_see_you_soon": "Ελπίζουμε να σας ξαναδούμε σύντομα!",
|
||||
"please_try_again_and_contact_us": "Παρακαλούμε δοκιμάστε ξανά και επικοινωνήστε μαζί μας αν το πρόβλημα παραμένει.",
|
||||
"no_account_exists": "Δεν υπάρχει λογαριασμός που να ταιριάζει με τη διεύθυνση email.",
|
||||
"2fa_enter_six_digit_code": "Εισάγετε τον εξαψήφιο κωδικό από την εφαρμογή ελέγχου ταυτότητας παρακάτω.",
|
||||
"create_an_account": "Δημιουργία λογαριασμού",
|
||||
"dont_have_an_account": "Δεν έχετε λογαριασμό;",
|
||||
"sign_in_account": "Συνδεθείτε στο λογαριασμό σας",
|
||||
"sign_in": "Είσοδος",
|
||||
"connect": "Σύνδεση",
|
||||
"try_for_free": "Δοκιμάστε δωρεάν",
|
||||
"add_to_calendar": "Προσθήκη στο ημερολόγιο",
|
||||
"add_another_calendar": "Προσθήκη άλλου ημερολογίου",
|
||||
"meeting_is_scheduled": "Η συνάντηση έχει προγραμματιστεί",
|
||||
"submitted": "Η κράτησή σας έχει υποβληθεί",
|
||||
"reset_password": "Επαναφορά Κωδικού Πρόσβασης",
|
||||
"change_your_password": "Αλλαγή κωδικού πρόσβασης",
|
||||
"show_password": "Εμφάνιση κωδικού πρόσβασης",
|
||||
"hide_password": "Απόκρυψη κωδικού πρόσβασης",
|
||||
"try_again": "Δοκιμάστε ξανά",
|
||||
"sunday_time_error": "Μη έγκυρη ώρα την Κυριακή",
|
||||
"monday_time_error": "Μη έγκυρη ώρα τη Δευτέρα",
|
||||
"tuesday_time_error": "Μη έγκυρη ώρα την Τρίτη",
|
||||
"wednesday_time_error": "Μη έγκυρη ώρα την Τετάρτη",
|
||||
"thursday_time_error": "Μη έγκυρη ώρα την Πέμπτη",
|
||||
"friday_time_error": "Μη έγκυρη ώρα την Παρασκευή",
|
||||
"saturday_time_error": "Μη έγκυρη ώρα το Σάββατο",
|
||||
"no_meeting_found": "Δε βρέθηκε συνάντηση",
|
||||
"bookings": "Κρατήσεις"
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"second_other": "{{count}} seconds",
|
||||
"upgrade_now": "Upgrade now",
|
||||
"accept_invitation": "Accept Invitation",
|
||||
"calcom_explained": "{{appName}} is the open source Calendly alternative putting you in control of your own data, workflow and appearance.",
|
||||
"calcom_explained": "{{appName}} provides scheduling infrastructure for absolutely everyone.",
|
||||
"have_any_questions": "Have questions? We're here to help.",
|
||||
"reset_password_subject": "{{appName}}: Reset password instructions",
|
||||
"event_declined_subject": "Declined: {{eventType}} with {{name}} at {{date}}",
|
||||
@@ -303,6 +303,7 @@
|
||||
"cancelling_all_recurring": "These are all remaining instances in the recurring event.",
|
||||
"error_with_status_code_occured": "An error with status code {{status}} occurred.",
|
||||
"booking_already_cancelled": "This booking was already cancelled",
|
||||
"booking_already_accepted_rejected": "This booking was already accepted or rejected",
|
||||
"go_back_home": "Go back home",
|
||||
"or_go_back_home": "Or go back home",
|
||||
"no_availability": "Unavailable",
|
||||
@@ -385,7 +386,8 @@
|
||||
"go_to_billing_portal": "Go to the billing portal",
|
||||
"need_anything_else": "Need anything else?",
|
||||
"further_billing_help": "If you need any further help with billing, our support team are here to help.",
|
||||
"contact_our_support_team": "Contact our support team",
|
||||
"contact": "Contact",
|
||||
"our_support_team": "our support team",
|
||||
"uh_oh": "Uh oh!",
|
||||
"no_event_types_have_been_setup": "This user hasn't set up any event types yet.",
|
||||
"edit_logo": "Edit logo",
|
||||
@@ -750,7 +752,7 @@
|
||||
"toggle_calendars_conflict": "Toggle the calendars you want to check for conflicts to prevent double bookings.",
|
||||
"select_destination_calendar": "Create events on",
|
||||
"connect_additional_calendar": "Connect additional calendar",
|
||||
"calendar_updated_successfully":"Calendar updated successfully",
|
||||
"calendar_updated_successfully": "Calendar updated successfully",
|
||||
"conferencing": "Conferencing",
|
||||
"calendar": "Calendar",
|
||||
"payments": "Payments",
|
||||
@@ -791,7 +793,7 @@
|
||||
"no_category_apps_description_analytics": "Add an analytics app for your booking pages",
|
||||
"no_category_apps_description_automation": "Add an automation app to use",
|
||||
"no_category_apps_description_other": "Add any other type of app to do all sorts of things",
|
||||
"installed_app_calendar_description": "Set the calendar(s) to check for conflicts to prevent double bookings.",
|
||||
"installed_app_calendar_description": "Set the calendars to check for conflicts to prevent double bookings.",
|
||||
"installed_app_conferencing_description": "Add your favourite video conferencing apps for your meetings",
|
||||
"installed_app_payment_description": "Configure which payment processing services to use when charging your clients.",
|
||||
"installed_app_analytics_description": "Configure which analytics apps to use for your booking pages",
|
||||
@@ -918,7 +920,7 @@
|
||||
"allow_booker_to_select_duration": "Allow booker to select duration",
|
||||
"impersonate_user_tip": "All uses of this feature is audited.",
|
||||
"impersonating_user_warning": "Impersonating username \"{{user}}\".",
|
||||
"impersonating_stop_instructions": "<0>Click Here to stop</0>.",
|
||||
"impersonating_stop_instructions": "Click here to stop",
|
||||
"event_location_changed": "Updated - Your event changed the location",
|
||||
"location_changed_event_type_subject": "Location Changed: {{eventType}} with {{name}} at {{date}}",
|
||||
"current_location": "Current Location",
|
||||
@@ -1326,6 +1328,8 @@
|
||||
"booking_confirmation_success": "Booking confirmation succeeded",
|
||||
"booking_rejection_success": "Booking rejection succeeded",
|
||||
"booking_confirmation_fail": "Booking confirmation failed",
|
||||
"booking_tentative": "This booking is tentative",
|
||||
"booking_accept_intent": "Oops, I want to accept",
|
||||
"we_wont_show_again": "We won't show this again",
|
||||
"couldnt_update_timezone": "We couldn't update the timezone",
|
||||
"updated_timezone_to": "Updated timezone to {{formattedCurrentTz}}",
|
||||
@@ -1389,9 +1393,6 @@
|
||||
"attendee_email_workflow": "Attendee email",
|
||||
"attendee_email_info": "The person booking's email",
|
||||
"kbar_search_placeholder": "Type a command or search...",
|
||||
"free_to_use_apps": "Free",
|
||||
"enterprise_license": "This is an enterprise feature",
|
||||
"enterprise_license_description": "To enable this feature, get a deployment key at {{consoleUrl}} console and add it to your .env as CALCOM_LICENSE_KEY. If your team already has a license, please contact {{supportMail}} for help.",
|
||||
"invalid_credential": "Oh no! Looks like permission expired or was revoked. Please reinstall again.",
|
||||
"choose_common_schedule_team_event": "Choose a common schedule",
|
||||
"choose_common_schedule_team_event_description": "Enable this if you want to use a common schedule between hosts. When disabled, each host will be booked based on their default schedule.",
|
||||
@@ -1412,7 +1413,7 @@
|
||||
"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",
|
||||
"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",
|
||||
"admin_has_disabled": "An admin has disabled {{appName}}",
|
||||
"disabled_app_affects_event_type": "An admin has disabled {{appName}} which affects your event type {{eventType}}",
|
||||
"disable_payment_app": "The admin has disabled {{appName}} which affects your event type {{title}}. Attendees are still able to book this type of event but will not be prompted to pay. You may hide hide the event type to prevent this until your admin renables your payment method.",
|
||||
@@ -1430,7 +1431,7 @@
|
||||
"disable_app": "Disable App",
|
||||
"disable_app_description": "Disabling this app could cause problems with how your users interact with Cal",
|
||||
"edit_keys": "Edit Keys",
|
||||
"apps_description": "Enable apps for your instance of Cal",
|
||||
"admin_apps_description": "Enable apps for your instance of Cal",
|
||||
"no_available_apps": "There are no available apps",
|
||||
"no_available_apps_description": "Please ensure there are apps in your deployment under 'packages/app-store'",
|
||||
"no_apps": "There are no apps enabled in this instance of Cal",
|
||||
@@ -1440,6 +1441,26 @@
|
||||
"enter_option": "Enter Option {{index}}",
|
||||
"add_an_option": "Add an option",
|
||||
"radio": "Radio",
|
||||
"kbar_search_placeholder" : "Start typing to search",
|
||||
"set_as_default": "Set as default"
|
||||
"date_overrides": "Date overrides",
|
||||
"date_overrides_subtitle": "Add dates when your availability changes from your daily hours.",
|
||||
"date_overrides_info": "Date overrides are archived automatically after the date has passed",
|
||||
"date_overrides_dialog_which_hours": "Which hours are you free?",
|
||||
"date_overrides_dialog_which_hours_unavailable": "Which hours are you busy?",
|
||||
"date_overrides_dialog_title": "Select the dates to override",
|
||||
"date_overrides_unavailable": "Unavailable all day",
|
||||
"date_overrides_mark_all_day_unavailable_one": "Mark unavailable (All day)",
|
||||
"date_overrides_mark_all_day_unavailable_other": "Mark unavailable on selected dates",
|
||||
"date_overrides_add_btn": "Add Override",
|
||||
"date_overrides_update_btn": "Update Override",
|
||||
"event_type_duplicate_copy_text": "{{slug}}-copy",
|
||||
"set_as_default": "Set as default",
|
||||
"hide_eventtype_details": "Hide EventType Details",
|
||||
"verification_code_sent": "Verification code sent",
|
||||
"verified_successfully": "Verified successfully",
|
||||
"wrong_code": "Wong verification code",
|
||||
"not_verified": "Not yet verified",
|
||||
"no_availability_in_month": "No availability in {{month}}",
|
||||
"view_next_month": "View next month",
|
||||
"send_code" : "Send code",
|
||||
"number_verified": "Number Verified"
|
||||
}
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "Ir al portal de facturación",
|
||||
"need_anything_else": "¿Necesita algo más?",
|
||||
"further_billing_help": "Si necesita más ayuda con la facturación, nuestro equipo de soporte está aquí para ayudarlo.",
|
||||
"contact_our_support_team": "Contacta con nuestro equipo de soporte",
|
||||
"uh_oh": "Uh oh!",
|
||||
"no_event_types_have_been_setup": "Este usuario aún no ha configurado ningún tipo de evento.",
|
||||
"edit_logo": "Cambiar la marca",
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
"event_request_cancelled": "Votre événement programmé a été annulé",
|
||||
"organizer": "Organisateur",
|
||||
"need_to_reschedule_or_cancel": "Besoin de reprogrammer ou d'annuler ?",
|
||||
"cancellation_reason": "Motif de l'annulation",
|
||||
"cancellation_reason_placeholder": "Pourquoi annulez-vous ? (facultatif)",
|
||||
"cancellation_reason": "Motif de l'annulation (facultatif)",
|
||||
"cancellation_reason_placeholder": "Pourquoi annulez-vous ?",
|
||||
"rejection_reason": "Motif de rejet",
|
||||
"rejection_reason_title": "Rejeter la demande de réservation ?",
|
||||
"rejection_reason_description": "Êtes-vous sûr de vouloir rejeter la réservation ? Nous informerons la personne qui a essayé de réserver. Vous pouvez fournir une raison ci-dessous.",
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "Un événement est toujours en attente d'approbation",
|
||||
"event_is_still_waiting": "La demande d'événement est toujours en attente : {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "Plus de résultats",
|
||||
"no_results": "Aucun résultat",
|
||||
"load_more_results": "Charger plus de résultats",
|
||||
"integration_meeting_id": "Identifiant de la réunion {{integrationName}} : {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Confirmé : {{eventType}} avec {{name}} le {{date}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "Ajouter au calendrier",
|
||||
"add_another_calendar": "Ajouter un autre calendrier",
|
||||
"other": "Autre",
|
||||
"email_sign_in_subject": "Votre lien de connexion pour {{appName}}",
|
||||
"emailed_you_and_attendees": "Nous vous avons envoyé, à vous et aux autres participants, une invitation par e-mail avec tous les détails.",
|
||||
"emailed_you_and_attendees_recurring": "Nous vous avons envoyé, à vous et aux autres participants, une invitation au calendrier pour le premier de ces événements récurrents.",
|
||||
"emailed_you_and_any_other_attendees": "Ces informations vous ont été envoyées par e-mail, ainsi qu'à tous les autres participants.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "Accéder au portail de facturation",
|
||||
"need_anything_else": "Besoin d'autre chose ?",
|
||||
"further_billing_help": "Si vous avez besoin d'aide pour la facturation, notre équipe d'assistance est là pour vous aider.",
|
||||
"contact_our_support_team": "Contactez notre équipe d'assistance",
|
||||
"uh_oh": "Oups !",
|
||||
"no_event_types_have_been_setup": "Cet utilisateur n'a pas encore configuré de types d'événements.",
|
||||
"edit_logo": "Modifier le logo",
|
||||
@@ -419,7 +420,8 @@
|
||||
"forgotten_secret_description": "Si vous avez perdu ou oublié ce code secret, vous pouvez le modifer, mais soyez conscient que toutes les intégrations l'utilisant devront être actualisées",
|
||||
"current_incorrect_password": "Le mot de passe actuel est incorrect",
|
||||
"password_hint_caplow": "Mélange de lettres majuscules et minuscules",
|
||||
"password_hint_min": "Minimum 7 caractères",
|
||||
"password_hint_min": "Minimum 8 caractères",
|
||||
"password_hint_admin_min": "Minimum 15 caractères",
|
||||
"password_hint_num": "Contient au moins 1 chiffre",
|
||||
"invalid_password_hint": "Le mot de passe doit comporter un minimum de 7 caractères, dont au moins un chiffre, et avoir un mélange de lettres majuscules et minuscules",
|
||||
"incorrect_password": "Le mot de passe est incorrect.",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "Confirmez votre {{eventTypeTitle}} avec {{profileName}}",
|
||||
"booking_reschedule_confirmation": "Reporté votre {{eventTypeTitle}} avec {{profileName}}",
|
||||
"in_person_meeting": "Lien ou réunion en présentiel",
|
||||
"attendeeInPerson": "En personne (adresse du participant)",
|
||||
"inPerson": "En personne (adresse de l'organisateur)",
|
||||
"link_meeting": "Lier une réunion",
|
||||
"phone_call": "Appel téléphonique",
|
||||
"your_number": "Votre numéro de téléphone",
|
||||
"phone_number": "Numéro de téléphone",
|
||||
"attendee_phone_number": "Numéro de téléphone du participant",
|
||||
"organizer_phone_number": "Numéro de téléphone de l'organisateur",
|
||||
"host_phone_number": "Votre numéro de téléphone",
|
||||
"enter_phone_number": "Saisissez le numéro de téléphone",
|
||||
"reschedule": "Reporter",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "Collectif",
|
||||
"collective_description": "Planifiez des réunions lorsque tous les membres de l'équipe sélectionnés sont disponibles.",
|
||||
"duration": "Durée",
|
||||
"available_durations": "Durées disponibles",
|
||||
"default_duration": "Durée par défaut",
|
||||
"default_duration_no_options": "Veuillez d'abord choisir les durées disponibles",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "Minutes",
|
||||
"round_robin": "Round Robin",
|
||||
"round_robin_description": "Faites tourner les réunions entre plusieurs membres de l'équipe.",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "Équipes",
|
||||
"team": "Équipe",
|
||||
"team_billing": "Facturation d'équipe",
|
||||
"team_billing_description": "Gérer la facturation pour votre équipe",
|
||||
"upgrade_to_flexible_pro_title": "Nous avons modifié la facturation pour les équipes",
|
||||
"upgrade_to_flexible_pro_message": "Des membres dans votre équipe n'ont pas de place. Mettez à niveau votre offre pro pour couvrir les places manquantes.",
|
||||
"changed_team_billing_info": "Depuis janvier 2022, nous facturons chaque place aux membres de l'équipe. Les membres de votre équipe qui ont eu la version Pro gratuitement disposent maintenant d'un essai de 14 jours. Une fois leur période d'essai expirée, ces membres seront cachés pour votre équipe, sauf si vous mettez à niveau maintenant.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "Masquer le type d'événement",
|
||||
"edit_location": "Modifier le lieu",
|
||||
"into_the_future": "dans le futur",
|
||||
"when_booked_with_less_than_notice": "Si réservé avec moins de <time></time> de préavis",
|
||||
"within_date_range": "Dans une plage de dates",
|
||||
"indefinitely_into_future": "Sans doute dans le futur",
|
||||
"add_new_custom_input_field": "Ajouter un nouveau champ de saisie personnalisé",
|
||||
@@ -713,6 +724,7 @@
|
||||
"delete_account_confirmation_message": "Êtes-vous sûr de vouloir supprimer votre compte {{appName}} ? Toute personne avec qui vous avez partagé le lien de votre compte ne pourra plus réserver en utilisant ce lien et toutes les préférences que vous avez enregistrées seront perdues.",
|
||||
"integrations": "Intégrations",
|
||||
"apps": "Applications",
|
||||
"apps_listing": "Liste des applications",
|
||||
"category_apps": "Applications {{category}}",
|
||||
"app_store": "App Store",
|
||||
"app_store_description": "Connecter les personnes, la technologie et l'espace de travail.",
|
||||
@@ -736,6 +748,7 @@
|
||||
"toggle_calendars_conflict": "Activer/désactiver les calendriers pour lesquels vous souhaiter vérifier les conflits afin d'éviter les doubles réservations.",
|
||||
"select_destination_calendar": "Créer des événements le",
|
||||
"connect_additional_calendar": "Connecter un calendrier supplémentaire",
|
||||
"calendar_updated_successfully": "Calendrier mis à jour avec succès",
|
||||
"conferencing": "Conférence",
|
||||
"calendar": "Calendrier",
|
||||
"payments": "Paiements",
|
||||
@@ -768,6 +781,7 @@
|
||||
"trending_apps": "Applications populaires",
|
||||
"explore_apps": "{{category}} applications",
|
||||
"installed_apps": "Applications installées",
|
||||
"free_to_use_apps": "Gratuit",
|
||||
"no_category_apps": "Aucune application {{category}}",
|
||||
"no_category_apps_description_calendar": "Ajouter 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 conférence pour interconnecter les appels vidéo avec vos clients",
|
||||
@@ -806,6 +820,8 @@
|
||||
"verify_wallet": "Vérifier le portefeuille",
|
||||
"connect_metamask": "Connecter Metamask",
|
||||
"create_events_on": "Créer des événements le :",
|
||||
"enterprise_license": "Il s'agit d'une fonctionnalité d'entreprise",
|
||||
"enterprise_license_description": "Pour activer cette fonctionnalité, obtenez une clé de déploiement sur la console {{consoleUrl}} et ajoutez-la à votre .env en tant que CALCOM_LICENSE_KEY. Si votre équipe a déjà une licence, veuillez contacter {{supportMail}} pour obtenir de l'aide.",
|
||||
"missing_license": "Licence manquante",
|
||||
"signup_requires": "Licence commerciale requise",
|
||||
"signup_requires_description": "{{companyName}} ne propose pas actuellement de version open source gratuite de la page d'inscription. Pour obtenir un accès complet aux composants d'inscription, vous devez acquérir une licence commerciale. Pour une utilisation personnelle, nous recommandons la Plateforme de Données Prisma ou toute autre interface Postgres pour créer des comptes.",
|
||||
@@ -897,6 +913,7 @@
|
||||
"user_impersonation_heading": "Connexion en tant qu'autre utilisateur",
|
||||
"user_impersonation_description": "Permet à notre équipe d'assistance de se connecter temporairement lorsque vous nous aidez à résoudre rapidement tous les problèmes que vous nous signalez.",
|
||||
"team_impersonation_description": "Permet aux administrateurs de votre équipe de se connecter temporairement en tant que vous-même.",
|
||||
"allow_booker_to_select_duration": "Autoriser l'organisateur à sélectionner la durée",
|
||||
"impersonate_user_tip": "Toutes les utilisations de cette fonctionnalité sont vérifiées.",
|
||||
"impersonating_user_warning": "Identification du nom d'utilisateur \"{{user}}\".",
|
||||
"impersonating_stop_instructions": "<0>Cliquez ici pour arrêter</0>.",
|
||||
@@ -1014,6 +1031,9 @@
|
||||
"error_removing_app": "Erreur lors de la suppression de l'application",
|
||||
"web_conference": "Conférence en ligne",
|
||||
"requires_confirmation": "Nécessite une confirmation",
|
||||
"always_requires_confirmation": "Toujours",
|
||||
"requires_confirmation_threshold": "Nécessite une confirmation si réservé avec un préavis de < {{time}} $t({{unit}}_timeUnit)",
|
||||
"may_require_confirmation": "Peut nécessiter une confirmation",
|
||||
"nr_event_type_one": "{{count}} type d'événement",
|
||||
"nr_event_type_other": "{{count}} types d'événements",
|
||||
"add_action": "Ajouter une action",
|
||||
@@ -1101,6 +1121,9 @@
|
||||
"event_limit_tab_description": "Fréquence de réservation",
|
||||
"event_advanced_tab_description": "Paramètres du calendrier & plus...",
|
||||
"event_advanced_tab_title": "Avancé",
|
||||
"event_setup_multiple_duration_error": "Configuration de l'événement : plusieurs durées requièrent au moins une option.",
|
||||
"event_setup_multiple_duration_default_error": "Configuration de l'événement: veuillez sélectionner une durée par défaut valide.",
|
||||
"event_setup_booking_limits_error": "Les limites de réservation doivent être en ordre croissant. [jour,semaine,mois,année]",
|
||||
"select_which_cal": "Sélectionnez le calendrier auquel ajouter des réservations",
|
||||
"custom_event_name": "Nom de l'événement personnalisé",
|
||||
"custom_event_name_description": "Créer des noms d'événements personnalisés à afficher sur l'événement du calendrier",
|
||||
@@ -1154,8 +1177,11 @@
|
||||
"invoices": "Factures",
|
||||
"embeds": "Intègre",
|
||||
"impersonation": "Identification",
|
||||
"impersonation_description": "Paramètres de gestion de l'identité de l'utilisateur",
|
||||
"users": "Utilisateurs",
|
||||
"profile_description": "Gérer les paramètres de votre profil {{appName}}",
|
||||
"users_description": "Vous trouverez ici une liste de tous les utilisateurs",
|
||||
"users_listing": "Liste des utilisateurs",
|
||||
"general_description": "Gérer les paramètres pour votre langue et votre fuseau horaire",
|
||||
"calendars_description": "Configurez la manière dont vos types d'événements interagissent avec vos calendriers",
|
||||
"appearance_description": "Gérer les paramètres pour votre apparence de réservation",
|
||||
@@ -1228,8 +1254,8 @@
|
||||
"exchange_authentication_ntlm": "Authentification NTLM",
|
||||
"exchange_compression": "Compression GZip",
|
||||
"routing_forms_description": "Vous pouvez voir tous les formulaires et tous les parcours que vous avez créés ici.",
|
||||
"routing_forms_send_email_owner": "Envoyer un e-mail au responsable",
|
||||
"routing_forms_send_email_owner_description": "Envoie un e-mail au responsable lorsque le formulaire est soumis",
|
||||
"routing_forms_send_email_owner": "Envoyer un e-mail au propriétaire",
|
||||
"routing_forms_send_email_owner_description": "Envoie un e-mail au propriétaire lorsque le formulaire est envoyé",
|
||||
"add_new_form": "Ajouter un nouveau formulaire",
|
||||
"form_description": "Créez votre formulaire pour acheminer un organisateur",
|
||||
"copy_link_to_form": "Copier le lien vers le formulaire",
|
||||
@@ -1296,7 +1322,7 @@
|
||||
"fetching_calendars_error": "Un problème est survenu lors de la récupération de vos calendriers. Veuillez <1>réessayer</1> ou contacter le service client.",
|
||||
"calendar_connection_fail": "Échec de la connexion au calendrier",
|
||||
"booking_confirmation_success": "Confirmation de réservation réussie",
|
||||
"booking_rejection_success": "Rejet de réservation réussi",
|
||||
"booking_rejection_success": "Refus de réservation réussi",
|
||||
"booking_confirmation_fail": "Échec de la confirmation de la réservation",
|
||||
"we_wont_show_again": "Nous n'afficherons plus ceci",
|
||||
"couldnt_update_timezone": "Nous n'avons pas pu mettre à jour le fuseau horaire",
|
||||
@@ -1346,21 +1372,22 @@
|
||||
"monthly": "Mensuellement",
|
||||
"yearly": "Annuellement",
|
||||
"checkout": "Paiement",
|
||||
"your_team_disbanded_successfully": "Votre équipe a été dissoute avec succès",
|
||||
"your_team_disbanded_successfully": "Votre équipe a bien été dissoute",
|
||||
"error_creating_team": "Erreur lors de la création de l'équipe",
|
||||
"you": "Vous",
|
||||
"send_email": "Envoyer un e-mail",
|
||||
"member_already_invited": "Le membre a déjà été invité",
|
||||
"enter_email_or_username": "Saisissez une adresse e-mail ou un nom d'utilisateur",
|
||||
"team_name_taken": "Ce nom est déjà pris",
|
||||
"must_enter_team_name": "Vous devez entrer un nom d'équipe",
|
||||
"team_url_required": "Vous devez entrer une URL d'équipe",
|
||||
"must_enter_team_name": "Vous devez saisir un nom d'équipe",
|
||||
"team_url_required": "Vous devez saisir une URL d'équipe",
|
||||
"team_url_taken": "Cette URL est déjà prise",
|
||||
"team_publish": "Publier l'équipe",
|
||||
"number_sms_notifications": "Numéro de téléphone (notifications SMS)",
|
||||
"attendee_email_workflow": "E-mail du participant",
|
||||
"attendee_email_info": "E-mail de la personne ayant réservé",
|
||||
"invalid_credential": "Oh non ! Il semble que l’autorisation ait expiré ou a été révoquée. Veuillez la réinstaller.",
|
||||
"kbar_search_placeholder": "Saisissez une commande ou une recherche...",
|
||||
"invalid_credential": "Oh non ! L'autorisation semble avoir expiré ou avoir été révoquée. Veuillez la réinstaller.",
|
||||
"choose_common_schedule_team_event": "Choisissez un horaire commun",
|
||||
"choose_common_schedule_team_event_description": "Activez cette option si vous souhaitez utiliser un horaire commun entre les hôtes. Si désactivée, chaque hôte sera réservé en fonction de son planning par défaut.",
|
||||
"reason": "Raison",
|
||||
@@ -1370,5 +1397,8 @@
|
||||
"test_preview": "Tester l'aperçu",
|
||||
"route_to": "Router vers",
|
||||
"test_preview_description": "Tester votre formulaire de routage sans envoyer de données",
|
||||
"test_routing": "Tester le routage"
|
||||
"test_routing": "Tester le routage",
|
||||
"payment_app_disabled": "Un administrateur a désactivé une application de paiement",
|
||||
"edit_event_type": "Modifier le type d'événement",
|
||||
"admin_apps_description": "Activer les applications pour votre instance de Cal"
|
||||
}
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "מעבר אל פורטל החיובים",
|
||||
"need_anything_else": "צריך משהו נוסף?",
|
||||
"further_billing_help": "אם דרוש לך סיוע נוסף בענייני חיוב, צוות התמיכה שלנו כאן כדי לעזור.",
|
||||
"contact_our_support_team": "יצירת קשר עם צוות התמיכה",
|
||||
"uh_oh": "אוי, לא!",
|
||||
"no_event_types_have_been_setup": "משתמש זה עדיין לא הגדיר סוג אירוע.",
|
||||
"edit_logo": "עריכת לוגו",
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "Un evento è ancora in attesa di approvazione",
|
||||
"event_is_still_waiting": "La richiesta d'evento è ancora in attesa: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "Nessun altro risultato",
|
||||
"no_results": "Nessun risultato",
|
||||
"load_more_results": "Carica più risultati",
|
||||
"integration_meeting_id": "{{integrationName}} meeting ID: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Confermato: {{eventType}} con {{name}} il {{date}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "Aggiungi al calendario",
|
||||
"add_another_calendar": "Aggiungi un altro calendario",
|
||||
"other": "Altro",
|
||||
"email_sign_in_subject": "Link di accesso a {{appName}}",
|
||||
"emailed_you_and_attendees": "Abbiamo inviato via email a te e agli altri partecipanti un invito al calendario con tutti i dettagli.",
|
||||
"emailed_you_and_attendees_recurring": "Abbiamo inviato via email a te e agli altri partecipanti un invito al primo di questi eventi ricorrenti.",
|
||||
"emailed_you_and_any_other_attendees": "Tu e tutti gli altri partecipanti siete stati inviati via email con queste informazioni.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "Vai al portale di fatturazione",
|
||||
"need_anything_else": "Hai bisogno di altro?",
|
||||
"further_billing_help": "Se hai bisogno di ulteriore aiuto per la fatturazione, il nostro team di supporto è qui per aiutarti.",
|
||||
"contact_our_support_team": "Contatta il nostro team di supporto",
|
||||
"uh_oh": "Uh oh!",
|
||||
"no_event_types_have_been_setup": "Questo utente non ha ancora impostato alcun tipo di evento.",
|
||||
"edit_logo": "Modifica logo",
|
||||
@@ -420,6 +421,7 @@
|
||||
"current_incorrect_password": "La password attuale non è corretta",
|
||||
"password_hint_caplow": "Combinazione di caratteri maiuscoli e minuscoli",
|
||||
"password_hint_min": "La lunghezza minima è di 8 caratteri",
|
||||
"password_hint_admin_min": "La lunghezza minima è di 15 caratteri",
|
||||
"password_hint_num": "Deve contenere almeno 1 numero",
|
||||
"invalid_password_hint": "La password deve avere una lunghezza minima di 7 caratteri e deve contenere almeno 1 numero e una combinazione di caratteri maiuscoli e minuscoli",
|
||||
"incorrect_password": "La password non è corretta.",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "Conferma il tuo {{eventTypeTitle}} con {{profileName}}",
|
||||
"booking_reschedule_confirmation": "Riprogramma il tuo {{eventTypeTitle}} con {{profileName}}",
|
||||
"in_person_meeting": "Link o riunione di persona",
|
||||
"attendeeInPerson": "Di persona (indirizzo del partecipante)",
|
||||
"inPerson": "Di persona (indirizzo dell'organizzatore)",
|
||||
"link_meeting": "Collegamento riunione",
|
||||
"phone_call": "Numero di telefono del partecipante",
|
||||
"your_number": "Il tuo numero di telefono",
|
||||
"phone_number": "Numero Di Telefono",
|
||||
"attendee_phone_number": "Numero di telefono del partecipante",
|
||||
"organizer_phone_number": "Numero di telefono organizzatore",
|
||||
"host_phone_number": "Il tuo numero di telefono",
|
||||
"enter_phone_number": "Inserisci numero di telefono",
|
||||
"reschedule": "Riprogramma",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "Collettivo",
|
||||
"collective_description": "Pianifica le riunioni quando tutti i membri del team selezionati sono disponibili.",
|
||||
"duration": "Durata",
|
||||
"available_durations": "Durate disponibili",
|
||||
"default_duration": "Durata predefinita",
|
||||
"default_duration_no_options": "Scegliere prima delle durate disponibili",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "Minuti",
|
||||
"round_robin": "Round Robin",
|
||||
"round_robin_description": "Ciclo di riunioni tra più membri del team.",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "Team",
|
||||
"team": "Team",
|
||||
"team_billing": "Fatturazione team",
|
||||
"team_billing_description": "Gestisci la fatturazione per il tuo team",
|
||||
"upgrade_to_flexible_pro_title": "Abbiamo cambiato la fatturazione per i team",
|
||||
"upgrade_to_flexible_pro_message": "Alcuni membri del tuo team non hanno un posto. Aggiorna il tuo piano Pro per coprire i posti mancanti.",
|
||||
"changed_team_billing_info": "A partire da gennaio 2022, applichiamo una tariffazione in base ai posti per i membri dei team. I membri del tuo team che utilizzavano Pro gratuitamente dispongono ora di un periodo di prova di 14 giorni. Terminata la prova, questi membri saranno nascosti dal tuo team, se non aggiornerai il piano.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "Nascondi tipo evento",
|
||||
"edit_location": "Aggiungi un luogo",
|
||||
"into_the_future": "nel futuro",
|
||||
"when_booked_with_less_than_notice": "Quando si prenota con un avviso inferiore a <time></time>",
|
||||
"within_date_range": "All'interno di un intervallo di date",
|
||||
"indefinitely_into_future": "Indefinitamente nel futuro",
|
||||
"add_new_custom_input_field": "Aggiungi un nuovo campo di input personalizzato",
|
||||
@@ -713,6 +724,8 @@
|
||||
"delete_account_confirmation_message": "Sei sicuro di voler eliminare il tuo account {{appName}}? Chiunque abbia il link del tuo account non potrà più utilizzarlo per prenotare e le preferenze che hai salvato andranno perse.",
|
||||
"integrations": "Integrazioni",
|
||||
"apps": "App",
|
||||
"apps_description": "Abilita le app per la tua istanza di Cal",
|
||||
"apps_listing": "Elenco delle app",
|
||||
"category_apps": "App {{category}}",
|
||||
"app_store": "App Store",
|
||||
"app_store_description": "Collegare persone, tecnologia e luogo di lavoro.",
|
||||
@@ -736,6 +749,7 @@
|
||||
"toggle_calendars_conflict": "Attiva/disattiva i calendari in cui desideri controllare i conflitti per evitare doppie prenotazioni.",
|
||||
"select_destination_calendar": "Crea eventi su",
|
||||
"connect_additional_calendar": "Collega calendario aggiuntivo",
|
||||
"calendar_updated_successfully": "Calendario aggiornato correttamente",
|
||||
"conferencing": "Conferenze",
|
||||
"calendar": "Calendario",
|
||||
"payments": "Pagamenti",
|
||||
@@ -768,6 +782,7 @@
|
||||
"trending_apps": "App di tendenza",
|
||||
"explore_apps": "App {{category}}",
|
||||
"installed_apps": "App installate",
|
||||
"free_to_use_apps": "Gratuito",
|
||||
"no_category_apps": "Nessuna app {{category}}",
|
||||
"no_category_apps_description_calendar": "Aggiungi un'app di calendario per controllare i conflitti ed evitare doppie prenotazioni",
|
||||
"no_category_apps_description_conferencing": "Prova ad aggiungere un'app di conferenza per integrare le videochiamate con i clienti",
|
||||
@@ -806,6 +821,8 @@
|
||||
"verify_wallet": "Verifica Wallet",
|
||||
"connect_metamask": "Connetti Metamask",
|
||||
"create_events_on": "Crea eventi su:",
|
||||
"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.",
|
||||
"missing_license": "Licenza mancante",
|
||||
"signup_requires": "È necessaria una licenza commerciale",
|
||||
"signup_requires_description": "{{companyName}} attualmente non offre una versione open source gratuita della pagina di registrazione. Per avere accesso completo ai componenti di registrazione è necessario acquisire una licenza commerciale. Per un uso personale consigliamo Prisma Data Platform o qualsiasi altra interfaccia Postgres per creare account.",
|
||||
@@ -897,6 +914,7 @@
|
||||
"user_impersonation_heading": "Accesso con altra identità",
|
||||
"user_impersonation_description": "Consente al nostro team di supporto di effettuare l'accesso temporaneo a tuo nome per risolvere rapidamente gli eventuali problemi da te segnalati.",
|
||||
"team_impersonation_description": "Consente ai membri del tuo team di accedere temporaneamente con il tuo nome.",
|
||||
"allow_booker_to_select_duration": "Consenti alla persona che prenota di selezionare la durata",
|
||||
"impersonate_user_tip": "Ogni utilizzo di questa funzionalità viene controllato.",
|
||||
"impersonating_user_warning": "Accesso con l'identità dell'utente \"{{user}}\".",
|
||||
"impersonating_stop_instructions": "<0>Fai clic qui per interrompere</0>.",
|
||||
@@ -1014,6 +1032,9 @@
|
||||
"error_removing_app": "Errore durante la rimozione dell'app",
|
||||
"web_conference": "Conferenza Web",
|
||||
"requires_confirmation": "Richiede conferma",
|
||||
"always_requires_confirmation": "Sempre",
|
||||
"requires_confirmation_threshold": "Richiede conferma se si prenota con un avviso di < {{time}} $t({{unit}}_timeUnit)",
|
||||
"may_require_confirmation": "Può richiedere conferma",
|
||||
"nr_event_type_one": "{{count}} tipo di evento",
|
||||
"nr_event_type_other": "{{count}} tipi di evento",
|
||||
"add_action": "Aggiungi azione",
|
||||
@@ -1101,6 +1122,9 @@
|
||||
"event_limit_tab_description": "Con quale frequenza è possibile fare una prenotazione",
|
||||
"event_advanced_tab_description": "Impostazioni calendario e altro...",
|
||||
"event_advanced_tab_title": "Avanzate",
|
||||
"event_setup_multiple_duration_error": "Impostazione evento: In caso di più durate è richiesta almeno 1 opzione.",
|
||||
"event_setup_multiple_duration_default_error": "Impostazione evento: Selezionare una durata predefinita valida.",
|
||||
"event_setup_booking_limits_error": "I limiti per le prenotazioni devono essere specificati in ordine crescente [giorno,settimana,mese,anno]",
|
||||
"select_which_cal": "Seleziona il calendario al quale aggiungere prenotazioni",
|
||||
"custom_event_name": "Nome evento personalizzato",
|
||||
"custom_event_name_description": "Crea nomi di eventi personalizzati da visualizzare nell'evento del calendario",
|
||||
@@ -1154,8 +1178,11 @@
|
||||
"invoices": "Fatture",
|
||||
"embeds": "Integrazioni",
|
||||
"impersonation": "Accesso con altra identità",
|
||||
"impersonation_description": "Impostazioni per gestire gli accessi con altra identità",
|
||||
"users": "Utenti",
|
||||
"profile_description": "Gestisci le impostazioni del tuo profilo {{appName}}",
|
||||
"users_description": "Qui è possibile trovare l'elenco di tutti gli utenti",
|
||||
"users_listing": "Elenco degli utenti",
|
||||
"general_description": "Gestisci le impostazioni di lingua e fuso orario",
|
||||
"calendars_description": "Configura come i tipi di eventi devono interagire con i tuoi calendari",
|
||||
"appearance_description": "Gestisci le impostazioni di aspetto delle tue prenotazioni",
|
||||
@@ -1360,6 +1387,7 @@
|
||||
"number_sms_notifications": "Numero di telefono (notifiche SMS)",
|
||||
"attendee_email_workflow": "E-mail partecipante",
|
||||
"attendee_email_info": "E-mail della persona che prenota",
|
||||
"kbar_search_placeholder": "Digitare un comando o eseguire una ricerca...",
|
||||
"invalid_credential": "Errore! Sembra che l'autorizzazione sia scaduta o che sia stata revocata. Prova a reinstallare.",
|
||||
"choose_common_schedule_team_event": "Scegli un programma comune",
|
||||
"choose_common_schedule_team_event_description": "Abilita questa opzione se desideri utilizzare un programma comune per tutti gli organizzatori. Quando l'opzione è disabilitata, ciascun organizzatore verrà prenotato in base al proprio programma predefinito.",
|
||||
@@ -1370,5 +1398,45 @@
|
||||
"test_preview": "Test anteprima",
|
||||
"route_to": "Instrada a",
|
||||
"test_preview_description": "Esegui un test del modulo di instradamento senza inviare alcun dato",
|
||||
"test_routing": "Test instradamento"
|
||||
"test_routing": "Test instradamento",
|
||||
"payment_app_disabled": "Un amministratore ha disabilitato un'app di pagamento",
|
||||
"edit_event_type": "Modifica tipo di evento",
|
||||
"collective_scheduling": "Pianificazione collettiva",
|
||||
"make_it_easy_to_book": "Facilita la prenotazione del tuo team quando tutti sono disponibili.",
|
||||
"find_the_best_person": "Trova la persona più adatta disponibile e passa tra i membri del team.",
|
||||
"fixed_round_robin": "Round robin fisso",
|
||||
"add_one_fixed_attendee": "Aggiungi un partecipante fisso e fai intervenire a turno altri partecipanti.",
|
||||
"calcom_is_better_with_team": "Cal.com funziona meglio in team",
|
||||
"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",
|
||||
"admin_has_disabled": "Un amministratore ha disabilitato {{appName}}",
|
||||
"disabled_app_affects_event_type": "Un amministratore ha disabilitato {{appName}}, il che influenza il tuo tipo di evento {{eventType}}",
|
||||
"disable_payment_app": "L'amministratore ha disabilitato {{appName}}, il che influenza il tuo tipo di evento {{title}}. I partecipanti sono ancora in grado di prenotare questo tipo di evento, ma non gli verrà richiesto di pagare. Per evitarlo, è possibile nascondere questo tipo di evento fino a che l'amministratore non riattivi il tuo metodo di pagamento.",
|
||||
"payment_disabled_still_able_to_book": "I partecipanti sono ancora in grado di prenotare questo tipo di evento, ma non gli verrà richiesto di pagare. Per evitarlo, è possibile nascondere questo tipo di evento fino a che l'amministratore non riattivi il tuo metodo di pagamento.",
|
||||
"app_disabled_with_event_type": "L'amministratore ha disabilitato {{appName}}, il che influenza il tuo tipo di evento {{title}}.",
|
||||
"app_disabled_video": "L'amministratore ha disabilitato {{appName}}, il che potrebbe influenzare i tuoi tipi di eventi. Se hai dei tipi di eventi che utilizzano {{appName}} come luogo, allora verrà usato Cal Video come luogo predefinito.",
|
||||
"app_disabled_subject": "{{appName}} è stato disabilitato",
|
||||
"navigate_installed_apps": "Vai alle app installate",
|
||||
"disabled_calendar": "Se si dispone di un altro calendario installato, le nuove prenotazioni saranno aggiunte a quel calendario. Se così non fosse, connettere un nuovo calendario in modo da non perdere nessuna nuova prenotazione.",
|
||||
"enable_apps": "Abilita app",
|
||||
"enable_apps_description": "Abilita le app che gli utenti possono integrare con Cal.com",
|
||||
"app_is_enabled": "{{appName}} è abilitato",
|
||||
"app_is_disabled": "{{appName}} è disabilitato",
|
||||
"keys_have_been_saved": "Le chiavi sono state salvate",
|
||||
"disable_app": "Disabilita app",
|
||||
"disable_app_description": "La disattivazione di questa app potrebbe causare problemi con il modo in cui i tuoi utenti interagiscono con Cal",
|
||||
"edit_keys": "Modifica chiavi",
|
||||
"admin_apps_description": "Abilita le app per la tua istanza di Cal",
|
||||
"no_available_apps": "Nessuna app disponibile",
|
||||
"no_available_apps_description": "Assicurarsi che ci siano delle applicazioni nella propria distribuzione in 'packages/app-store'",
|
||||
"no_apps": "Non ci sono applicazioni abilitate in questa istanza di Cal",
|
||||
"apps_settings": "Impostazioni delle app",
|
||||
"fill_this_field": "Compilare il campo",
|
||||
"options": "Opzioni",
|
||||
"enter_option": "Immetti opzione {{index}}",
|
||||
"add_an_option": "Aggiungi un'opzione",
|
||||
"radio": "Radio",
|
||||
"event_type_duplicate_copy_text": "{{slug}}-copia",
|
||||
"set_as_default": "Imposta come predefinito",
|
||||
"hide_eventtype_details": "Nascondi dettagli tipo di evento"
|
||||
}
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "請求ポータルに移動",
|
||||
"need_anything_else": "他に必要なものはありませんか?",
|
||||
"further_billing_help": "請求に関するサポートが必要な場合は、サポートチームがお手伝いします。",
|
||||
"contact_our_support_team": "サポートチームに問い合わせる",
|
||||
"uh_oh": "おっと!",
|
||||
"no_event_types_have_been_setup": "このユーザーはまだイベントタイプを設定していません。",
|
||||
"edit_logo": "ロゴを編集",
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "이벤트가 아직 승인을 기다리고 있습니다.",
|
||||
"event_is_still_waiting": "이벤트 요청이 아직 대기중입니다: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "더 이상 결과 없음",
|
||||
"no_results": "결과 없음",
|
||||
"load_more_results": "더 많은 결과 보기",
|
||||
"integration_meeting_id": "{{integrationName}} 회의 ID: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "확인됨: {{date}}, {{name}} 의 {{eventType}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "캘린더에 추가하기",
|
||||
"add_another_calendar": "다른 캘린더 추가",
|
||||
"other": "더 보기",
|
||||
"email_sign_in_subject": "{{appName}}의 로그인 링크",
|
||||
"emailed_you_and_attendees": "당신과 다른 참여자들에게 상세 사항이 담긴 캘린더 초대 이메일을 보냈습니다.",
|
||||
"emailed_you_and_attendees_recurring": "귀하와 다른 참석자들에게 이 되풀이 이벤트의 첫 이벤트에 대한 예약 초대장을 이메일로 발송했습니다.",
|
||||
"emailed_you_and_any_other_attendees": "당신과 다른 참여자들이 이 정보가 담긴 이메일을 주고 받았습니다.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "결제 포털로 이동",
|
||||
"need_anything_else": "다른 것이 필요하십니까?",
|
||||
"further_billing_help": "청구와 관련하여 추가 도움이 필요한 경우 지원 팀이 도와드리겠습니다.",
|
||||
"contact_our_support_team": "지원팀에 문의하기",
|
||||
"uh_oh": "오!",
|
||||
"no_event_types_have_been_setup": "사용자가 이벤트 타입을 설정하지 않았습니다.",
|
||||
"edit_logo": "로고 수정하기",
|
||||
@@ -420,6 +421,7 @@
|
||||
"current_incorrect_password": "현재 비밀번호가 잘못되었습니다.",
|
||||
"password_hint_caplow": "대문자와 소문자의 혼합",
|
||||
"password_hint_min": "최소 7자 길이",
|
||||
"password_hint_admin_min": "최소 15자 길이",
|
||||
"password_hint_num": "1개 이상 숫자 포함",
|
||||
"invalid_password_hint": "비밀번호는 7자 이상이어야 하고 숫자가 하나 이상 포함되어야 하며 대문자와 소문자가 혼합되어야 합니다",
|
||||
"incorrect_password": "비밀번호가 잘못되었습니다",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "{{profileName}}로 {{eventTypeTitle}} 확인",
|
||||
"booking_reschedule_confirmation": "{{profileName}}을 사용하여 {{eventTypeTitle}} 일정을 변경하세요.",
|
||||
"in_person_meeting": "온라인 또는 오프라인 회의",
|
||||
"attendeeInPerson": "직접 방문(참석자 주소)",
|
||||
"inPerson": "방문(주최자 주소)",
|
||||
"link_meeting": "회의 링크",
|
||||
"phone_call": "참석자 전화 번호",
|
||||
"your_number": "본인 전화 번호",
|
||||
"phone_number": "전화 번호",
|
||||
"attendee_phone_number": "참석자 전화 번호",
|
||||
"organizer_phone_number": "주최자 전화번호",
|
||||
"host_phone_number": "본인 전화 번호",
|
||||
"enter_phone_number": "전화 번호 입력",
|
||||
"reschedule": "일정 변경",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "집단",
|
||||
"collective_description": "선택한 모든 팀원이 참석할 수 있을 때 회의를 예약합니다.",
|
||||
"duration": "기간",
|
||||
"available_durations": "사용 가능한 기간",
|
||||
"default_duration": "기본 기간",
|
||||
"default_duration_no_options": "사용 가능한 기간을 먼저 선택하세요",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "분",
|
||||
"round_robin": "라운드 로빈",
|
||||
"round_robin_description": "여러 팀 구성원 간의 주기적인 회의",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "팀",
|
||||
"team": "팀",
|
||||
"team_billing": "팀 비용 청구",
|
||||
"team_billing_description": "팀의 청구 관리",
|
||||
"upgrade_to_flexible_pro_title": "팀에 대한 청구를 변경했습니다",
|
||||
"upgrade_to_flexible_pro_message": "팀에 시트가 없는 구성원이 있습니다. 누락된 시트를 보완하려면 Pro 플랜을 업그레이드하세요.",
|
||||
"changed_team_billing_info": "2022년 1월부터 팀원에 대해 시트별로 요금을 부과합니다. 무료로 Pro를 사용하던 팀원은 이제 14일 평가판을 사용할 수 있습니다. 평가판 기한이 만료되고 업그레이드하지 않으면 이 팀원은 팀에서 숨겨집니다.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "이벤트 타입 숨기기",
|
||||
"edit_location": "위치 수정",
|
||||
"into_the_future": "미래로",
|
||||
"when_booked_with_less_than_notice": "<time></time>회 미만 통지로 예약한 경우",
|
||||
"within_date_range": "기간 내",
|
||||
"indefinitely_into_future": "무한히 미래로",
|
||||
"add_new_custom_input_field": "새 사용자 정의 입력 필드 추가",
|
||||
@@ -713,6 +724,8 @@
|
||||
"delete_account_confirmation_message": "{{appName}} 계정을 삭제하시겠습니까? 계정 링크를 공유한 사람은 더 이상 이 링크를 사용하여 예약할 수 없으며 저장한 모든 기본 설정이 손실됩니다.",
|
||||
"integrations": "통합",
|
||||
"apps": "앱",
|
||||
"apps_description": "Cal 인스턴스용 앱 활성화",
|
||||
"apps_listing": "앱 목록화",
|
||||
"category_apps": "{{category}} 앱",
|
||||
"app_store": "앱 스토어",
|
||||
"app_store_description": "사람, 기술, 직장을 연결합니다.",
|
||||
@@ -736,6 +749,7 @@
|
||||
"toggle_calendars_conflict": "중복 예약을 방지하기 위해 충돌을 확인하려는 캘린더를 전환합니다.",
|
||||
"select_destination_calendar": "이벤트 작성일",
|
||||
"connect_additional_calendar": "추가 캘린더 연결",
|
||||
"calendar_updated_successfully": "캘린더가 업데이트되었습니다",
|
||||
"conferencing": "회의",
|
||||
"calendar": "달력",
|
||||
"payments": "결제",
|
||||
@@ -768,6 +782,7 @@
|
||||
"trending_apps": "트랜드 앱",
|
||||
"explore_apps": "{{category}} 앱",
|
||||
"installed_apps": "설치된 앱",
|
||||
"free_to_use_apps": "무료",
|
||||
"no_category_apps": "{{category}} 앱 없음",
|
||||
"no_category_apps_description_calendar": "중복 예약을 방지하기 위해 충돌을 확인하려는 캘린더 앱을 추가합니다",
|
||||
"no_category_apps_description_conferencing": "고객과 화상 통화를 통합하려면 회의 앱을 추가해 보세요",
|
||||
@@ -806,6 +821,8 @@
|
||||
"verify_wallet": "지갑 인증",
|
||||
"connect_metamask": "메타마스크 연결",
|
||||
"create_events_on": "이벤트 생성일:",
|
||||
"enterprise_license": "엔터프라이즈 기능입니다",
|
||||
"enterprise_license_description": "이 기능을 활성화하려면 {{consoleUrl}} 콘솔에서 배포 키를 가져와 .env에 CALCOM_LICENSE_KEY로 추가하세요. 팀에 이미 라이선스가 있는 경우 {{supportMail}}에 문의하여 도움을 받으세요.",
|
||||
"missing_license": "라이선스 없음",
|
||||
"signup_requires": "상용 라이선스 필요",
|
||||
"signup_requires_description": "지금은 {{companyName}}에서 가입 페이지의 무료 오픈 소스 버전을 제공하지 않습니다. 가입 구성 요소에 대한 정식 액세스 권한을 받으려면 상용 라이선스를 취득해야 합니다. 개인 용도의 경우 Prisma Data Platform 또는 기타 Postgres 인터페이스를 사용하여 계정을 생성하는 것이 좋습니다.",
|
||||
@@ -897,6 +914,7 @@
|
||||
"user_impersonation_heading": "사용자 가장",
|
||||
"user_impersonation_description": "신고하신 문제를 신속하게 해결할 수 있도록 지원 팀이 귀하의 계정에 일시적으로 로그인할 수 있게 허용합니다.",
|
||||
"team_impersonation_description": "팀 구성원이 일시적으로 귀하의 자격으로 로그인할 수 있게 합니다.",
|
||||
"allow_booker_to_select_duration": "예약자가 기간을 선택하도록 허용",
|
||||
"impersonate_user_tip": "이 기능의 사용은 모두 감사됩니다.",
|
||||
"impersonating_user_warning": "\"{{user}}\"의 사용자 이름을 가장하는 중입니다.",
|
||||
"impersonating_stop_instructions": "<0>중지하려면 여기를 클릭하십시오</0>.",
|
||||
@@ -1014,6 +1032,9 @@
|
||||
"error_removing_app": "앱 제거 중 오류 발생",
|
||||
"web_conference": "웹 화상 회의",
|
||||
"requires_confirmation": "확인 필수",
|
||||
"always_requires_confirmation": "항상",
|
||||
"requires_confirmation_threshold": "< {{time}} $t({{unit}}_timeUnit) 알림으로 예약한 경우 확인이 필요합니다",
|
||||
"may_require_confirmation": "확인이 필요할 수 있음",
|
||||
"nr_event_type_one": "{{count}} 이벤트 타입",
|
||||
"nr_event_type_other": "{{count}} 이벤트 타입",
|
||||
"add_action": "작업 추가",
|
||||
@@ -1101,6 +1122,9 @@
|
||||
"event_limit_tab_description": "예약 가능 횟수",
|
||||
"event_advanced_tab_description": "캘린더 설정 및 기타...",
|
||||
"event_advanced_tab_title": "고급",
|
||||
"event_setup_multiple_duration_error": "이벤트 설정: 복수 기간에는 최소 1개의 옵션이 필요합니다.",
|
||||
"event_setup_multiple_duration_default_error": "이벤트 설정: 유효한 기본 기간을 선택하십시오.",
|
||||
"event_setup_booking_limits_error": "예약 한도는 오름차순이어야 합니다. [일,주,월,년]",
|
||||
"select_which_cal": "예약을 추가할 캘린더 선택",
|
||||
"custom_event_name": "사용자 정의 이벤트 이름",
|
||||
"custom_event_name_description": "캘린더 이벤트에 표시할 사용자 정의 이벤트 이름 만들기",
|
||||
@@ -1154,8 +1178,11 @@
|
||||
"invoices": "청구서",
|
||||
"embeds": "내장",
|
||||
"impersonation": "가장",
|
||||
"impersonation_description": "사용자 가장을 관리하기 위한 설정",
|
||||
"users": "사용자",
|
||||
"profile_description": "사용자 {{appName}} 프로필 설정 관리",
|
||||
"users_description": "여기에서 모든 사용자 목록을 찾을 수 있습니다",
|
||||
"users_listing": "사용자 목록화",
|
||||
"general_description": "언어 및 시간대 설정 관리",
|
||||
"calendars_description": "이벤트 타입이 캘린더와 상호 작용하는 방식 구성",
|
||||
"appearance_description": "예약 모양 설정 관리",
|
||||
@@ -1360,6 +1387,7 @@
|
||||
"number_sms_notifications": "전화번호 (SMS notifications)",
|
||||
"attendee_email_workflow": "참석자 이메일",
|
||||
"attendee_email_info": "예약자 이메일",
|
||||
"kbar_search_placeholder": "명령어를 입력하거나 검색하세요...",
|
||||
"invalid_credential": "죄송합니다! 권한이 만료되었거나 취소된 것 같습니다. 다시 설치하십시오.",
|
||||
"choose_common_schedule_team_event": "공통 일정 선택",
|
||||
"choose_common_schedule_team_event_description": "호스트 간에 공통 일정을 사용하려면 이 옵션을 활성화하세요. 비활성화되면 각 호스트는 기본 일정에 따라 예약됩니다.",
|
||||
@@ -1370,5 +1398,44 @@
|
||||
"test_preview": "미리보기 테스트",
|
||||
"route_to": "목표 경로",
|
||||
"test_preview_description": "데이터를 제출하지 않고 라우팅 양식 테스트",
|
||||
"test_routing": "라우팅 테스트"
|
||||
"test_routing": "라우팅 테스트",
|
||||
"payment_app_disabled": "관리자가 결제 앱을 비활성화했습니다",
|
||||
"edit_event_type": "이벤트 타입 편집",
|
||||
"collective_scheduling": "집단 일정 관리",
|
||||
"make_it_easy_to_book": "모든 사람이 참석할 수 있을 때 팀을 쉽게 예약할 수 있게 합니다.",
|
||||
"find_the_best_person": "가능한 최상의 인원을 찾고 팀원을 순환 배정하십시오.",
|
||||
"fixed_round_robin": "고정 라운드 로빈",
|
||||
"add_one_fixed_attendee": "한 명의 고정 참석자를 추가하고 여러 참석자를 통해 라운드 로빈을 추가합니다.",
|
||||
"calcom_is_better_with_team": "Cal.com은 팀과 함께라면 더욱 좋습니다",
|
||||
"add_your_team_members": "이벤트 타입에 팀원을 추가하세요. 집단 일정 관리를 사용해 모든 사람을 포함하거나 라운드 로빈 일정 관리로 가장 적합한 인원을 찾으십시오.",
|
||||
"booking_limit_reached": "이 이벤트 타입에 대한 예약 한도에 도달했습니다",
|
||||
"admin_has_disabled": "관리자가 {{appName}} 앱을 비활성화했습니다",
|
||||
"disabled_app_affects_event_type": "관리자가 이벤트 타입 {{eventType}}에 영향을 미치는 {{appName}} 앱을 비활성화했습니다",
|
||||
"disable_payment_app": "관리자가 이벤트 타입 {{title}}에 영향을 미치는 {{appName}} 앱을 비활성화했습니다. 참석자는 여전히 이러한 타입의 이벤트를 예약할 수 있지만 결제하라는 메시지는 표시되지 않습니다. 관리자가 결제 수단을 다시 활성화할 때까지 이를 방지하기 위해 이벤트 타입을 숨길 수 있습니다.",
|
||||
"payment_disabled_still_able_to_book": "참석자는 여전히 이러한 타입의 이벤트를 예약할 수 있지만 결제하라는 메시지는 표시되지 않습니다. 관리자가 결제 수단을 다시 활성화할 때까지 이를 방지하기 위해 이벤트 타입을 숨길 수 있습니다.",
|
||||
"app_disabled_with_event_type": "관리자가 이벤트 타입 {{title}}에 영향을 미치는 {{appName}} 앱을 비활성화했습니다.",
|
||||
"app_disabled_video": "관리자가 이벤트 타입에 영향을 미칠 수 있는 {{appName}} 앱을 비활성화했습니다. 위치가 {{appName}} 앱에 대한 이벤트 타입이 있는 경우 기본적으로 Cal Video로 설정됩니다.",
|
||||
"app_disabled_subject": "{{appName}} 앱이 비활성화되었습니다",
|
||||
"navigate_installed_apps": "설치된 앱으로 이동",
|
||||
"disabled_calendar": "다른 캘린더를 설치한 경우 새 예약이 추가됩니다. 그렇지 않은 경우 새로운 예약을 놓치지 않도록 새 캘린더를 연결하십시오.",
|
||||
"enable_apps": "앱 활성화",
|
||||
"enable_apps_description": "사용자가 Cal.com과 통합할 수 있는 앱 활성화",
|
||||
"app_is_enabled": "{{appName}} 앱이 활성화되었습니다",
|
||||
"app_is_disabled": "{{appName}} 앱이 비활성화되었습니다",
|
||||
"keys_have_been_saved": "키가 저장되었습니다",
|
||||
"disable_app": "앱 비활성화",
|
||||
"disable_app_description": "이 앱을 비활성화하면 사용자가 Cal과 상호 작용하는 방식에 문제가 발생할 수 있습니다",
|
||||
"edit_keys": "키 편집",
|
||||
"admin_apps_description": "Cal 인스턴스용 앱 활성화",
|
||||
"no_available_apps": "사용 가능한 앱이 없습니다",
|
||||
"no_available_apps_description": "'packages/app-store' 아래 배포에 앱이 있는지 확인하세요",
|
||||
"no_apps": "Cal의 이 인스턴스에서 활성화된 앱이 없습니다",
|
||||
"apps_settings": "앱 설정",
|
||||
"fill_this_field": "이 필드에 입력하세요",
|
||||
"options": "선택사항",
|
||||
"enter_option": "선택사항 {{index}} 입력",
|
||||
"add_an_option": "선택사항 추가",
|
||||
"radio": "라디오",
|
||||
"event_type_duplicate_copy_text": "{{slug}}-카피",
|
||||
"set_as_default": "기본값으로 설정"
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
"event_request_cancelled": "Uw geplande gebeurtenis is geannuleerd",
|
||||
"organizer": "Organisator",
|
||||
"need_to_reschedule_or_cancel": "Moet u verplaatsen of annuleren?",
|
||||
"cancellation_reason": "Reden voor annulering",
|
||||
"cancellation_reason_placeholder": "Waarom annuleert u? (optioneel)",
|
||||
"cancellation_reason": "Reden voor annulering (optioneel)",
|
||||
"cancellation_reason_placeholder": "Waarom annuleert u?",
|
||||
"rejection_reason": "Reden voor weigering",
|
||||
"rejection_reason_title": "Boekingsverzoek weigeren?",
|
||||
"rejection_reason_description": "Weet u zeker dat u de boeking wilt weigeren? We informeren de persoon die probeerde te boeken. U kunt hieronder een reden opgeven.",
|
||||
@@ -108,7 +108,7 @@
|
||||
"link_expires": "p.s. De uitnodiging verloopt over {{expiresIn}} uur.",
|
||||
"upgrade_to_per_seat": "Upgraden naar per plaats",
|
||||
"team_upgrade_seats_details": "Van de {{memberCount}} leden in uw team zijn {{unpaidCount}} plaats(en) onbetaald. Voor $ {{seatPrice}}/maand per plaats bedragen de geschatte totale kosten van uw abonnement $ {{totalCost}}/maand.",
|
||||
"team_upgrade_banner_description": "Bedankt voor het testen van ons nieuwe teamabonnement. We hebben gemerkt dat uw team \"{{teamName}}\" moet worden geüpgraded.",
|
||||
"team_upgrade_banner_description": "Bedankt voor het testen van ons nieuwe teamabonnement. We hebben geconstateerd dat uw team \"{{teamName}}\" moet worden geüpgraded.",
|
||||
"team_upgrade_banner_action": "Hier upgraden",
|
||||
"team_upgraded_successfully": "Uw team is geüpgraded!",
|
||||
"use_link_to_reset_password": "Gebruik de onderstaande link om uw wachtwoord te resetten",
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "Ga naar het facturatiepaneel",
|
||||
"need_anything_else": "Nog iets nodig?",
|
||||
"further_billing_help": "Als u verdere hulp nodig heeft bij facturering, is ons ondersteuningsteam er om u te helpen.",
|
||||
"contact_our_support_team": "Neem contact op met onze klantenservice",
|
||||
"uh_oh": "Oeps!",
|
||||
"no_event_types_have_been_setup": "Deze gebruiker heeft nog geen evenementen.",
|
||||
"edit_logo": "Bewerk logo",
|
||||
@@ -419,7 +418,7 @@
|
||||
"forgotten_secret_description": "Als u dit geheim vergeten of verloren bent, kunt u het wijzigen. Maar wees u ervan bewust dat alle integraties die dit geheim gebruiken bijgewerkt moeten worden",
|
||||
"current_incorrect_password": "Uw wachtwoord is verkeerd",
|
||||
"password_hint_caplow": "Mix van hoofd- en kleine letters",
|
||||
"password_hint_min": "Minimaal 7 tekens lang",
|
||||
"password_hint_min": "Minimaal 8 tekens lang",
|
||||
"password_hint_num": "Minimaal 1 cijfer bevatten",
|
||||
"invalid_password_hint": "Het wachtwoord moet minimaal 7 tekens lang zijn, minimaal 1 cijfer bevatten en bestaan uit een mix van hoofd- en kleine letters",
|
||||
"incorrect_password": "Uw wachtwoord is incorrect.",
|
||||
@@ -784,7 +783,7 @@
|
||||
"analytics": "Analyse",
|
||||
"empty_installed_apps_headline": "Geen apps geïnstalleerd",
|
||||
"empty_installed_apps_description": "Met apps kunt u uw workflow en uw planning aanzienlijk verbeteren.",
|
||||
"empty_installed_apps_button": "Ontdek de App Store",
|
||||
"empty_installed_apps_button": "Bladeren in App Store",
|
||||
"manage_your_connected_apps": "Beheer uw geïnstalleerde apps of wijzig instellingen",
|
||||
"browse_apps": "Door apps bladeren",
|
||||
"features": "Functies",
|
||||
|
||||
@@ -385,7 +385,6 @@
|
||||
"go_to_billing_portal": "Gå til betalingsportalen",
|
||||
"need_anything_else": "Trenger du noe annet?",
|
||||
"further_billing_help": "Hvis du trenger ytterligere hjelp med betaling, er supportteamet vårt her for å hjelpe.",
|
||||
"contact_our_support_team": "Kontakt supportteamet vårt",
|
||||
"uh_oh": "Uh oh!",
|
||||
"no_event_types_have_been_setup": "Denne brukeren har ikke konfigurert noen hendelsestyper ennå.",
|
||||
"edit_logo": "Rediger logo",
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "Przejdź do portalu rozliczeniowego",
|
||||
"need_anything_else": "Potrzebujesz czegoś innego?",
|
||||
"further_billing_help": "Jeśli potrzebujesz dalszej pomocy przy rozliczaniu, nasz zespół wsparcia jest tutaj, aby pomóc.",
|
||||
"contact_our_support_team": "Skontaktuj się z naszym zespołem wsparcia",
|
||||
"uh_oh": "Uh oh!",
|
||||
"no_event_types_have_been_setup": "Ten użytkownik nie ustawił jeszcze żadnych typów wydarzeń.",
|
||||
"edit_logo": "Edytuj logo",
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "Ir para o portal de pagamento",
|
||||
"need_anything_else": "Precisa de algo mais?",
|
||||
"further_billing_help": "Se precisar de mais ajuda com o faturamento, o nosso time de suporte está aqui para ajudar.",
|
||||
"contact_our_support_team": "Fale com a nossa equipe de suporte",
|
||||
"uh_oh": "Oh oh!",
|
||||
"no_event_types_have_been_setup": "Este usuário ainda não definiu nenhum tipo de evento.",
|
||||
"edit_logo": "Editar logotipo",
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "Um evento ainda aguarda aprovação",
|
||||
"event_is_still_waiting": "Pedido de evento pendente: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "Não existem mais resultados",
|
||||
"no_results": "Sem resultados",
|
||||
"load_more_results": "Carregar mais resultados",
|
||||
"integration_meeting_id": "ID da reunião de {{integrationName}}: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Confirmado: {{eventType}} com {{name}} em {{date}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "Adicionar ao calendário",
|
||||
"add_another_calendar": "Adicionar outro calendário",
|
||||
"other": "Outras",
|
||||
"email_sign_in_subject": "A sua ligação de início de sessão para {{appName}}",
|
||||
"emailed_you_and_attendees": "Enviámos um email para si e para os outros participantes com um convite de calendário com todos os detalhes.",
|
||||
"emailed_you_and_attendees_recurring": "Enviámos um email para si e para os outros participantes com um convite de calendário para o primeiro destes eventos recorrentes.",
|
||||
"emailed_you_and_any_other_attendees": "Esta informação foi enviada para si e para todos os outros participantes.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "Ir para o portal de pagamento",
|
||||
"need_anything_else": "Precisa de algo mais?",
|
||||
"further_billing_help": "Se precisar de mais ajuda com a faturação, a nossa equipa de suporte está aqui para ajudar.",
|
||||
"contact_our_support_team": "Contacte a nossa equipa de suporte",
|
||||
"uh_oh": "Uh oh!",
|
||||
"no_event_types_have_been_setup": "Este utilizador ainda não configurou nenhum tipo de evento.",
|
||||
"edit_logo": "Editar logótipo",
|
||||
@@ -420,6 +421,7 @@
|
||||
"current_incorrect_password": "A senha atual está incorreta",
|
||||
"password_hint_caplow": "Mistura de letras maiúsculas e minúsculas",
|
||||
"password_hint_min": "Tamanho mínimo de 7 caracteres",
|
||||
"password_hint_admin_min": "Tamanho mínimo de 15 caracteres",
|
||||
"password_hint_num": "Contém pelo menos 1 número",
|
||||
"invalid_password_hint": "A palavra-passe deve ter no mínimo 7 caracteres, com pelo menos um número e uma mistura de letras maiúsculas e minúsculas",
|
||||
"incorrect_password": "Palavra-Passe incorreta",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "Confirme o seu {{eventTypeTitle}} com {{profileName}}",
|
||||
"booking_reschedule_confirmation": "Reagende o seu {{eventTypeTitle}} com {{profileName}}",
|
||||
"in_person_meeting": "Ligação ou reunião presencial",
|
||||
"attendeeInPerson": "Pessoalmente (endereço do participante)",
|
||||
"inPerson": "Pessoalmente (endereço do organizador)",
|
||||
"link_meeting": "Ligar reunião",
|
||||
"phone_call": "Número de telefone do participante",
|
||||
"your_number": "O seu número de telefone",
|
||||
"phone_number": "Número de Telefone",
|
||||
"attendee_phone_number": "Número de telefone do participante",
|
||||
"organizer_phone_number": "Número de telefone do organizador",
|
||||
"host_phone_number": "O seu número de telefone",
|
||||
"enter_phone_number": "Inserir Número do Telefone",
|
||||
"reschedule": "Reagendar",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "Coletivo",
|
||||
"collective_description": "Agende reuniões quando todos os membros selecionados da equipa estiverem disponíveis.",
|
||||
"duration": "Duração",
|
||||
"available_durations": "Durações disponíveis",
|
||||
"default_duration": "Duração predefinida",
|
||||
"default_duration_no_options": "Por favor, selecione primeiro as durações disponíveis",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "Minutos",
|
||||
"round_robin": "Round Robin",
|
||||
"round_robin_description": "Reuniões de ciclo entre vários membros da equipa.",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "Equipas",
|
||||
"team": "Equipa",
|
||||
"team_billing": "Facturação da equipa",
|
||||
"team_billing_description": "Gerir a faturação para a sua equipa",
|
||||
"upgrade_to_flexible_pro_title": "Alterámos os termos de facturação",
|
||||
"upgrade_to_flexible_pro_message": "Há membros sem lugar na sua equipa. Actualize para o plano Pro para cobrir os lugares em falta.",
|
||||
"changed_team_billing_info": "Desde Janeiro de 2022 a cobrança é efectuada por cada lugar de membro da equipa. Os membros da sua equipa que tivessem a versão Pro gratuitamente, estão agora num período experimental de 14 dias. Assim que este período expirar, estes membros ficarão ocultos da sua equipa, a menos que actualize agora.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "Ocultar Tipo de Evento",
|
||||
"edit_location": "Editar Localização",
|
||||
"into_the_future": "no futuro",
|
||||
"when_booked_with_less_than_notice": "Quando reservado com aviso prévio inferior a <time></time>",
|
||||
"within_date_range": "Dentro de um período",
|
||||
"indefinitely_into_future": "Indefinidamente para o futuro",
|
||||
"add_new_custom_input_field": "Adicionar novo campo personalizado",
|
||||
@@ -713,6 +724,8 @@
|
||||
"delete_account_confirmation_message": "De certeza que quer eliminar a sua conta {{appName}}? Qualquer pessoa com quem tenha partilhado esta ligação de equipa deixará de poder fazer reservas através da respetiva ligação, e quaisquer preferências que tenha guardado serão perdidas.",
|
||||
"integrations": "Integrações",
|
||||
"apps": "Aplicações",
|
||||
"apps_description": "Ativar aplicações para a sua instância do Cal",
|
||||
"apps_listing": "Lista de aplicações",
|
||||
"category_apps": "Aplicações de {{category}}",
|
||||
"app_store": "App Store",
|
||||
"app_store_description": "Ligar pessoas, tecnologia e o local de trabalho.",
|
||||
@@ -736,6 +749,7 @@
|
||||
"toggle_calendars_conflict": "Escolha os calendários que deseja verificar para evitar conflitos e duplicação de reservas.",
|
||||
"select_destination_calendar": "Criar eventos em",
|
||||
"connect_additional_calendar": "Ligar um calendário adicional",
|
||||
"calendar_updated_successfully": "Calendário atualizado com sucesso",
|
||||
"conferencing": "Conferência",
|
||||
"calendar": "Calendário",
|
||||
"payments": "Pagamentos",
|
||||
@@ -768,6 +782,7 @@
|
||||
"trending_apps": "Aplicações em destaque",
|
||||
"explore_apps": "Aplicações de {{category}}",
|
||||
"installed_apps": "Aplicações instaladas",
|
||||
"free_to_use_apps": "Grátis",
|
||||
"no_category_apps": "Sem aplicações de {{category}}",
|
||||
"no_category_apps_description_calendar": "Adicione uma aplicação de calendário para verificar se existem conflitos e assim evitar sobreposição de marcações",
|
||||
"no_category_apps_description_conferencing": "Experimente adicionar uma aplicação de conferência para integrar chamadas de vídeo com os seus clientes",
|
||||
@@ -806,6 +821,8 @@
|
||||
"verify_wallet": "Verificar carteira",
|
||||
"connect_metamask": "Ligar Metamask",
|
||||
"create_events_on": "Criar eventos em:",
|
||||
"enterprise_license": "Esta é uma funcionalidade empresarial",
|
||||
"enterprise_license_description": "Para ativar esta funcionalidade, obtenha uma chave de instalação na consola {{consoleUrl}} e adicione-a ao seu .env como CALCOM_LICENSE_KEY. Se a sua equipa já tem uma licença, entre em contacto com {{supportMail}} para obter ajuda.",
|
||||
"missing_license": "Licença em falta",
|
||||
"signup_requires": "Necessita de licença comercial",
|
||||
"signup_requires_description": "De momento a {{companyName}} não oferece uma versão gratuita de código aberto da página de registo. Para aceder completamente aos componentes de registo tem de adquirir uma licença comercial. Para uso pessoal, recomendamos a Prisma Data Platform ou qualquer outra interface Postgres para criar contas.",
|
||||
@@ -897,6 +914,7 @@
|
||||
"user_impersonation_heading": "Representação de utilizador",
|
||||
"user_impersonation_description": "Permite à nossa equipa de suporte iniciar sessão temporariamente em seu nome para rapidamente resolver quaisquer erros que nos reporte.",
|
||||
"team_impersonation_description": "Permite que os administradores da sua equipa iniciem a sessão temporariamente em seu nome.",
|
||||
"allow_booker_to_select_duration": "Permitir que o responsável pela reserva selecione a duração",
|
||||
"impersonate_user_tip": "Todas as utilizações desta funcionalidade são auditadas.",
|
||||
"impersonating_user_warning": "Representar o nome de utilizador \"{{user}}\".",
|
||||
"impersonating_stop_instructions": "<0>Clique aqui para parar</0>.",
|
||||
@@ -1014,6 +1032,9 @@
|
||||
"error_removing_app": "Erro ao remover a aplicação",
|
||||
"web_conference": "Conferência web",
|
||||
"requires_confirmation": "Requer confirmação",
|
||||
"always_requires_confirmation": "Sempre",
|
||||
"requires_confirmation_threshold": "Requer confirmação se reservado com um aviso prévio inferior a {{time}} $t({{unit}}_timeUnit)",
|
||||
"may_require_confirmation": "Pode necessitar de confirmação",
|
||||
"nr_event_type_one": "{{count}} tipo de evento",
|
||||
"nr_event_type_other": "{{count}} tipos de evento",
|
||||
"add_action": "Adicionar acção",
|
||||
@@ -1101,6 +1122,9 @@
|
||||
"event_limit_tab_description": "Com que frequência pode ser reservado",
|
||||
"event_advanced_tab_description": "Definições do calendário e muito mais...",
|
||||
"event_advanced_tab_title": "Avançado",
|
||||
"event_setup_multiple_duration_error": "Configuração do evento: durações múltiplas requerem pelo menos 1 opção.",
|
||||
"event_setup_multiple_duration_default_error": "Configuração do evento: por favor, selecione uma duração predefinida válida.",
|
||||
"event_setup_booking_limits_error": "Os limites de reserva devem estar ordenados de forma ascendente. [dia,semana,mês,ano]",
|
||||
"select_which_cal": "Selecione para que calendário devem ser adicionadas as marcações",
|
||||
"custom_event_name": "Nome de evento personalizado",
|
||||
"custom_event_name_description": "Crie nomes de eventos personalizados a mostrar no calendário de eventos",
|
||||
@@ -1154,8 +1178,11 @@
|
||||
"invoices": "Faturas",
|
||||
"embeds": "Incorporações",
|
||||
"impersonation": "Representação",
|
||||
"impersonation_description": "Definições para gerir a personificação de utilizadores",
|
||||
"users": "Utilizadores",
|
||||
"profile_description": "Gerir as definições para o seu perfil {{appName}}",
|
||||
"users_description": "Aqui pode encontrar uma lista de todos os utilizadores",
|
||||
"users_listing": "Lista de utilizadores",
|
||||
"general_description": "Faça a gestão das definições do seu idioma e fuso horário",
|
||||
"calendars_description": "Configure como os tipos de evento devem interagir com os seus calendários",
|
||||
"appearance_description": "Faça a gestão das definições de aparência da sua reserva",
|
||||
@@ -1360,6 +1387,7 @@
|
||||
"number_sms_notifications": "Número de telefone (notificações SMS)",
|
||||
"attendee_email_workflow": "E-mail do participante",
|
||||
"attendee_email_info": "O e-mail do responsável pela reserva",
|
||||
"kbar_search_placeholder": "Digite um comando ou pesquise...",
|
||||
"invalid_credential": "Oh não! Parece que a permissão expirou ou foi revogada. Por favor, reinstale novamente.",
|
||||
"choose_common_schedule_team_event": "Escolha uma agenda comum",
|
||||
"choose_common_schedule_team_event_description": "Ative esta opção se quiser utilizar uma agenda comum entre anfitriões. Quando desativada, cada anfitrião será reservado com base na respetiva agenda pré-definida.",
|
||||
@@ -1370,5 +1398,44 @@
|
||||
"test_preview": "Pré-visualização do teste",
|
||||
"route_to": "Encaminhar para",
|
||||
"test_preview_description": "Teste o encaminhamento do seu formulário sem submeter qualquer dado",
|
||||
"test_routing": "Testar encaminhamento"
|
||||
"test_routing": "Testar encaminhamento",
|
||||
"payment_app_disabled": "Um administrador desativou uma aplicação de pagamentos",
|
||||
"edit_event_type": "Editar o tipo de evento",
|
||||
"collective_scheduling": "Agendamento coletivo",
|
||||
"make_it_easy_to_book": "Faça com que seja simples reservar a sua equipa quando todos estiverem disponíveis.",
|
||||
"find_the_best_person": "Encontre a melhor pessoa disponível e navegue na sua equipa.",
|
||||
"fixed_round_robin": "Distribuição equilibrada fixa",
|
||||
"add_one_fixed_attendee": "Adicione um participante fixo e distribua de forma equilibrada a partir de um número de participantes.",
|
||||
"calcom_is_better_with_team": "O Cal.com é melhor com equipas",
|
||||
"add_your_team_members": "Adicione os membros da sua equipa aos seus tipos de eventos. Utilize o agendamento coletivo para incluir todos os membros ou encontre a pessoa mais adequada com o agendamento baseado numa distribuição equilibrada.",
|
||||
"booking_limit_reached": "O limite de reservas para este tipo de evento foi atingido",
|
||||
"admin_has_disabled": "{{appName}} foi desativada por um administrador",
|
||||
"disabled_app_affects_event_type": "{{appName}} foi desativada por um administrador o que afeta o seu tipo de evento {{eventType}}",
|
||||
"disable_payment_app": "O administrador desativou {{appName}} o que afeta o seu tipo de evento {{title}}. Os participantes ainda poderão reservar este tipo de evento, mas não será solicitado que façam qualquer pagamento. Pode ocultar o tipo de evento para evitar esta situação, até que o seu administrador reative o seu método de pagamento.",
|
||||
"payment_disabled_still_able_to_book": "Os participantes ainda poderão reservar este tipo de evento, mas não será solicitado que façam qualquer pagamento. Pode ocultar o tipo de evento para evitar esta situação, até que o seu administrador reative o seu método de pagamento.",
|
||||
"app_disabled_with_event_type": "O administrador desativou {{appName}} o que afeta o seu tipo de evento {{title}}.",
|
||||
"app_disabled_video": "O administrador desativou {{appName}} o que afeta os seus tipos de eventos. Se tiver tipos de eventos com {{appName}} como o sítio, então o mesmo será predefinido para o Cal Video.",
|
||||
"app_disabled_subject": "{{appName}} foi desativada",
|
||||
"navigate_installed_apps": "Ir para as aplicações instaladas",
|
||||
"disabled_calendar": "Se tiver outro calendário instalado, os novos pedidos serão adicionados ao mesmo. Se não é este o caso, deve associar um novo calendário para garantir que não perde novas reservas.",
|
||||
"enable_apps": "Ativar aplicações",
|
||||
"enable_apps_description": "Ativar aplicações que os utilizadores podem integrar com o Cal.com",
|
||||
"app_is_enabled": "{{appName}} foi ativada",
|
||||
"app_is_disabled": "{{appName}} foi desativada",
|
||||
"keys_have_been_saved": "As chaves foram guardadas",
|
||||
"disable_app": "Desativar a aplicação",
|
||||
"disable_app_description": "A desativação desta aplicação pode causar problemas na forma como os seus utilizadores interagem com o Cal",
|
||||
"edit_keys": "Editar chaves",
|
||||
"admin_apps_description": "Ativar aplicações para a sua instância do Cal",
|
||||
"no_available_apps": "Não existem aplicações disponíveis",
|
||||
"no_available_apps_description": "Por favor, certifique-se que existem aplicações na sua instalação em 'packages/app-store'",
|
||||
"no_apps": "Não existem aplicações ativas nesta instância do Cal",
|
||||
"apps_settings": "Definições de aplicações",
|
||||
"fill_this_field": "Por favor, preencha este campo",
|
||||
"options": "Opções",
|
||||
"enter_option": "Insira a opção {{index}}",
|
||||
"add_an_option": "Adicione uma opção",
|
||||
"radio": "Radio",
|
||||
"event_type_duplicate_copy_text": "{{slug}}-copia",
|
||||
"set_as_default": "Predefinir"
|
||||
}
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "Accesați portalul de facturare",
|
||||
"need_anything_else": "Aveți nevoie de altceva?",
|
||||
"further_billing_help": "Dacă ai nevoie de ajutor suplimentar pentru facturare, echipa noastră de asistență este aici pentru a te ajuta.",
|
||||
"contact_our_support_team": "Contactează echipa noastră de suport",
|
||||
"uh_oh": "Uh oh!",
|
||||
"no_event_types_have_been_setup": "Acest utilizator nu a configurat încă niciun tip de eveniment.",
|
||||
"edit_logo": "Editare logo",
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "Перейти на платёжный портал",
|
||||
"need_anything_else": "Нужно что-нибудь еще?",
|
||||
"further_billing_help": "Если вам нужна дальнейшая помощь с оплатой счета, наша служба поддержки готова помочь.",
|
||||
"contact_our_support_team": "Свяжитесь с нашей службой поддержки",
|
||||
"uh_oh": "О нет!",
|
||||
"no_event_types_have_been_setup": "Этот пользователь еще не создал ни одного события.",
|
||||
"edit_logo": "Изменить логотип",
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
"event_request_cancelled": "Vaš zakazan dogadjaj je odbijen",
|
||||
"organizer": "Organizator",
|
||||
"need_to_reschedule_or_cancel": "Morate da odložite ili otkažete?",
|
||||
"cancellation_reason": "Razlog otkazivanja",
|
||||
"cancellation_reason_placeholder": "Zašto otkazujete? (opciono)",
|
||||
"cancellation_reason": "Razlog otkazivanja (opciono)",
|
||||
"cancellation_reason_placeholder": "Zašto otkazujete?",
|
||||
"rejection_reason": "Razlog odbijanja",
|
||||
"rejection_reason_title": "Odbij zahtev za rezervaciju?",
|
||||
"rejection_reason_description": "Da li ste sigurni da želite da odbijete rezervaciju? Obavestićemo osobu koja je pokušala da rezerviše. Možete navesti razlog ispod.",
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "Dogadjaj još čeka na odobrenje",
|
||||
"event_is_still_waiting": "Zahtev na dogadjaj još čeka: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "Nema više rezultata",
|
||||
"no_results": "Nema rezultata",
|
||||
"load_more_results": "Učitaj više rezultata",
|
||||
"integration_meeting_id": "{{integrationName}} ID sastanka: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Potvrdjeno: {{eventType}} sa {{name}} datuma {{date}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "Dodaj u kalendar",
|
||||
"add_another_calendar": "Dodaj još jedan kalendar",
|
||||
"other": "Drugo",
|
||||
"email_sign_in_subject": "Vaša veza za prijavu na {{appName}}",
|
||||
"emailed_you_and_attendees": "Poslali smo vama i ostalim učesnicima kalendarski poziv sa svim detaljima.",
|
||||
"emailed_you_and_attendees_recurring": "Poslali smo vama i ostalim učesnicima kalendarski poziv za prvi od ovih ponavljajućih događaja.",
|
||||
"emailed_you_and_any_other_attendees": "Vi i ostali učesnici ste dobili e-poštu sa ovim informacijama.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "Idite na portal naplate",
|
||||
"need_anything_else": "Treba li vam još nešto?",
|
||||
"further_billing_help": "Ako vam treba pomoć sa naplatom, naš tim podrške je tu da pomogne.",
|
||||
"contact_our_support_team": "Kontaktirjate naš tim podrške",
|
||||
"uh_oh": "O ne!",
|
||||
"no_event_types_have_been_setup": "Ovaj korisnik još nije podesio tipove događaja.",
|
||||
"edit_logo": "Uredi logo",
|
||||
@@ -420,6 +421,7 @@
|
||||
"current_incorrect_password": "Trenutna lozinka je netačna",
|
||||
"password_hint_caplow": "Mešavina velikih i malih slova",
|
||||
"password_hint_min": "Dugačka minimalno 7 znakova",
|
||||
"password_hint_admin_min": "Dugačka minimalno 15 znakova",
|
||||
"password_hint_num": "Sadrži barem 1 broj",
|
||||
"invalid_password_hint": "Lozinka mora da bude dugačka najmanje 7 znakova, da sadrži najmanje jedan broj i da ima mešavinu velikih i malih slova",
|
||||
"incorrect_password": "Lozinka je netačna.",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "Potvrdite vaš {{eventTypeTitle}} sa {{profileName}}",
|
||||
"booking_reschedule_confirmation": "Odložite vaš {{eventTypeTitle}} sa {{profileName}}",
|
||||
"in_person_meeting": "Sastanak uživo ili preko online linka",
|
||||
"attendeeInPerson": "Lično (adresa polaznika)",
|
||||
"inPerson": "Lično (adresa organizatora)",
|
||||
"link_meeting": "Link za sastanak",
|
||||
"phone_call": "Broj telefona učesnika",
|
||||
"your_number": "Vaš broj telefona",
|
||||
"phone_number": "Broj Telefona",
|
||||
"attendee_phone_number": "Broj telefona učesnika",
|
||||
"organizer_phone_number": "Broj telefona organizatora",
|
||||
"host_phone_number": "Vaš broj telefona",
|
||||
"enter_phone_number": "Unesite broj telefona",
|
||||
"reschedule": "Odloži",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "Kolektiv",
|
||||
"collective_description": "Rezerviši sastanke kad su izabrani članovi tima dostupni.",
|
||||
"duration": "Trajanje",
|
||||
"available_durations": "Dostupna trajanja",
|
||||
"default_duration": "Podrazumevano trajanje",
|
||||
"default_duration_no_options": "Najpre izaberite dostupna trajanja",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "Minuti",
|
||||
"round_robin": "Round Robin",
|
||||
"round_robin_description": "Ciklusirajte sastanke između više članova tima.",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "Timovi",
|
||||
"team": "Tim",
|
||||
"team_billing": "Naplata za timove",
|
||||
"team_billing_description": "Upravljajte naplatom za vaš tim",
|
||||
"upgrade_to_flexible_pro_title": "Promenili smo proces naplate za timove",
|
||||
"upgrade_to_flexible_pro_message": "Imate članove u timu koji nemaju mesto. Nadogradite svoj pro plan da biste pokrili mesta koja nedostaju.",
|
||||
"changed_team_billing_info": "Od Januara 2022 vršimo naplatu po mestu za članove tima. Članovi vašeg tima koji su imali Pro besplatno su sada na Pro probnom periodu od 14 dana. Kad probni period istekne ovi članovi biće sakriveni od vašeg tima ukoliko se ne pretplatite na ovu uslugu.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "Sakrij tip događaja",
|
||||
"edit_location": "Uredi lokaciju",
|
||||
"into_the_future": "u budućnost",
|
||||
"when_booked_with_less_than_notice": "Kada je rezervisano sa manje od <time></time> napomenom",
|
||||
"within_date_range": "U okviru vremenskog perioda",
|
||||
"indefinitely_into_future": "Na neodređeno u budućnost",
|
||||
"add_new_custom_input_field": "Dodajte prilagodljivo polje unosa",
|
||||
@@ -713,6 +724,8 @@
|
||||
"delete_account_confirmation_message": "Da li ste sigurni da želite izbrisati svoj {{appName}} nalog? S kim god ste podelili link ovog naloga više neće moći da ga koristi za rezervacije i sva podešavanja koja imate neće biti sačuvana.",
|
||||
"integrations": "Integracije",
|
||||
"apps": "Aplikacije",
|
||||
"apps_description": "Omogućite aplikacije za vašu instancu Cal-a",
|
||||
"apps_listing": "Spisak aplikacija",
|
||||
"category_apps": "{{category}} aplikacije",
|
||||
"app_store": "App Store",
|
||||
"app_store_description": "Povezujemo ljude, tehnologiju i radno mesto.",
|
||||
@@ -736,6 +749,7 @@
|
||||
"toggle_calendars_conflict": "Uključite kalendare koje želite da proverite da li imaju konflikta da biste sprečili dvostruka zakazivanja.",
|
||||
"select_destination_calendar": "Napravi događaje na",
|
||||
"connect_additional_calendar": "Poveži se sa dodatnim kalendarom",
|
||||
"calendar_updated_successfully": "Kalendar je uspešno ažuriran",
|
||||
"conferencing": "Konferencija",
|
||||
"calendar": "Kalendar",
|
||||
"payments": "Plaćanja",
|
||||
@@ -768,6 +782,7 @@
|
||||
"trending_apps": "Aplikacije u trendu",
|
||||
"explore_apps": "{{category}} aplikacije",
|
||||
"installed_apps": "Instalirane aplikacije",
|
||||
"free_to_use_apps": "Besplatno",
|
||||
"no_category_apps": "Nema {{category}} aplikacija",
|
||||
"no_category_apps_description_calendar": "Dodajte kalendar aplikaciju da biste proverili da li postoje konflikti i time sprečili dvostruka zakazivanja",
|
||||
"no_category_apps_description_conferencing": "Pokušajte da dodate aplikaciju za konferenciju da biste integrisali video poziv sa svojim klijentima",
|
||||
@@ -784,7 +799,7 @@
|
||||
"analytics": "Analitika",
|
||||
"empty_installed_apps_headline": "Aplikacije nisu instalirane",
|
||||
"empty_installed_apps_description": "Aplikacije omogućavaju da unapredite svoj rad i značajno poboljšate svoja zakazivanja.",
|
||||
"empty_installed_apps_button": "Istražite App Store ili instalirajte neku od aplikacija u nastavku",
|
||||
"empty_installed_apps_button": "Istražite App Store",
|
||||
"manage_your_connected_apps": "Upravljajte instaliranim aplikacijama ili promenite postavke",
|
||||
"browse_apps": "Pregledajte aplikacije",
|
||||
"features": "Funkcije",
|
||||
@@ -806,6 +821,8 @@
|
||||
"verify_wallet": "Verifikuj Wallet",
|
||||
"connect_metamask": "Poveži Metamask",
|
||||
"create_events_on": "Kreiraj događaje na",
|
||||
"enterprise_license": "Ovo je enterprise funkcija",
|
||||
"enterprise_license_description": "Da biste omogućili ovu funkciju, nabavite ključ za primenu na {{consoleUrl}} konzoli i dodajte ga u svoj .env kao CALCOM_LICENCE_KEY. Ako vaš tim već ima licencu, obratite se na {{supportMail}} za pomoć.",
|
||||
"missing_license": "Nedostaje Licenca",
|
||||
"signup_requires": "Komercijalna dozvola je neophodna",
|
||||
"signup_requires_description": "{{companyName}} trenutno ne nudi besplatnu verziju otvorenog koda od stranice za prijavu. Da bi dobili potpuni pristup kompenentama za prijavu, neophodno je da ste vlasnik komercijalne licence. Za ličnu upotrebu preporučujemo Prisma Data Platformu ili bilo koji drugi Postgres interfejs za pravljenje naloga.",
|
||||
@@ -897,6 +914,7 @@
|
||||
"user_impersonation_heading": "Predstavljanje kao korisnik",
|
||||
"user_impersonation_description": "Dozvoljava našem timu za podršku da se privremeno prijavi umesto vas kako bismo vam pomogli da brzo rešite sve probleme koje ste nam prijavili.",
|
||||
"team_impersonation_description": "Dozvolite administratorima svog tima da se privremeno prijave kao vi.",
|
||||
"allow_booker_to_select_duration": "Dozvoli polazniku da izabere trajanje",
|
||||
"impersonate_user_tip": "Sva korišćenja ove funkcije se nadgledaju.",
|
||||
"impersonating_user_warning": "Predstavljanje kao korisnik „{{user}}“.",
|
||||
"impersonating_stop_instructions": "<0>Kliknite ovde da zaustavite</0>.",
|
||||
@@ -1014,6 +1032,9 @@
|
||||
"error_removing_app": "Greška prilikom uklanjanja aplikacije",
|
||||
"web_conference": "Veb konferencija",
|
||||
"requires_confirmation": "Potrebna je potvrda",
|
||||
"always_requires_confirmation": "Uvek",
|
||||
"requires_confirmation_threshold": "Zahteva potvrdu ako je rezervisano sa < {{time}}$t({{unit}}_timeUnit) napomenom",
|
||||
"may_require_confirmation": "Može da zahteva potvrdu",
|
||||
"nr_event_type_one": "{{count}} tip događaja",
|
||||
"nr_event_type_other": "{{count}} tipova događaja",
|
||||
"add_action": "Dodaj radnju",
|
||||
@@ -1101,6 +1122,9 @@
|
||||
"event_limit_tab_description": "Koliko često možete da budete rezervisani",
|
||||
"event_advanced_tab_description": "Podešavanja kalendara i više...",
|
||||
"event_advanced_tab_title": "Napredno",
|
||||
"event_setup_multiple_duration_error": "Podešavanje događaja: Višestruka trajanja zahteva najmanje 1 opciju.",
|
||||
"event_setup_multiple_duration_default_error": "Podešavanje događaja: Izaberite važeće podrazumevano trajanje.",
|
||||
"event_setup_booking_limits_error": "Ograničenja zakazivanja moraju da budu u rastućem nizu. [dan,nedelja,mesec,godina]",
|
||||
"select_which_cal": "Izaberite u koji kalendar želite da dodate rezervacije",
|
||||
"custom_event_name": "Prilagođeno ime događaja",
|
||||
"custom_event_name_description": "Kreirajte prilagođena imena događaja za prikaz na kalendaru događaja",
|
||||
@@ -1154,8 +1178,11 @@
|
||||
"invoices": "Fakture",
|
||||
"embeds": "Ugrađivanja",
|
||||
"impersonation": "Predstavljanje kao",
|
||||
"impersonation_description": "Podešavanja za upravljanje lažnim predstavljanjem korisnika",
|
||||
"users": "Korisnici",
|
||||
"profile_description": "Upravljajte podešavanjima vašeg {{appName}} profila",
|
||||
"users_description": "Ovde možete da nađete spisak svih korisnika",
|
||||
"users_listing": "Spisak korisnika",
|
||||
"general_description": "Upravljajte podešavanjima za vaš jezik i vremensku zonu",
|
||||
"calendars_description": "Konfigurišite način na koji tipovi događaja vrše interakciju sa vašim kalendarima",
|
||||
"appearance_description": "Upravljajte podešavanjima za izgled vaše rezervacije",
|
||||
@@ -1345,7 +1372,7 @@
|
||||
"billing_frequency": "Učestalost naplate",
|
||||
"monthly": "Mesečno",
|
||||
"yearly": "Godišnje",
|
||||
"checkout": "Odjava",
|
||||
"checkout": "Kasa",
|
||||
"your_team_disbanded_successfully": "Vaš tim je uspešno rasformiran",
|
||||
"error_creating_team": "Greška prilikom kreiranja tima",
|
||||
"you": "Vi",
|
||||
@@ -1353,22 +1380,62 @@
|
||||
"member_already_invited": "Član je već pozvan",
|
||||
"enter_email_or_username": "Unesite imejl ili korisničko ime",
|
||||
"team_name_taken": "Ime je zauzeto",
|
||||
"must_enter_team_name": "Unesite ime tima",
|
||||
"must_enter_team_name": "Morate uneti naziv tima",
|
||||
"team_url_required": "Morate da unesete URL tima",
|
||||
"team_url_taken": "Ovaj URL je zauzet",
|
||||
"team_publish": "Objavite tim",
|
||||
"number_sms_notifications": "Broj telefona (obaveštenja putem SMS-a)",
|
||||
"attendee_email_workflow": "Imejl polaznika",
|
||||
"attendee_email_info": "Imejl osobe koja rezerviše",
|
||||
"invalid_credential": "Izgleda da je dozvola istekla ili je povučena. Instalirajte ponovo.",
|
||||
"kbar_search_placeholder": "Unesite komandu ili pretražite...",
|
||||
"invalid_credential": "O, ne! Izgleda da je dozvola istekla ili je povučena. Instalirajte ponovo.",
|
||||
"choose_common_schedule_team_event": "Izaberite zajednički raspored",
|
||||
"choose_common_schedule_team_event_description": "Omogućite to ako želite da koristite zajednički raspored između domaćina. Kada je onemogućen, svaki domaćin može rezervisati na osnovu svog podrazumevanog rasporeda.",
|
||||
"reason": "Razlog",
|
||||
"sender_id": "ID pošiljaoca",
|
||||
"sender_id_error_message": "Dozvoljena su samo slova, brojevi i razmaci (maks. 11 karaktera)",
|
||||
"sender_id_error_message": "Dozvoljena su samo slova, brojevi i razmaci (maks. 11 znakova)",
|
||||
"test_routing_form": "Testiranje obrasca za usmeravanje",
|
||||
"test_preview": "Pregled testa",
|
||||
"route_to": "Usmeri na",
|
||||
"test_preview_description": "Proverite obrazac za usmeravanje bez slanja bilo kog podatka",
|
||||
"test_routing": "Testiranje usmeravanja"
|
||||
"test_routing": "Testiranje usmeravanja",
|
||||
"payment_app_disabled": "Administrator je onemogućio aplikaciju za plaćanje",
|
||||
"edit_event_type": "Izmenite tip događaja",
|
||||
"collective_scheduling": "Kolektivno zakazivanje",
|
||||
"make_it_easy_to_book": "Učinite lakim da zakažete svoj tim kada je su svi dostupni.",
|
||||
"find_the_best_person": "Nađite najbolju dostupnu osobu i pregledajte svoj tim.",
|
||||
"fixed_round_robin": "Fiksno kružno dodeljivanje",
|
||||
"add_one_fixed_attendee": "Dodajte jednog fiksnog polaznika i kružno dodelite velikom broju polaznika.",
|
||||
"calcom_is_better_with_team": "Cal.com je bolji uz timove",
|
||||
"add_your_team_members": "Dodajte članove svog tima vašem tipovima događaja. Koristite kolektivno zakazivanje da uključite svakoga ili pronađete osobu koja najviše odgovara pomoću zakazivanja kružnim dodeljivanjem.",
|
||||
"booking_limit_reached": "Dostignuta je granica zakazivanja za ovaj tip događaja",
|
||||
"admin_has_disabled": "Administrator je onemogućio {{appName}}",
|
||||
"disabled_app_affects_event_type": "Administrator je onemogućio {{appName}} što utiče na vaš tip događaja {{eventType}}",
|
||||
"disable_payment_app": "Administrator je onemogućio {{appName}} što utiče na vaš tip događaja {{title}}. Polaznici još uvek mogu da zakažu ovaj tip događaja, ali im neće biti zatraženo da plate. Možete da sakrijete ovaj tip događaja da biste to sprečili dok vaš administrator ponovo ne omogući vaš način plaćanja.",
|
||||
"payment_disabled_still_able_to_book": "Polaznici još uvek mogu da zakažu ovaj tip događaja, ali im neće biti zatraženo da plate. Možete da sakrijete ovaj tip događaja da biste to sprečili dok vaš administrator ponovo ne omogući vaš način plaćanja.",
|
||||
"app_disabled_with_event_type": "Administrator je onemogućio {{appName}} što utiče na vaš tip događaja {{title}}.",
|
||||
"app_disabled_video": "Administrator je onemogućio {{appName}} što može da utiče na vaš tip događaja. Ako imate tipove događaja sa {{appName}} kao lokacijom, onda će biti podrazumevano usmereni na Cal Video.",
|
||||
"app_disabled_subject": "Aplikacija {{appName}} je onemogućena",
|
||||
"navigate_installed_apps": "Idi na instalirane aplikacije",
|
||||
"disabled_calendar": "Ako imate instaliran drugi kalendar, nova zakazivanja će biti dodata na njega. Ako nemate, onda povežite novi kalendar da ne biste propustili nova zakazivanja.",
|
||||
"enable_apps": "Omogući aplikacije",
|
||||
"enable_apps_description": "Omogući aplikacije koje korisnik može da integriše sa Cal.com",
|
||||
"app_is_enabled": "Aplikacija {{appName}} je omogućena",
|
||||
"app_is_disabled": "Aplikacija {{appName}} je onemogućena",
|
||||
"keys_have_been_saved": "Ključevi su sačuvani",
|
||||
"disable_app": "Onemogući aplikaciju",
|
||||
"disable_app_description": "Onemogućavanje ove aplikacije može da stvori probleme u komunikaciji vaših korisnika sa Cal-om",
|
||||
"edit_keys": "Izmeni ključeve",
|
||||
"admin_apps_description": "Omogućite aplikacije za vašu instancu Cal-a",
|
||||
"no_available_apps": "Nema dostupnih aplikacija",
|
||||
"no_available_apps_description": "Uverite se da ima aplikacija u vašoj fascikli za instalaciju pod „packages/app-store“",
|
||||
"no_apps": "Nema omogućenih aplikacija u ovoj instanci Cal-a",
|
||||
"apps_settings": "Podešavanja aplikacija",
|
||||
"fill_this_field": "Popunite ovo polje",
|
||||
"options": "Opcije",
|
||||
"enter_option": "Unesite opciju {{index}}",
|
||||
"add_an_option": "Dodajte opciju",
|
||||
"radio": "Radio",
|
||||
"event_type_duplicate_copy_text": "{{slug}}-kopija",
|
||||
"set_as_default": "Postavi kao podrazumevano"
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "En bokning väntar fortfarande på godkännande",
|
||||
"event_is_still_waiting": "Bokningsförfrågan väntar fortfarande: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "Inga fler resultat",
|
||||
"no_results": "Inga resultat",
|
||||
"load_more_results": "Hämta fler resultat",
|
||||
"integration_meeting_id": "{{integrationName}} mötes-ID: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Bekräftad: {{eventType}} med {{name}} vid {{date}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "Lägg till i kalender",
|
||||
"add_another_calendar": "Lägg till en annan kalender",
|
||||
"other": "Annat",
|
||||
"email_sign_in_subject": "Din inloggningslänk för {{appName}}",
|
||||
"emailed_you_and_attendees": "Vi skickade dig och de andra deltagarna en kalenderinbjudan med alla detaljer.",
|
||||
"emailed_you_and_attendees_recurring": "Vi skickade dig och de andra deltagarna en kalenderinbjudan via e-post för den första av dessa återkommande händelser.",
|
||||
"emailed_you_and_any_other_attendees": "Du och alla andra deltagare har fått e-post med denna information.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "Gå till faktureringsportalen",
|
||||
"need_anything_else": "Behöver du något annat?",
|
||||
"further_billing_help": "Om du behöver ytterligare hjälp med fakturering finns vårt supportteam här för att hjälpa till.",
|
||||
"contact_our_support_team": "Kontakta vårt kundsupportteam",
|
||||
"uh_oh": "Åh nej!",
|
||||
"no_event_types_have_been_setup": "Den här användaren har inte skapat några händelsetyper ännu.",
|
||||
"edit_logo": "Ändra logotyp",
|
||||
@@ -420,6 +421,7 @@
|
||||
"current_incorrect_password": "Nuvarande lösenord är felaktigt",
|
||||
"password_hint_caplow": "Blandning av versaler och gemener",
|
||||
"password_hint_min": "Minst 8 tecken",
|
||||
"password_hint_admin_min": "Minst 15 tecken",
|
||||
"password_hint_num": "Innehåller minst 1 siffra",
|
||||
"invalid_password_hint": "Lösenordet måste innehålla minst 7 tecken och har minst en siffra samt en blandning av versaler och gemener",
|
||||
"incorrect_password": "Lösenordet är felaktigt.",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "Bekräfta {{eventTypeTitle}} med {{profileName}}",
|
||||
"booking_reschedule_confirmation": "Omboka {{eventTypeTitle}} med {{profileName}}",
|
||||
"in_person_meeting": "Länk eller fysiskt möte",
|
||||
"attendeeInPerson": "Personligen (deltagandeadress)",
|
||||
"inPerson": "Personligen (orgnanisatörsadress)",
|
||||
"link_meeting": "Länka möte",
|
||||
"phone_call": "Deltagarens telefonnummer",
|
||||
"your_number": "Ditt telefonnummer",
|
||||
"phone_number": "Telefonnummer",
|
||||
"attendee_phone_number": "Deltagarens telefonnummer",
|
||||
"organizer_phone_number": "Organisatörens telefonnummer",
|
||||
"host_phone_number": "Ditt telefonnummer",
|
||||
"enter_phone_number": "Fyll i telefonnummer",
|
||||
"reschedule": "Omplanera",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "Kollektiv",
|
||||
"collective_description": "Schemalägg möten när alla valda teammedlemmar är tillgängliga.",
|
||||
"duration": "Längd",
|
||||
"available_durations": "Tillgänglig varaktighet",
|
||||
"default_duration": "Standardvaraktighet",
|
||||
"default_duration_no_options": "Välj först tillgänglig varaktighet",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "Minuter",
|
||||
"round_robin": "Tur och ordning",
|
||||
"round_robin_description": "Variera möten mellan olika teammedlemmar.",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "Teams",
|
||||
"team": "Team",
|
||||
"team_billing": "Team-fakturering",
|
||||
"team_billing_description": "Hantera fakturering för ditt team",
|
||||
"upgrade_to_flexible_pro_title": "Vi har ändrat fakturering för team",
|
||||
"upgrade_to_flexible_pro_message": "Det finns medlemmar i ditt team utan en plats. Uppgradera din pro plan för att täcka saknade platser.",
|
||||
"changed_team_billing_info": "Från och med januari 2022 tar vi betalt på plats-basis för teammedlemmar. Medlemmar i ditt team som hade Pro gratis är nu på en 14 dagars provperiod. När deras provperiod löper ut kommer dessa medlemmar att döljas från ditt team om du inte uppgraderar nu.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "Dölj händelsetyp",
|
||||
"edit_location": "Redigera plats",
|
||||
"into_the_future": "in i framtiden",
|
||||
"when_booked_with_less_than_notice": "Vid bokning med mindre än <time></time> varsel",
|
||||
"within_date_range": "Inom ett datumintervall",
|
||||
"indefinitely_into_future": "På obestämd tid in i framtiden",
|
||||
"add_new_custom_input_field": "Lägg till nytt anpassat inmatningsfält",
|
||||
@@ -713,6 +724,8 @@
|
||||
"delete_account_confirmation_message": "Är du säker på att du vill radera ditt {{appName}} konto? Alla som du har delat din kontolänk med kommer inte längre att kunna boka med hjälp av den och eventuella inställningar du har sparat kommer att gå förlorade.",
|
||||
"integrations": "Integrationer",
|
||||
"apps": "Appar",
|
||||
"apps_description": "Aktivera appar för din Cal-version",
|
||||
"apps_listing": "App-listning",
|
||||
"category_apps": "{{category}}-appar",
|
||||
"app_store": "App Store",
|
||||
"app_store_description": "Kopplar samman människor, teknik och arbetsplats.",
|
||||
@@ -736,6 +749,7 @@
|
||||
"toggle_calendars_conflict": "Ändra de kalendrar du vill kontrollera för konflikter för att förhindra dubbelbokningar.",
|
||||
"select_destination_calendar": "Skapa händelser i",
|
||||
"connect_additional_calendar": "Anslut ytterligare kalender",
|
||||
"calendar_updated_successfully": "Kalendern har uppdaterats",
|
||||
"conferencing": "Konferenser",
|
||||
"calendar": "Kalender",
|
||||
"payments": "Betalningar",
|
||||
@@ -768,6 +782,7 @@
|
||||
"trending_apps": "Trendande appar",
|
||||
"explore_apps": "{{category}}-appar",
|
||||
"installed_apps": "Installerade appar",
|
||||
"free_to_use_apps": "Gratis",
|
||||
"no_category_apps": "Inga {{category}}-appar",
|
||||
"no_category_apps_description_calendar": "Lägg till en kalenderapp för att kontrollera konflikter och förhindra dubbelbokningar",
|
||||
"no_category_apps_description_conferencing": "Prova att lägga till en konferensapp för att integrera videosamtal med dina kunder",
|
||||
@@ -806,6 +821,8 @@
|
||||
"verify_wallet": "Verifiera plånbok",
|
||||
"connect_metamask": "Anslut Metamask",
|
||||
"create_events_on": "Skapa händelser i",
|
||||
"enterprise_license": "Det här är en företagsfunktion",
|
||||
"enterprise_license_description": "För att aktivera den här funktionen hämtar du en distributionsnyckel i konsolen {{consoleUrl}} och lägger till den i din .env som CALCOM_LICENSE_KEY. Om ditt team redan har en licens kan du kontakta {{supportMail}} för att få hjälp.",
|
||||
"missing_license": "Licens saknas",
|
||||
"signup_requires": "Kommersiell licens krävs",
|
||||
"signup_requires_description": "{{companyName}} erbjuder för närvarande inte en gratis open source-version av registreringssidan. För att få full tillgång till de registreringskomponenter du behöver för att skaffa en kommersiell licens. För personligt bruk rekommenderar vi Prisma Data Platform eller något annat Postgres-gränssnitt för att skapa konton.",
|
||||
@@ -897,6 +914,7 @@
|
||||
"user_impersonation_heading": "Användarpersonifiering",
|
||||
"user_impersonation_description": "Gör det möjligt för vårt supportteam att tillfälligt logga in som du så att vi snabbt kan lösa problem som du rapporterar till oss.",
|
||||
"team_impersonation_description": "Tillåter dina teamadministratörer att tillfälligt logga in som dig.",
|
||||
"allow_booker_to_select_duration": "Låt bokaren välja varaktighet",
|
||||
"impersonate_user_tip": "All användning av denna funktion granskas.",
|
||||
"impersonating_user_warning": "Imiterar användarnamn \"{{user}}\".",
|
||||
"impersonating_stop_instructions": "<0>Klicka här för att sluta</0>.",
|
||||
@@ -1014,6 +1032,9 @@
|
||||
"error_removing_app": "Det gick inte att ta bort app",
|
||||
"web_conference": "Webbkonferens",
|
||||
"requires_confirmation": "Kräver bekräftelse",
|
||||
"always_requires_confirmation": "Alltid",
|
||||
"requires_confirmation_threshold": "Kräver bekräftelse om bokat med < {{time}} $t({{unit}}_timeUnit) varsel",
|
||||
"may_require_confirmation": "Kan kräva bekräftelse",
|
||||
"nr_event_type_one": "{{count}} händelsetyp",
|
||||
"nr_event_type_other": "{{count}} händelsetyper",
|
||||
"add_action": "Lägg till åtgärd",
|
||||
@@ -1101,6 +1122,9 @@
|
||||
"event_limit_tab_description": "Hur ofta du kan bokas",
|
||||
"event_advanced_tab_description": "Kalenderinställningar och mer...",
|
||||
"event_advanced_tab_title": "Avancerat",
|
||||
"event_setup_multiple_duration_error": "Konfiguration av händelse: Flera varaktigheter kräver minst 1 alternativ.",
|
||||
"event_setup_multiple_duration_default_error": "Konfiguration av händelse: Välj en giltig standardvaraktighet.",
|
||||
"event_setup_booking_limits_error": "Bokningsgränserna ska vara i stigande ordning. [dag,vecka,månad,år]",
|
||||
"select_which_cal": "Välj vilken kalender du vill lägga till bokningar till",
|
||||
"custom_event_name": "Anpassat händelsenamn",
|
||||
"custom_event_name_description": "Skapa anpassade händelsenamn som ska visas på kalenderhändelse",
|
||||
@@ -1154,8 +1178,11 @@
|
||||
"invoices": "Fakturor",
|
||||
"embeds": "Inbäddningar",
|
||||
"impersonation": "Imitering",
|
||||
"impersonation_description": "Inställningar för att hantera användarens personifiering",
|
||||
"users": "Användare",
|
||||
"profile_description": "Hantera inställningar för din {{appName}}-profil",
|
||||
"users_description": "Här hittar du en lista med alla användare",
|
||||
"users_listing": "Användarlistning",
|
||||
"general_description": "Hantera inställningar för språk och tidszon",
|
||||
"calendars_description": "Ställ in hur dina händelsetyper interagerar med dina kalendrar",
|
||||
"appearance_description": "Hantera inställningar för ditt bokningsutseende",
|
||||
@@ -1360,6 +1387,7 @@
|
||||
"number_sms_notifications": "Telefonnummer (SMS-notiser)",
|
||||
"attendee_email_workflow": "Deltagarens e-postadress",
|
||||
"attendee_email_info": "Personens e-postadress för bokning",
|
||||
"kbar_search_placeholder": "Skriv ett kommando eller sök...",
|
||||
"invalid_credential": "Åh nej! Det verkar som om behörigheten löpt ut eller återkallats. Installera om igen.",
|
||||
"choose_common_schedule_team_event": "Välj ett gemensamt schema",
|
||||
"choose_common_schedule_team_event_description": "Aktivera den här funktionen om du vill använda ett gemensamt schema mellan värdarna. När den är inaktiverad bokas varje värd enligt sitt standardschema.",
|
||||
@@ -1370,5 +1398,44 @@
|
||||
"test_preview": "Testa förhandsgranskning",
|
||||
"route_to": "Dirigera till",
|
||||
"test_preview_description": "Testa ditt routingformulär utan att skicka data",
|
||||
"test_routing": "Testa routing"
|
||||
"test_routing": "Testa routing",
|
||||
"payment_app_disabled": "En administratör har inaktiverat en betalningsapp",
|
||||
"edit_event_type": "Redigera händelsetyp",
|
||||
"collective_scheduling": "Kollektiv schemaläggning",
|
||||
"make_it_easy_to_book": "Gör det enkelt att boka ditt team när alla är tillgängliga.",
|
||||
"find_the_best_person": "Hitta den bästa personen som finns och cykla genom ditt team.",
|
||||
"fixed_round_robin": "Fast runda robin",
|
||||
"add_one_fixed_attendee": "Lägg till en fast deltagare och rundgång för ett antal deltagare.",
|
||||
"calcom_is_better_with_team": "Cal.com är bättre med teams",
|
||||
"add_your_team_members": "Lägg till dina teammedlemmar i dina händelsetyper. Använd kollektiv schemaläggning för att inkludera alla eller hitta den lämpligaste personen med rundgångsschemaläggning.",
|
||||
"booking_limit_reached": "Bokningsgränsen för denna händelsetyp har uppnåtts",
|
||||
"admin_has_disabled": "En administratör har inaktiverat {{appName}}",
|
||||
"disabled_app_affects_event_type": "En administratör har inaktiverat {{appName}} vilket påverkar din händelsetyp {{eventType}}",
|
||||
"disable_payment_app": "Administratören har inaktiverat {{appName}} vilket påverkar din evenemangstyp {{title}}. Deltagarna kan fortfarande boka den här typen av händelse men kommer inte att uppmanas att betala. Du kan dölja händelsetypen för att förhindra detta tills din administratör återaktiverar din betalningsmetod.",
|
||||
"payment_disabled_still_able_to_book": "Deltagarna kan fortfarande boka den här typen av händelse, men kommer inte att uppmanas att betala. Du kan dölja händelsetypen för att förhindra detta tills din administratör återaktiverar betalningsmetoden.",
|
||||
"app_disabled_with_event_type": "Administratören har inaktiverat {{appName}} vilket påverkar din händelsetyp {{title}}.",
|
||||
"app_disabled_video": "Administratören har inaktiverat {{appName}} vilket kan påverka dina händelsetyper. Om du har händelsetyper med {{appName}} som plats kommer den att vara standard för Cal Video.",
|
||||
"app_disabled_subject": "{{appName}} har inaktiverats",
|
||||
"navigate_installed_apps": "Gå till installerade appar",
|
||||
"disabled_calendar": "Om du har en annan kalender installerad kommer nya bokningar att läggas till i den. Om du inte sedan ansluter en ny kalender så missar du inga nya bokningar.",
|
||||
"enable_apps": "Aktivera appar",
|
||||
"enable_apps_description": "Aktivera appar som användare kan integrera med Cal.com",
|
||||
"app_is_enabled": "{{appName}} har aktiverats",
|
||||
"app_is_disabled": "{{appName}} har inaktiverats",
|
||||
"keys_have_been_saved": "Nycklar har sparats",
|
||||
"disable_app": "Inaktivera app",
|
||||
"disable_app_description": "Inaktivering av den här appen kan orsaka problem med hur dina användare interagerar med Cal",
|
||||
"edit_keys": "Redigera nycklar",
|
||||
"admin_apps_description": "Aktivera appar för din Cal-version",
|
||||
"no_available_apps": "Det finns inga tillgängliga appar",
|
||||
"no_available_apps_description": "Se till att det finns appar i din distribution under \"paket/app-store\"",
|
||||
"no_apps": "Det finns inga appar aktiverade i denna instans av Cal",
|
||||
"apps_settings": "App-inställningar",
|
||||
"fill_this_field": "Fyll i det här fältet",
|
||||
"options": "Alternativ",
|
||||
"enter_option": "Ange alternativ {{index}}",
|
||||
"add_an_option": "Lägg till ett alternativ",
|
||||
"radio": "Radio",
|
||||
"event_type_duplicate_copy_text": "{{slug}}-kopia",
|
||||
"set_as_default": "Ange som standard"
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "Bir etkinlik hâlâ onay bekliyor",
|
||||
"event_is_still_waiting": "Etkinlik isteği hâlâ beklemede: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "Başka sonuç yok",
|
||||
"no_results": "Sonuç yok",
|
||||
"load_more_results": "Daha fazla sonuç yükle",
|
||||
"integration_meeting_id": "{{integrationName}} toplantı kimliği: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Onaylandı: {{date}} tarihinde {{name}} ile {{eventType}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "Takvime ekle",
|
||||
"add_another_calendar": "Başka bir takvim ekle",
|
||||
"other": "Diğer",
|
||||
"email_sign_in_subject": "{{appName}} için giriş bağlantınız",
|
||||
"emailed_you_and_attendees": "Size ve diğer katılımcılara tüm ayrıntıları içeren bir takvim daveti e-postası gönderdik.",
|
||||
"emailed_you_and_attendees_recurring": "Size ve diğer katılımcılara bu yinelenen etkinliklerin ilki için bir takvim daveti e-postası gönderdik.",
|
||||
"emailed_you_and_any_other_attendees": "Bu bilgiler size ve diğer katılımcılara e-posta ile gönderildi.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "Fatura portalına git",
|
||||
"need_anything_else": "Başka bir şeye ihtiyacınız var mı?",
|
||||
"further_billing_help": "Faturalandırma konusunda daha fazla yardıma ihtiyacınız olursa destek ekibimiz size yardımcı olmaya hazır.",
|
||||
"contact_our_support_team": "Destek ekibimizle iletişime geçin",
|
||||
"uh_oh": "Hay aksi!",
|
||||
"no_event_types_have_been_setup": "Bu kullanıcı henüz etkinlik türü ayarlamadı.",
|
||||
"edit_logo": "Logoyu düzenle",
|
||||
@@ -420,6 +421,7 @@
|
||||
"current_incorrect_password": "Mevcut şifre hatalı",
|
||||
"password_hint_caplow": "Büyük ve küçük harf karışımı",
|
||||
"password_hint_min": "En az 8 karakter uzunluğunda",
|
||||
"password_hint_admin_min": "Minimum uzunluk 15 karakter",
|
||||
"password_hint_num": "En az 1 rakam içermelidir",
|
||||
"invalid_password_hint": "Şifre en az 7 karakter uzunluğunda olmalı, en az bir rakam içermeli ve büyük ve küçük harflerin karışımından oluşmalıdır",
|
||||
"incorrect_password": "Şifre hatalı.",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "{{profileName}} ile {{eventTypeTitle}} etkinliğinizi onaylayın",
|
||||
"booking_reschedule_confirmation": "{{profileName}} ile {{eventTypeTitle}} etkinliğinizi yeniden planlayın",
|
||||
"in_person_meeting": "Yüz yüze görüşme",
|
||||
"attendeeInPerson": "Şahsen (Katılımcı Adresi)",
|
||||
"inPerson": "Şahsen (Organizatör Adresi)",
|
||||
"link_meeting": "Bağlantılı toplantı",
|
||||
"phone_call": "Katılımcı Telefon Numarası",
|
||||
"your_number": "Telefon numaranız",
|
||||
"phone_number": "Telefon Numarası",
|
||||
"attendee_phone_number": "Katılımcı Telefon Numarası",
|
||||
"organizer_phone_number": "Organizatör Telefon Numarası",
|
||||
"host_phone_number": "Telefon Numaranız",
|
||||
"enter_phone_number": "Telefon numarası girin",
|
||||
"reschedule": "Yeniden planla",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "Toplu",
|
||||
"collective_description": "Tüm seçili ekip üyeleri müsait olduğunda toplantıları planlayın.",
|
||||
"duration": "Süre",
|
||||
"available_durations": "Uygun süreler",
|
||||
"default_duration": "Varsayılan süre",
|
||||
"default_duration_no_options": "Lütfen önce uygun süreleri seçin",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "Dakika",
|
||||
"round_robin": "Round Robin",
|
||||
"round_robin_description": "Toplantıları birden fazla ekip üyesi arasında döndürün.",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "Ekipler",
|
||||
"team": "Ekip",
|
||||
"team_billing": "Ekip Faturası",
|
||||
"team_billing_description": "Ekibiniz için faturalandırmayı yönetin",
|
||||
"upgrade_to_flexible_pro_title": "Ekipler için faturayı değiştirdik",
|
||||
"upgrade_to_flexible_pro_message": "Ekibinizde alanı olmayan üyeler var. Eksik alanları doldurmak için profesyonel plana yükseltin.",
|
||||
"changed_team_billing_info": "Ocak 2022'den itibaren her ekip üyesi alanı için ücret alıyoruz. Ücretsiz PRO'ya sahip olan ekip üyeleriniz şu anda 14 günlük deneme süresinde. Deneme süreleri sona erdiğinde ve yükseltme yapmadığınızda bu üyeler ekibinizden gizlenecektir.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "Etkinlik türünü gizle",
|
||||
"edit_location": "Konumu düzenle",
|
||||
"into_the_future": "gelecekte",
|
||||
"when_booked_with_less_than_notice": "<time></time> bildiriminden daha az süre ile rezervasyon yapıldığında",
|
||||
"within_date_range": "Bir tarih aralığında",
|
||||
"indefinitely_into_future": "Süresiz olarak gelecekte",
|
||||
"add_new_custom_input_field": "Yeni özel veri girdi alanı ekle",
|
||||
@@ -713,6 +724,8 @@
|
||||
"delete_account_confirmation_message": "{{appName}} hesabınızı silmek istediğinizden emin misiniz? Hesap bağlantısı paylaştığınız herkes artık bu bağlantıyı kullanarak rezervasyon yapamayacak ve kaydettiğiniz tüm tercihler kaybolacak.",
|
||||
"integrations": "Entegrasyonlar",
|
||||
"apps": "Uygulamalar",
|
||||
"apps_description": "Cal örneğiniz için uygulamayı etkinleştirin",
|
||||
"apps_listing": "Uygulama listesi",
|
||||
"category_apps": "{{category}} uygulamaları",
|
||||
"app_store": "App Store",
|
||||
"app_store_description": "İnsanları, teknolojiyi ve çalışma ortamını birbirine bağlıyor.",
|
||||
@@ -736,6 +749,7 @@
|
||||
"toggle_calendars_conflict": "Çifte rezervasyonu önlemek için çakışmaları kontrol etmek istediğiniz takvimleri değiştirin.",
|
||||
"select_destination_calendar": "Şurada etkinlik oluştur:",
|
||||
"connect_additional_calendar": "Ek takvim bağlayın",
|
||||
"calendar_updated_successfully": "Takvim başarıyla güncellendi",
|
||||
"conferencing": "Konferans",
|
||||
"calendar": "Takvim",
|
||||
"payments": "Ödemeler",
|
||||
@@ -768,6 +782,7 @@
|
||||
"trending_apps": "Popüler Uygulamalar",
|
||||
"explore_apps": "{{category}} uygulamaları",
|
||||
"installed_apps": "Yüklü Uygulamalar",
|
||||
"free_to_use_apps": "Ücretsiz",
|
||||
"no_category_apps": "{{category}} uygulaması yok",
|
||||
"no_category_apps_description_calendar": "Çifte rezervasyonları önlemek amacıyla çakışmaları kontrol etmek için bir takvim uygulaması ekleyin",
|
||||
"no_category_apps_description_conferencing": "Müşterilerinizle görüntülü arama yapmak için bir konferans uygulaması eklemeyi deneyin",
|
||||
@@ -806,6 +821,8 @@
|
||||
"verify_wallet": "Cüzdanı Doğrula",
|
||||
"connect_metamask": "MetaMask'i Bağla",
|
||||
"create_events_on": "Şurada etkinlik oluşturun:",
|
||||
"enterprise_license": "Bu bir kurumsal özelliktir",
|
||||
"enterprise_license_description": "Bu özelliği etkinleştirmek için {{consoleUrl}} konsolundan bir dağıtım anahtarı alın ve bunu .env dosyanıza CALCOM_LICENSE_KEY olarak ekleyin. Ekibinizin zaten bir lisansı varsa yardım için lütfen {{supportMail}} adresinden iletişime geçin.",
|
||||
"missing_license": "Eksik Lisans",
|
||||
"signup_requires": "Ticari lisans gerekli",
|
||||
"signup_requires_description": "{{companyName}} şu anda kayıt sayfasının ücretsiz, açık kaynaklı bir sürümünü sunmamaktadır. Kayıt bileşenlerine tam erişim elde etmek için ticari bir lisans almanız gerekiyor. Kişisel kullanım için hesap oluşturmak üzere Prisma Data veya başka bir Postgres arayüzü öneriyoruz.",
|
||||
@@ -897,6 +914,7 @@
|
||||
"user_impersonation_heading": "Kullanıcı Kimliğine Bürünme",
|
||||
"user_impersonation_description": "Bize bildirdiğiniz hataları hızlı bir şekilde çözmek için destek ekibimizin sizin adınıza geçici olarak oturum açmasına izin verir.",
|
||||
"team_impersonation_description": "Ekip üyelerinizin sizin adınıza geçici olarak oturum açmasına izin verir.",
|
||||
"allow_booker_to_select_duration": "Rezervasyon yapan kişinin süreyi seçmesine izin ver",
|
||||
"impersonate_user_tip": "Bu özelliğin tüm kullanımları denetlenir.",
|
||||
"impersonating_user_warning": "\"{{user}}\" kullanıcı adı kimliğine bürünme.",
|
||||
"impersonating_stop_instructions": "<0>Durdurmak için Buraya tıklayın</0>.",
|
||||
@@ -1014,6 +1032,9 @@
|
||||
"error_removing_app": "Uygulama kaldırılırken bir hata oluştu",
|
||||
"web_conference": "Web konferansı",
|
||||
"requires_confirmation": "Onay gerekli",
|
||||
"always_requires_confirmation": "Her zaman",
|
||||
"requires_confirmation_threshold": "{{time}} $t({{unit}}_timeUnit) bildiriminden daha az süre ile rezervasyon yapıldığında onay gerekir",
|
||||
"may_require_confirmation": "Onay gerekebilir",
|
||||
"nr_event_type_one": "{{count}} etkinlik türü",
|
||||
"nr_event_type_other": "{{count}} etkinlik türü",
|
||||
"add_action": "Eylem ekle",
|
||||
@@ -1101,6 +1122,9 @@
|
||||
"event_limit_tab_description": "Ne sıklıkla rezervasyon yapabilirsiniz",
|
||||
"event_advanced_tab_description": "Takvim ayarları ve daha fazlası...",
|
||||
"event_advanced_tab_title": "Gelişmiş",
|
||||
"event_setup_multiple_duration_error": "Etkinlik Kurulumu: Birden çok süre için en az 1 seçenek gereklidir.",
|
||||
"event_setup_multiple_duration_default_error": "Etkinlik Kurulumu: Lütfen geçerli bir varsayılan süre seçin.",
|
||||
"event_setup_booking_limits_error": "Rezervasyon limitleri artan sırada olmalıdır. [gün,hafta,ay,yıl]",
|
||||
"select_which_cal": "Rezervasyonların hangi takvime ekleneceğini seçin",
|
||||
"custom_event_name": "Özel etkinlik adı",
|
||||
"custom_event_name_description": "Takvim etkinliğinde görüntülenecek özelleştirilmiş etkinlik adları oluşturun",
|
||||
@@ -1154,8 +1178,11 @@
|
||||
"invoices": "Faturalar",
|
||||
"embeds": "Gömülüler",
|
||||
"impersonation": "Kimliğe bürünme",
|
||||
"impersonation_description": "Kullanıcı kimliğine bürünmeyi yönetmek için ayarlar",
|
||||
"users": "Kullanıcılar",
|
||||
"profile_description": "{{appName}} profiliniz için ayarları yönetin",
|
||||
"users_description": "Burada tüm kullanıcıların bir listesini bulabilirsiniz",
|
||||
"users_listing": "Kullanıcı listesi",
|
||||
"general_description": "Diliniz ve saat diliminiz için ayarları yönetin",
|
||||
"calendars_description": "Etkinlik türlerinizin takvimlerinizle nasıl etkileşimde bulunacağını yapılandırın",
|
||||
"appearance_description": "Rezervasyon görünümünüz için ayarları yönetin",
|
||||
@@ -1360,6 +1387,7 @@
|
||||
"number_sms_notifications": "Telefon numarası (SMS bildirimleri)",
|
||||
"attendee_email_workflow": "Katılımcı e-postası",
|
||||
"attendee_email_info": "Rezervasyon yaptıran kişinin e-postası",
|
||||
"kbar_search_placeholder": "Bir komut girin veya arayın...",
|
||||
"invalid_credential": "Hata! İznin süresi dolmuş veya iptal edilmiş gibi görünüyor. Lütfen yeniden yükleyin.",
|
||||
"choose_common_schedule_team_event": "Ortak bir program seçin",
|
||||
"choose_common_schedule_team_event_description": "Toplantı sahipleri arasında ortak bir plan kullanmak istiyorsanız bunu etkinleştirin. Devre dışı bırakıldığında, her toplantı sahibi varsayılan programına göre rezerve edilir.",
|
||||
@@ -1370,5 +1398,44 @@
|
||||
"test_preview": "Ön İzlemeyi Test Et",
|
||||
"route_to": "Şuraya yönlendir:",
|
||||
"test_preview_description": "Herhangi bir veri göndermeden yönlendirme formunuzu test edin",
|
||||
"test_routing": "Yönlendirmeyi Test Et"
|
||||
"test_routing": "Yönlendirmeyi Test Et",
|
||||
"payment_app_disabled": "Bir yönetici, ödeme uygulamasını devre dışı bıraktı",
|
||||
"edit_event_type": "Etkinlik türünü düzenle",
|
||||
"collective_scheduling": "Toplu Planlama",
|
||||
"make_it_easy_to_book": "Herkes müsait olduğunda ekibinizin rezervasyon yapmasını kolaylaştırın.",
|
||||
"find_the_best_person": "Mevcut en iyi kişiyi bulun ve ekip üyeleriniz arasında rotasyon yapın.",
|
||||
"fixed_round_robin": "Sabit döngü",
|
||||
"add_one_fixed_attendee": "Tek bir sabit katılımcı ve birden fazla katılımcının olduğu bir döngü ekleyin.",
|
||||
"calcom_is_better_with_team": "Cal.com ekiplerle daha iyidir",
|
||||
"add_your_team_members": "Ekip üyelerinizi etkinlik türlerinize ekleyin. Herkesi eklemek için toplu planlamayı kullanın veya döngüsel planlama ile en uygun kişiyi bulun.",
|
||||
"booking_limit_reached": "Bu etkinlik türü için Rezervasyon Sınırına ulaşıldı",
|
||||
"admin_has_disabled": "Bir yönetici {{appName}} uygulamasını devre dışı bıraktı",
|
||||
"disabled_app_affects_event_type": "Bir yönetici {{eventType}} etkinlik türünüzü etkileyen {{appName}} uygulamasını devre dışı bıraktı",
|
||||
"disable_payment_app": "Yönetici, {{title}} etkinlik türünüzü etkileyebilecek {{appName}} uygulamasını devre dışı bıraktı. Katılımcılar yine de bu tür bir etkinlik için rezervasyon yaptırabilirler ancak herhangi bir ödeme yapmalarına gerek yoktur. Bu durumu önlemek için yöneticiniz ödeme yönteminizi yeniden etkinleştirene kadar etkinlik türünü gizleyebilirsiniz.",
|
||||
"payment_disabled_still_able_to_book": "Katılımcılar yine de bu tür bir etkinlik için rezervasyon yaptırabilirler ancak herhangi bir ödeme yapmalarına gerek yoktur. Bu durumu önlemek için yöneticiniz ödeme yönteminizi yeniden etkinleştirene kadar etkinlik türünü gizleyebilirsiniz.",
|
||||
"app_disabled_with_event_type": "Yönetici, etkinlik {{title}} türünüzü etkileyen {{appName}} uygulamasını devre dışı bıraktı.",
|
||||
"app_disabled_video": "Yönetici, etkinlik türlerinizi etkileyebilecek {{appName}} uygulamasını devre dışı bıraktı. Konum olarak {{appName}} olan etkinlik türleriniz varsa varsayılan uygulama Cal Video olacaktır.",
|
||||
"app_disabled_subject": "{{appName}} devre dışı bırakıldı",
|
||||
"navigate_installed_apps": "Yüklü uygulamalara git",
|
||||
"disabled_calendar": "Yüklü başka bir takviminiz varsa yeni randevular bu takvime eklenecektir. Aksi takdirde yeni bir takvim bağlamazsanız yeni rezervasyonları kaçırabilirsiniz.",
|
||||
"enable_apps": "Uygulamaları Etkinleştir",
|
||||
"enable_apps_description": "Kullanıcıların Cal.com ile entegre edebileceği uygulamaları etkinleştirin",
|
||||
"app_is_enabled": "{{appName}} etkinleştirildi",
|
||||
"app_is_disabled": "{{appName}} devre dışı bırakıldı",
|
||||
"keys_have_been_saved": "Anahtarlar kaydedildi",
|
||||
"disable_app": "Uygulamaları Devre Dışı Bırak",
|
||||
"disable_app_description": "Bu uygulamanın devre dışı bırakılması kullanıcılarınızın Cal ile etkileşimde bulunmaları konusunda sorunlara neden olabilir",
|
||||
"edit_keys": "Anahtarları Düzenle",
|
||||
"admin_apps_description": "Cal örneğiniz için uygulamayı etkinleştirin",
|
||||
"no_available_apps": "Kullanılabilir uygulama yok",
|
||||
"no_available_apps_description": "'Paketler/uygulama mağazası' altındaki dağıtım klasörünüzde uygulamaların olduğundan emin olun",
|
||||
"no_apps": "Bu Cal örneğindeki hiçbir uygulama etkin değil",
|
||||
"apps_settings": "Uygulama ayarları",
|
||||
"fill_this_field": "Lütfen bu alanı doldurun",
|
||||
"options": "Seçenekler",
|
||||
"enter_option": "{{index}} Seçeneğini Girin",
|
||||
"add_an_option": "Bir seçenek ekle",
|
||||
"radio": "Radio",
|
||||
"event_type_duplicate_copy_text": "{{slug}}-kopyala",
|
||||
"set_as_default": "Varsayılan olarak ayarla"
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "Захід досі чекає на схвалення",
|
||||
"event_is_still_waiting": "Запит на захід досі в очікуванні: {{attendeeName}} – {{date}} – {{eventType}}",
|
||||
"no_more_results": "Інших результатів немає",
|
||||
"no_results": "Немає результатів",
|
||||
"load_more_results": "Завантажити інші результати",
|
||||
"integration_meeting_id": "Ідентифікатор наради «{{integrationName}}»: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Підтверджено: {{eventType}} «{{name}}», {{date}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "Додати в календар",
|
||||
"add_another_calendar": "Додати інший календар",
|
||||
"other": "Інше",
|
||||
"email_sign_in_subject": "Ваше посилання для входу в {{appName}}",
|
||||
"emailed_you_and_attendees": "Ми надіслали вам та іншим учасникам запрошення до календаря з усіма деталями.",
|
||||
"emailed_you_and_attendees_recurring": "Ми надіслали вам та іншим учасникам запрошення з календаря на перший із цих періодичних заходів.",
|
||||
"emailed_you_and_any_other_attendees": "Цю інформацію надіслано вам і всім іншим учасникам.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "Перейти на портал виставлення рахунків",
|
||||
"need_anything_else": "Потрібно щось інше?",
|
||||
"further_billing_help": "Якщо вам потрібна додаткова допомога з виставленням рахунків, наша служба підтримки готова її надати.",
|
||||
"contact_our_support_team": "Зв’язатися зі службою підтримки",
|
||||
"uh_oh": "Отакої!",
|
||||
"no_event_types_have_been_setup": "Цей користувач ще не налаштував жодних типів заходів.",
|
||||
"edit_logo": "Редагувати логотип",
|
||||
@@ -420,6 +421,7 @@
|
||||
"current_incorrect_password": "Поточний пароль неправильний",
|
||||
"password_hint_caplow": "Комбінація великих і малих літер",
|
||||
"password_hint_min": "Щонайменше 8 символів завдовжки",
|
||||
"password_hint_admin_min": "Щонайменше 15 символів",
|
||||
"password_hint_num": "Містить принаймні 1 цифру",
|
||||
"invalid_password_hint": "Пароль має містити не менше ніж 7 символів: принаймні одну цифру та комбінацію великих і малих літер",
|
||||
"incorrect_password": "Пароль неправильний.",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "Підтвердьте свій захід ({{eventTypeTitle}}) із користувачем {{profileName}}",
|
||||
"booking_reschedule_confirmation": "Перенесіть свій захід ({{eventTypeTitle}}) із користувачем {{profileName}}",
|
||||
"in_person_meeting": "Посилання або особиста зустріч",
|
||||
"attendeeInPerson": "Особисто (адреса відвідувача)",
|
||||
"inPerson": "Особисто (адреса організатора)",
|
||||
"link_meeting": "Нарада з посиланням",
|
||||
"phone_call": "Номер телефону учасника",
|
||||
"your_number": "Ваш номер телефону",
|
||||
"phone_number": "Номер телефону",
|
||||
"attendee_phone_number": "Номер телефону учасника",
|
||||
"organizer_phone_number": "Телефон організатора",
|
||||
"host_phone_number": "Ваш номер телефону",
|
||||
"enter_phone_number": "Введіть номер телефону",
|
||||
"reschedule": "Перенести",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "Групова",
|
||||
"collective_description": "Плануйте наради, коли доступні всі вибрані учасники команди.",
|
||||
"duration": "Тривалість",
|
||||
"available_durations": "Доступні варіанти тривалості",
|
||||
"default_duration": "Тривалість за замовчуванням",
|
||||
"default_duration_no_options": "Спочатку виберіть доступні варіанти тривалості",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "Хвилини",
|
||||
"round_robin": "Ротація",
|
||||
"round_robin_description": "Кілька учасників команди призначаються для нарад циклічно й по черзі.",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "Команди",
|
||||
"team": "Команда",
|
||||
"team_billing": "Виставлення рахунків для команд",
|
||||
"team_billing_description": "Керуйте виставленням рахунків у своїй команді",
|
||||
"upgrade_to_flexible_pro_title": "Ми змінили умови оплати для команд",
|
||||
"upgrade_to_flexible_pro_message": "У вашій команді є учасники без придбаних місць. Перейдіть на план Pro, щоб отримати всі потрібні місця.",
|
||||
"changed_team_billing_info": "Станом на січень 2022 року оплата з учасників команди стягується за кількістю місць. Учасників вашої команди, які безкоштовно користувалися функціями Pro, тепер переведено на 14-денні пробні версії. Щойно пробний період завершиться, учасників вашої команди, для яких не придбано план Pro, буде приховано.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "Приховати тип заходу",
|
||||
"edit_location": "Змінити розташування",
|
||||
"into_the_future": "у майбутньому",
|
||||
"when_booked_with_less_than_notice": "Якщо бронювання створено менше ніж за <time></time> до заходу",
|
||||
"within_date_range": "У діапазоні дат",
|
||||
"indefinitely_into_future": "Колись у майбутньому",
|
||||
"add_new_custom_input_field": "Додати нове власне поле введення",
|
||||
@@ -713,6 +724,7 @@
|
||||
"delete_account_confirmation_message": "Справді видалити обліковий запис {{appName}}? Усі, кому ви надавали посилання на свій обліковий запис, більше не зможуть бронювати ваш час за його допомогою. Усі збережені налаштування буде втрачено.",
|
||||
"integrations": "Інтеграції",
|
||||
"apps": "Додатки",
|
||||
"apps_listing": "Список додатків",
|
||||
"category_apps": "Додатки з категорії «{{category}}»",
|
||||
"app_store": "App Store",
|
||||
"app_store_description": "Спілкування та технології на робочому місці.",
|
||||
@@ -736,6 +748,7 @@
|
||||
"toggle_calendars_conflict": "Увімкніть ті календарі, які потрібно перевірити на наявність конфліктів, щоб уникнути подвійних бронювань.",
|
||||
"select_destination_calendar": "Створюйте заходи в календарі",
|
||||
"connect_additional_calendar": "Підключити додатковий календар",
|
||||
"calendar_updated_successfully": "Календар оновлено",
|
||||
"conferencing": "Відеоконференції",
|
||||
"calendar": "Календар",
|
||||
"payments": "Платежі",
|
||||
@@ -768,6 +781,7 @@
|
||||
"trending_apps": "Популярні додатки",
|
||||
"explore_apps": "Додатки з категорії «{{category}}»",
|
||||
"installed_apps": "Установлені додатки",
|
||||
"free_to_use_apps": "Безкоштовні",
|
||||
"no_category_apps": "{{category}} — немає додатків",
|
||||
"no_category_apps_description_calendar": "Додайте додаток для календаря, щоб перевіряти, чи немає конфліктів у розкладі, і уникати подвійних бронювань",
|
||||
"no_category_apps_description_conferencing": "Спробуйте додати додаток для конференцій, щоб інтегрувати можливість відеорозмов зі своїми клієнтами",
|
||||
@@ -806,6 +820,8 @@
|
||||
"verify_wallet": "Пройдіть перевірку гаманця",
|
||||
"connect_metamask": "Підключіть Metamask",
|
||||
"create_events_on": "Створюйте заходи в календарі",
|
||||
"enterprise_license": "Це корпоративна функція",
|
||||
"enterprise_license_description": "Щоб увімкнути цю функцію, отримайте ключ розгортання в консолі {{consoleUrl}} і додайте його у свій файл .env як CALCOM_LICENSE_KEY. Якщо у вашої команди вже є ліцензія, зверніться по допомогу за адресою {{supportMail}}.",
|
||||
"missing_license": "Відсутня ліцензія",
|
||||
"signup_requires": "Потрібна комерційна ліцензія",
|
||||
"signup_requires_description": "{{companyName}} зараз не надає безкоштовну версію сторінки реєстрації з відкритим кодом. Щоб отримати повний доступ до складових функціоналу реєстрації, потрібно придбати комерційну ліцензію. Для особистого використання та створення облікових записів радимо Prisma Data Platform або будь-який інший інтерфейс Postgres.",
|
||||
@@ -897,6 +913,7 @@
|
||||
"user_impersonation_heading": "Виконання ролі користувача",
|
||||
"user_impersonation_description": "Ви можете дозволити нашій команді підтримки тимчасово входити в систему під вашим іменем, щоб швидко вирішувати проблеми, про які ви повідомляєте.",
|
||||
"team_impersonation_description": "Дозвольте адміністраторам своєї команди тимчасово входити під вашим іменем.",
|
||||
"allow_booker_to_select_duration": "Дозволити автору бронювання вибирати тривалість",
|
||||
"impersonate_user_tip": "Усі випадки використання цієї функції підпадають під аудит.",
|
||||
"impersonating_user_warning": "Виконується роль користувача {{user}}.",
|
||||
"impersonating_stop_instructions": "<0>Натисніть тут, щоб зупинити</0>.",
|
||||
@@ -1014,6 +1031,9 @@
|
||||
"error_removing_app": "Не вдалося вилучити додаток",
|
||||
"web_conference": "Вебконференція",
|
||||
"requires_confirmation": "Потрібне підтвердження",
|
||||
"always_requires_confirmation": "Завжди",
|
||||
"requires_confirmation_threshold": "Вимагати підтвердження, якщо бронювання створено менше ніж за {{time}} $t({{unit}}_timeUnit) до заходу",
|
||||
"may_require_confirmation": "Може вимагати підтвердження",
|
||||
"nr_event_type_one": "{{count}} тип заходу",
|
||||
"nr_event_type_other": "Типів заходів: {{count}}",
|
||||
"add_action": "Додати дію",
|
||||
@@ -1101,6 +1121,9 @@
|
||||
"event_limit_tab_description": "Як часто ваш час можуть бронювати",
|
||||
"event_advanced_tab_description": "Налаштування календаря та інше…",
|
||||
"event_advanced_tab_title": "Додатково",
|
||||
"event_setup_multiple_duration_error": "Налаштування заходу: якщо мають бути доступні різні варіанти, потрібно вказати принаймні один.",
|
||||
"event_setup_multiple_duration_default_error": "Налаштування заходу: виберіть припустиму тривалість за замовчуванням.",
|
||||
"event_setup_booking_limits_error": "Ліміти на бронювання мають бути впорядковані за зростанням. [день,тиждень,місяць,рік]",
|
||||
"select_which_cal": "Виберіть календар, у який додаватимуться бронювання",
|
||||
"custom_event_name": "Користувацька назва події",
|
||||
"custom_event_name_description": "Вибирайте для заходів власні назви, що показуватимуться в календарі",
|
||||
@@ -1154,8 +1177,11 @@
|
||||
"invoices": "Рахунки-фактури",
|
||||
"embeds": "Вставки",
|
||||
"impersonation": "Вхід під іншим іменем",
|
||||
"impersonation_description": "Налаштування входу під іншим іменем",
|
||||
"users": "Користувачі",
|
||||
"profile_description": "Керуйте налаштуваннями свого профілю {{appName}}",
|
||||
"users_description": "Тут наведено список усіх користувачів",
|
||||
"users_listing": "Список користувачів",
|
||||
"general_description": "Налаштуйте параметри мови й часового поясу",
|
||||
"calendars_description": "Налаштуйте, як типи заходів мають взаємодіяти з вашими календарями",
|
||||
"appearance_description": "Налаштуйте варіанти оформлення свого бронювання",
|
||||
@@ -1360,6 +1386,7 @@
|
||||
"number_sms_notifications": "Номер телефону (SMS-сповіщення)",
|
||||
"attendee_email_workflow": "Адреса ел. пошти учасника",
|
||||
"attendee_email_info": "Адреса ел. пошти особи, яка бронює",
|
||||
"kbar_search_placeholder": "Введіть команду або пошуковий запис…",
|
||||
"invalid_credential": "Отакої! Схоже, дозвіл більше не дійсний або його відкликано. Перевстановіть додаток знову.",
|
||||
"choose_common_schedule_team_event": "Виберіть спільний розклад",
|
||||
"choose_common_schedule_team_event_description": "Увімкніть цей параметр, щоб використовувати спільний для двох ведучих розклад. Якщо цей параметр вимкнено, бронювання для кожного з ведучих відбуватиметься за їхніми власними графіками.",
|
||||
@@ -1370,5 +1397,43 @@
|
||||
"test_preview": "Перевірити попередній перегляд",
|
||||
"route_to": "Кінцева точка",
|
||||
"test_preview_description": "Перевірте свою форму переспрямування без надсилання даних",
|
||||
"test_routing": "Перевірка переспрямування"
|
||||
"test_routing": "Перевірка переспрямування",
|
||||
"payment_app_disabled": "Додаток для оплати вимкнув адміністратор",
|
||||
"edit_event_type": "Редагувати тип заходу",
|
||||
"collective_scheduling": "Колективне планування",
|
||||
"make_it_easy_to_book": "Просте бронювання у випадках, коли всі члени вашої команди доступні.",
|
||||
"find_the_best_person": "Пошук найкращого доступного члена команди та циклічна ротація між ними.",
|
||||
"fixed_round_robin": "Фіксована циклічна ротація",
|
||||
"add_one_fixed_attendee": "Додавання одного фіксованого учасника та циклічна ротація між кількома учасниками.",
|
||||
"calcom_is_better_with_team": "З Cal.com краще працювати в командах",
|
||||
"add_your_team_members": "Додавайте членів своєї команди в типи заходів. Колективне планування дає змогу включати всіх або знаходити найвідповіднішого члена завдяки циклічній ротації.",
|
||||
"booking_limit_reached": "Для цього типу заходу досягнуто ліміт бронювання",
|
||||
"admin_has_disabled": "Адміністратор вимкнув {{appName}}",
|
||||
"disabled_app_affects_event_type": "Адміністратор вимкнув {{appName}}, що впливає на ваш тип заходу «{{eventType}}»",
|
||||
"disable_payment_app": "Адміністратор вимкнув {{appName}}, що впливає на ваш тип заходу «{{title}}». Учасники все одно можуть бронювати події такого типу, але від них не вимагатиметься оплата. Ви можете приховати цей тип заходу, щоб цього не ставалося, та дочекатися на активацію способу оплати з боку адміністратора.",
|
||||
"payment_disabled_still_able_to_book": "Учасники все одно можуть бронювати події такого типу, але від них не вимагатиметься оплата. Ви можете приховати цей тип заходу, щоб цього не ставалося, та дочекатися на активацію способу оплати з боку адміністратора.",
|
||||
"app_disabled_with_event_type": "Адміністратор вимкнув {{appName}}, що впливає на ваш тип заходу «{{title}}».",
|
||||
"app_disabled_video": "Адміністратор вимкнув {{appName}}, що впливає на ваші типи заходів. Якщо у вас є типи заходів, де {{appName}} визначає розташування, за замовчуванням використовуватиметься Cal Video.",
|
||||
"app_disabled_subject": "{{appName}} вимкнено",
|
||||
"navigate_installed_apps": "Перейти до встановлених додатків",
|
||||
"disabled_calendar": "Якщо ви встановите інший календар, у нього буде додано нові бронювання. Якщо цього не станеться, під’єднайте новий календар, щоб не пропускати нові бронювання.",
|
||||
"enable_apps": "Увімкнення додатків",
|
||||
"enable_apps_description": "Активуйте додатки, які користувачі зможуть інтегрувати з Cal.com",
|
||||
"app_is_enabled": "{{appName}} увімкнено",
|
||||
"app_is_disabled": "{{appName}} вимкнено",
|
||||
"keys_have_been_saved": "Ключі збережено",
|
||||
"disable_app": "Вимкнути додаток",
|
||||
"disable_app_description": "Якщо вимкнути цей додаток, у користувачів можуть виникнути проблеми із роботою з Cal",
|
||||
"edit_keys": "Редагувати ключі",
|
||||
"no_available_apps": "Немає доступних додатків",
|
||||
"no_available_apps_description": "Перевірте, чи в «packages/app-store» є додатки для розгортання",
|
||||
"no_apps": "У цьому екземплярі Cal немає ввімкнених додатків",
|
||||
"apps_settings": "Налаштування додатків",
|
||||
"fill_this_field": "Заповніть це поле",
|
||||
"options": "Варіанти",
|
||||
"enter_option": "Введіть варіант {{index}}",
|
||||
"add_an_option": "Додайте варіант",
|
||||
"radio": "Радіо",
|
||||
"event_type_duplicate_copy_text": "{{slug}}-копія",
|
||||
"set_as_default": "Встановити за замовчуванням"
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
"event_request_cancelled": "Sự kiện của bạn đã bị huỷ",
|
||||
"organizer": "Tổ chức",
|
||||
"need_to_reschedule_or_cancel": "Cần phải đổi lịch hẹn hoặc huỷ?",
|
||||
"cancellation_reason": "Lý do huỷ",
|
||||
"cancellation_reason_placeholder": "Tại sao bạn huỷ? (nếu có)",
|
||||
"cancellation_reason": "Lý do hủy",
|
||||
"cancellation_reason_placeholder": "Lý do bạn muốn hủy?",
|
||||
"rejection_reason": "Lý do từ chối",
|
||||
"rejection_reason_title": "Từ chối lịch hẹn?",
|
||||
"rejection_reason_description": "Bạn có chắc bạn muốn từ chối đặt lịch hẹn? Chúng tôi sẽ cho người đặt biết. Bạn có thể cho người dùng biết lý do từ chối dưới đây.",
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "Một sự kiện vẫn đang chờ được chấp thuận",
|
||||
"event_is_still_waiting": "Lời mời sự kiện vẫn đang chờ: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "Không còn kết quả",
|
||||
"no_results": "Không có kết quả",
|
||||
"load_more_results": "Tải thêm kết quả",
|
||||
"integration_meeting_id": "{{integrationName}} ID buổi hẹn: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "Đã chấp nhận: {{eventType}} với {{name}} tại {{date}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "Thêm vào lịch",
|
||||
"add_another_calendar": "Thêm lịch khác",
|
||||
"other": "Khác",
|
||||
"email_sign_in_subject": "Liên kết đăng nhập cho {{appName}}",
|
||||
"emailed_you_and_attendees": "Chúng tôi đã gửi email cho bạn và những người tham dự khác một lời mời theo lịch hẹn với tất cả các chi tiết đi kèm.",
|
||||
"emailed_you_and_attendees_recurring": "Chúng tôi đã gửi email cho bạn và những người tham dự khác một lời mời theo lịch hẹn cho sự kiện định kỳ đầu tiên trong số những sự kiện định kỳ này.",
|
||||
"emailed_you_and_any_other_attendees": "Bạn và mọi người tham dự khác đã được gửi email với thông tin này.",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "Đi tới cổng thanh toán",
|
||||
"need_anything_else": "Cần gì nữa không?",
|
||||
"further_billing_help": "Nếu bạn cần thêm bất kỳ trợ giúp nào về thanh toán, nhóm hỗ trợ của chúng tôi luôn sẵn sàng trợ giúp.",
|
||||
"contact_our_support_team": "Liên hệ với nhóm hỗ trợ của chúng tôi",
|
||||
"uh_oh": "\bÔi không!",
|
||||
"no_event_types_have_been_setup": "Người dùng này chưa thiết lập bất kỳ loại sự kiện nào.",
|
||||
"edit_logo": "Chỉnh sửa logo",
|
||||
@@ -419,7 +420,8 @@
|
||||
"forgotten_secret_description": "Nếu bạn mất hoặc quên từ bí mật này, bạn có thể đổi nó, nhưng hãy biết cho tất cả mọi tích hợp dùng từ bí mật này sẽ cần được cập nhật",
|
||||
"current_incorrect_password": "Mật khẩu hiện tại không đúng",
|
||||
"password_hint_caplow": "Kết hợp các chữ cái in hoa & in thường",
|
||||
"password_hint_min": "Tối thiểu có 7 ký tự",
|
||||
"password_hint_min": "Dài tối thiểu 8 ký tự",
|
||||
"password_hint_admin_min": "Dài tối thiểu 15 ký tự",
|
||||
"password_hint_num": "Chứa ít nhất 1 con số",
|
||||
"invalid_password_hint": "Mật khẩu phải có tối thiểu 7 ký tự chứa ít nhất một con số và phải kết hợp chữ cái in hoa lẫn in thường",
|
||||
"incorrect_password": "Mật khẩu không đúng.",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "Xác nhận {{eventTypeTitle}} của bạn với {{profileName}}",
|
||||
"booking_reschedule_confirmation": "Lên lịch lại {{eventTypeTitle}} của bạn với {{profileName}}",
|
||||
"in_person_meeting": "Gặp mặt trực tiếp",
|
||||
"attendeeInPerson": "Đích thân (địa chỉ người tham gia)",
|
||||
"inPerson": "Đích thân (địa chỉ người tổ chức)",
|
||||
"link_meeting": "Liên kết cuộc họp",
|
||||
"phone_call": "Số điện thoại của người tham gia",
|
||||
"your_number": "Số điện thoại của bạn",
|
||||
"phone_number": "Số điện thoại",
|
||||
"attendee_phone_number": "Số điện thoại của người tham gia",
|
||||
"organizer_phone_number": "Số điện thoại người tổ chức",
|
||||
"host_phone_number": "Số điện thoại của bạn",
|
||||
"enter_phone_number": "Nhập số điện thoại",
|
||||
"reschedule": "Thay đổi lịch hẹn",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "Tập thể",
|
||||
"collective_description": "Lên lịch họp khi tất cả các thành viên trong nhóm đã chọn đều có mặt.",
|
||||
"duration": "Khoảng thời gian",
|
||||
"available_durations": "Khoảng thời gian khả dụng",
|
||||
"default_duration": "Khoảng thời gian mặc định",
|
||||
"default_duration_no_options": "Vui lòng chọn trước tiên những khoảng thời gian khả dụng",
|
||||
"multiple_duration_mins": "{{count}}$t(minute_timeUnit)",
|
||||
"minutes": "Phút",
|
||||
"round_robin": "Round Robin",
|
||||
"round_robin_description": "Luân phiên những cuộc họp giữa các thành viên trong nhóm.",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "Các nhóm",
|
||||
"team": "Nhóm",
|
||||
"team_billing": "Thanh toán nhóm",
|
||||
"team_billing_description": "Quản lí thanh toán cho đội ngũ của bạn",
|
||||
"upgrade_to_flexible_pro_title": "Chúng tôi đã thay đổi thanh toán cho các nhóm",
|
||||
"upgrade_to_flexible_pro_message": "Có những thành viên trong nhóm của bạn không có gói. Nâng cấp gói PRO của bạn để trang trải những gói bị thiếu.",
|
||||
"changed_team_billing_info": "Kể từ tháng 1 năm 2022, chúng tôi tính phí trên cơ sở từng người cho các thành viên trong nhóm. Các thành viên trong nhóm của bạn mà từng có PRO miễn phí nay sẽ chuyển sang dùng thử 14 ngày. Khi thời gian dùng thử hết hạn, các thành viên này sẽ bị ẩn khỏi nhóm của bạn trừ khi bạn nâng cấp.",
|
||||
@@ -694,6 +704,7 @@
|
||||
"hide_event_type": "Ẩn loại sự kiện",
|
||||
"edit_location": "Chỉnh sửa vị trí",
|
||||
"into_the_future": "trong tương lai",
|
||||
"when_booked_with_less_than_notice": "Khi đặt hẹn với khoảng thời gian thông báo ít hơn <time></time>",
|
||||
"within_date_range": "Trong phạm vi ngày",
|
||||
"indefinitely_into_future": "Vô thời hạn trong tương lai",
|
||||
"add_new_custom_input_field": "Thêm trường tùy chỉnh mới",
|
||||
@@ -713,6 +724,7 @@
|
||||
"delete_account_confirmation_message": "Bạn có chắc chắn muốn xóa tài khoản {{appName}} của mình không? Bất kỳ ai mà bạn đã chia sẻ liên kết tài khoản của mình sẽ không thể đặt trước bằng liên kết đó nữa và mọi tùy chọn bạn đã lưu sẽ bị mất.",
|
||||
"integrations": "Tích hợp",
|
||||
"apps": "Ứng dụng",
|
||||
"apps_listing": "Danh sách ứng dụng",
|
||||
"category_apps": "Ứng dụng {{category}}",
|
||||
"app_store": "Cửa hàng ứng dụng",
|
||||
"app_store_description": "Kết nối con người, công nghệ và nơi làm việc.",
|
||||
@@ -736,6 +748,7 @@
|
||||
"toggle_calendars_conflict": "Bật lịch mà bạn muốn kiểm tra trùng ngày để tránh đặt lịch hẹn trùng.",
|
||||
"select_destination_calendar": "Tạo sự kiện trên",
|
||||
"connect_additional_calendar": "Kết nối lịch bổ sung",
|
||||
"calendar_updated_successfully": "Đã cập nhật lịch thành công",
|
||||
"conferencing": "Hội nghị",
|
||||
"calendar": "Lịch",
|
||||
"payments": "Thanh toán",
|
||||
@@ -768,6 +781,7 @@
|
||||
"trending_apps": "Ứng dụng thịnh hành",
|
||||
"explore_apps": "{{category}} ứng dụng",
|
||||
"installed_apps": "Ứng dụng đã cài đặt",
|
||||
"free_to_use_apps": "Miễn phí",
|
||||
"no_category_apps": "Không có ứng dụng {{category}}",
|
||||
"no_category_apps_description_calendar": "Thêm một ứng dụng lịch để kiểm tra xung đột nhằm tránh đặt lịch hẹn trùng",
|
||||
"no_category_apps_description_conferencing": "Thử thêm vào một ứng dụng hội nghị để hợp nhất cuộc gọi video với khách hàng của bạn",
|
||||
@@ -784,7 +798,7 @@
|
||||
"analytics": "Phân tích",
|
||||
"empty_installed_apps_headline": "Chưa cài ứng dụng nào",
|
||||
"empty_installed_apps_description": "Ứng dụng cho phép bạn cải thiện tiến độ công việc và cải thiện đáng kể việc sắp xếp tổ chức.",
|
||||
"empty_installed_apps_button": "Khám phá App Store hoặc Cài đặt các ứng dụng dưới đây",
|
||||
"empty_installed_apps_button": "Duyệt xem App Store",
|
||||
"manage_your_connected_apps": "Quản lý các ứng dụng đã cài đặt của bạn hoặc thay đổi cài đặt",
|
||||
"browse_apps": "Xem ứng dụng",
|
||||
"features": "Tính năng",
|
||||
@@ -806,6 +820,8 @@
|
||||
"verify_wallet": "Xác minh Ví",
|
||||
"connect_metamask": "Kết nối Metamask",
|
||||
"create_events_on": "Tạo sự kiện trên",
|
||||
"enterprise_license": "Đây là tính năng doanh nghiệp",
|
||||
"enterprise_license_description": "Để bật tính năng này, nhận khoá triển khai tại console {{consoleUrl}} và thêm nó vào .env của bạn ở dạng CALCOM_LICENSE_KEY. Nếu nhóm của bạn đã có giấy phép, vui lòng liên hệ {{supportMail}} để được trợ giúp.",
|
||||
"missing_license": "Giấy phép bị thiếu",
|
||||
"signup_requires": "Yêu cầu giấy phép thương mại",
|
||||
"signup_requires_description": "{{companyName}} hiện không cung cấp phiên bản nguồn mở miễn phí của trang đăng ký. Để nhận toàn quyền truy cập vào các thành phần đăng ký, bạn cần có giấy phép thương mại. Đối với mục đích sử dụng cá nhân, chúng tôi khuyên bạn nên sử dụng Nền tảng dữ liệu Prisma hoặc bất kỳ giao diện Postgres nào khác để tạo tài khoản.",
|
||||
@@ -897,6 +913,7 @@
|
||||
"user_impersonation_heading": "Mạo danh người dùng",
|
||||
"user_impersonation_description": "Cho phép đội ngũ hỗ trợ tạm thời đăng nhập với tư cách là bạn nhằm giúp chúng tôi nhanh chóng giải quyết mọi vấn đề mà bạn báo cáo cho chúng tôi.",
|
||||
"team_impersonation_description": "Cho phép các quản trị viên của nhóm bạn tạm thời đăng nhập bằng danh tính của bạn.",
|
||||
"allow_booker_to_select_duration": "Cho phép người đặt hẹn chọn khoảng thời gian",
|
||||
"impersonate_user_tip": "Tất cả những lần dùng tính năng này đều bị kiểm toán.",
|
||||
"impersonating_user_warning": "Đang mạo danh tên người dùng \"{{user}}\".",
|
||||
"impersonating_stop_instructions": "<0>Nhấp vào đây để ngừng lại</0>.",
|
||||
@@ -1014,6 +1031,9 @@
|
||||
"error_removing_app": "Lỗi khi gỡ bỏ ứng dụng",
|
||||
"web_conference": "Hội nghị web",
|
||||
"requires_confirmation": "Yêu cầu xác nhận",
|
||||
"always_requires_confirmation": "Luôn luôn",
|
||||
"requires_confirmation_threshold": "Cần xác nhận nếu đặt hẹn với thông báo trước chưa đầy {{time}}$t({{unit}}_timeUnit)",
|
||||
"may_require_confirmation": "Có thể yêu cầu xác nhận",
|
||||
"nr_event_type_one": "{{count}} loại sự kiện",
|
||||
"nr_event_type_other": "{{count}} loại sự kiện",
|
||||
"add_action": "Thêm hoạt động",
|
||||
@@ -1101,6 +1121,9 @@
|
||||
"event_limit_tab_description": "Bạn có thể được đặt lịch bao lần",
|
||||
"event_advanced_tab_description": "Cài đặt cho lịch & nhiều tính năng khác...",
|
||||
"event_advanced_tab_title": "Nâng cao",
|
||||
"event_setup_multiple_duration_error": "Thiết lập sự kiện: Nhiều khoảng thời gian cần ít nhất 1 tuỳ chọn.",
|
||||
"event_setup_multiple_duration_default_error": "Thiết lập sự kiện: Vui lòng chọn một khoảng thời gian mặc định hợp lệ.",
|
||||
"event_setup_booking_limits_error": "Giới hạn lịch hẹn phải theo thứ tự tăng dần. [day,week,month,year]",
|
||||
"select_which_cal": "Chọn lịch nào cần thêm lịch hẹn vào",
|
||||
"custom_event_name": "Tên sự kiện tuỳ chỉnh",
|
||||
"custom_event_name_description": "Tạo những tên sự kiện tuỳ chỉnh để hiển thị ở phần sự kiện lịch",
|
||||
@@ -1154,8 +1177,11 @@
|
||||
"invoices": "Hoá đơn",
|
||||
"embeds": "Nhúng",
|
||||
"impersonation": "Mạo danh",
|
||||
"impersonation_description": "Cài đặt để quản lý mạo danh người dùng",
|
||||
"users": "Người dùng",
|
||||
"profile_description": "Quản lí cài đặt cho hồ sơ {{appName}} của bạn",
|
||||
"users_description": "Tại đây bạn có thể tìm thấy danh sách tất cả người dùng",
|
||||
"users_listing": "Danh sách người dùng",
|
||||
"general_description": "Quản lí cài đặt cho ngôn ngữ và múi giờ của bạn",
|
||||
"calendars_description": "Cấu hình cách các loại sự kiện của bạn tương tác với lịch của bạn",
|
||||
"appearance_description": "Quản lí cài đặt cho giao diện lịch hẹn của bạn",
|
||||
@@ -1356,19 +1382,24 @@
|
||||
"must_enter_team_name": "Cần phải nhập một tên nhóm",
|
||||
"team_url_required": "Cần phải nhập một URL của nhóm",
|
||||
"team_url_taken": "URL này đã có người lấy rồi",
|
||||
"team_publish": "Công bố nhóm",
|
||||
"team_publish": "Đăng nhóm",
|
||||
"number_sms_notifications": "Số điện thoại (thông báo SMS)",
|
||||
"attendee_email_workflow": "Email người tham dự",
|
||||
"attendee_email_info": "Email người tham gia lịch hẹn",
|
||||
"kbar_search_placeholder": "Nhập một lệnh hoặc tìm kiếm...",
|
||||
"invalid_credential": "Ôi không! Có vẻ như quyền đã hết hạn hoặc đã bị thu hồi. Vui lòng cài đặt lại.",
|
||||
"choose_common_schedule_team_event": "Chọn một lịch chung",
|
||||
"choose_common_schedule_team_event_description": "Bật cái này nếu bạn muốn dùng lịch thông thường giữa các chủ sự kiện. Khi tắt đi, mỗi chủ sự kiện sẽ được đặt lịch theo lịch mặc định của họ.",
|
||||
"choose_common_schedule_team_event_description": "Bật mục này nếu bạn muốn dùng lịch thông thường giữa các chủ sự kiện. Khi tắt đi, mỗi chủ sự kiện sẽ được đặt lịch theo lịch mặc định của họ.",
|
||||
"reason": "Lý do",
|
||||
"sender_id": "ID người gửi",
|
||||
"sender_id_error_message": "Chỉ chữ cái, số và khoảng trắng là được phép (tối đa 11 ký tự)",
|
||||
"sender_id_error_message": "Chỉ được phép sử dụng chữ cái, số và khoảng trắng (tối đa 11 ký tự)",
|
||||
"test_routing_form": "Kiểm tra Biểu mẫu định hướng",
|
||||
"test_preview": "Kiểm tra Xem trước",
|
||||
"route_to": "Định hướng đến",
|
||||
"test_preview_description": "Kiểm tra biểu mẫu định hướng mà không cần gửi bất kỳ dữ liệu nào",
|
||||
"test_routing": "Kiểm tra định hướng"
|
||||
"test_routing": "Kiểm tra định hướng",
|
||||
"payment_app_disabled": "Một quản trị viên đã vô hiệu hoá một ứng dụng thanh toán",
|
||||
"edit_event_type": "Sửa loại sự kiện",
|
||||
"collective_scheduling": "Lên lịch tập thể",
|
||||
"admin_apps_description": "Bật các ứng dụng cho thực thể Cal của bạn"
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
"still_waiting_for_approval": "有活动正在等待您的批准",
|
||||
"event_is_still_waiting": "活动请求仍在等待中: {{attendeeName}} - {{date}} - {{eventType}}",
|
||||
"no_more_results": "无更多结果",
|
||||
"no_results": "无结果",
|
||||
"load_more_results": "加载更多结果",
|
||||
"integration_meeting_id": "{{integrationName}} 会议 ID: {{meetingId}}",
|
||||
"confirmed_event_type_subject": "已确认: 和 {{name}} 在 {{date}} 的 {{eventType}}",
|
||||
@@ -248,6 +249,7 @@
|
||||
"add_to_calendar": "添加到日历",
|
||||
"add_another_calendar": "添加另一个日历",
|
||||
"other": "其他",
|
||||
"email_sign_in_subject": "您的 {{appName}} 登录链接",
|
||||
"emailed_you_and_attendees": "我们通过电子邮件给您和其他参与者发送了一份包含所有详细信息的日历邀请。",
|
||||
"emailed_you_and_attendees_recurring": "我们通过电子邮件给您和其他参与者发送了第一次定期活动的日历邀请。",
|
||||
"emailed_you_and_any_other_attendees": "已向您和其他参与者发送了关于此信息的电子邮件",
|
||||
@@ -383,7 +385,6 @@
|
||||
"go_to_billing_portal": "转到账单门户网站",
|
||||
"need_anything_else": "还有其他需要?",
|
||||
"further_billing_help": "如果您在支付帐单时需要任何进一步的帮助,我们的支持团队会给您提供帮助。",
|
||||
"contact_our_support_team": "联系我们的支持团队",
|
||||
"uh_oh": "糟糕!",
|
||||
"no_event_types_have_been_setup": "此用户尚未设置任何活动类型。",
|
||||
"edit_logo": "编辑标志",
|
||||
@@ -420,6 +421,7 @@
|
||||
"current_incorrect_password": "当前密码不正确",
|
||||
"password_hint_caplow": "大写和小写字母混合",
|
||||
"password_hint_min": "至少 8 个字符长",
|
||||
"password_hint_admin_min": "至少 15 个字符长",
|
||||
"password_hint_num": "包含至少 1 个数字",
|
||||
"invalid_password_hint": "密码必须是至少 7 个字符长,包含至少一个数字,并且是大写和小写字母混合",
|
||||
"incorrect_password": "密码不正确。",
|
||||
@@ -463,11 +465,14 @@
|
||||
"booking_confirmation": "确认您和 {{profileName}} 的 {{eventTypeTitle}}",
|
||||
"booking_reschedule_confirmation": "重新安排您和 {{profileName}} 的 {{eventTypeTitle}}",
|
||||
"in_person_meeting": "线上或线下会议",
|
||||
"attendeeInPerson": "本人(参与者地址)",
|
||||
"inPerson": "本人(组织者地址)",
|
||||
"link_meeting": "线上会议",
|
||||
"phone_call": "参与者电话号码",
|
||||
"your_number": "您的电话号码",
|
||||
"phone_number": "电话号码",
|
||||
"attendee_phone_number": "参与者电话号码",
|
||||
"organizer_phone_number": "组织者电话号码",
|
||||
"host_phone_number": "您的电话号码",
|
||||
"enter_phone_number": "输入电话号码",
|
||||
"reschedule": "重新安排",
|
||||
@@ -554,6 +559,10 @@
|
||||
"collective": "集体模式",
|
||||
"collective_description": "当所有选定的团队成员都可预约时安排会议。",
|
||||
"duration": "时长",
|
||||
"available_durations": "可用时长",
|
||||
"default_duration": "默认时长",
|
||||
"default_duration_no_options": "请先选择可用时长",
|
||||
"multiple_duration_mins": "{{count}} $t(minute_timeUnit)",
|
||||
"minutes": "分钟",
|
||||
"round_robin": "轮流模式",
|
||||
"round_robin_description": "和多个团队成员之间轮流举行会议。",
|
||||
@@ -619,6 +628,7 @@
|
||||
"teams": "团队",
|
||||
"team": "团队",
|
||||
"team_billing": "团队计费",
|
||||
"team_billing_description": "管理您团队的计费",
|
||||
"upgrade_to_flexible_pro_title": "我们更改了团队的计费方式",
|
||||
"upgrade_to_flexible_pro_message": "您的团队中有没有位置的成员。升级到专业版来获得更多位置。",
|
||||
"changed_team_billing_info": "自2022年1月起,我们将按每个位置向团队成员收取费用。 您的团队中免费获得专业版的成员现在正在进行为期14天的试用。 试用期结束后,这些成员将在您的团队中隐藏,除非您现在升级到专业版。",
|
||||
@@ -713,6 +723,8 @@
|
||||
"delete_account_confirmation_message": "您确定要删除您的 {{appName}} 账户? 任何曾通过您的账户链接与您预约过的人都将无法再使用它和您预约,您保存的任何偏好设置都将丢失。",
|
||||
"integrations": "集成",
|
||||
"apps": "应用",
|
||||
"apps_description": "为您的 Cal 实例启用应用",
|
||||
"apps_listing": "应用列表",
|
||||
"category_apps": "{{category}}应用",
|
||||
"app_store": "应用商店",
|
||||
"app_store_description": "连接人员、技术和工作场所。",
|
||||
@@ -736,6 +748,7 @@
|
||||
"toggle_calendars_conflict": "切换要检查冲突的日历,以防止重复预约。",
|
||||
"select_destination_calendar": "创建活动于",
|
||||
"connect_additional_calendar": "连接其他日历",
|
||||
"calendar_updated_successfully": "日历已成功更新",
|
||||
"conferencing": "会议",
|
||||
"calendar": "日历",
|
||||
"payments": "付款",
|
||||
@@ -768,6 +781,7 @@
|
||||
"trending_apps": "热门应用",
|
||||
"explore_apps": "{{category}}应用",
|
||||
"installed_apps": "已安装的应用",
|
||||
"free_to_use_apps": "免费",
|
||||
"no_category_apps": "无{{category}}应用",
|
||||
"no_category_apps_description_calendar": "添加日历应用以检查冲突,防止重复预约",
|
||||
"no_category_apps_description_conferencing": "尝试添加会议应用以整合与客户的视频通话",
|
||||
@@ -806,6 +820,8 @@
|
||||
"verify_wallet": "验证钱包",
|
||||
"connect_metamask": "连接元掩码",
|
||||
"create_events_on": "活动创建于:",
|
||||
"enterprise_license": "这是企业版功能",
|
||||
"enterprise_license_description": "要启用此功能,请在 {{consoleUrl}} 控制台获取一个部署密钥,并将其添加到您的 .env 中作为 CALCOM_LICENSE_KEY。如果您的团队已经有许可证,请联系 {{supportMail}} 获取帮助。",
|
||||
"missing_license": "缺少许可证",
|
||||
"signup_requires": "需要商业许可证",
|
||||
"signup_requires_description": "{{companyName}} 免费开源版目前不提供的注册页面。 要获得对注册页面组件的完全访问权,您需要获得商业许可证。 对于个人使用用途,我们推荐使用Prisma 数据平台或任何其他Postgres接口创建账户。",
|
||||
@@ -897,6 +913,7 @@
|
||||
"user_impersonation_heading": "用户模拟",
|
||||
"user_impersonation_description": "允许我们的支持团队临时以您的身份登录,帮助我们快速解决您报告给我们的问题。",
|
||||
"team_impersonation_description": "允许您的团队成员以您的身份临时登录。",
|
||||
"allow_booker_to_select_duration": "允许预约者选择时长",
|
||||
"impersonate_user_tip": "此功能的所有使用都已审核。",
|
||||
"impersonating_user_warning": "正在模拟用户名“{{user}}”。",
|
||||
"impersonating_stop_instructions": "<0>点击此处停止</0>。",
|
||||
@@ -1014,6 +1031,8 @@
|
||||
"error_removing_app": "删除应用时出错",
|
||||
"web_conference": "网络会议",
|
||||
"requires_confirmation": "需要确认",
|
||||
"always_requires_confirmation": "始终",
|
||||
"may_require_confirmation": "可能需要确认",
|
||||
"nr_event_type_one": "{{count}} 种活动类型",
|
||||
"nr_event_type_other": "{{count}} 种活动类型",
|
||||
"add_action": "添加操作",
|
||||
@@ -1101,6 +1120,9 @@
|
||||
"event_limit_tab_description": "您多久可被预约一次",
|
||||
"event_advanced_tab_description": "日历设置及更多...",
|
||||
"event_advanced_tab_title": "高级",
|
||||
"event_setup_multiple_duration_error": "活动设置: 多个时长需要至少 1 个选项。",
|
||||
"event_setup_multiple_duration_default_error": "活动设置: 请选择有效的默认时长。",
|
||||
"event_setup_booking_limits_error": "预约限制必须按升序排列。[日,周,月,年]",
|
||||
"select_which_cal": "选择要添加预约的日历",
|
||||
"custom_event_name": "自定义活动名称",
|
||||
"custom_event_name_description": "创建要在日历活动上显示的自定义活动名称",
|
||||
@@ -1154,8 +1176,11 @@
|
||||
"invoices": "发票",
|
||||
"embeds": "嵌入项",
|
||||
"impersonation": "模拟",
|
||||
"impersonation_description": "用于管理用户模拟的设置",
|
||||
"users": "用户",
|
||||
"profile_description": "管理您的 {{appName}} 个人资料的设置",
|
||||
"users_description": "在这里可以找到所有用户的列表",
|
||||
"users_listing": "用户列表",
|
||||
"general_description": "管理语言和时区的设置",
|
||||
"calendars_description": "配置您的活动类型与日历的交互方式",
|
||||
"appearance_description": "管理预约页面外观的设置",
|
||||
@@ -1360,6 +1385,7 @@
|
||||
"number_sms_notifications": "电话号码(短信通知)",
|
||||
"attendee_email_workflow": "参与者电子邮件",
|
||||
"attendee_email_info": "预约人的电子邮件",
|
||||
"kbar_search_placeholder": "输入命令或搜索...",
|
||||
"invalid_credential": "哦不!看起来权限已过期或被撤销。请重新安装。",
|
||||
"choose_common_schedule_team_event": "选择通用时间表",
|
||||
"choose_common_schedule_team_event_description": "如果您希望在主持人之间使用通用时间表,请启用此选项。如果禁用,将根据主持人的默认时间表预约每个主持人。",
|
||||
@@ -1370,5 +1396,36 @@
|
||||
"test_preview": "测试预览",
|
||||
"route_to": "根据途径找到",
|
||||
"test_preview_description": "测试途径表格而不提交任何数据",
|
||||
"test_routing": "测试途径"
|
||||
"test_routing": "测试途径",
|
||||
"payment_app_disabled": "管理员已禁用支付应用",
|
||||
"edit_event_type": "编辑活动类型",
|
||||
"collective_scheduling": "集体日程安排",
|
||||
"fixed_round_robin": "固定轮流模式",
|
||||
"calcom_is_better_with_team": "Cal.com 更适合团队",
|
||||
"admin_has_disabled": "管理员已禁用 {{appName}}",
|
||||
"disabled_app_affects_event_type": "管理员已禁用会影响活动类型 {{eventType}} 的 {{appName}}",
|
||||
"disable_payment_app": "管理员已禁用会影响活动类型 {{title}} 的 {{appName}}。参与者仍然能预约此类型的活动,但不会被提示付款。您可以隐藏该活动类型来防止出现这种情况,直到管理员重新启用您的支付方式。",
|
||||
"payment_disabled_still_able_to_book": "参与者仍然能预约此类型的活动,但不会被提示付款。您可以隐藏该活动类型来防止出现这种情况,直到管理员重新启用您的支付方式。",
|
||||
"app_disabled_with_event_type": "管理员已禁用会影响活动类型 {{title}} 的 {{appName}}。",
|
||||
"app_disabled_video": "管理员已禁用可能会影响活动类型的 {{appName}}。如果您有将 {{appName}} 作为位置的活动类型,则默认为 Cal Video。",
|
||||
"app_disabled_subject": "{{appName}} 已被禁用",
|
||||
"navigate_installed_apps": "转到已安装的应用",
|
||||
"enable_apps": "启用应用",
|
||||
"enable_apps_description": "启用用户可以与 Cal.com 集成的应用",
|
||||
"app_is_enabled": "{{appName}} 已启用",
|
||||
"app_is_disabled": "{{appName}} 已禁用",
|
||||
"keys_have_been_saved": "密钥已保存",
|
||||
"disable_app": "禁用应用",
|
||||
"disable_app_description": "禁用此应用可能会导致您的用户与 Cal 的交互方式出现问题",
|
||||
"edit_keys": "编辑密钥",
|
||||
"admin_apps_description": "为您的 Cal 实例启用应用",
|
||||
"no_available_apps": "没有可用的应用",
|
||||
"no_available_apps_description": "请确保您在“packages/app-store”下的部署中有应用",
|
||||
"no_apps": "此 Cal 实例中未启用任何应用",
|
||||
"apps_settings": "应用设置",
|
||||
"fill_this_field": "请填写此字段",
|
||||
"options": "选项",
|
||||
"enter_option": "输入选项 {{index}}",
|
||||
"add_an_option": "添加选项",
|
||||
"set_as_default": "设置为默认"
|
||||
}
|
||||
|
||||
@@ -383,7 +383,6 @@
|
||||
"go_to_billing_portal": "前往付費入口",
|
||||
"need_anything_else": "還要什麼嗎?",
|
||||
"further_billing_help": "如果有關於付費的進一步需求,我們的支援團隊隨時上前幫忙。",
|
||||
"contact_our_support_team": "聯繫支援團隊",
|
||||
"uh_oh": "哎呦喂呀!",
|
||||
"no_event_types_have_been_setup": "使用者尚未設定任何活動類型。",
|
||||
"edit_logo": "編輯標誌",
|
||||
|
||||
|
After Width: | Height: | Size: 697 KiB |
@@ -432,6 +432,11 @@ hr {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.react-date-picker__inputGroup__input {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
/* animations */
|
||||
.slideInBottom {
|
||||
animation-duration: 0.3s;
|
||||
|
||||
@@ -10,6 +10,7 @@ const HAWAII_AND_NEWYORK_TEAM = [
|
||||
timeZone: "America/Detroit", // GMT -4 per 22th of Aug, 2022
|
||||
workingHours: [{ days: [1, 2, 3, 4, 5], startTime: 780, endTime: 1260 }],
|
||||
busy: [],
|
||||
dateOverrides: [],
|
||||
},
|
||||
{
|
||||
timeZone: "Pacific/Honolulu", // GMT -10 per 22th of Aug, 2022
|
||||
@@ -20,6 +21,7 @@ const HAWAII_AND_NEWYORK_TEAM = [
|
||||
{ days: [5], startTime: 780, endTime: 1439 },
|
||||
],
|
||||
busy: [],
|
||||
dateOverrides: [],
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useAutoAnimate } from "@formkit/auto-animate/react";
|
||||
import { useMemo } from "react";
|
||||
|
||||
import { classNames } from "@calcom/lib";
|
||||
@@ -17,16 +18,19 @@ const AppCategoryNavigation = ({
|
||||
className?: string;
|
||||
}) => {
|
||||
const appCategories = useMemo(() => getAppCategories(baseURL), [baseURL]);
|
||||
const [animationRef] = useAutoAnimate<HTMLDivElement>();
|
||||
|
||||
return (
|
||||
<div className={classNames("flex flex-col p-2 md:p-0 xl:flex-row", className)}>
|
||||
<div className="hidden xl:block">
|
||||
<VerticalTabs tabs={appCategories} sticky linkProps={{ shallow: true }} />
|
||||
</div>
|
||||
<div className="block overflow-x-scroll xl:hidden">
|
||||
<div className="mb-4 block overflow-x-scroll xl:hidden">
|
||||
<HorizontalTabs tabs={appCategories} linkProps={{ shallow: true }} />
|
||||
</div>
|
||||
<main className={containerClassname}>{children}</main>
|
||||
<main className={containerClassname} ref={animationRef}>
|
||||
{children}
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ import { metadata as stripepayment_meta } from "./stripepayment/_metadata";
|
||||
import { metadata as tandemvideo_meta } from "./tandemvideo/_metadata";
|
||||
import { metadata as telegram_meta } from "./telegram/_metadata";
|
||||
import { metadata as typeform_meta } from "./typeform/_metadata";
|
||||
import { metadata as vimcal_meta } from "./vimcal/_metadata";
|
||||
import { metadata as vital_meta } from "./vital/_metadata";
|
||||
import { metadata as weather_in_your_calendar_meta } from "./weather_in_your_calendar/_metadata";
|
||||
import { metadata as whatsapp_meta } from "./whatsapp/_metadata";
|
||||
@@ -86,6 +87,7 @@ export const appStoreMetadata = {
|
||||
tandemvideo: tandemvideo_meta,
|
||||
telegram: telegram_meta,
|
||||
typeform: typeform_meta,
|
||||
vimcal: vimcal_meta,
|
||||
vital: vital_meta,
|
||||
weather_in_your_calendar: weather_in_your_calendar_meta,
|
||||
whatsapp: whatsapp_meta,
|
||||
|
||||
@@ -38,6 +38,7 @@ export const apiHandlers = {
|
||||
tandemvideo: import("./tandemvideo/api"),
|
||||
telegram: import("./telegram/api"),
|
||||
typeform: import("./typeform/api"),
|
||||
vimcal: import("./vimcal/api"),
|
||||
vital: import("./vital/api"),
|
||||
weather_in_your_calendar: import("./weather_in_your_calendar/api"),
|
||||
whatsapp: import("./whatsapp/api"),
|
||||
|
||||
@@ -40,8 +40,22 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
await prisma.credential.create({
|
||||
data,
|
||||
});
|
||||
} catch (reason) {
|
||||
logger.error("Could not add this caldav account", reason);
|
||||
} catch (e) {
|
||||
logger.error("Could not add this caldav account", e);
|
||||
if (e instanceof Error) {
|
||||
let message = e.message;
|
||||
if (e.message.indexOf("Invalid credentials") > -1 && url.indexOf("dav.php") > -1) {
|
||||
const parsedUrl = new URL(url);
|
||||
const adminUrl =
|
||||
parsedUrl.protocol +
|
||||
"//" +
|
||||
parsedUrl.hostname +
|
||||
(parsedUrl.port ? ":" + parsedUrl.port : "") +
|
||||
"/admin/?/settings/standard/";
|
||||
message = `Couldn\'t connect to caldav account, please verify WebDAV authentication type is set to "Basic"`;
|
||||
return res.status(500).json({ message, actionUrl: adminUrl });
|
||||
}
|
||||
}
|
||||
return res.status(500).json({ message: "Could not add this caldav account" });
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ export default function CalDavCalendarSetup() {
|
||||
});
|
||||
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
const [errorActionUrl, setErrorActionUrl] = useState("");
|
||||
|
||||
return (
|
||||
<div className="flex h-screen bg-gray-200">
|
||||
@@ -49,6 +50,9 @@ export default function CalDavCalendarSetup() {
|
||||
const json = await res.json();
|
||||
if (!res.ok) {
|
||||
setErrorMessage(json?.message || t("something_went_wrong"));
|
||||
if (json.actionUrl) {
|
||||
setErrorActionUrl(json.actionUrl);
|
||||
}
|
||||
} else {
|
||||
router.push(json.url);
|
||||
}
|
||||
@@ -78,7 +82,24 @@ export default function CalDavCalendarSetup() {
|
||||
/>
|
||||
</fieldset>
|
||||
|
||||
{errorMessage && <Alert severity="error" title={errorMessage} className="my-4" />}
|
||||
{errorMessage && (
|
||||
<Alert
|
||||
severity="error"
|
||||
title={errorMessage}
|
||||
actions={
|
||||
errorActionUrl !== "" ? (
|
||||
<Button
|
||||
href={errorActionUrl}
|
||||
color="secondary"
|
||||
target="_blank"
|
||||
className="ml-5 w-32 !p-5">
|
||||
Go to Admin
|
||||
</Button>
|
||||
) : undefined
|
||||
}
|
||||
className="my-4"
|
||||
/>
|
||||
)}
|
||||
<div className="mt-5 justify-end space-x-2 sm:mt-4 sm:flex">
|
||||
<Button type="button" color="secondary" onClick={() => router.back()}>
|
||||
{t("cancel")}
|
||||
|
||||
@@ -135,7 +135,7 @@ export const FormActionsDropdown = ({ form, children }: { form: RoutingForm; chi
|
||||
return (
|
||||
<dropdownCtx.Provider value={{ dropdown: true }}>
|
||||
<Dropdown>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<DropdownMenuTrigger data-testid="form-dropdown" asChild>
|
||||
<Button
|
||||
type="button"
|
||||
size="icon"
|
||||
|
||||
@@ -120,6 +120,7 @@ const Actions = ({
|
||||
{typeformApp?.isInstalled ? (
|
||||
<FormActionsDropdown form={form}>
|
||||
<FormAction
|
||||
data-testid="copy-redirect-url"
|
||||
routingForm={form}
|
||||
action="copyRedirectUrl"
|
||||
color="minimal"
|
||||
@@ -172,6 +173,7 @@ const Actions = ({
|
||||
</FormAction>
|
||||
{typeformApp ? (
|
||||
<FormAction
|
||||
data-testid="copy-redirect-url"
|
||||
routingForm={form}
|
||||
action="copyRedirectUrl"
|
||||
color="minimal"
|
||||
|
||||
@@ -131,6 +131,7 @@ export default function RoutingForms({
|
||||
</FormAction>
|
||||
{typeformApp?.isInstalled ? (
|
||||
<FormAction
|
||||
data-testid="copy-redirect-url"
|
||||
routingForm={form}
|
||||
action="copyRedirectUrl"
|
||||
color="minimal"
|
||||
|
||||
@@ -8,7 +8,7 @@ async function gotoRoutingLink(page: Page, formId: string) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
}
|
||||
|
||||
async function addForm(page: Page) {
|
||||
export async function addForm(page: Page) {
|
||||
await page.click('[data-testid="new-routing-form"]');
|
||||
await page.fill("input[name]", "Test Form Name");
|
||||
await page.click('[data-testid="add-form"]');
|
||||
@@ -41,7 +41,7 @@ async function verifySelectOptions(
|
||||
};
|
||||
}
|
||||
|
||||
async function fillForm(
|
||||
export async function fillForm(
|
||||
page: Page,
|
||||
form: { description: string; field?: { typeIndex: number; label: string } }
|
||||
) {
|
||||
|
||||
@@ -20,7 +20,7 @@ export const metadata = {
|
||||
trending: false,
|
||||
url: "https://cal.com/",
|
||||
verified: true,
|
||||
isGlobal: false,
|
||||
isGlobal: true,
|
||||
email: "help@cal.com",
|
||||
appData: {
|
||||
location: {
|
||||
|
||||
@@ -157,13 +157,32 @@ export default class Office365CalendarService implements Calendar {
|
||||
}
|
||||
|
||||
async listCalendars(): Promise<IntegrationCalendar[]> {
|
||||
const response = await this.fetcher(`/me/calendars`);
|
||||
let responseBody = await handleErrorsJson<{ value: OfficeCalendar[] }>(response);
|
||||
// If responseBody is valid then parse the JSON text
|
||||
if (typeof responseBody === "string") {
|
||||
responseBody = JSON.parse(responseBody) as { value: OfficeCalendar[] };
|
||||
const officeCalendars: OfficeCalendar[] = [];
|
||||
// List calendars from MS are paginated
|
||||
let finishedParsingCalendars = false;
|
||||
// Store @odata.nextLink if in response
|
||||
let requestLink = "/me/calendars";
|
||||
|
||||
while (!finishedParsingCalendars) {
|
||||
const response = await this.fetcher(requestLink);
|
||||
let responseBody = await handleErrorsJson<{ value: OfficeCalendar[]; "@odata.nextLink"?: string }>(
|
||||
response
|
||||
);
|
||||
// If responseBody is valid then parse the JSON text
|
||||
if (typeof responseBody === "string") {
|
||||
responseBody = JSON.parse(responseBody) as { value: OfficeCalendar[] };
|
||||
}
|
||||
|
||||
officeCalendars.push(...responseBody.value);
|
||||
|
||||
if (responseBody["@odata.nextLink"]) {
|
||||
requestLink = responseBody["@odata.nextLink"].replace(this.apiGraphUrl, "");
|
||||
} else {
|
||||
finishedParsingCalendars = true;
|
||||
}
|
||||
}
|
||||
return responseBody?.value.map((cal: OfficeCalendar) => {
|
||||
|
||||
return officeCalendars.map((cal: OfficeCalendar) => {
|
||||
const calendar: IntegrationCalendar = {
|
||||
externalId: cal.id ?? "No Id",
|
||||
integration: this.integrationName,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"@stripe/stripe-js": "^1.35.0",
|
||||
"stripe": "^9.16.0",
|
||||
"uuid": "^8.3.2",
|
||||
"zod": "^3.19.1"
|
||||
"zod": "^3.20.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@calcom/types": "*",
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import { Page, expect } from "@playwright/test";
|
||||
|
||||
import {
|
||||
addForm as addRoutingForm,
|
||||
fillForm as fillRoutingForm,
|
||||
} from "@calcom/app-store/ee/routing-forms/playwright/tests/basic.e2e";
|
||||
import { CAL_URL } from "@calcom/lib/constants";
|
||||
import { Fixtures, test } from "@calcom/web/playwright/lib/fixtures";
|
||||
|
||||
const installApps = async (page: Page, users: Fixtures["users"]) => {
|
||||
const user = await users.create({ username: "routing-forms" });
|
||||
await user.login();
|
||||
await page.goto(`/apps/routing-forms`);
|
||||
await page.click('[data-testid="install-app-button"]');
|
||||
await page.waitForNavigation({
|
||||
url: (url) => url.pathname === `/apps/routing-forms/forms`,
|
||||
});
|
||||
await page.goto(`/apps/typeform`);
|
||||
await page.click('[data-testid="install-app-button"]');
|
||||
await page.waitForNavigation({
|
||||
url: (url) => url.pathname === `/apps/typeform/how-to-use`,
|
||||
});
|
||||
};
|
||||
|
||||
test.describe("Typeform App", () => {
|
||||
test.afterEach(async ({ users }) => {
|
||||
// This also delete forms on cascade
|
||||
await users.deleteAll();
|
||||
});
|
||||
|
||||
test.describe("Typeform Redirect Link", () => {
|
||||
test("should copy link in editing area", async ({ page, context, users }) => {
|
||||
await installApps(page, users);
|
||||
context.grantPermissions(["clipboard-read", "clipboard-write"]);
|
||||
|
||||
await page.goto(`/apps/routing-forms/forms`);
|
||||
const formId = await addRoutingForm(page);
|
||||
await fillRoutingForm(page, {
|
||||
description: "",
|
||||
field: { label: "test", typeIndex: 1 },
|
||||
});
|
||||
|
||||
await page.click('[data-testid="form-dropdown"]');
|
||||
await page.click('[data-testid="copy-redirect-url"]');
|
||||
const text = await page.evaluate(async () => {
|
||||
return navigator.clipboard.readText();
|
||||
});
|
||||
expect(text).toBe(`${CAL_URL}/router?form=${formId}&test={Recalled_Response_For_This_Field}`);
|
||||
});
|
||||
|
||||
test("should copy link in RoutingForms list", async ({ page, context, users }) => {
|
||||
await installApps(page, users);
|
||||
context.grantPermissions(["clipboard-read", "clipboard-write"]);
|
||||
|
||||
await page.goto("/apps/routing-forms/forms");
|
||||
const formId = await addRoutingForm(page);
|
||||
await fillRoutingForm(page, {
|
||||
description: "",
|
||||
field: { label: "test", typeIndex: 1 },
|
||||
});
|
||||
|
||||
await page.goto("/apps/routing-forms/forms");
|
||||
await page.click('[data-testid="form-dropdown"]');
|
||||
await page.click('[data-testid="copy-redirect-url"]');
|
||||
const text = await page.evaluate(async () => {
|
||||
return navigator.clipboard.readText();
|
||||
});
|
||||
expect(text).toBe(`${CAL_URL}/router?form=${formId}&test={Recalled_Response_For_This_Field}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
description: The world's fastest calendar, beautifully designed for a remote world
|
||||
items:
|
||||
- /api/app-store/vimcal/1.gif
|
||||
- /api/app-store/vimcal/2.gif
|
||||
- /api/app-store/vimcal/3.gif
|
||||
- /api/app-store/vimcal/4.gif
|
||||
---
|
||||
|
||||
{description}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { AppMeta } from "@calcom/types/App";
|
||||
|
||||
import config from "./config.json";
|
||||
|
||||
export const metadata = {
|
||||
category: "other",
|
||||
...config,
|
||||
} as AppMeta;
|
||||
|
||||
export default metadata;
|
||||
@@ -0,0 +1,21 @@
|
||||
import { AppDeclarativeHandler } from "@calcom/types/AppHandler";
|
||||
|
||||
import { createDefaultInstallation } from "../../_utils/installation";
|
||||
import appConfig from "../config.json";
|
||||
|
||||
const handler: AppDeclarativeHandler = {
|
||||
// Instead of passing appType and slug from here, api/integrations/[..args] should be able to derive and pass these directly to createCredential
|
||||
appType: appConfig.type,
|
||||
variant: appConfig.variant,
|
||||
slug: appConfig.slug,
|
||||
supportsMultipleInstalls: false,
|
||||
handlerType: "add",
|
||||
redirect: {
|
||||
newTab: true,
|
||||
url: "https://cal.com/blog/cal-plus-vimcal",
|
||||
},
|
||||
createCredential: ({ appType, user, slug }) =>
|
||||
createDefaultInstallation({ appType, userId: user.id, slug, key: {} }),
|
||||
};
|
||||
|
||||
export default handler;
|
||||
@@ -0,0 +1 @@
|
||||
export { default as add } from "./add";
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"/*": "Don't modify slug - If required, do it using cli edit command",
|
||||
"name": "Vimcal",
|
||||
"slug": "vimcal",
|
||||
"type": "vimcal_other",
|
||||
"imageSrc": "/api/app-store/vimcal/icon.svg",
|
||||
"logo": "/api/app-store/vimcal/icon.svg",
|
||||
"url": "https://cal.com/apps/vimcal",
|
||||
"variant": "other",
|
||||
"categories": ["calendar"],
|
||||
"publisher": "Cal.com, Inc.",
|
||||
"email": "support@cal.com",
|
||||
"description": "The world's fastest calendar, beautifully designed for a remote world\r",
|
||||
"extendsFeature": "User",
|
||||
"__createdUsingCli": true
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * as api from "./api";
|
||||
export { metadata } from "./_metadata";
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"private": true,
|
||||
"name": "@calcom/vimcal",
|
||||
"version": "0.0.0",
|
||||
"main": "./index.ts",
|
||||
"description": "The world's fastest calendar, beautifully designed for a remote world\r",
|
||||
"dependencies": {
|
||||
"@calcom/lib": "*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@calcom/types": "*"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 522 KiB |
|
After Width: | Height: | Size: 2.8 MiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 844 KiB |
|
After Width: | Height: | Size: 212 KiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 1.6 MiB |
@@ -0,0 +1,28 @@
|
||||
<svg width="62" height="58" viewBox="0 0 62 58" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.90676 11.7682C0.331514 15.5535 -0.904363 20.8542 2.31152 24.925C4.55796 27.7688 8.12817 28.9722 11.4731 28.3502C25.0725 15.2446 38.1409 10.9884 48.1289 10.1525C49.6733 10.0233 51.1425 9.97591 52.5271 9.98991C55.2643 7.11068 58.346 4.54111 61.7196 2.35078L61.7443 2.28935C61.7443 2.28935 47.1718 -1.08376 32.9863 0.929534C20.5999 2.68751 8.38054 7.03215 3.90676 11.7682Z" fill="url(#paint0_linear_1303_1047)"/>
|
||||
<path d="M13.9571 39.6669C11.2816 36.28 11.3264 31.6336 13.7764 28.3277C26.6775 16.3673 38.9317 12.4894 48.26 11.7088L50.7032 12.0128C46.1398 17.3558 42.6942 23.6199 40.6579 30.4189C37.9724 31.1454 35.321 32.4756 32.801 34.2211C29.4853 36.5177 26.3539 39.561 23.607 42.988C20.1257 43.8278 16.3134 42.6495 13.9571 39.6669Z" fill="url(#paint1_linear_1303_1047)"/>
|
||||
<path d="M24.7519 44.0672C24.5613 44.4084 24.3899 44.7653 24.2397 45.1369C22.2998 49.9396 24.6453 55.3958 29.4789 57.3235C31.0785 57.9616 32.7496 58.1333 34.3407 57.9032C35.9331 57.6814 37.4896 57.0516 38.8456 55.9941C39.1282 55.7738 39.3946 55.5405 39.6449 55.296C39.4201 54.2267 39.2282 53.1435 39.0705 52.047C38.0873 45.208 38.525 38.4931 40.1611 32.1969C37.9955 32.9019 35.8236 34.0315 33.7003 35.5022C30.4914 37.7248 27.4375 40.6986 24.7519 44.0672Z" fill="url(#paint2_linear_1303_1047)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_1303_1047" x1="57.8884" y1="7.12205" x2="-11.0432" y2="37.0341" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFB6BE"/>
|
||||
<stop offset="0.113339" stop-color="#FA6753"/>
|
||||
<stop offset="0.432815" stop-color="#F50058"/>
|
||||
<stop offset="0.61187" stop-color="#F50081"/>
|
||||
<stop offset="0.77952" stop-color="#C71FD6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1303_1047" x1="57.8876" y1="7.12205" x2="-11.0441" y2="37.0341" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFB6BE"/>
|
||||
<stop offset="0.113339" stop-color="#FA6753"/>
|
||||
<stop offset="0.432815" stop-color="#F50058"/>
|
||||
<stop offset="0.61187" stop-color="#F50081"/>
|
||||
<stop offset="0.77952" stop-color="#C71FD6"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_1303_1047" x1="57.8879" y1="7.12206" x2="-11.0437" y2="37.0341" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFB6BE"/>
|
||||
<stop offset="0.113339" stop-color="#FA6753"/>
|
||||
<stop offset="0.432815" stop-color="#F50058"/>
|
||||
<stop offset="0.61187" stop-color="#F50081"/>
|
||||
<stop offset="0.77952" stop-color="#C71FD6"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -47,6 +47,7 @@ const getEventType = async (id: number) => {
|
||||
startTime: true,
|
||||
endTime: true,
|
||||
days: true,
|
||||
date: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -225,18 +226,32 @@ export async function getUserAvailability(
|
||||
const startGetWorkingHours = performance.now();
|
||||
|
||||
const timeZone = schedule.timeZone || eventType?.timeZone || currentUser.timeZone;
|
||||
const workingHours = getWorkingHours(
|
||||
{ timeZone },
|
||||
|
||||
const availability =
|
||||
schedule.availability ||
|
||||
(eventType?.availability.length ? eventType.availability : currentUser.availability)
|
||||
);
|
||||
(eventType?.availability.length ? eventType.availability : currentUser.availability);
|
||||
|
||||
const workingHours = getWorkingHours({ timeZone }, availability);
|
||||
|
||||
const endGetWorkingHours = performance.now();
|
||||
logger.debug(`getWorkingHours took ${endGetWorkingHours - startGetWorkingHours}ms for userId ${userId}`);
|
||||
|
||||
const dateOverrides = availability
|
||||
.filter((availability) => !!availability.date)
|
||||
.map((override) => {
|
||||
const startTime = dayjs.utc(override.startTime);
|
||||
const endTime = dayjs.utc(override.endTime);
|
||||
return {
|
||||
start: dayjs.utc(override.date).hour(startTime.hour()).minute(startTime.minute()).toDate(),
|
||||
end: dayjs.utc(override.date).hour(endTime.hour()).minute(endTime.minute()).toDate(),
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
busy: bufferedBusyTimes,
|
||||
timeZone,
|
||||
workingHours,
|
||||
dateOverrides,
|
||||
currentSeats,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import customParseFormat from "dayjs/plugin/customParseFormat";
|
||||
import isBetween from "dayjs/plugin/isBetween";
|
||||
import isToday from "dayjs/plugin/isToday";
|
||||
import localizedFormat from "dayjs/plugin/localizedFormat";
|
||||
import minmax from "dayjs/plugin/minMax";
|
||||
import relativeTime from "dayjs/plugin/relativeTime";
|
||||
import timeZone from "dayjs/plugin/timezone";
|
||||
import toArray from "dayjs/plugin/toArray";
|
||||
@@ -44,6 +45,7 @@ dayjs.extend(relativeTime);
|
||||
dayjs.extend(timeZone);
|
||||
dayjs.extend(toArray);
|
||||
dayjs.extend(utc);
|
||||
dayjs.extend(minmax);
|
||||
|
||||
export type Dayjs = dayjs.Dayjs;
|
||||
|
||||
|
||||
@@ -1,30 +1,33 @@
|
||||
import { LinkIcon } from "./LinkIcon";
|
||||
|
||||
export const CallToAction = (props: { label: string; href: string }) => (
|
||||
export const CallToAction = (props: { label: string; href: string; secondary?: boolean }) => (
|
||||
<p
|
||||
style={{
|
||||
display: "inline-block",
|
||||
background: "#292929",
|
||||
background: props.secondary ? "#FFFFFF" : "#292929",
|
||||
border: props.secondary ? "1px solid #d1d5db" : "",
|
||||
color: "#ffffff",
|
||||
fontFamily: "Roboto, Helvetica, sans-serif",
|
||||
fontSize: "16px",
|
||||
fontSize: "14px",
|
||||
fontWeight: 500,
|
||||
lineHeight: "120%",
|
||||
lineHeight: "20px",
|
||||
margin: 0,
|
||||
textDecoration: "none",
|
||||
textTransform: "none",
|
||||
padding: "10px 25px",
|
||||
padding: "10px 16px",
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
msoPaddingAlt: "0px",
|
||||
borderRadius: "3px",
|
||||
borderRadius: "6px",
|
||||
boxSizing: "border-box",
|
||||
}}>
|
||||
<a
|
||||
style={{ color: "#FFFFFF", textDecoration: "none" }}
|
||||
style={{ color: props.secondary ? "#292929" : "#FFFFFF", textDecoration: "none" }}
|
||||
href={props.href}
|
||||
target="_blank"
|
||||
rel="noreferrer">
|
||||
{props.label} <LinkIcon />
|
||||
{props.label}
|
||||
<LinkIcon secondary />
|
||||
</a>
|
||||
</p>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,6 @@ export const CallToActionTable = (props: { children: React.ReactNode }) => (
|
||||
<tr>
|
||||
<td
|
||||
align="center"
|
||||
bgcolor="#292929"
|
||||
role="presentation"
|
||||
style={{
|
||||
border: "none",
|
||||
@@ -13,7 +12,6 @@ export const CallToActionTable = (props: { children: React.ReactNode }) => (
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
msoPaddingAlt: "10px 25px",
|
||||
background: "#292929",
|
||||
}}
|
||||
valign="middle">
|
||||
{props.children}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { BASE_URL, IS_PRODUCTION } from "@calcom/lib/constants";
|
||||
|
||||
export const LinkIcon = () => (
|
||||
export const LinkIcon = ({ secondary }: { secondary?: boolean }) => (
|
||||
<img
|
||||
src={IS_PRODUCTION ? BASE_URL + "/emails/linkIcon.png" : "https://app.cal.com/emails/linkIcon.png"}
|
||||
width="12px"
|
||||
srcSet={IS_PRODUCTION ? BASE_URL + "/emails/linkIcon.svg" : "https://app.cal.com/emails/linkIcon.svg"}
|
||||
width="16px"
|
||||
style={{ marginBottom: "-3px", marginLeft: "8px", ...(secondary && { filter: "brightness(80%)" }) }}
|
||||
alt=""
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -28,16 +28,18 @@ export function ManageLink(props: { calEvent: CalendarEvent; attendee: Person })
|
||||
width: "100%",
|
||||
gap: "8px",
|
||||
}}>
|
||||
<>{t("need_to_make_a_change")}</>{" "}
|
||||
<>{t("need_to_make_a_change")}</>
|
||||
{!props.calEvent.recurringEvent && (
|
||||
<>
|
||||
<a href={getRescheduleLink(props.calEvent)} style={{ color: "#3e3e3e" }}>
|
||||
<>{t("reschedule")}</>{" "}
|
||||
<a
|
||||
href={getRescheduleLink(props.calEvent)}
|
||||
style={{ color: "#3e3e3e", marginLeft: "5px", marginRight: "5px" }}>
|
||||
<>{t("reschedule")}</>
|
||||
</a>
|
||||
<>{t("or_lowercase")}</>{" "}
|
||||
<>{t("or_lowercase")}</>
|
||||
</>
|
||||
)}
|
||||
<a href={getCancelLink(props.calEvent)} style={{ color: "#3e3e3e" }}>
|
||||
<a href={getCancelLink(props.calEvent)} style={{ color: "#3e3e3e", marginLeft: "5px" }}>
|
||||
<>{t("cancel")}</>
|
||||
</a>
|
||||
</p>
|
||||
|
||||