Compare commits
18 Commits
feat/seats
...
fix/worksp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3bd3684b6 | ||
|
|
c2ccb6b13b | ||
|
|
4ee1d6f2d5 | ||
|
|
2f88366418 | ||
|
|
4f7fa1a228 | ||
|
|
308cb22729 | ||
|
|
6c04a10b1f | ||
|
|
99459415d5 | ||
|
|
5a4835091f | ||
|
|
061a54dadd | ||
|
|
a532fa1ce2 | ||
|
|
2a355238a4 | ||
|
|
874353e8b8 | ||
|
|
18e60333ae | ||
|
|
d729785802 | ||
|
|
abbbb4b928 | ||
|
|
3cea9377e6 | ||
|
|
06c268bed1 |
@@ -55,6 +55,7 @@ checksums:
|
||||
Billing%20portal/singular: dc3afa14ffe19f5920992a0c9d49d525
|
||||
Blog%20Post/singular: 38e027f212be445dc530e427fc642a20
|
||||
Board/singular: 101ff39aab674c033c15ab978d0d8bac
|
||||
Board%20analytics/singular: 336a8c70a91adc49c15266167ee84cc0
|
||||
Board%20name%20cannot%20exceed%20100%20characters/singular: 985c0177744ec56d8dac84f66ec284ca
|
||||
Board%20name%20is%20required/singular: dbd0c6cc945ab19e702fc27f970a023b
|
||||
Board%20not%20found/singular: 5af9844595fa8aed5985066620435515
|
||||
@@ -87,7 +88,6 @@ checksums:
|
||||
Complete%20control%20and%20ownership%3A/singular: 0d8b682ba873272217425ccfc96aa9cd
|
||||
completed%20a%20checklist%20item/singular: 757b04c6c80cc927e1c597c0ad4fda33
|
||||
completed%20checklist%20item%20%3C0%3E%7B0%7D%3C%2F0%3E/singular: 71ec18acf051fc909a48a07ca3578673
|
||||
Confirm%20URL%20change/singular: e14b4ce081d1ef6194b37e1814e97b39
|
||||
Confirm%20your%20new%20password/singular: a0d2935d7b63f8dd19d7c0de47524416
|
||||
Connect%20Trello/singular: 4440a0b9e387ef7136e3958e7a089213
|
||||
Connect%20your%20favorite%20tools%20to%20streamline%20your%20workflow./singular: 033c5dcdb059ccb634aef7fe63f2f45d
|
||||
@@ -113,7 +113,8 @@ checksums:
|
||||
Critical/singular: eb327cd411b50aee954f8d1d215d003a
|
||||
Current%20password%20is%20required/singular: 72536bca9598680027f2be8ce80ac280
|
||||
Custom%20domain/singular: b09e7a9c187b7163b4a6cfc78042fe42
|
||||
Custom%20URLs%20are%20a%20premium%20feature.%20You'll%20be%20directed%20to%20upgrade%20your%20account./singular: b52e4f6122cf739c9551d29beb89b25e
|
||||
Custom%20URLs%20require%20upgrading%20to%20a%20Pro%20plan/singular: f7275e3b473b8f7b39dab6b37eb26fea
|
||||
Custom%20workspace%20URL/singular: 7ba841d0946eb04fa3d17d74365be37b
|
||||
Customer%20Support/singular: 50e3c77e22e41061ca85ea2f02625a2e
|
||||
Dark/singular: 73e6e208ba628b26e90fcf6dce15e1b2
|
||||
Delete/singular: 8bcf303dd10a645b5baacb02b47d72c9
|
||||
@@ -166,6 +167,7 @@ checksums:
|
||||
Error%20updating%20workspace%20name/singular: 46025f42a7d5eff689e9cb8bed14a1e4
|
||||
Error%20updating%20workspace%20URL/singular: 9da6c012e1b512d8c7fbd812626c4675
|
||||
Error%20upgrading%20subscription/singular: 57cc47581c7faaffb3b1721b6352b576
|
||||
Error%20upgrading%20to%20Pro/singular: 934c6867d9bdbe6099b2c0f5a3107f78
|
||||
Error%20uploading%20profile%20image/singular: 0ba02753a797a74c6ea7b622c9f69c71
|
||||
Everything%20in%20the%20free%20plan%2C%20plus%3A/singular: 62b44c4973b92b806c69a4b15e0256dc
|
||||
Everything%20you%20need%2C%20free%20forever.%20Unlimited%20boards%2C%20unlimited%20lists%2C%20unlimited%20cards.%20Upgrade%20any%20time./singular: fa21632ab1468edf10acda2fe7b71323
|
||||
@@ -230,6 +232,9 @@ checksums:
|
||||
Labels/singular: 6f15627a90002323eac018274b6922d6
|
||||
Labels%20%26%20Filters/singular: 8f0bdd6084516f8241cb613178114390
|
||||
Language/singular: 277fd1a41cc237a437cd1d5e4a80463b
|
||||
Launch%20offer/singular: 624592ba2ecf647a3fe60d493c1ee71a
|
||||
Launch%20offer%3A%20Get%20unlimited%20members%20with%20Pro/singular: 8c1be80f5b2fcc112922282afbe30287
|
||||
Launch%20offer%3A%20unlimited%20seats%20for%20just%20%2429%2Fmonth%20with%20Pro/singular: 235d1cda21811c296afdc0dcc438cc24
|
||||
Learning/singular: 90e91da3f870f065f2da9aa9adf53514
|
||||
Legal/singular: 00d3f08da61a21887009819cf93fb414
|
||||
License/singular: ac2bcac75151e2fcd9eb768cea275a77
|
||||
@@ -296,6 +301,8 @@ checksums:
|
||||
Priority%20email%20support/singular: 678538c912a770b1e1416ecdb8e299b1
|
||||
Privacy%20policy/singular: 462c6a536b52873e4498785c66dd48c8
|
||||
Private/singular: d740d0660e68c61db1853489356030ae
|
||||
Pro%20Plan/singular: 76a09fd843b496610f8cf1dced417b62
|
||||
Pro%20Plan%20%E2%88%9E/singular: a898be9e4610706b9b8146a209e8ba16
|
||||
Profile%20image%20updated/singular: 1ba6609b50bc217a36ab659563e78dae
|
||||
Profile%20picture/singular: d9b5e595877ffe2557486a987dd28274
|
||||
Public/singular: c834f11dab0881632aded3f01d4f8fa9
|
||||
@@ -344,6 +351,7 @@ checksums:
|
||||
Software%20Development/singular: 67659097ef6bcb194839858b2c4f3a3c
|
||||
Star%20on%20Github/singular: e5cb0428f1ac6485688f120d78742875
|
||||
Success/singular: c43827becada6750f7a25890905f38b9
|
||||
Supercharge%20your%20workspace%20for%20just%20%2429%2Fmonth.%20Here's%20what%20you'll%20get%3A/singular: 21af8119141afcce5f12da489f34db6a
|
||||
Support/singular: 55aab5fd0f31a9cb055a2edeeedfaf63
|
||||
Support%20the%20development%20of%20the%20project/singular: c63bab228ab2b1be4370c668a99cd278
|
||||
System/singular: 803281c327a02a2feba182f4a2b38311
|
||||
@@ -363,6 +371,8 @@ checksums:
|
||||
This%20board%20URL%20has%20already%20been%20taken/singular: 1d8b40332a031b5b77a3658e48dd51ca
|
||||
This%20will%20result%20in%20the%20permanent%20deletion%20of%20all%20data%20associated%20with%20this%20workspace./singular: a31141558af793635c1ddd2fa0a33499
|
||||
This%20will%20result%20in%20the%20permanent%20deletion%20of%20all%20data%20associated%20with%20your%20account./singular: b49224632bd6c3b7f5e462912aeb1081
|
||||
This%20workspace%20URL%20has%20already%20been%20taken/singular: b455329e2a71da677acab91d3a00bad6
|
||||
This%20workspace%20URL%20is%20reserved/singular: 7e47c892b93d4334c1606010c06e875e
|
||||
This%20workspace%20username%20has%20already%20been%20taken/singular: b7eadb89c615874f416d9658d0428c4c
|
||||
To%20Do/singular: d60813ea824f373462471e092d136eed
|
||||
Toggle%20menu/singular: 29dea3e0b6238874f8c7a27619df8e36
|
||||
@@ -399,6 +409,7 @@ checksums:
|
||||
Unlimited%20cards/singular: f44c1050c4d6aa39c8cdf5f4a7d12577
|
||||
Unlimited%20comments/singular: 31dbcf487c49a9997142e96bb3ab0040
|
||||
Unlimited%20lists/singular: 5c418701b27b9acbc5dd199719007362
|
||||
Unlimited%20members/singular: f2949ca2dc18b0063af92e60779abb65
|
||||
Update/singular: 079fc039262fd31b10532929685c2d1b
|
||||
Update%20label/singular: 97880b503dfe956941c5f23025a1c102
|
||||
updated%20a%20checklist%20item/singular: 198e1d1d503f4b69b752dd84d0cc0e9d
|
||||
@@ -406,6 +417,8 @@ checksums:
|
||||
updated%20the%20title/singular: 98cf8f12923ec1a58e767e3a40863b21
|
||||
updated%20the%20title%20to%20%3C0%3E%7B0%7D%3C%2F0%3E/singular: aca196d729401d8adc5c8ca9d558840e
|
||||
Upgrade/singular: 63c3b52882e0d779859307d672c178c2
|
||||
Upgrade%20to%20Pro/singular: 972773025e763ddf53273df6d37a729a
|
||||
Upgrade%20to%20Pro%20(%2429%2Fmonth)/singular: 9a91ea70f5eb55aac96640bf0fd7feff
|
||||
Upgrade%20to%20Team%20Plan/singular: 40e2ef151266937f8bbe63b3d361f645
|
||||
Urgent/singular: e79afcd4398e52e10e7e8243a7eecabe
|
||||
URL%20can%20only%20contain%20letters%2C%20numbers%2C%20and%20hyphens/singular: 875d37d2d920f98ef60a314eda8a5d9a
|
||||
@@ -430,6 +443,7 @@ checksums:
|
||||
When%20Trello%20launched%20in%202011%2C%20it%20blew%20everyone%20away%20with%20its%20carefully%20designed%20simplicity%2C%20but%20over%20time%20(and%20atlassification)%20it%20lost%20its%20magic%20and%20grew%20into%20something%20closer%20to%20%22Jira%20Lite%22.%20This%20project%20is%20our%20attempt%20to%20recapture%20the%20original%20magic%20of%20Trello's%20simplicity%2C%20in%20open%20source./singular: 60a55e9bd16c3d1beff1a6c7633c5911
|
||||
Why%20make%20an%20open%20source%20Trello%3F/singular: 090833338ba8c64ef7a75e0f2615b34b
|
||||
Workspace/singular: b63ef0e99ee6f7fef6cbe4971ca6cf0f
|
||||
Workspace%20created%20successfully.%20You%20can%20upgrade%20later%20in%20settings./singular: 8bbaba9f82ff076a08185ada1ee7eb94
|
||||
Workspace%20deleted/singular: bc5c267ce3f04de94ff1379cf2ca48a3
|
||||
Workspace%20description/singular: 7159d620b7ef5c5afef734989a5be08b
|
||||
Workspace%20description%20cannot%20exceed%20280%20characters/singular: d0e83b9a0304d7c36cf8c85d98783ce2
|
||||
@@ -438,10 +452,12 @@ checksums:
|
||||
Workspace%20members/singular: 1857292f9567c556c781a23bd7e10544
|
||||
Workspace%20name/singular: 855614bbf862fd6a9f6a3e76943f92d4
|
||||
Workspace%20name%20cannot%20exceed%2024%20characters/singular: c8b8f79fb83abf8329cc34c1f51fcfc9
|
||||
Workspace%20name%20is%20required/singular: b8c5162dd08c4d941bc57f9d0cbee451
|
||||
Workspace%20name%20must%20be%20at%20least%203%20characters%20long/singular: e448ea97418d44b18b4c21c22b8ba779
|
||||
Workspace%20name%20updated/singular: 3206ea410ee1ea4182b27ac0d89f92a1
|
||||
Workspace%20slug%20updated/singular: 527b92711d38cb35b40741df43aef047
|
||||
Workspace%20URL/singular: f4397a838da0f3a44cbd3ebe408ed6c3
|
||||
workspace-url/singular: 2d034732ec536f3a2667f956fa50d394
|
||||
Writing/singular: 4f5f3ee3320c252921f80c42653c5d49
|
||||
Yearly/singular: 87f43e016c19cb25860f456549a2f431
|
||||
Yes%2C%20we%20offer%20an%20forever%20free%20plan%20for%20individual%20use.%20No%20restrictions%2C%20no%20paywalls%2C%20no%20limits./singular: 963cee303d0ff13c1719f4575e774fe3
|
||||
@@ -451,6 +467,7 @@ checksums:
|
||||
You%20can%20self-host%20by%20following%20the%20instructions%20in%20our%20%3C0%3Erepo%3C%2F0%3E./singular: a6152a41b2d8f64d5a657e5b8bc808a9
|
||||
You%20have%20been%20logged%20in%20successfully./singular: ef8fad1dce13ae4112f17c5258655fea
|
||||
You%20have%20been%20signed%20up%20successfully./singular: f614a6e3b45f5ffb9a3b0fb420fef84b
|
||||
You%20have%20unlimited%20seats%20with%20your%20Pro%20Plan.%20There%20is%20no%20additional%20charge%20for%20new%20members!/singular: e3dc59a5ba7211cd3d8516b3a79d85ca
|
||||
Your%20account%20has%20been%20deleted./singular: 8c8d944e07388c5877effdb2c2803dcf
|
||||
Your%20boards%20have%20been%20imported./singular: 403972e7a25afc2415762c1c2b1ec868
|
||||
Your%20display%20name%20has%20been%20updated./singular: 15e5fff36c554c16ec5214427fae1bf4
|
||||
|
||||
@@ -1,30 +1,106 @@
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useEffect } from "react";
|
||||
import { env } from "next-runtime-env";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { HiXMark } from "react-icons/hi2";
|
||||
import {
|
||||
HiBolt,
|
||||
HiCheck,
|
||||
HiCheckBadge,
|
||||
HiInformationCircle,
|
||||
HiXMark,
|
||||
} from "react-icons/hi2";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { z } from "zod";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import Input from "~/components/Input";
|
||||
import Toggle from "~/components/Toggle";
|
||||
import { useDebounce } from "~/hooks/useDebounce";
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { usePopup } from "~/providers/popup";
|
||||
import { useWorkspace } from "~/providers/workspace";
|
||||
import { api } from "~/utils/api";
|
||||
import LoadingSpinner from "./LoadingSpinner";
|
||||
|
||||
interface FormValues {
|
||||
name: string;
|
||||
}
|
||||
const schema = z.object({
|
||||
name: z.string().min(1, { message: t`Workspace name is required` }),
|
||||
slug: z
|
||||
.string()
|
||||
.min(3, {
|
||||
message: t`URL must be at least 3 characters long`,
|
||||
})
|
||||
.max(24, { message: t`URL cannot exceed 24 characters` })
|
||||
.regex(/^(?![-]+$)[a-zA-Z0-9-]+$/, {
|
||||
message: t`URL can only contain letters, numbers, and hyphens`,
|
||||
})
|
||||
.optional()
|
||||
.or(z.literal("")),
|
||||
});
|
||||
|
||||
type FormValues = z.infer<typeof schema>;
|
||||
|
||||
export function NewWorkspaceForm() {
|
||||
const { closeModal } = useModal();
|
||||
const { showPopup } = usePopup();
|
||||
const { switchWorkspace } = useWorkspace();
|
||||
const { register, handleSubmit } = useForm<FormValues>();
|
||||
const { switchWorkspace, availableWorkspaces } = useWorkspace();
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
watch,
|
||||
trigger,
|
||||
clearErrors,
|
||||
setValue,
|
||||
} = useForm<FormValues>({
|
||||
resolver: zodResolver(schema),
|
||||
defaultValues: {
|
||||
name: "",
|
||||
slug: "",
|
||||
},
|
||||
mode: "onSubmit",
|
||||
});
|
||||
const utils = api.useUtils();
|
||||
|
||||
const hasAvailableWorkspaces = availableWorkspaces.length > 0;
|
||||
|
||||
const isCloudEnv = env("NEXT_PUBLIC_KAN_ENV") === "cloud";
|
||||
|
||||
const slug = watch("slug");
|
||||
const [debouncedSlug] = useDebounce(slug, 500);
|
||||
const isTyping = slug !== debouncedSlug;
|
||||
|
||||
// Pro toggle state management
|
||||
const [isProToggleEnabled, setIsProToggleEnabled] = useState(false);
|
||||
const [lastAvailableSlug, setLastAvailableSlug] = useState<string>("");
|
||||
|
||||
// Validate slug only after debounce
|
||||
useEffect(() => {
|
||||
if (isTyping) {
|
||||
// Clear errors while typing
|
||||
clearErrors("slug");
|
||||
} else if (debouncedSlug) {
|
||||
// Validate after debounce
|
||||
void trigger("slug");
|
||||
}
|
||||
}, [isTyping, debouncedSlug, trigger, clearErrors]);
|
||||
|
||||
const checkWorkspaceSlugAvailability =
|
||||
api.workspace.checkSlugAvailability.useQuery(
|
||||
{
|
||||
workspaceSlug: debouncedSlug ?? "",
|
||||
},
|
||||
{
|
||||
enabled: !!debouncedSlug && debouncedSlug.length >= 3 && !errors.slug,
|
||||
},
|
||||
);
|
||||
|
||||
const isWorkspaceSlugAvailable = checkWorkspaceSlugAvailability.data;
|
||||
|
||||
const createWorkspace = api.workspace.create.useMutation({
|
||||
onSuccess: (values) => {
|
||||
onSuccess: async (values, variables) => {
|
||||
if (values.publicId && values.name) {
|
||||
utils.workspace.all.invalidate();
|
||||
void utils.workspace.all.invalidate();
|
||||
switchWorkspace({
|
||||
publicId: values.publicId,
|
||||
name: values.name,
|
||||
@@ -33,6 +109,43 @@ export function NewWorkspaceForm() {
|
||||
plan: values.plan,
|
||||
role: "admin",
|
||||
});
|
||||
|
||||
// If in cloud and Pro toggle is enabled, create checkout session for pro
|
||||
if (env("NEXT_PUBLIC_KAN_ENV") === "cloud" && isProToggleEnabled) {
|
||||
try {
|
||||
const response = await fetch(
|
||||
"/api/stripe/create_checkout_session",
|
||||
{
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
slug: slug || undefined,
|
||||
workspacePublicId: values.publicId,
|
||||
cancelUrl: "/settings?upgrade=pro",
|
||||
successUrl: "/boards",
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
const url = (data as { url: string }).url;
|
||||
|
||||
if (url) {
|
||||
window.location.href = url;
|
||||
return; // Don't close modal if redirecting to checkout
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error creating checkout session:", error);
|
||||
showPopup({
|
||||
header: t`Error upgrading to Pro`,
|
||||
message: t`Workspace created successfully. You can upgrade later in settings.`,
|
||||
icon: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
closeModal();
|
||||
}
|
||||
},
|
||||
@@ -51,12 +164,74 @@ export function NewWorkspaceForm() {
|
||||
if (nameElement) nameElement.focus();
|
||||
}, []);
|
||||
|
||||
const [shouldShowBenefits, setShouldShowBenefits] = useState(false);
|
||||
|
||||
const isValidSlug = slug && slug.length >= 3 && !errors.slug;
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
isCloudEnv &&
|
||||
!checkWorkspaceSlugAvailability.isPending &&
|
||||
isValidSlug
|
||||
) {
|
||||
const isAvailable = isWorkspaceSlugAvailable?.isAvailable === true;
|
||||
setShouldShowBenefits(isAvailable);
|
||||
|
||||
// Automatically enable Pro toggle when slug is available
|
||||
if (isAvailable) {
|
||||
setIsProToggleEnabled(true);
|
||||
setLastAvailableSlug(slug);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
isValidSlug,
|
||||
isWorkspaceSlugAvailable?.isAvailable,
|
||||
checkWorkspaceSlugAvailability.isPending,
|
||||
slug,
|
||||
isCloudEnv,
|
||||
]);
|
||||
|
||||
// Reset benefits when slug becomes invalid
|
||||
useEffect(() => {
|
||||
if (!isValidSlug) {
|
||||
setShouldShowBenefits(false);
|
||||
}
|
||||
}, [isValidSlug]);
|
||||
|
||||
// Handle Pro toggle changes
|
||||
const handleProToggleChange = () => {
|
||||
if (isProToggleEnabled) {
|
||||
// Turning off: clear the slug and disable Pro
|
||||
setValue("slug", "");
|
||||
setIsProToggleEnabled(false);
|
||||
} else {
|
||||
// Turning on: restore the last available slug if we have one
|
||||
if (lastAvailableSlug) {
|
||||
setValue("slug", lastAvailableSlug);
|
||||
}
|
||||
setIsProToggleEnabled(true);
|
||||
}
|
||||
};
|
||||
|
||||
const showProBenefits = isProToggleEnabled;
|
||||
|
||||
const onSubmit = (values: FormValues) => {
|
||||
// Don't submit if slug is provided but not available
|
||||
if (values.slug && isWorkspaceSlugAvailable?.isAvailable === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
createWorkspace.mutate({
|
||||
name: values.name,
|
||||
slug: !isCloudEnv && values.slug ? values.slug : undefined,
|
||||
});
|
||||
};
|
||||
|
||||
const isSlugAvailable =
|
||||
isValidSlug &&
|
||||
isWorkspaceSlugAvailable?.isAvailable &&
|
||||
!isWorkspaceSlugAvailable?.isReserved;
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="px-5 pt-5">
|
||||
@@ -66,7 +241,10 @@ export function NewWorkspaceForm() {
|
||||
</h2>
|
||||
<button
|
||||
type="button"
|
||||
className="rounded p-1 hover:bg-light-200 focus:outline-none dark:hover:bg-dark-300"
|
||||
className={twMerge(
|
||||
"rounded p-1 hover:bg-light-200 focus:outline-none dark:hover:bg-dark-300",
|
||||
!hasAvailableWorkspaces && "invisible",
|
||||
)}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
closeModal();
|
||||
@@ -80,6 +258,7 @@ export function NewWorkspaceForm() {
|
||||
id="workspace-name"
|
||||
placeholder={t`Workspace name`}
|
||||
{...register("name")}
|
||||
errorMessage={errors.name?.message}
|
||||
onKeyDown={async (e) => {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
@@ -87,10 +266,121 @@ export function NewWorkspaceForm() {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="mt-4">
|
||||
<Input
|
||||
id="workspace-slug"
|
||||
placeholder={t`workspace-url`}
|
||||
{...register("slug")}
|
||||
className={`${
|
||||
isSlugAvailable
|
||||
? "focus:ring-green-500 dark:focus:ring-green-500"
|
||||
: ""
|
||||
}`}
|
||||
errorMessage={
|
||||
errors.slug?.message ??
|
||||
(isWorkspaceSlugAvailable?.isAvailable === false &&
|
||||
isWorkspaceSlugAvailable?.isReserved === false
|
||||
? t`This workspace URL has already been taken`
|
||||
: isWorkspaceSlugAvailable?.isReserved
|
||||
? t`This workspace URL is reserved`
|
||||
: undefined)
|
||||
}
|
||||
prefix={
|
||||
env("NEXT_PUBLIC_KAN_ENV") === "cloud"
|
||||
? "kan.bn/"
|
||||
: `${env("NEXT_PUBLIC_BASE_URL")}/`
|
||||
}
|
||||
iconRight={
|
||||
slug && slug.length >= 3 && !errors.slug ? (
|
||||
isWorkspaceSlugAvailable?.isAvailable ? (
|
||||
<HiCheck className="h-4 w-4 text-green-500" />
|
||||
) : checkWorkspaceSlugAvailability.isPending || isTyping ? (
|
||||
<LoadingSpinner />
|
||||
) : null
|
||||
) : null
|
||||
}
|
||||
onKeyDown={async (e) => {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
await handleSubmit(onSubmit)();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{slug && slug.length >= 3 && shouldShowBenefits && (
|
||||
<div className="mt-2 flex items-center gap-1">
|
||||
<HiInformationCircle className="h-4 w-4 text-dark-900" />
|
||||
<p className="text-xs text-gray-500 dark:text-dark-900">
|
||||
{t`Custom URLs require upgrading to a Pro plan`}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{showProBenefits && (
|
||||
<div className="mt-6">
|
||||
<div className="rounded-md bg-light-100 p-3 text-xs text-light-900 dark:bg-dark-200 dark:text-dark-900">
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center space-x-3">
|
||||
<HiCheckBadge className="h-[18px] w-[18px] flex-shrink-0 text-light-1000 dark:text-dark-950" />
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="text-xs text-neutral-900 dark:text-dark-1000">
|
||||
{t`Unlimited members`}
|
||||
</span>
|
||||
<span className="inline-flex items-center rounded-full bg-emerald-500/10 px-2 py-0.5 text-[10px] font-medium text-emerald-600 ring-1 ring-inset ring-emerald-500/20 dark:text-emerald-400 sm:text-[10px]">
|
||||
{t`Launch offer`}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<HiCheckBadge className="h-[18px] w-[18px] flex-shrink-0 text-light-1000 dark:text-dark-950" />
|
||||
<span className="text-xs text-neutral-900 dark:text-dark-1000">
|
||||
{t`Custom workspace URL`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<HiCheckBadge className="h-[18px] w-[18px] flex-shrink-0 text-light-1000 dark:text-dark-950" />
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="text-xs text-neutral-900 dark:text-dark-1000">
|
||||
{t`Board analytics`}
|
||||
</span>
|
||||
<span className="inline-flex items-center rounded-full bg-gray-500/10 px-2 py-0.5 text-[10px] font-medium text-gray-600 ring-1 ring-inset ring-gray-500/20 dark:text-gray-400 sm:text-[10px]">
|
||||
{t`Coming soon`}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-12 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
<div
|
||||
className={twMerge(
|
||||
"mt-6 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600",
|
||||
!showProBenefits && "mt-12",
|
||||
)}
|
||||
>
|
||||
{/* Pro Toggle - only show in cloud environment */}
|
||||
{isCloudEnv && (
|
||||
<Toggle
|
||||
isChecked={isProToggleEnabled}
|
||||
onChange={handleProToggleChange}
|
||||
label={t`Upgrade to Pro ($29/month)`}
|
||||
/>
|
||||
)}
|
||||
<div>
|
||||
<Button type="submit" isLoading={createWorkspace.isPending}>
|
||||
<Button
|
||||
type="submit"
|
||||
isLoading={createWorkspace.isPending}
|
||||
disabled={
|
||||
createWorkspace.isPending ||
|
||||
(!!slug &&
|
||||
(checkWorkspaceSlugAvailability.isPending ||
|
||||
isWorkspaceSlugAvailable?.isAvailable === false ||
|
||||
isTyping))
|
||||
}
|
||||
>
|
||||
{t`Create workspace`}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -20,12 +20,12 @@ export default function WorkspaceMenu({
|
||||
<Menu as="div" className="relative inline-block w-full pb-3 text-left">
|
||||
<div>
|
||||
{isLoading ? (
|
||||
<div className={twMerge("mb-1", isCollapsed && "md:flex md:p-1.5")}>
|
||||
<div className={twMerge("mb-1 flex", isCollapsed && "md:p-1.5")}>
|
||||
<div className="h-6 w-6 animate-pulse rounded-md bg-light-200 dark:bg-dark-200" />
|
||||
<div
|
||||
className={twMerge(
|
||||
"ml-2 h-6 w-[150px] animate-pulse rounded-md bg-light-200 dark:bg-dark-200",
|
||||
isCollapsed && "hidden md:block",
|
||||
isCollapsed && "md:hidden",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
@@ -44,7 +44,7 @@ export default function WorkspaceMenu({
|
||||
</span>
|
||||
<span
|
||||
className={twMerge(
|
||||
"ml-2 text-sm font-bold text-neutral-900 dark:text-dark-1000",
|
||||
"ml-2 truncate text-sm font-bold text-neutral-900 dark:text-dark-1000",
|
||||
isCollapsed && "md:hidden",
|
||||
)}
|
||||
>
|
||||
@@ -87,17 +87,17 @@ export default function WorkspaceMenu({
|
||||
onClick={() => switchWorkspace(availableWorkspace)}
|
||||
className="flex w-full items-center justify-between rounded-[5px] px-3 py-2 text-left text-sm text-neutral-900 hover:bg-light-200 dark:text-dark-1000 dark:hover:bg-dark-400"
|
||||
>
|
||||
<div>
|
||||
<span className="inline-flex h-5 w-5 items-center justify-center rounded-[5px] bg-indigo-700">
|
||||
<div className="flex min-w-0 flex-1 items-center">
|
||||
<span className="inline-flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-[5px] bg-indigo-700">
|
||||
<span className="text-xs font-medium leading-none text-white">
|
||||
{availableWorkspace.name.charAt(0).toUpperCase()}
|
||||
</span>
|
||||
</span>
|
||||
<span className="ml-2 text-xs font-medium">
|
||||
<span className="ml-2 truncate text-xs font-medium">
|
||||
{availableWorkspace.name}
|
||||
</span>
|
||||
</div>
|
||||
{workspace.name === availableWorkspace.name && (
|
||||
{workspace.publicId === availableWorkspace.publicId && (
|
||||
<span>
|
||||
<HiCheck className="h-4 w-4" aria-hidden="true" />
|
||||
</span>
|
||||
|
||||
@@ -36,12 +36,12 @@ msgstr "{0} Labels"
|
||||
msgid "{boardCount, plural, one {Import board (1)} other {Import boards ({boardCount})}}"
|
||||
msgstr "{boardCount, plural, one {Board importieren (1)} other {Boards importieren ({boardCount})}}"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:91
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$10/month"
|
||||
msgstr "$10/Monat"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$8/month"
|
||||
msgstr "$8/Monat"
|
||||
|
||||
@@ -97,7 +97,7 @@ msgid "Add label"
|
||||
msgstr "Label hinzufügen"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:130
|
||||
#: src/views/members/components/InviteMemberForm.tsx:149
|
||||
#: src/views/members/components/InviteMemberForm.tsx:147
|
||||
msgid "Add member"
|
||||
msgstr "Mitglied hinzufügen"
|
||||
|
||||
@@ -132,7 +132,7 @@ msgstr "hat Checklistenelement <0>{0}</0> hinzugefügt"
|
||||
msgid "added label <0>{0}</0>"
|
||||
msgstr "hat Label <0>{0}</0> hinzugefügt"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
#: src/views/members/components/InviteMemberForm.tsx:187
|
||||
msgid "Adding a new member will cost an additional {price} ({billingType}) per seat."
|
||||
msgstr "Das Hinzufügen eines neuen Mitglieds kostet zusätzlich {price} ({billingType}) pro Platz."
|
||||
|
||||
@@ -148,7 +148,7 @@ msgstr "Alle Systeme funktionieren"
|
||||
msgid "Already have an account? <0><1>Sign in</1></0>"
|
||||
msgstr "Du hast bereits ein Konto? <0><1>Anmelden</1></0>"
|
||||
|
||||
#: src/views/settings/index.tsx:102
|
||||
#: src/views/settings/index.tsx:127
|
||||
msgid "An error occurred while disconnecting your Trello account."
|
||||
msgstr "Beim Trennen deines Trello-Kontos ist ein Fehler aufgetreten."
|
||||
|
||||
@@ -156,7 +156,7 @@ msgstr "Beim Trennen deines Trello-Kontos ist ein Fehler aufgetreten."
|
||||
msgid "An unexpected error occurred. Please try again later."
|
||||
msgstr "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es später erneut."
|
||||
|
||||
#: src/views/settings/index.tsx:259
|
||||
#: src/views/settings/index.tsx:296
|
||||
msgid "API keys"
|
||||
msgstr "API-Schlüssel"
|
||||
|
||||
@@ -218,20 +218,20 @@ msgstr "Backlog"
|
||||
msgid "Basic Kanban"
|
||||
msgstr "Einfaches Kanban"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed annually"
|
||||
msgstr "jährlich abgerechnet"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed monthly"
|
||||
msgstr "monatlich abgerechnet"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
#: src/views/settings/index.tsx:198
|
||||
#: src/views/settings/index.tsx:235
|
||||
msgid "Billing"
|
||||
msgstr "Abrechnung"
|
||||
|
||||
#: src/views/settings/index.tsx:208
|
||||
#: src/views/settings/index.tsx:245
|
||||
msgid "Billing portal"
|
||||
msgstr "Abrechnungsportal"
|
||||
|
||||
@@ -243,6 +243,11 @@ msgstr "Blogbeitrag"
|
||||
msgid "Board"
|
||||
msgstr "Board"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:346
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:81
|
||||
msgid "Board analytics"
|
||||
msgstr "Board-Analytik"
|
||||
|
||||
#: src/views/boards/components/NewBoardForm.tsx:21
|
||||
msgid "Board name cannot exceed 100 characters"
|
||||
msgstr "Der Name des Boards darf 100 Zeichen nicht überschreiten"
|
||||
@@ -309,9 +314,9 @@ msgstr "Fehlerbericht"
|
||||
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:168
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:50
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:88
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:98
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:104
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
@@ -325,12 +330,12 @@ msgstr "Kartentitel"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:109
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:178
|
||||
#: src/views/settings/index.tsx:291
|
||||
#: src/views/settings/index.tsx:301
|
||||
#: src/views/settings/index.tsx:328
|
||||
#: src/views/settings/index.tsx:338
|
||||
msgid "Change Password"
|
||||
msgstr "Passwort ändern"
|
||||
|
||||
#: src/views/settings/index.tsx:190
|
||||
#: src/views/settings/index.tsx:227
|
||||
msgid "Change the language of the app."
|
||||
msgstr "Ändere die Sprache der App."
|
||||
|
||||
@@ -360,7 +365,9 @@ msgstr "Code-Review"
|
||||
msgid "Collaborate seamlessly with your team."
|
||||
msgstr "Arbeite nahtlos mit deinem Team zusammen."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:349
|
||||
#: src/views/home/components/Features.tsx:66
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:84
|
||||
msgid "Coming soon"
|
||||
msgstr "Demnächst verfügbar"
|
||||
|
||||
@@ -389,16 +396,12 @@ msgstr "hat ein Checklistenelement abgeschlossen"
|
||||
msgid "completed checklist item <0>{0}</0>"
|
||||
msgstr "hat Checklistenelement <0>{0}</0> abgeschlossen"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:42
|
||||
msgid "Confirm URL change"
|
||||
msgstr "URL-Änderung bestätigen"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:150
|
||||
msgid "Confirm your new password"
|
||||
msgstr "Bestätigen Sie Ihr neues Passwort"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:157
|
||||
#: src/views/settings/index.tsx:235
|
||||
#: src/views/settings/index.tsx:272
|
||||
msgid "Connect Trello"
|
||||
msgstr "Trello verbinden"
|
||||
|
||||
@@ -406,7 +409,7 @@ msgstr "Trello verbinden"
|
||||
msgid "Connect your favorite tools to streamline your workflow."
|
||||
msgstr "Verbinde deine Lieblingstools, um deinen Arbeitsablauf zu optimieren."
|
||||
|
||||
#: src/views/settings/index.tsx:222
|
||||
#: src/views/settings/index.tsx:259
|
||||
msgid "Connect your Trello account to import boards."
|
||||
msgstr "Verbinde dein Trello-Konto, um Boards zu importieren."
|
||||
|
||||
@@ -478,7 +481,7 @@ msgstr "Neues Label erstellen"
|
||||
msgid "Create new list"
|
||||
msgstr "Neue Liste erstellen"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:94
|
||||
#: src/components/NewWorkspaceForm.tsx:384
|
||||
#: src/components/WorkspaceMenu.tsx:116
|
||||
msgid "Create workspace"
|
||||
msgstr "Arbeitsbereich erstellen"
|
||||
@@ -499,9 +502,14 @@ msgstr "Aktuelles Passwort ist erforderlich"
|
||||
msgid "Custom domain"
|
||||
msgstr "Benutzerdefinierte Domain"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:45
|
||||
msgid "Custom URLs are a premium feature. You'll be directed to upgrade your account."
|
||||
msgstr "Benutzerdefinierte URLs sind eine Premium-Funktion. Du wirst zur Aktualisierung deines Kontos weitergeleitet."
|
||||
#: src/components/NewWorkspaceForm.tsx:315
|
||||
msgid "Custom URLs require upgrading to a Pro plan"
|
||||
msgstr "Benutzerdefinierte URLs erfordern ein Upgrade auf einen Pro-Plan"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:339
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:74
|
||||
msgid "Custom workspace URL"
|
||||
msgstr "Benutzerdefinierte Workspace-URL"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:41
|
||||
msgid "Customer Support"
|
||||
@@ -520,8 +528,8 @@ msgid "Delete"
|
||||
msgstr "Löschen"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:96
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:319
|
||||
#: src/views/settings/index.tsx:346
|
||||
#: src/views/settings/index.tsx:356
|
||||
msgid "Delete account"
|
||||
msgstr "Konto löschen"
|
||||
|
||||
@@ -542,8 +550,8 @@ msgid "Delete list"
|
||||
msgstr "Liste löschen"
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:106
|
||||
#: src/views/settings/index.tsx:272
|
||||
#: src/views/settings/index.tsx:283
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:320
|
||||
msgid "Delete workspace"
|
||||
msgstr "Workspace löschen"
|
||||
|
||||
@@ -569,7 +577,7 @@ msgstr "hat Checklistenelement <0>{0}</0> gelöscht"
|
||||
msgid "Design"
|
||||
msgstr "Design"
|
||||
|
||||
#: src/views/settings/index.tsx:250
|
||||
#: src/views/settings/index.tsx:287
|
||||
msgid "Disconnect Trello"
|
||||
msgstr "Trello trennen"
|
||||
|
||||
@@ -577,7 +585,7 @@ msgstr "Trello trennen"
|
||||
msgid "Discuss and collaborate on cards."
|
||||
msgstr "Diskutiere und arbeite gemeinsam an Karten."
|
||||
|
||||
#: src/views/settings/index.tsx:151
|
||||
#: src/views/settings/index.tsx:176
|
||||
msgid "Display name"
|
||||
msgstr "Anzeigename"
|
||||
|
||||
@@ -647,7 +655,7 @@ msgstr "Bearbeitung"
|
||||
msgid "email"
|
||||
msgstr "E-Mail"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:163
|
||||
#: src/views/members/components/InviteMemberForm.tsx:161
|
||||
msgid "Email"
|
||||
msgstr "E-Mail"
|
||||
|
||||
@@ -695,12 +703,12 @@ msgstr "Fehler beim Löschen des Labels"
|
||||
msgid "Error deleting workspace"
|
||||
msgstr "Fehler beim Löschen des Arbeitsbereichs"
|
||||
|
||||
#: src/views/settings/index.tsx:101
|
||||
#: src/views/settings/index.tsx:126
|
||||
msgid "Error disconnecting Trello"
|
||||
msgstr "Fehler beim Trennen von Trello"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:76
|
||||
#: src/views/members/components/InviteMemberForm.tsx:82
|
||||
#: src/views/members/components/InviteMemberForm.tsx:71
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
msgid "Error inviting member"
|
||||
msgstr "Fehler beim Einladen des Mitglieds"
|
||||
|
||||
@@ -724,10 +732,15 @@ msgstr "Fehler beim Aktualisieren des Arbeitsbereichsnamens"
|
||||
msgid "Error updating workspace URL"
|
||||
msgstr "Fehler beim Aktualisieren der Workspace-URL"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:132
|
||||
#: src/views/members/components/InviteMemberForm.tsx:130
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:41
|
||||
msgid "Error upgrading subscription"
|
||||
msgstr "Fehler beim Upgrade des Abonnements"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:142
|
||||
msgid "Error upgrading to Pro"
|
||||
msgstr "Fehler beim Upgrade auf Pro"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:56
|
||||
#: src/views/settings/components/Avatar.tsx:97
|
||||
msgid "Error uploading profile image"
|
||||
@@ -794,8 +807,8 @@ msgstr "Für langfristige Nachhaltigkeit erkennen wir an, dass alle guten Open-S
|
||||
msgid "Free"
|
||||
msgstr "Kostenlos"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:192
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:193
|
||||
#: src/views/members/index.tsx:208
|
||||
msgid "Free Plan"
|
||||
msgstr "Kostenloser Plan"
|
||||
|
||||
@@ -950,24 +963,24 @@ msgstr "Integrationen"
|
||||
msgid "Interviewing"
|
||||
msgstr "Vorstellungsgespräch"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:45
|
||||
#: src/views/members/components/InviteMemberForm.tsx:40
|
||||
msgid "Invalid email address"
|
||||
msgstr "Ungültige E-Mail-Adresse"
|
||||
|
||||
#: src/views/members/index.tsx:193
|
||||
#: src/views/members/index.tsx:221
|
||||
msgid "Invite"
|
||||
msgstr "Einladen"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:207
|
||||
#: src/views/members/components/InviteMemberForm.tsx:208
|
||||
msgid "Invite another"
|
||||
msgstr "Weitere Person einladen"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:112
|
||||
#: src/views/members/components/InviteMemberForm.tsx:231
|
||||
#: src/views/members/components/InviteMemberForm.tsx:233
|
||||
msgid "Invite member"
|
||||
msgstr "Mitglied einladen"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:195
|
||||
#: src/views/members/components/InviteMemberForm.tsx:196
|
||||
msgid "Inviting members requires a Team Plan. You'll be redirected to upgrade your workspace."
|
||||
msgstr "Das Einladen von Mitgliedern erfordert einen Team-Plan. Sie werden weitergeleitet, um Ihren Workspace zu upgraden."
|
||||
|
||||
@@ -998,10 +1011,23 @@ msgstr "Labels"
|
||||
msgid "Labels & Filters"
|
||||
msgstr "Labels & Filter"
|
||||
|
||||
#: src/views/settings/index.tsx:187
|
||||
#: src/views/settings/index.tsx:224
|
||||
msgid "Language"
|
||||
msgstr "Sprache"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:332
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:67
|
||||
msgid "Launch offer"
|
||||
msgstr "Einführungsangebot"
|
||||
|
||||
#: src/views/members/index.tsx:191
|
||||
msgid "Launch offer: Get unlimited members with Pro"
|
||||
msgstr "Einführungsangebot: Erhalten Sie unbegrenzte Mitglieder mit Pro"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:99
|
||||
msgid "Launch offer: unlimited seats for just $29/month with Pro"
|
||||
msgstr "Einführungsangebot: unbegrenzte Plätze für nur $29/Monat mit Pro"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:83
|
||||
msgid "Learning"
|
||||
msgstr "Lernen"
|
||||
@@ -1067,12 +1093,12 @@ msgstr "Mittlere Priorität"
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:357
|
||||
#: src/views/card/index.tsx:125
|
||||
#: src/views/members/index.tsx:171
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Mitglieder"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/members/index.tsx:167
|
||||
#: src/views/members/index.tsx:173
|
||||
msgid "Members | {0}"
|
||||
msgstr "Mitglieder | {0}"
|
||||
|
||||
@@ -1080,7 +1106,7 @@ msgstr "Mitglieder | {0}"
|
||||
msgid "Monthly"
|
||||
msgstr "Monatlich"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:93
|
||||
msgid "monthly billing"
|
||||
msgstr "monatliche Abrechnung"
|
||||
|
||||
@@ -1144,7 +1170,7 @@ msgstr "Neues Passwort muss sich vom aktuellen Passwort unterscheiden"
|
||||
msgid "New Ticket"
|
||||
msgstr "Neues Ticket"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:65
|
||||
#: src/components/NewWorkspaceForm.tsx:240
|
||||
msgid "New workspace"
|
||||
msgstr "Neuer Workspace"
|
||||
|
||||
@@ -1180,11 +1206,11 @@ msgstr "Angebot"
|
||||
msgid "Onboarding"
|
||||
msgstr "Einarbeitung"
|
||||
|
||||
#: src/views/settings/index.tsx:312
|
||||
#: src/views/settings/index.tsx:349
|
||||
msgid "Once you delete your account, there is no going back. This action cannot be undone."
|
||||
msgstr "Sobald Sie Ihr Konto löschen, gibt es kein Zurück mehr. Diese Aktion kann nicht rückgängig gemacht werden."
|
||||
|
||||
#: src/views/settings/index.tsx:275
|
||||
#: src/views/settings/index.tsx:312
|
||||
msgid "Once you delete your workspace, there is no going back. This action cannot be undone."
|
||||
msgstr "Sobald Sie Ihren Arbeitsbereich löschen, gibt es kein Zurück mehr. Diese Aktion kann nicht rückgängig gemacht werden."
|
||||
|
||||
@@ -1216,11 +1242,11 @@ msgstr "Passwort muss mindestens 8 Zeichen lang sein"
|
||||
msgid "Passwords do not match"
|
||||
msgstr "Passwörter stimmen nicht überein"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:96
|
||||
#: src/views/home/components/Pricing.tsx:102
|
||||
msgid "Payment frequency"
|
||||
msgstr "Zahlungshäufigkeit"
|
||||
|
||||
#: src/views/members/index.tsx:128
|
||||
#: src/views/members/index.tsx:134
|
||||
msgid "Pending"
|
||||
msgstr "Ausstehend"
|
||||
|
||||
@@ -1259,7 +1285,7 @@ msgstr "Bitte wähle eine Datei zum Hochladen aus."
|
||||
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:42
|
||||
#: src/components/NewWorkspaceForm.tsx:155
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
@@ -1282,8 +1308,8 @@ msgstr "Bitte wähle eine Datei zum Hochladen aus."
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:173
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:83
|
||||
#: src/views/members/components/InviteMemberForm.tsx:133
|
||||
#: src/views/members/components/InviteMemberForm.tsx:78
|
||||
#: src/views/members/components/InviteMemberForm.tsx:131
|
||||
#: src/views/settings/components/Avatar.tsx:40
|
||||
#: src/views/settings/components/Avatar.tsx:98
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
|
||||
@@ -1292,6 +1318,7 @@ msgstr "Bitte wähle eine Datei zum Hochladen aus."
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:62
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:57
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:74
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:42
|
||||
msgid "Please try again later, or contact customer support."
|
||||
msgstr "Bitte versuche es später noch einmal oder kontaktiere den Kundensupport."
|
||||
|
||||
@@ -1302,6 +1329,7 @@ msgid "Pricing"
|
||||
msgstr "Preise"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:56
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:91
|
||||
msgid "Priority email support"
|
||||
msgstr "Prioritäts-E-Mail-Support"
|
||||
|
||||
@@ -1313,11 +1341,19 @@ msgstr "Datenschutzrichtlinie"
|
||||
msgid "Private"
|
||||
msgstr "Privat"
|
||||
|
||||
#: src/views/members/index.tsx:205
|
||||
msgid "Pro Plan"
|
||||
msgstr "Pro-Plan"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
msgid "Pro Plan ∞"
|
||||
msgstr "Pro-Plan ∞"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:26
|
||||
msgid "Profile image updated"
|
||||
msgstr "Profilbild aktualisiert"
|
||||
|
||||
#: src/views/settings/index.tsx:146
|
||||
#: src/views/settings/index.tsx:171
|
||||
msgid "Profile picture"
|
||||
msgstr "Profilbild"
|
||||
|
||||
@@ -1353,7 +1389,7 @@ msgstr "Remote"
|
||||
msgid "Remove"
|
||||
msgstr "Entfernen"
|
||||
|
||||
#: src/views/members/index.tsx:142
|
||||
#: src/views/members/index.tsx:148
|
||||
msgid "Remove member"
|
||||
msgstr "Mitglied entfernen"
|
||||
|
||||
@@ -1409,7 +1445,7 @@ msgstr "Widerrufen"
|
||||
msgid "Roadmap"
|
||||
msgstr "Roadmap"
|
||||
|
||||
#: src/views/members/index.tsx:215
|
||||
#: src/views/members/index.tsx:243
|
||||
msgid "Role"
|
||||
msgstr "Rolle"
|
||||
|
||||
@@ -1458,12 +1494,12 @@ msgid "Senior"
|
||||
msgstr "Senior"
|
||||
|
||||
#: src/components/SideNavigation.tsx:78
|
||||
#: src/views/settings/index.tsx:140
|
||||
#: src/views/settings/index.tsx:165
|
||||
msgid "Settings"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/settings/index.tsx:136
|
||||
#: src/views/settings/index.tsx:161
|
||||
msgid "Settings | {0}"
|
||||
msgstr "Einstellungen | {0}"
|
||||
|
||||
@@ -1514,6 +1550,10 @@ msgstr "Stern auf Github"
|
||||
msgid "Success"
|
||||
msgstr "Erfolg"
|
||||
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:55
|
||||
msgid "Supercharge your workspace for just $29/month. Here's what you'll get:"
|
||||
msgstr "Optimiere deinen Workspace für nur $29/Monat. Das bekommst du dafür:"
|
||||
|
||||
#: src/components/UserMenu.tsx:180
|
||||
msgid "Support"
|
||||
msgstr "Support"
|
||||
@@ -1526,8 +1566,8 @@ msgstr "Unterstütze die Entwicklung des Projekts"
|
||||
msgid "System"
|
||||
msgstr "System"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:183
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
#: src/views/members/index.tsx:207
|
||||
msgid "Team Plan"
|
||||
msgstr "Team-Plan"
|
||||
|
||||
@@ -1595,6 +1635,14 @@ msgstr "Dies führt zur permanenten Löschung aller mit diesem Workspace verbund
|
||||
msgid "This will result in the permanent deletion of all data associated with your account."
|
||||
msgstr "Dies führt zur permanenten Löschung aller mit deinem Konto verbundenen Daten."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:284
|
||||
msgid "This workspace URL has already been taken"
|
||||
msgstr "Diese Workspace-URL ist bereits vergeben"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:286
|
||||
msgid "This workspace URL is reserved"
|
||||
msgstr "Diese Workspace-URL ist reserviert"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:123
|
||||
msgid "This workspace username has already been taken"
|
||||
msgstr "Dieser Workspace-Benutzername ist bereits vergeben"
|
||||
@@ -1612,7 +1660,7 @@ msgstr "Menü umschalten"
|
||||
msgid "Track all card changes with detailed activity history."
|
||||
msgstr "Verfolge alle kartenänderungen mit detaillierter aktivitätshistorie."
|
||||
|
||||
#: src/views/settings/index.tsx:94
|
||||
#: src/views/settings/index.tsx:119
|
||||
msgid "Trello disconnected"
|
||||
msgstr "Trello getrennt"
|
||||
|
||||
@@ -1644,7 +1692,7 @@ msgstr "Checkliste kann nicht erstellt werden"
|
||||
msgid "Unable to create list"
|
||||
msgstr "Liste konnte nicht erstellt werden"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:154
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Workspace konnte nicht erstellt werden"
|
||||
|
||||
@@ -1743,6 +1791,11 @@ msgstr "Unbegrenzte kommentare"
|
||||
msgid "Unlimited lists"
|
||||
msgstr "Unbegrenzte listen"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:329
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:64
|
||||
msgid "Unlimited members"
|
||||
msgstr "Unbegrenzte Mitglieder"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
|
||||
@@ -1772,11 +1825,20 @@ msgstr "hat den Titel aktualisiert"
|
||||
msgid "updated the title to <0>{0}</0>"
|
||||
msgstr "hat den Titel in <0>{0}</0> geändert"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:52
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:109
|
||||
msgid "Upgrade"
|
||||
msgstr "Upgrade"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:222
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:52
|
||||
#: src/views/settings/index.tsx:216
|
||||
msgid "Upgrade to Pro"
|
||||
msgstr "Upgrade auf Pro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:369
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Upgrade auf Pro ($29/Monat)"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:224
|
||||
msgid "Upgrade to Team Plan"
|
||||
msgstr "Upgrade auf Team-Plan"
|
||||
|
||||
@@ -1785,14 +1847,17 @@ msgstr "Upgrade auf Team-Plan"
|
||||
msgid "Urgent"
|
||||
msgstr "Dringend"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:35
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:36
|
||||
msgid "URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "URL darf nur Buchstaben, Zahlen und Bindestriche enthalten"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:33
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:34
|
||||
msgid "URL cannot exceed 24 characters"
|
||||
msgstr "URL darf nicht länger als 24 Zeichen sein"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:31
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:32
|
||||
msgid "URL must be at least 3 characters long"
|
||||
msgstr "URL muss mindestens 3 Zeichen lang sein"
|
||||
@@ -1801,11 +1866,11 @@ msgstr "URL muss mindestens 3 Zeichen lang sein"
|
||||
msgid "Use template"
|
||||
msgstr "Vorlage verwenden"
|
||||
|
||||
#: src/views/members/index.tsx:209
|
||||
#: src/views/members/index.tsx:237
|
||||
msgid "User"
|
||||
msgstr "Benutzer"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
#: src/views/members/components/InviteMemberForm.tsx:72
|
||||
msgid "User is already a member of this workspace"
|
||||
msgstr "Benutzer ist bereits Mitglied dieses Arbeitsbereichs"
|
||||
|
||||
@@ -1813,11 +1878,11 @@ msgstr "Benutzer ist bereits Mitglied dieses Arbeitsbereichs"
|
||||
msgid "Video"
|
||||
msgstr "Video"
|
||||
|
||||
#: src/views/settings/index.tsx:262
|
||||
#: src/views/settings/index.tsx:299
|
||||
msgid "View and manage your API keys."
|
||||
msgstr "API-Schlüssel anzeigen und verwalten."
|
||||
|
||||
#: src/views/settings/index.tsx:201
|
||||
#: src/views/settings/index.tsx:238
|
||||
msgid "View and manage your billing and subscription."
|
||||
msgstr "Verwalte deine Abrechnung und dein Abonnement."
|
||||
|
||||
@@ -1873,11 +1938,15 @@ msgstr "Warum ein open source Trello entwickeln?"
|
||||
msgid "Workspace"
|
||||
msgstr "Arbeitsbereich"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:143
|
||||
msgid "Workspace created successfully. You can upgrade later in settings."
|
||||
msgstr "Workspace erfolgreich erstellt. Du kannst später in den Einstellungen upgraden."
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:26
|
||||
msgid "Workspace deleted"
|
||||
msgstr "Workspace gelöscht"
|
||||
|
||||
#: src/views/settings/index.tsx:177
|
||||
#: src/views/settings/index.tsx:202
|
||||
msgid "Workspace description"
|
||||
msgstr "Workspace-Beschreibung"
|
||||
|
||||
@@ -1898,8 +1967,8 @@ msgstr "Workspace-Beschreibung aktualisiert"
|
||||
msgid "Workspace members"
|
||||
msgstr "Workspace-mitglieder"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:81
|
||||
#: src/views/settings/index.tsx:158
|
||||
#: src/components/NewWorkspaceForm.tsx:259
|
||||
#: src/views/settings/index.tsx:183
|
||||
msgid "Workspace name"
|
||||
msgstr "Name des Workspaces"
|
||||
|
||||
@@ -1907,6 +1976,10 @@ msgstr "Name des Workspaces"
|
||||
msgid "Workspace name cannot exceed 24 characters"
|
||||
msgstr "Der Workspace-Name darf nicht länger als 24 Zeichen sein"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:27
|
||||
msgid "Workspace name is required"
|
||||
msgstr "Workspace-Name ist erforderlich"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:14
|
||||
msgid "Workspace name must be at least 3 characters long"
|
||||
msgstr "Der Workspace-Name muss mindestens 3 Zeichen lang sein"
|
||||
@@ -1919,10 +1992,14 @@ msgstr "Workspace-Name aktualisiert"
|
||||
msgid "Workspace slug updated"
|
||||
msgstr "Workspace-Slug aktualisiert"
|
||||
|
||||
#: src/views/settings/index.tsx:167
|
||||
#: src/views/settings/index.tsx:192
|
||||
msgid "Workspace URL"
|
||||
msgstr "Workspace-URL"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:273
|
||||
msgid "workspace-url"
|
||||
msgstr "workspace-url"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:30
|
||||
msgid "Writing"
|
||||
msgstr "Schreiben"
|
||||
@@ -1935,7 +2012,7 @@ msgstr "Jährlich"
|
||||
msgid "Yes, we offer an forever free plan for individual use. No restrictions, no paywalls, no limits."
|
||||
msgstr "Ja, wir bieten einen dauerhaft kostenlosen plan für die individuelle nutzung an. Keine einschränkungen, keine paywalls, keine limits."
|
||||
|
||||
#: src/views/settings/index.tsx:294
|
||||
#: src/views/settings/index.tsx:331
|
||||
msgid "You are about to change your password."
|
||||
msgstr "Sie sind dabei, Ihr Passwort zu ändern."
|
||||
|
||||
@@ -1959,6 +2036,10 @@ msgstr "Sie haben sich erfolgreich angemeldet."
|
||||
msgid "You have been signed up successfully."
|
||||
msgstr "Sie haben sich erfolgreich registriert."
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
msgid "You have unlimited seats with your Pro Plan. There is no additional charge for new members!"
|
||||
msgstr "Sie haben unbegrenzte Plätze mit Ihrem Pro-Plan. Für neue Mitglieder fallen keine zusätzlichen Kosten an!"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:28
|
||||
msgid "Your account has been deleted."
|
||||
msgstr "Dein Konto wurde gelöscht."
|
||||
@@ -1979,11 +2060,11 @@ msgstr "Ihr Passwort wurde geändert."
|
||||
msgid "Your profile image has been updated."
|
||||
msgstr "Dein Profilbild wurde aktualisiert."
|
||||
|
||||
#: src/views/settings/index.tsx:95
|
||||
#: src/views/settings/index.tsx:120
|
||||
msgid "Your Trello account has been disconnected."
|
||||
msgstr "Dein Trello-Konto wurde getrennt."
|
||||
|
||||
#: src/views/settings/index.tsx:244
|
||||
#: src/views/settings/index.tsx:281
|
||||
msgid "Your Trello account is connected."
|
||||
msgstr "Dein Trello-Konto ist verbunden."
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -40,12 +40,12 @@ msgstr "{boardCount, plural, one {Import board (1)} other {Import boards ({board
|
||||
#~ msgid "#1 Hacker News"
|
||||
#~ msgstr "#1 Hacker News"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:91
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$10/month"
|
||||
msgstr "$10/month"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$8/month"
|
||||
msgstr "$8/month"
|
||||
|
||||
@@ -113,7 +113,7 @@ msgid "Add label"
|
||||
msgstr "Add label"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:130
|
||||
#: src/views/members/components/InviteMemberForm.tsx:149
|
||||
#: src/views/members/components/InviteMemberForm.tsx:147
|
||||
msgid "Add member"
|
||||
msgstr "Add member"
|
||||
|
||||
@@ -152,7 +152,7 @@ msgstr "added label <0>{0}</0>"
|
||||
#~ msgid "added label <0>{label}</0>"
|
||||
#~ msgstr "added label <0>{label}</0>"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
#: src/views/members/components/InviteMemberForm.tsx:187
|
||||
msgid "Adding a new member will cost an additional {price} ({billingType}) per seat."
|
||||
msgstr "Adding a new member will cost an additional {price} ({billingType}) per seat."
|
||||
|
||||
@@ -172,7 +172,7 @@ msgstr "All systems operational"
|
||||
msgid "Already have an account? <0><1>Sign in</1></0>"
|
||||
msgstr "Already have an account? <0><1>Sign in</1></0>"
|
||||
|
||||
#: src/views/settings/index.tsx:102
|
||||
#: src/views/settings/index.tsx:127
|
||||
msgid "An error occurred while disconnecting your Trello account."
|
||||
msgstr "An error occurred while disconnecting your Trello account."
|
||||
|
||||
@@ -180,7 +180,7 @@ msgstr "An error occurred while disconnecting your Trello account."
|
||||
msgid "An unexpected error occurred. Please try again later."
|
||||
msgstr "An unexpected error occurred. Please try again later."
|
||||
|
||||
#: src/views/settings/index.tsx:259
|
||||
#: src/views/settings/index.tsx:296
|
||||
msgid "API keys"
|
||||
msgstr "API keys"
|
||||
|
||||
@@ -254,20 +254,20 @@ msgstr "Backlog"
|
||||
msgid "Basic Kanban"
|
||||
msgstr "Basic Kanban"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed annually"
|
||||
msgstr "billed annually"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed monthly"
|
||||
msgstr "billed monthly"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
#: src/views/settings/index.tsx:198
|
||||
#: src/views/settings/index.tsx:235
|
||||
msgid "Billing"
|
||||
msgstr "Billing"
|
||||
|
||||
#: src/views/settings/index.tsx:208
|
||||
#: src/views/settings/index.tsx:245
|
||||
msgid "Billing portal"
|
||||
msgstr "Billing portal"
|
||||
|
||||
@@ -279,6 +279,16 @@ msgstr "Blog Post"
|
||||
msgid "Board"
|
||||
msgstr "Board"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:346
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:81
|
||||
msgid "Board analytics"
|
||||
msgstr "Board analytics"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:310
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:80
|
||||
#~ msgid "Board analytics (coming soon)"
|
||||
#~ msgstr "Board analytics (coming soon)"
|
||||
|
||||
#: src/views/boards/components/NewBoardForm.tsx:21
|
||||
msgid "Board name cannot exceed 100 characters"
|
||||
msgstr "Board name cannot exceed 100 characters"
|
||||
@@ -353,9 +363,9 @@ msgstr "Bug Report"
|
||||
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:168
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:50
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:88
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:98
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:104
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
@@ -369,12 +379,12 @@ msgstr "Card title"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:109
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:178
|
||||
#: src/views/settings/index.tsx:291
|
||||
#: src/views/settings/index.tsx:301
|
||||
#: src/views/settings/index.tsx:328
|
||||
#: src/views/settings/index.tsx:338
|
||||
msgid "Change Password"
|
||||
msgstr "Change Password"
|
||||
|
||||
#: src/views/settings/index.tsx:190
|
||||
#: src/views/settings/index.tsx:227
|
||||
msgid "Change the language of the app."
|
||||
msgstr "Change the language of the app."
|
||||
|
||||
@@ -404,7 +414,9 @@ msgstr "Code Review"
|
||||
msgid "Collaborate seamlessly with your team."
|
||||
msgstr "Collaborate seamlessly with your team."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:349
|
||||
#: src/views/home/components/Features.tsx:66
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:84
|
||||
msgid "Coming soon"
|
||||
msgstr "Coming soon"
|
||||
|
||||
@@ -433,16 +445,16 @@ msgstr "completed a checklist item"
|
||||
msgid "completed checklist item <0>{0}</0>"
|
||||
msgstr "completed checklist item <0>{0}</0>"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:42
|
||||
msgid "Confirm URL change"
|
||||
msgstr "Confirm URL change"
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:47
|
||||
#~ msgid "Confirm URL change"
|
||||
#~ msgstr "Confirm URL change"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:150
|
||||
msgid "Confirm your new password"
|
||||
msgstr "Confirm your new password"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:157
|
||||
#: src/views/settings/index.tsx:235
|
||||
#: src/views/settings/index.tsx:272
|
||||
msgid "Connect Trello"
|
||||
msgstr "Connect Trello"
|
||||
|
||||
@@ -450,7 +462,7 @@ msgstr "Connect Trello"
|
||||
msgid "Connect your favorite tools to streamline your workflow."
|
||||
msgstr "Connect your favorite tools to streamline your workflow."
|
||||
|
||||
#: src/views/settings/index.tsx:222
|
||||
#: src/views/settings/index.tsx:259
|
||||
msgid "Connect your Trello account to import boards."
|
||||
msgstr "Connect your Trello account to import boards."
|
||||
|
||||
@@ -530,7 +542,11 @@ msgstr "Create new label"
|
||||
msgid "Create new list"
|
||||
msgstr "Create new list"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:94
|
||||
#: src/components/NewWorkspaceForm.tsx:337
|
||||
#~ msgid "Create Pro workspace"
|
||||
#~ msgstr "Create Pro workspace"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:384
|
||||
#: src/components/WorkspaceMenu.tsx:116
|
||||
msgid "Create workspace"
|
||||
msgstr "Create workspace"
|
||||
@@ -551,9 +567,22 @@ msgstr "Current password is required"
|
||||
msgid "Custom domain"
|
||||
msgstr "Custom domain"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:45
|
||||
msgid "Custom URLs are a premium feature. You'll be directed to upgrade your account."
|
||||
msgstr "Custom URLs are a premium feature. You'll be directed to upgrade your account."
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:50
|
||||
#~ msgid "Custom URLs are a premium feature. You'll be directed to upgrade your account."
|
||||
#~ msgstr "Custom URLs are a premium feature. You'll be directed to upgrade your account."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:280
|
||||
#~ msgid "Custom URLs require Pro plan ($29/month)"
|
||||
#~ msgstr "Custom URLs require Pro plan ($29/month)"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:315
|
||||
msgid "Custom URLs require upgrading to a Pro plan"
|
||||
msgstr "Custom URLs require upgrading to a Pro plan"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:339
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:74
|
||||
msgid "Custom workspace URL"
|
||||
msgstr "Custom workspace URL"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:41
|
||||
msgid "Customer Support"
|
||||
@@ -572,8 +601,8 @@ msgid "Delete"
|
||||
msgstr "Delete"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:96
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:319
|
||||
#: src/views/settings/index.tsx:346
|
||||
#: src/views/settings/index.tsx:356
|
||||
msgid "Delete account"
|
||||
msgstr "Delete account"
|
||||
|
||||
@@ -594,8 +623,8 @@ msgid "Delete list"
|
||||
msgstr "Delete list"
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:106
|
||||
#: src/views/settings/index.tsx:272
|
||||
#: src/views/settings/index.tsx:283
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:320
|
||||
msgid "Delete workspace"
|
||||
msgstr "Delete workspace"
|
||||
|
||||
@@ -621,7 +650,7 @@ msgstr "deleted checklist item <0>{0}</0>"
|
||||
msgid "Design"
|
||||
msgstr "Design"
|
||||
|
||||
#: src/views/settings/index.tsx:250
|
||||
#: src/views/settings/index.tsx:287
|
||||
msgid "Disconnect Trello"
|
||||
msgstr "Disconnect Trello"
|
||||
|
||||
@@ -629,7 +658,7 @@ msgstr "Disconnect Trello"
|
||||
msgid "Discuss and collaborate on cards."
|
||||
msgstr "Discuss and collaborate on cards."
|
||||
|
||||
#: src/views/settings/index.tsx:151
|
||||
#: src/views/settings/index.tsx:176
|
||||
msgid "Display name"
|
||||
msgstr "Display name"
|
||||
|
||||
@@ -699,7 +728,7 @@ msgstr "Editing"
|
||||
msgid "email"
|
||||
msgstr "email"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:163
|
||||
#: src/views/members/components/InviteMemberForm.tsx:161
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
|
||||
@@ -747,12 +776,12 @@ msgstr "Error deleting label"
|
||||
msgid "Error deleting workspace"
|
||||
msgstr "Error deleting workspace"
|
||||
|
||||
#: src/views/settings/index.tsx:101
|
||||
#: src/views/settings/index.tsx:126
|
||||
msgid "Error disconnecting Trello"
|
||||
msgstr "Error disconnecting Trello"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:76
|
||||
#: src/views/members/components/InviteMemberForm.tsx:82
|
||||
#: src/views/members/components/InviteMemberForm.tsx:71
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
msgid "Error inviting member"
|
||||
msgstr "Error inviting member"
|
||||
|
||||
@@ -776,10 +805,15 @@ msgstr "Error updating workspace name"
|
||||
msgid "Error updating workspace URL"
|
||||
msgstr "Error updating workspace URL"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:132
|
||||
#: src/views/members/components/InviteMemberForm.tsx:130
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:41
|
||||
msgid "Error upgrading subscription"
|
||||
msgstr "Error upgrading subscription"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:142
|
||||
msgid "Error upgrading to Pro"
|
||||
msgstr "Error upgrading to Pro"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:56
|
||||
#: src/views/settings/components/Avatar.tsx:97
|
||||
msgid "Error uploading profile image"
|
||||
@@ -847,8 +881,8 @@ msgstr "For long-term sustainability, we recognise all good open source projects
|
||||
msgid "Free"
|
||||
msgstr "Free"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:192
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:193
|
||||
#: src/views/members/index.tsx:208
|
||||
msgid "Free Plan"
|
||||
msgstr "Free Plan"
|
||||
|
||||
@@ -1007,24 +1041,24 @@ msgstr "Integrations"
|
||||
msgid "Interviewing"
|
||||
msgstr "Interviewing"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:45
|
||||
#: src/views/members/components/InviteMemberForm.tsx:40
|
||||
msgid "Invalid email address"
|
||||
msgstr "Invalid email address"
|
||||
|
||||
#: src/views/members/index.tsx:193
|
||||
#: src/views/members/index.tsx:221
|
||||
msgid "Invite"
|
||||
msgstr "Invite"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:207
|
||||
#: src/views/members/components/InviteMemberForm.tsx:208
|
||||
msgid "Invite another"
|
||||
msgstr "Invite another"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:112
|
||||
#: src/views/members/components/InviteMemberForm.tsx:231
|
||||
#: src/views/members/components/InviteMemberForm.tsx:233
|
||||
msgid "Invite member"
|
||||
msgstr "Invite member"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:195
|
||||
#: src/views/members/components/InviteMemberForm.tsx:196
|
||||
msgid "Inviting members requires a Team Plan. You'll be redirected to upgrade your workspace."
|
||||
msgstr "Inviting members requires a Team Plan. You'll be redirected to upgrade your workspace."
|
||||
|
||||
@@ -1055,10 +1089,23 @@ msgstr "Labels"
|
||||
msgid "Labels & Filters"
|
||||
msgstr "Labels & Filters"
|
||||
|
||||
#: src/views/settings/index.tsx:187
|
||||
#: src/views/settings/index.tsx:224
|
||||
msgid "Language"
|
||||
msgstr "Language"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:332
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:67
|
||||
msgid "Launch offer"
|
||||
msgstr "Launch offer"
|
||||
|
||||
#: src/views/members/index.tsx:191
|
||||
msgid "Launch offer: Get unlimited members with Pro"
|
||||
msgstr "Launch offer: Get unlimited members with Pro"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:99
|
||||
msgid "Launch offer: unlimited seats for just $29/month with Pro"
|
||||
msgstr "Launch offer: unlimited seats for just $29/month with Pro"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:83
|
||||
msgid "Learning"
|
||||
msgstr "Learning"
|
||||
@@ -1124,12 +1171,12 @@ msgstr "Medium Priority"
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:357
|
||||
#: src/views/card/index.tsx:125
|
||||
#: src/views/members/index.tsx:171
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Members"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/members/index.tsx:167
|
||||
#: src/views/members/index.tsx:173
|
||||
msgid "Members | {0}"
|
||||
msgstr "Members | {0}"
|
||||
|
||||
@@ -1137,7 +1184,7 @@ msgstr "Members | {0}"
|
||||
msgid "Monthly"
|
||||
msgstr "Monthly"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:93
|
||||
msgid "monthly billing"
|
||||
msgstr "monthly billing"
|
||||
|
||||
@@ -1155,6 +1202,10 @@ msgstr "moved the card from <0>{0}</0> to<1>{1}</1>"
|
||||
msgid "moved the card to another list"
|
||||
msgstr "moved the card to another list"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:273
|
||||
#~ msgid "my-workspace-name"
|
||||
#~ msgstr "my-workspace-name"
|
||||
|
||||
#: src/components/LabelForm.tsx:135
|
||||
#: src/views/boards/components/NewBoardForm.tsx:99
|
||||
msgid "Name"
|
||||
@@ -1209,7 +1260,7 @@ msgstr "New Ticket"
|
||||
#~ msgid "New Ticket, Triaging, In Progress, Awaiting Customer, Resolution, Done"
|
||||
#~ msgstr "New Ticket, Triaging, In Progress, Awaiting Customer, Resolution, Done"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:65
|
||||
#: src/components/NewWorkspaceForm.tsx:240
|
||||
msgid "New workspace"
|
||||
msgstr "New workspace"
|
||||
|
||||
@@ -1245,11 +1296,11 @@ msgstr "Offer"
|
||||
msgid "Onboarding"
|
||||
msgstr "Onboarding"
|
||||
|
||||
#: src/views/settings/index.tsx:312
|
||||
#: src/views/settings/index.tsx:349
|
||||
msgid "Once you delete your account, there is no going back. This action cannot be undone."
|
||||
msgstr "Once you delete your account, there is no going back. This action cannot be undone."
|
||||
|
||||
#: src/views/settings/index.tsx:275
|
||||
#: src/views/settings/index.tsx:312
|
||||
msgid "Once you delete your workspace, there is no going back. This action cannot be undone."
|
||||
msgstr "Once you delete your workspace, there is no going back. This action cannot be undone."
|
||||
|
||||
@@ -1281,11 +1332,11 @@ msgstr "Password must be at least 8 characters"
|
||||
msgid "Passwords do not match"
|
||||
msgstr "Passwords do not match"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:96
|
||||
#: src/views/home/components/Pricing.tsx:102
|
||||
msgid "Payment frequency"
|
||||
msgstr "Payment frequency"
|
||||
|
||||
#: src/views/members/index.tsx:128
|
||||
#: src/views/members/index.tsx:134
|
||||
msgid "Pending"
|
||||
msgstr "Pending"
|
||||
|
||||
@@ -1324,7 +1375,7 @@ msgstr "Please select a file to upload."
|
||||
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:42
|
||||
#: src/components/NewWorkspaceForm.tsx:155
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
@@ -1347,8 +1398,8 @@ msgstr "Please select a file to upload."
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:173
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:83
|
||||
#: src/views/members/components/InviteMemberForm.tsx:133
|
||||
#: src/views/members/components/InviteMemberForm.tsx:78
|
||||
#: src/views/members/components/InviteMemberForm.tsx:131
|
||||
#: src/views/settings/components/Avatar.tsx:40
|
||||
#: src/views/settings/components/Avatar.tsx:98
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
|
||||
@@ -1357,6 +1408,7 @@ msgstr "Please select a file to upload."
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:62
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:57
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:74
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:42
|
||||
msgid "Please try again later, or contact customer support."
|
||||
msgstr "Please try again later, or contact customer support."
|
||||
|
||||
@@ -1367,6 +1419,7 @@ msgid "Pricing"
|
||||
msgstr "Pricing"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:56
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:91
|
||||
msgid "Priority email support"
|
||||
msgstr "Priority email support"
|
||||
|
||||
@@ -1378,11 +1431,19 @@ msgstr "Privacy policy"
|
||||
msgid "Private"
|
||||
msgstr "Private"
|
||||
|
||||
#: src/views/members/index.tsx:205
|
||||
msgid "Pro Plan"
|
||||
msgstr "Pro Plan"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
msgid "Pro Plan ∞"
|
||||
msgstr "Pro Plan ∞"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:26
|
||||
msgid "Profile image updated"
|
||||
msgstr "Profile image updated"
|
||||
|
||||
#: src/views/settings/index.tsx:146
|
||||
#: src/views/settings/index.tsx:171
|
||||
msgid "Profile picture"
|
||||
msgstr "Profile picture"
|
||||
|
||||
@@ -1418,7 +1479,7 @@ msgstr "Remote"
|
||||
msgid "Remove"
|
||||
msgstr "Remove"
|
||||
|
||||
#: src/views/members/index.tsx:142
|
||||
#: src/views/members/index.tsx:148
|
||||
msgid "Remove member"
|
||||
msgstr "Remove member"
|
||||
|
||||
@@ -1478,7 +1539,7 @@ msgstr "Revoke"
|
||||
msgid "Roadmap"
|
||||
msgstr "Roadmap"
|
||||
|
||||
#: src/views/members/index.tsx:215
|
||||
#: src/views/members/index.tsx:243
|
||||
msgid "Role"
|
||||
msgstr "Role"
|
||||
|
||||
@@ -1531,12 +1592,12 @@ msgid "Senior"
|
||||
msgstr "Senior"
|
||||
|
||||
#: src/components/SideNavigation.tsx:78
|
||||
#: src/views/settings/index.tsx:140
|
||||
#: src/views/settings/index.tsx:165
|
||||
msgid "Settings"
|
||||
msgstr "Settings"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/settings/index.tsx:136
|
||||
#: src/views/settings/index.tsx:161
|
||||
msgid "Settings | {0}"
|
||||
msgstr "Settings | {0}"
|
||||
|
||||
@@ -1587,6 +1648,10 @@ msgstr "Star on Github"
|
||||
msgid "Success"
|
||||
msgstr "Success"
|
||||
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:55
|
||||
msgid "Supercharge your workspace for just $29/month. Here's what you'll get:"
|
||||
msgstr "Supercharge your workspace for just $29/month. Here's what you'll get:"
|
||||
|
||||
#: src/components/UserMenu.tsx:180
|
||||
msgid "Support"
|
||||
msgstr "Support"
|
||||
@@ -1599,8 +1664,8 @@ msgstr "Support the development of the project"
|
||||
msgid "System"
|
||||
msgstr "System"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:183
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
#: src/views/members/index.tsx:207
|
||||
msgid "Team Plan"
|
||||
msgstr "Team Plan"
|
||||
|
||||
@@ -1668,6 +1733,14 @@ msgstr "This will result in the permanent deletion of all data associated with t
|
||||
msgid "This will result in the permanent deletion of all data associated with your account."
|
||||
msgstr "This will result in the permanent deletion of all data associated with your account."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:284
|
||||
msgid "This workspace URL has already been taken"
|
||||
msgstr "This workspace URL has already been taken"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:286
|
||||
msgid "This workspace URL is reserved"
|
||||
msgstr "This workspace URL is reserved"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:123
|
||||
msgid "This workspace username has already been taken"
|
||||
msgstr "This workspace username has already been taken"
|
||||
@@ -1689,7 +1762,7 @@ msgstr "Toggle menu"
|
||||
msgid "Track all card changes with detailed activity history."
|
||||
msgstr "Track all card changes with detailed activity history."
|
||||
|
||||
#: src/views/settings/index.tsx:94
|
||||
#: src/views/settings/index.tsx:119
|
||||
msgid "Trello disconnected"
|
||||
msgstr "Trello disconnected"
|
||||
|
||||
@@ -1721,7 +1794,7 @@ msgstr "Unable to create checklist"
|
||||
msgid "Unable to create list"
|
||||
msgstr "Unable to create list"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:154
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Unable to create workspace"
|
||||
|
||||
@@ -1824,6 +1897,11 @@ msgstr "Unlimited comments"
|
||||
msgid "Unlimited lists"
|
||||
msgstr "Unlimited lists"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:329
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:64
|
||||
msgid "Unlimited members"
|
||||
msgstr "Unlimited members"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
|
||||
@@ -1857,11 +1935,20 @@ msgstr "updated the title to <0>{0}</0>"
|
||||
#~ msgid "updated the title to <0>{toTitle}</0>"
|
||||
#~ msgstr "updated the title to <0>{toTitle}</0>"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:52
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:109
|
||||
msgid "Upgrade"
|
||||
msgstr "Upgrade"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:222
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:52
|
||||
#: src/views/settings/index.tsx:216
|
||||
msgid "Upgrade to Pro"
|
||||
msgstr "Upgrade to Pro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:369
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Upgrade to Pro ($29/month)"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:224
|
||||
msgid "Upgrade to Team Plan"
|
||||
msgstr "Upgrade to Team Plan"
|
||||
|
||||
@@ -1870,14 +1957,17 @@ msgstr "Upgrade to Team Plan"
|
||||
msgid "Urgent"
|
||||
msgstr "Urgent"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:35
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:36
|
||||
msgid "URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "URL can only contain letters, numbers, and hyphens"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:33
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:34
|
||||
msgid "URL cannot exceed 24 characters"
|
||||
msgstr "URL cannot exceed 24 characters"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:31
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:32
|
||||
msgid "URL must be at least 3 characters long"
|
||||
msgstr "URL must be at least 3 characters long"
|
||||
@@ -1886,11 +1976,11 @@ msgstr "URL must be at least 3 characters long"
|
||||
msgid "Use template"
|
||||
msgstr "Use template"
|
||||
|
||||
#: src/views/members/index.tsx:209
|
||||
#: src/views/members/index.tsx:237
|
||||
msgid "User"
|
||||
msgstr "User"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
#: src/views/members/components/InviteMemberForm.tsx:72
|
||||
msgid "User is already a member of this workspace"
|
||||
msgstr "User is already a member of this workspace"
|
||||
|
||||
@@ -1898,11 +1988,11 @@ msgstr "User is already a member of this workspace"
|
||||
msgid "Video"
|
||||
msgstr "Video"
|
||||
|
||||
#: src/views/settings/index.tsx:262
|
||||
#: src/views/settings/index.tsx:299
|
||||
msgid "View and manage your API keys."
|
||||
msgstr "View and manage your API keys."
|
||||
|
||||
#: src/views/settings/index.tsx:201
|
||||
#: src/views/settings/index.tsx:238
|
||||
msgid "View and manage your billing and subscription."
|
||||
msgstr "View and manage your billing and subscription."
|
||||
|
||||
@@ -1962,11 +2052,15 @@ msgstr "Why make an open source Trello?"
|
||||
msgid "Workspace"
|
||||
msgstr "Workspace"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:143
|
||||
msgid "Workspace created successfully. You can upgrade later in settings."
|
||||
msgstr "Workspace created successfully. You can upgrade later in settings."
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:26
|
||||
msgid "Workspace deleted"
|
||||
msgstr "Workspace deleted"
|
||||
|
||||
#: src/views/settings/index.tsx:177
|
||||
#: src/views/settings/index.tsx:202
|
||||
msgid "Workspace description"
|
||||
msgstr "Workspace description"
|
||||
|
||||
@@ -1987,8 +2081,8 @@ msgstr "Workspace description updated"
|
||||
msgid "Workspace members"
|
||||
msgstr "Workspace members"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:81
|
||||
#: src/views/settings/index.tsx:158
|
||||
#: src/components/NewWorkspaceForm.tsx:259
|
||||
#: src/views/settings/index.tsx:183
|
||||
msgid "Workspace name"
|
||||
msgstr "Workspace name"
|
||||
|
||||
@@ -1996,6 +2090,10 @@ msgstr "Workspace name"
|
||||
msgid "Workspace name cannot exceed 24 characters"
|
||||
msgstr "Workspace name cannot exceed 24 characters"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:27
|
||||
msgid "Workspace name is required"
|
||||
msgstr "Workspace name is required"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:14
|
||||
msgid "Workspace name must be at least 3 characters long"
|
||||
msgstr "Workspace name must be at least 3 characters long"
|
||||
@@ -2008,10 +2106,14 @@ msgstr "Workspace name updated"
|
||||
msgid "Workspace slug updated"
|
||||
msgstr "Workspace slug updated"
|
||||
|
||||
#: src/views/settings/index.tsx:167
|
||||
#: src/views/settings/index.tsx:192
|
||||
msgid "Workspace URL"
|
||||
msgstr "Workspace URL"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:273
|
||||
msgid "workspace-url"
|
||||
msgstr "workspace-url"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:30
|
||||
msgid "Writing"
|
||||
msgstr "Writing"
|
||||
@@ -2024,7 +2126,7 @@ msgstr "Yearly"
|
||||
msgid "Yes, we offer an forever free plan for individual use. No restrictions, no paywalls, no limits."
|
||||
msgstr "Yes, we offer an forever free plan for individual use. No restrictions, no paywalls, no limits."
|
||||
|
||||
#: src/views/settings/index.tsx:294
|
||||
#: src/views/settings/index.tsx:331
|
||||
msgid "You are about to change your password."
|
||||
msgstr "You are about to change your password."
|
||||
|
||||
@@ -2048,6 +2150,10 @@ msgstr "You have been logged in successfully."
|
||||
msgid "You have been signed up successfully."
|
||||
msgstr "You have been signed up successfully."
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
msgid "You have unlimited seats with your Pro Plan. There is no additional charge for new members!"
|
||||
msgstr "You have unlimited seats with your Pro Plan. There is no additional charge for new members!"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:28
|
||||
msgid "Your account has been deleted."
|
||||
msgstr "Your account has been deleted."
|
||||
@@ -2068,11 +2174,11 @@ msgstr "Your password has been changed."
|
||||
msgid "Your profile image has been updated."
|
||||
msgstr "Your profile image has been updated."
|
||||
|
||||
#: src/views/settings/index.tsx:95
|
||||
#: src/views/settings/index.tsx:120
|
||||
msgid "Your Trello account has been disconnected."
|
||||
msgstr "Your Trello account has been disconnected."
|
||||
|
||||
#: src/views/settings/index.tsx:244
|
||||
#: src/views/settings/index.tsx:281
|
||||
msgid "Your Trello account is connected."
|
||||
msgstr "Your Trello account is connected."
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -36,12 +36,12 @@ msgstr "{0} etiquetas"
|
||||
msgid "{boardCount, plural, one {Import board (1)} other {Import boards ({boardCount})}}"
|
||||
msgstr "{boardCount, plural, one {Importar tablero (1)} other {Importar tableros ({boardCount})}}"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:91
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$10/month"
|
||||
msgstr "$10/mes"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$8/month"
|
||||
msgstr "$8/mes"
|
||||
|
||||
@@ -97,7 +97,7 @@ msgid "Add label"
|
||||
msgstr "Añadir etiqueta"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:130
|
||||
#: src/views/members/components/InviteMemberForm.tsx:149
|
||||
#: src/views/members/components/InviteMemberForm.tsx:147
|
||||
msgid "Add member"
|
||||
msgstr "Añadir miembro"
|
||||
|
||||
@@ -132,7 +132,7 @@ msgstr "añadió el elemento <0>{0}</0> a la lista de verificación"
|
||||
msgid "added label <0>{0}</0>"
|
||||
msgstr "añadió la etiqueta <0>{0}</0>"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
#: src/views/members/components/InviteMemberForm.tsx:187
|
||||
msgid "Adding a new member will cost an additional {price} ({billingType}) per seat."
|
||||
msgstr "Añadir un nuevo miembro costará {price} adicionales ({billingType}) por asiento."
|
||||
|
||||
@@ -148,7 +148,7 @@ msgstr "Todos los sistemas operativos"
|
||||
msgid "Already have an account? <0><1>Sign in</1></0>"
|
||||
msgstr "¿Ya tienes una cuenta? <0><1>Iniciar sesión</1></0>"
|
||||
|
||||
#: src/views/settings/index.tsx:102
|
||||
#: src/views/settings/index.tsx:127
|
||||
msgid "An error occurred while disconnecting your Trello account."
|
||||
msgstr "Ocurrió un error al desconectar tu cuenta de Trello."
|
||||
|
||||
@@ -156,7 +156,7 @@ msgstr "Ocurrió un error al desconectar tu cuenta de Trello."
|
||||
msgid "An unexpected error occurred. Please try again later."
|
||||
msgstr "Ha ocurrido un error inesperado. Por favor, inténtalo de nuevo más tarde."
|
||||
|
||||
#: src/views/settings/index.tsx:259
|
||||
#: src/views/settings/index.tsx:296
|
||||
msgid "API keys"
|
||||
msgstr "Claves API"
|
||||
|
||||
@@ -218,20 +218,20 @@ msgstr "Pendientes"
|
||||
msgid "Basic Kanban"
|
||||
msgstr "Kanban básico"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed annually"
|
||||
msgstr "facturado anualmente"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed monthly"
|
||||
msgstr "facturado mensualmente"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
#: src/views/settings/index.tsx:198
|
||||
#: src/views/settings/index.tsx:235
|
||||
msgid "Billing"
|
||||
msgstr "Facturación"
|
||||
|
||||
#: src/views/settings/index.tsx:208
|
||||
#: src/views/settings/index.tsx:245
|
||||
msgid "Billing portal"
|
||||
msgstr "Portal de facturación"
|
||||
|
||||
@@ -243,6 +243,11 @@ msgstr "Entrada de blog"
|
||||
msgid "Board"
|
||||
msgstr "Tablero"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:346
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:81
|
||||
msgid "Board analytics"
|
||||
msgstr "Análisis del tablero"
|
||||
|
||||
#: src/views/boards/components/NewBoardForm.tsx:21
|
||||
msgid "Board name cannot exceed 100 characters"
|
||||
msgstr "El nombre del tablero no puede exceder los 100 caracteres"
|
||||
@@ -309,9 +314,9 @@ msgstr "Informe de error"
|
||||
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:168
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:50
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:88
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:98
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:104
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
@@ -325,12 +330,12 @@ msgstr "Título de la tarjeta"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:109
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:178
|
||||
#: src/views/settings/index.tsx:291
|
||||
#: src/views/settings/index.tsx:301
|
||||
#: src/views/settings/index.tsx:328
|
||||
#: src/views/settings/index.tsx:338
|
||||
msgid "Change Password"
|
||||
msgstr "Cambiar contraseña"
|
||||
|
||||
#: src/views/settings/index.tsx:190
|
||||
#: src/views/settings/index.tsx:227
|
||||
msgid "Change the language of the app."
|
||||
msgstr "Cambiar el idioma de la aplicación."
|
||||
|
||||
@@ -360,7 +365,9 @@ msgstr "Revisión de código"
|
||||
msgid "Collaborate seamlessly with your team."
|
||||
msgstr "Colabora sin problemas con tu equipo."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:349
|
||||
#: src/views/home/components/Features.tsx:66
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:84
|
||||
msgid "Coming soon"
|
||||
msgstr "Próximamente"
|
||||
|
||||
@@ -389,16 +396,12 @@ msgstr "completó un elemento de la lista de verificación"
|
||||
msgid "completed checklist item <0>{0}</0>"
|
||||
msgstr "completó el elemento <0>{0}</0> de la lista de verificación"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:42
|
||||
msgid "Confirm URL change"
|
||||
msgstr "Confirmar cambio de URL"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:150
|
||||
msgid "Confirm your new password"
|
||||
msgstr "Confirma tu nueva contraseña"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:157
|
||||
#: src/views/settings/index.tsx:235
|
||||
#: src/views/settings/index.tsx:272
|
||||
msgid "Connect Trello"
|
||||
msgstr "Conectar Trello"
|
||||
|
||||
@@ -406,7 +409,7 @@ msgstr "Conectar Trello"
|
||||
msgid "Connect your favorite tools to streamline your workflow."
|
||||
msgstr "Conecta tus herramientas favoritas para agilizar tu flujo de trabajo."
|
||||
|
||||
#: src/views/settings/index.tsx:222
|
||||
#: src/views/settings/index.tsx:259
|
||||
msgid "Connect your Trello account to import boards."
|
||||
msgstr "Conecta tu cuenta de Trello para importar tableros."
|
||||
|
||||
@@ -478,7 +481,7 @@ msgstr "Crear nueva etiqueta"
|
||||
msgid "Create new list"
|
||||
msgstr "Crear nueva lista"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:94
|
||||
#: src/components/NewWorkspaceForm.tsx:384
|
||||
#: src/components/WorkspaceMenu.tsx:116
|
||||
msgid "Create workspace"
|
||||
msgstr "Crear espacio de trabajo"
|
||||
@@ -499,9 +502,14 @@ msgstr "Se requiere la contraseña actual"
|
||||
msgid "Custom domain"
|
||||
msgstr "Dominio personalizado"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:45
|
||||
msgid "Custom URLs are a premium feature. You'll be directed to upgrade your account."
|
||||
msgstr "Las URL personalizadas son una función premium. Serás dirigido a actualizar tu cuenta."
|
||||
#: src/components/NewWorkspaceForm.tsx:315
|
||||
msgid "Custom URLs require upgrading to a Pro plan"
|
||||
msgstr "Las URLs personalizadas requieren actualizar a un plan Pro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:339
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:74
|
||||
msgid "Custom workspace URL"
|
||||
msgstr "URL personalizada del espacio de trabajo"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:41
|
||||
msgid "Customer Support"
|
||||
@@ -520,8 +528,8 @@ msgid "Delete"
|
||||
msgstr "Eliminar"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:96
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:319
|
||||
#: src/views/settings/index.tsx:346
|
||||
#: src/views/settings/index.tsx:356
|
||||
msgid "Delete account"
|
||||
msgstr "Eliminar cuenta"
|
||||
|
||||
@@ -542,8 +550,8 @@ msgid "Delete list"
|
||||
msgstr "Eliminar lista"
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:106
|
||||
#: src/views/settings/index.tsx:272
|
||||
#: src/views/settings/index.tsx:283
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:320
|
||||
msgid "Delete workspace"
|
||||
msgstr "Eliminar espacio de trabajo"
|
||||
|
||||
@@ -569,7 +577,7 @@ msgstr "eliminó el elemento <0>{0}</0> de la lista de verificación"
|
||||
msgid "Design"
|
||||
msgstr "Diseño"
|
||||
|
||||
#: src/views/settings/index.tsx:250
|
||||
#: src/views/settings/index.tsx:287
|
||||
msgid "Disconnect Trello"
|
||||
msgstr "Desconectar Trello"
|
||||
|
||||
@@ -577,7 +585,7 @@ msgstr "Desconectar Trello"
|
||||
msgid "Discuss and collaborate on cards."
|
||||
msgstr "Discute y colabora en las tarjetas."
|
||||
|
||||
#: src/views/settings/index.tsx:151
|
||||
#: src/views/settings/index.tsx:176
|
||||
msgid "Display name"
|
||||
msgstr "Nombre visible"
|
||||
|
||||
@@ -647,7 +655,7 @@ msgstr "Editando"
|
||||
msgid "email"
|
||||
msgstr "correo electrónico"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:163
|
||||
#: src/views/members/components/InviteMemberForm.tsx:161
|
||||
msgid "Email"
|
||||
msgstr "Correo electrónico"
|
||||
|
||||
@@ -695,12 +703,12 @@ msgstr "Error al eliminar la etiqueta"
|
||||
msgid "Error deleting workspace"
|
||||
msgstr "Error al eliminar el espacio de trabajo"
|
||||
|
||||
#: src/views/settings/index.tsx:101
|
||||
#: src/views/settings/index.tsx:126
|
||||
msgid "Error disconnecting Trello"
|
||||
msgstr "Error al desconectar Trello"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:76
|
||||
#: src/views/members/components/InviteMemberForm.tsx:82
|
||||
#: src/views/members/components/InviteMemberForm.tsx:71
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
msgid "Error inviting member"
|
||||
msgstr "Error al invitar al miembro"
|
||||
|
||||
@@ -724,10 +732,15 @@ msgstr "Error al actualizar el nombre del espacio de trabajo"
|
||||
msgid "Error updating workspace URL"
|
||||
msgstr "Error al actualizar la URL del espacio de trabajo"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:132
|
||||
#: src/views/members/components/InviteMemberForm.tsx:130
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:41
|
||||
msgid "Error upgrading subscription"
|
||||
msgstr "Error al actualizar la suscripción"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:142
|
||||
msgid "Error upgrading to Pro"
|
||||
msgstr "Error al actualizar a Pro"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:56
|
||||
#: src/views/settings/components/Avatar.tsx:97
|
||||
msgid "Error uploading profile image"
|
||||
@@ -794,8 +807,8 @@ msgstr "Para la sostenibilidad a largo plazo, reconocemos que todos los buenos p
|
||||
msgid "Free"
|
||||
msgstr "Gratis"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:192
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:193
|
||||
#: src/views/members/index.tsx:208
|
||||
msgid "Free Plan"
|
||||
msgstr "Plan gratuito"
|
||||
|
||||
@@ -950,24 +963,24 @@ msgstr "Integraciones"
|
||||
msgid "Interviewing"
|
||||
msgstr "Entrevistando"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:45
|
||||
#: src/views/members/components/InviteMemberForm.tsx:40
|
||||
msgid "Invalid email address"
|
||||
msgstr "Dirección de correo electrónico no válida"
|
||||
|
||||
#: src/views/members/index.tsx:193
|
||||
#: src/views/members/index.tsx:221
|
||||
msgid "Invite"
|
||||
msgstr "Invitar"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:207
|
||||
#: src/views/members/components/InviteMemberForm.tsx:208
|
||||
msgid "Invite another"
|
||||
msgstr "Invitar a otro"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:112
|
||||
#: src/views/members/components/InviteMemberForm.tsx:231
|
||||
#: src/views/members/components/InviteMemberForm.tsx:233
|
||||
msgid "Invite member"
|
||||
msgstr "Invitar miembro"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:195
|
||||
#: src/views/members/components/InviteMemberForm.tsx:196
|
||||
msgid "Inviting members requires a Team Plan. You'll be redirected to upgrade your workspace."
|
||||
msgstr "Invitar miembros requiere un Plan de Equipo. Serás redirigido para actualizar tu espacio de trabajo."
|
||||
|
||||
@@ -998,10 +1011,23 @@ msgstr "Etiquetas"
|
||||
msgid "Labels & Filters"
|
||||
msgstr "Etiquetas y filtros"
|
||||
|
||||
#: src/views/settings/index.tsx:187
|
||||
#: src/views/settings/index.tsx:224
|
||||
msgid "Language"
|
||||
msgstr "Idioma"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:332
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:67
|
||||
msgid "Launch offer"
|
||||
msgstr "Oferta de lanzamiento"
|
||||
|
||||
#: src/views/members/index.tsx:191
|
||||
msgid "Launch offer: Get unlimited members with Pro"
|
||||
msgstr "Oferta de lanzamiento: Obtén miembros ilimitados con Pro"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:99
|
||||
msgid "Launch offer: unlimited seats for just $29/month with Pro"
|
||||
msgstr "Oferta de lanzamiento: asientos ilimitados por solo $29/mes con Pro"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:83
|
||||
msgid "Learning"
|
||||
msgstr "Aprendizaje"
|
||||
@@ -1067,12 +1093,12 @@ msgstr "Prioridad media"
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:357
|
||||
#: src/views/card/index.tsx:125
|
||||
#: src/views/members/index.tsx:171
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Miembros"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/members/index.tsx:167
|
||||
#: src/views/members/index.tsx:173
|
||||
msgid "Members | {0}"
|
||||
msgstr "Miembros | {0}"
|
||||
|
||||
@@ -1080,7 +1106,7 @@ msgstr "Miembros | {0}"
|
||||
msgid "Monthly"
|
||||
msgstr "Mensual"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:93
|
||||
msgid "monthly billing"
|
||||
msgstr "facturación mensual"
|
||||
|
||||
@@ -1144,7 +1170,7 @@ msgstr "La nueva contraseña debe ser diferente de la contraseña actual"
|
||||
msgid "New Ticket"
|
||||
msgstr "Nuevo ticket"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:65
|
||||
#: src/components/NewWorkspaceForm.tsx:240
|
||||
msgid "New workspace"
|
||||
msgstr "Nuevo espacio de trabajo"
|
||||
|
||||
@@ -1180,11 +1206,11 @@ msgstr "Oferta"
|
||||
msgid "Onboarding"
|
||||
msgstr "Incorporación"
|
||||
|
||||
#: src/views/settings/index.tsx:312
|
||||
#: src/views/settings/index.tsx:349
|
||||
msgid "Once you delete your account, there is no going back. This action cannot be undone."
|
||||
msgstr "Una vez que elimines tu cuenta, no hay vuelta atrás. Esta acción no se puede deshacer."
|
||||
|
||||
#: src/views/settings/index.tsx:275
|
||||
#: src/views/settings/index.tsx:312
|
||||
msgid "Once you delete your workspace, there is no going back. This action cannot be undone."
|
||||
msgstr "Una vez que elimines tu espacio de trabajo, no hay vuelta atrás. Esta acción no se puede deshacer."
|
||||
|
||||
@@ -1216,11 +1242,11 @@ msgstr "La contraseña debe tener al menos 8 caracteres"
|
||||
msgid "Passwords do not match"
|
||||
msgstr "Las contraseñas no coinciden"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:96
|
||||
#: src/views/home/components/Pricing.tsx:102
|
||||
msgid "Payment frequency"
|
||||
msgstr "Frecuencia de pago"
|
||||
|
||||
#: src/views/members/index.tsx:128
|
||||
#: src/views/members/index.tsx:134
|
||||
msgid "Pending"
|
||||
msgstr "Pendiente"
|
||||
|
||||
@@ -1259,7 +1285,7 @@ msgstr "Por favor selecciona un archivo para subir."
|
||||
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:42
|
||||
#: src/components/NewWorkspaceForm.tsx:155
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
@@ -1282,8 +1308,8 @@ msgstr "Por favor selecciona un archivo para subir."
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:173
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:83
|
||||
#: src/views/members/components/InviteMemberForm.tsx:133
|
||||
#: src/views/members/components/InviteMemberForm.tsx:78
|
||||
#: src/views/members/components/InviteMemberForm.tsx:131
|
||||
#: src/views/settings/components/Avatar.tsx:40
|
||||
#: src/views/settings/components/Avatar.tsx:98
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
|
||||
@@ -1292,6 +1318,7 @@ msgstr "Por favor selecciona un archivo para subir."
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:62
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:57
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:74
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:42
|
||||
msgid "Please try again later, or contact customer support."
|
||||
msgstr "Por favor, inténtalo de nuevo más tarde o contacta con atención al cliente."
|
||||
|
||||
@@ -1302,6 +1329,7 @@ msgid "Pricing"
|
||||
msgstr "Precios"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:56
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:91
|
||||
msgid "Priority email support"
|
||||
msgstr "Soporte prioritario por email"
|
||||
|
||||
@@ -1313,11 +1341,19 @@ msgstr "Política de privacidad"
|
||||
msgid "Private"
|
||||
msgstr "Privado"
|
||||
|
||||
#: src/views/members/index.tsx:205
|
||||
msgid "Pro Plan"
|
||||
msgstr "Plan Pro"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
msgid "Pro Plan ∞"
|
||||
msgstr "Plan Pro ∞"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:26
|
||||
msgid "Profile image updated"
|
||||
msgstr "Imagen de perfil actualizada"
|
||||
|
||||
#: src/views/settings/index.tsx:146
|
||||
#: src/views/settings/index.tsx:171
|
||||
msgid "Profile picture"
|
||||
msgstr "Foto de perfil"
|
||||
|
||||
@@ -1353,7 +1389,7 @@ msgstr "Remoto"
|
||||
msgid "Remove"
|
||||
msgstr "Eliminar"
|
||||
|
||||
#: src/views/members/index.tsx:142
|
||||
#: src/views/members/index.tsx:148
|
||||
msgid "Remove member"
|
||||
msgstr "Eliminar miembro"
|
||||
|
||||
@@ -1409,7 +1445,7 @@ msgstr "Revocar"
|
||||
msgid "Roadmap"
|
||||
msgstr "Hoja de ruta"
|
||||
|
||||
#: src/views/members/index.tsx:215
|
||||
#: src/views/members/index.tsx:243
|
||||
msgid "Role"
|
||||
msgstr "Rol"
|
||||
|
||||
@@ -1458,12 +1494,12 @@ msgid "Senior"
|
||||
msgstr "Senior"
|
||||
|
||||
#: src/components/SideNavigation.tsx:78
|
||||
#: src/views/settings/index.tsx:140
|
||||
#: src/views/settings/index.tsx:165
|
||||
msgid "Settings"
|
||||
msgstr "Configuración"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/settings/index.tsx:136
|
||||
#: src/views/settings/index.tsx:161
|
||||
msgid "Settings | {0}"
|
||||
msgstr "Configuración | {0}"
|
||||
|
||||
@@ -1514,6 +1550,10 @@ msgstr "Estrella en Github"
|
||||
msgid "Success"
|
||||
msgstr "Éxito"
|
||||
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:55
|
||||
msgid "Supercharge your workspace for just $29/month. Here's what you'll get:"
|
||||
msgstr "Potencia tu espacio de trabajo por solo $29/mes. Esto es lo que obtendrás:"
|
||||
|
||||
#: src/components/UserMenu.tsx:180
|
||||
msgid "Support"
|
||||
msgstr "Soporte"
|
||||
@@ -1526,8 +1566,8 @@ msgstr "Apoya el desarrollo del proyecto"
|
||||
msgid "System"
|
||||
msgstr "Sistema"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:183
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
#: src/views/members/index.tsx:207
|
||||
msgid "Team Plan"
|
||||
msgstr "Plan de Equipo"
|
||||
|
||||
@@ -1595,6 +1635,14 @@ msgstr "Esto resultará en la eliminación permanente de todos los datos asociad
|
||||
msgid "This will result in the permanent deletion of all data associated with your account."
|
||||
msgstr "Esto resultará en la eliminación permanente de todos los datos asociados con tu cuenta."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:284
|
||||
msgid "This workspace URL has already been taken"
|
||||
msgstr "Esta URL de espacio de trabajo ya ha sido tomada"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:286
|
||||
msgid "This workspace URL is reserved"
|
||||
msgstr "Esta URL de espacio de trabajo está reservada"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:123
|
||||
msgid "This workspace username has already been taken"
|
||||
msgstr "Este nombre de usuario del espacio de trabajo ya ha sido tomado"
|
||||
@@ -1612,7 +1660,7 @@ msgstr "Alternar menú"
|
||||
msgid "Track all card changes with detailed activity history."
|
||||
msgstr "Rastrea todos los cambios en las tarjetas con un historial de actividad detallado."
|
||||
|
||||
#: src/views/settings/index.tsx:94
|
||||
#: src/views/settings/index.tsx:119
|
||||
msgid "Trello disconnected"
|
||||
msgstr "Trello desconectado"
|
||||
|
||||
@@ -1644,7 +1692,7 @@ msgstr "No se puede crear la lista de verificación"
|
||||
msgid "Unable to create list"
|
||||
msgstr "No se puede crear la lista"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:154
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "No se puede crear el espacio de trabajo"
|
||||
|
||||
@@ -1743,6 +1791,11 @@ msgstr "Comentarios ilimitados"
|
||||
msgid "Unlimited lists"
|
||||
msgstr "Listas ilimitadas"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:329
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:64
|
||||
msgid "Unlimited members"
|
||||
msgstr "Miembros ilimitados"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
|
||||
@@ -1772,11 +1825,20 @@ msgstr "actualizó el título"
|
||||
msgid "updated the title to <0>{0}</0>"
|
||||
msgstr "actualizó el título a <0>{0}</0>"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:52
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:109
|
||||
msgid "Upgrade"
|
||||
msgstr "Actualizar"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:222
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:52
|
||||
#: src/views/settings/index.tsx:216
|
||||
msgid "Upgrade to Pro"
|
||||
msgstr "Actualizar a Pro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:369
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Actualizar a Pro ($29/mes)"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:224
|
||||
msgid "Upgrade to Team Plan"
|
||||
msgstr "Actualizar al Plan de Equipo"
|
||||
|
||||
@@ -1785,14 +1847,17 @@ msgstr "Actualizar al Plan de Equipo"
|
||||
msgid "Urgent"
|
||||
msgstr "Urgente"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:35
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:36
|
||||
msgid "URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "La URL solo puede contener letras, números y guiones"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:33
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:34
|
||||
msgid "URL cannot exceed 24 characters"
|
||||
msgstr "La URL no puede exceder los 24 caracteres"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:31
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:32
|
||||
msgid "URL must be at least 3 characters long"
|
||||
msgstr "La URL debe tener al menos 3 caracteres"
|
||||
@@ -1801,11 +1866,11 @@ msgstr "La URL debe tener al menos 3 caracteres"
|
||||
msgid "Use template"
|
||||
msgstr "Usar plantilla"
|
||||
|
||||
#: src/views/members/index.tsx:209
|
||||
#: src/views/members/index.tsx:237
|
||||
msgid "User"
|
||||
msgstr "Usuario"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
#: src/views/members/components/InviteMemberForm.tsx:72
|
||||
msgid "User is already a member of this workspace"
|
||||
msgstr "El usuario ya es miembro de este espacio de trabajo"
|
||||
|
||||
@@ -1813,11 +1878,11 @@ msgstr "El usuario ya es miembro de este espacio de trabajo"
|
||||
msgid "Video"
|
||||
msgstr "Video"
|
||||
|
||||
#: src/views/settings/index.tsx:262
|
||||
#: src/views/settings/index.tsx:299
|
||||
msgid "View and manage your API keys."
|
||||
msgstr "Ver y gestionar tus claves API."
|
||||
|
||||
#: src/views/settings/index.tsx:201
|
||||
#: src/views/settings/index.tsx:238
|
||||
msgid "View and manage your billing and subscription."
|
||||
msgstr "Ver y gestionar tu facturación y suscripción."
|
||||
|
||||
@@ -1873,11 +1938,15 @@ msgstr "¿Por qué crear un Trello de código abierto?"
|
||||
msgid "Workspace"
|
||||
msgstr "Espacio de trabajo"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:143
|
||||
msgid "Workspace created successfully. You can upgrade later in settings."
|
||||
msgstr "Espacio de trabajo creado con éxito. Puedes actualizar más tarde en configuración."
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:26
|
||||
msgid "Workspace deleted"
|
||||
msgstr "Espacio de trabajo eliminado"
|
||||
|
||||
#: src/views/settings/index.tsx:177
|
||||
#: src/views/settings/index.tsx:202
|
||||
msgid "Workspace description"
|
||||
msgstr "Descripción del espacio de trabajo"
|
||||
|
||||
@@ -1898,8 +1967,8 @@ msgstr "Descripción del espacio de trabajo actualizada"
|
||||
msgid "Workspace members"
|
||||
msgstr "Miembros del espacio de trabajo"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:81
|
||||
#: src/views/settings/index.tsx:158
|
||||
#: src/components/NewWorkspaceForm.tsx:259
|
||||
#: src/views/settings/index.tsx:183
|
||||
msgid "Workspace name"
|
||||
msgstr "Nombre del espacio de trabajo"
|
||||
|
||||
@@ -1907,6 +1976,10 @@ msgstr "Nombre del espacio de trabajo"
|
||||
msgid "Workspace name cannot exceed 24 characters"
|
||||
msgstr "El nombre del espacio de trabajo no puede exceder los 24 caracteres"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:27
|
||||
msgid "Workspace name is required"
|
||||
msgstr "El nombre del espacio de trabajo es obligatorio"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:14
|
||||
msgid "Workspace name must be at least 3 characters long"
|
||||
msgstr "El nombre del espacio de trabajo debe tener al menos 3 caracteres"
|
||||
@@ -1919,10 +1992,14 @@ msgstr "Nombre del espacio de trabajo actualizado"
|
||||
msgid "Workspace slug updated"
|
||||
msgstr "Slug del espacio de trabajo actualizado"
|
||||
|
||||
#: src/views/settings/index.tsx:167
|
||||
#: src/views/settings/index.tsx:192
|
||||
msgid "Workspace URL"
|
||||
msgstr "URL del espacio de trabajo"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:273
|
||||
msgid "workspace-url"
|
||||
msgstr "workspace-url"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:30
|
||||
msgid "Writing"
|
||||
msgstr "Escritura"
|
||||
@@ -1935,7 +2012,7 @@ msgstr "Anual"
|
||||
msgid "Yes, we offer an forever free plan for individual use. No restrictions, no paywalls, no limits."
|
||||
msgstr "Sí, ofrecemos un plan gratuito para siempre para uso individual. Sin restricciones, sin muros de pago, sin límites."
|
||||
|
||||
#: src/views/settings/index.tsx:294
|
||||
#: src/views/settings/index.tsx:331
|
||||
msgid "You are about to change your password."
|
||||
msgstr "Estás a punto de cambiar tu contraseña."
|
||||
|
||||
@@ -1959,6 +2036,10 @@ msgstr "Has iniciado sesión correctamente."
|
||||
msgid "You have been signed up successfully."
|
||||
msgstr "Te has registrado correctamente."
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
msgid "You have unlimited seats with your Pro Plan. There is no additional charge for new members!"
|
||||
msgstr "Tienes plazas ilimitadas con tu Plan Pro. ¡No hay cargos adicionales por nuevos miembros!"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:28
|
||||
msgid "Your account has been deleted."
|
||||
msgstr "Tu cuenta ha sido eliminada."
|
||||
@@ -1979,11 +2060,11 @@ msgstr "Tu contraseña ha sido cambiada."
|
||||
msgid "Your profile image has been updated."
|
||||
msgstr "Tu imagen de perfil ha sido actualizada."
|
||||
|
||||
#: src/views/settings/index.tsx:95
|
||||
#: src/views/settings/index.tsx:120
|
||||
msgid "Your Trello account has been disconnected."
|
||||
msgstr "Tu cuenta de Trello ha sido desconectada."
|
||||
|
||||
#: src/views/settings/index.tsx:244
|
||||
#: src/views/settings/index.tsx:281
|
||||
msgid "Your Trello account is connected."
|
||||
msgstr "Tu cuenta de Trello está conectada."
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -36,12 +36,12 @@ msgstr "{0} étiquettes"
|
||||
msgid "{boardCount, plural, one {Import board (1)} other {Import boards ({boardCount})}}"
|
||||
msgstr "{boardCount, plural, one {Importer le tableau (1)} other {Importer les tableaux ({boardCount})}}"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:91
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$10/month"
|
||||
msgstr "10 $/mois"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$8/month"
|
||||
msgstr "8 $/mois"
|
||||
|
||||
@@ -97,7 +97,7 @@ msgid "Add label"
|
||||
msgstr "Ajouter une étiquette"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:130
|
||||
#: src/views/members/components/InviteMemberForm.tsx:149
|
||||
#: src/views/members/components/InviteMemberForm.tsx:147
|
||||
msgid "Add member"
|
||||
msgstr "Ajouter un membre"
|
||||
|
||||
@@ -132,7 +132,7 @@ msgstr "a ajouté l'élément <0>{0}</0> à la checklist"
|
||||
msgid "added label <0>{0}</0>"
|
||||
msgstr "a ajouté l'étiquette <0>{0}</0>"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
#: src/views/members/components/InviteMemberForm.tsx:187
|
||||
msgid "Adding a new member will cost an additional {price} ({billingType}) per seat."
|
||||
msgstr "L'ajout d'un nouveau membre coûtera {price} supplémentaires ({billingType}) par siège."
|
||||
|
||||
@@ -148,7 +148,7 @@ msgstr "Tous les systèmes opérationnels"
|
||||
msgid "Already have an account? <0><1>Sign in</1></0>"
|
||||
msgstr "Vous avez déjà un compte ? <0><1>Connectez-vous</1></0>"
|
||||
|
||||
#: src/views/settings/index.tsx:102
|
||||
#: src/views/settings/index.tsx:127
|
||||
msgid "An error occurred while disconnecting your Trello account."
|
||||
msgstr "Une erreur s'est produite lors de la déconnexion de votre compte Trello."
|
||||
|
||||
@@ -156,7 +156,7 @@ msgstr "Une erreur s'est produite lors de la déconnexion de votre compte Trello
|
||||
msgid "An unexpected error occurred. Please try again later."
|
||||
msgstr "Une erreur inattendue s'est produite. Veuillez réessayer plus tard."
|
||||
|
||||
#: src/views/settings/index.tsx:259
|
||||
#: src/views/settings/index.tsx:296
|
||||
msgid "API keys"
|
||||
msgstr "Clés API"
|
||||
|
||||
@@ -218,20 +218,20 @@ msgstr "Backlog"
|
||||
msgid "Basic Kanban"
|
||||
msgstr "Kanban basique"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed annually"
|
||||
msgstr "facturation annuelle"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed monthly"
|
||||
msgstr "facturation mensuelle"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
#: src/views/settings/index.tsx:198
|
||||
#: src/views/settings/index.tsx:235
|
||||
msgid "Billing"
|
||||
msgstr "Facturation"
|
||||
|
||||
#: src/views/settings/index.tsx:208
|
||||
#: src/views/settings/index.tsx:245
|
||||
msgid "Billing portal"
|
||||
msgstr "Portail de facturation"
|
||||
|
||||
@@ -243,6 +243,11 @@ msgstr "Article de blog"
|
||||
msgid "Board"
|
||||
msgstr "Tableau"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:346
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:81
|
||||
msgid "Board analytics"
|
||||
msgstr "Analyses du tableau"
|
||||
|
||||
#: src/views/boards/components/NewBoardForm.tsx:21
|
||||
msgid "Board name cannot exceed 100 characters"
|
||||
msgstr "Le nom du tableau ne peut pas dépasser 100 caractères"
|
||||
@@ -309,9 +314,9 @@ msgstr "Rapport de bug"
|
||||
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:168
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:50
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:88
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:98
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:104
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
@@ -325,12 +330,12 @@ msgstr "Titre de la carte"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:109
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:178
|
||||
#: src/views/settings/index.tsx:291
|
||||
#: src/views/settings/index.tsx:301
|
||||
#: src/views/settings/index.tsx:328
|
||||
#: src/views/settings/index.tsx:338
|
||||
msgid "Change Password"
|
||||
msgstr "Modifier le mot de passe"
|
||||
|
||||
#: src/views/settings/index.tsx:190
|
||||
#: src/views/settings/index.tsx:227
|
||||
msgid "Change the language of the app."
|
||||
msgstr "Changer la langue de l'application."
|
||||
|
||||
@@ -360,7 +365,9 @@ msgstr "Revue de code"
|
||||
msgid "Collaborate seamlessly with your team."
|
||||
msgstr "Collaborez en toute fluidité avec votre équipe."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:349
|
||||
#: src/views/home/components/Features.tsx:66
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:84
|
||||
msgid "Coming soon"
|
||||
msgstr "Bientôt disponible"
|
||||
|
||||
@@ -389,16 +396,12 @@ msgstr "a terminé un élément de la checklist"
|
||||
msgid "completed checklist item <0>{0}</0>"
|
||||
msgstr "a terminé l'élément <0>{0}</0> de la checklist"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:42
|
||||
msgid "Confirm URL change"
|
||||
msgstr "Confirmer le changement d'URL"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:150
|
||||
msgid "Confirm your new password"
|
||||
msgstr "Confirmez votre nouveau mot de passe"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:157
|
||||
#: src/views/settings/index.tsx:235
|
||||
#: src/views/settings/index.tsx:272
|
||||
msgid "Connect Trello"
|
||||
msgstr "Connecter Trello"
|
||||
|
||||
@@ -406,7 +409,7 @@ msgstr "Connecter Trello"
|
||||
msgid "Connect your favorite tools to streamline your workflow."
|
||||
msgstr "Connectez vos outils favoris pour simplifier votre flux de travail."
|
||||
|
||||
#: src/views/settings/index.tsx:222
|
||||
#: src/views/settings/index.tsx:259
|
||||
msgid "Connect your Trello account to import boards."
|
||||
msgstr "Connectez votre compte Trello pour importer des tableaux."
|
||||
|
||||
@@ -478,7 +481,7 @@ msgstr "Créer une nouvelle étiquette"
|
||||
msgid "Create new list"
|
||||
msgstr "Créer une nouvelle liste"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:94
|
||||
#: src/components/NewWorkspaceForm.tsx:384
|
||||
#: src/components/WorkspaceMenu.tsx:116
|
||||
msgid "Create workspace"
|
||||
msgstr "Créer un espace de travail"
|
||||
@@ -499,9 +502,14 @@ msgstr "Le mot de passe actuel est requis"
|
||||
msgid "Custom domain"
|
||||
msgstr "Domaine personnalisé"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:45
|
||||
msgid "Custom URLs are a premium feature. You'll be directed to upgrade your account."
|
||||
msgstr "Les URL personnalisées sont une fonctionnalité premium. Vous serez dirigé vers la mise à niveau de votre compte."
|
||||
#: src/components/NewWorkspaceForm.tsx:315
|
||||
msgid "Custom URLs require upgrading to a Pro plan"
|
||||
msgstr "Les URL personnalisées nécessitent une mise à niveau vers un forfait Pro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:339
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:74
|
||||
msgid "Custom workspace URL"
|
||||
msgstr "URL d'espace de travail personnalisée"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:41
|
||||
msgid "Customer Support"
|
||||
@@ -520,8 +528,8 @@ msgid "Delete"
|
||||
msgstr "Supprimer"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:96
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:319
|
||||
#: src/views/settings/index.tsx:346
|
||||
#: src/views/settings/index.tsx:356
|
||||
msgid "Delete account"
|
||||
msgstr "Supprimer le compte"
|
||||
|
||||
@@ -542,8 +550,8 @@ msgid "Delete list"
|
||||
msgstr "Supprimer la liste"
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:106
|
||||
#: src/views/settings/index.tsx:272
|
||||
#: src/views/settings/index.tsx:283
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:320
|
||||
msgid "Delete workspace"
|
||||
msgstr "Supprimer l'espace de travail"
|
||||
|
||||
@@ -569,7 +577,7 @@ msgstr "a supprimé l'élément <0>{0}</0> de la checklist"
|
||||
msgid "Design"
|
||||
msgstr "Design"
|
||||
|
||||
#: src/views/settings/index.tsx:250
|
||||
#: src/views/settings/index.tsx:287
|
||||
msgid "Disconnect Trello"
|
||||
msgstr "Déconnecter Trello"
|
||||
|
||||
@@ -577,7 +585,7 @@ msgstr "Déconnecter Trello"
|
||||
msgid "Discuss and collaborate on cards."
|
||||
msgstr "Discutez et collaborez sur les cartes."
|
||||
|
||||
#: src/views/settings/index.tsx:151
|
||||
#: src/views/settings/index.tsx:176
|
||||
msgid "Display name"
|
||||
msgstr "Nom d'affichage"
|
||||
|
||||
@@ -647,7 +655,7 @@ msgstr "Édition"
|
||||
msgid "email"
|
||||
msgstr "e-mail"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:163
|
||||
#: src/views/members/components/InviteMemberForm.tsx:161
|
||||
msgid "Email"
|
||||
msgstr "E-mail"
|
||||
|
||||
@@ -695,12 +703,12 @@ msgstr "Erreur lors de la suppression de l'étiquette"
|
||||
msgid "Error deleting workspace"
|
||||
msgstr "Erreur lors de la suppression de l'espace de travail"
|
||||
|
||||
#: src/views/settings/index.tsx:101
|
||||
#: src/views/settings/index.tsx:126
|
||||
msgid "Error disconnecting Trello"
|
||||
msgstr "Erreur lors de la déconnexion de Trello"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:76
|
||||
#: src/views/members/components/InviteMemberForm.tsx:82
|
||||
#: src/views/members/components/InviteMemberForm.tsx:71
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
msgid "Error inviting member"
|
||||
msgstr "Erreur lors de l'invitation du membre"
|
||||
|
||||
@@ -724,10 +732,15 @@ msgstr "Erreur lors de la mise à jour du nom de l'espace de travail"
|
||||
msgid "Error updating workspace URL"
|
||||
msgstr "Erreur lors de la mise à jour de l'URL de l'espace de travail"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:132
|
||||
#: src/views/members/components/InviteMemberForm.tsx:130
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:41
|
||||
msgid "Error upgrading subscription"
|
||||
msgstr "Erreur lors de la mise à niveau de l'abonnement"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:142
|
||||
msgid "Error upgrading to Pro"
|
||||
msgstr "Erreur lors de la mise à niveau vers Pro"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:56
|
||||
#: src/views/settings/components/Avatar.tsx:97
|
||||
msgid "Error uploading profile image"
|
||||
@@ -794,8 +807,8 @@ msgstr "Pour une durabilité à long terme, nous reconnaissons que tous les bons
|
||||
msgid "Free"
|
||||
msgstr "Gratuit"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:192
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:193
|
||||
#: src/views/members/index.tsx:208
|
||||
msgid "Free Plan"
|
||||
msgstr "Forfait gratuit"
|
||||
|
||||
@@ -950,24 +963,24 @@ msgstr "Intégrations"
|
||||
msgid "Interviewing"
|
||||
msgstr "Entretien"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:45
|
||||
#: src/views/members/components/InviteMemberForm.tsx:40
|
||||
msgid "Invalid email address"
|
||||
msgstr "Adresse e-mail invalide"
|
||||
|
||||
#: src/views/members/index.tsx:193
|
||||
#: src/views/members/index.tsx:221
|
||||
msgid "Invite"
|
||||
msgstr "Inviter"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:207
|
||||
#: src/views/members/components/InviteMemberForm.tsx:208
|
||||
msgid "Invite another"
|
||||
msgstr "Inviter un autre"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:112
|
||||
#: src/views/members/components/InviteMemberForm.tsx:231
|
||||
#: src/views/members/components/InviteMemberForm.tsx:233
|
||||
msgid "Invite member"
|
||||
msgstr "Inviter un membre"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:195
|
||||
#: src/views/members/components/InviteMemberForm.tsx:196
|
||||
msgid "Inviting members requires a Team Plan. You'll be redirected to upgrade your workspace."
|
||||
msgstr "L'invitation de membres nécessite un forfait d'équipe. Vous serez redirigé pour mettre à niveau votre espace de travail."
|
||||
|
||||
@@ -998,10 +1011,23 @@ msgstr "Étiquettes"
|
||||
msgid "Labels & Filters"
|
||||
msgstr "Étiquettes & filtres"
|
||||
|
||||
#: src/views/settings/index.tsx:187
|
||||
#: src/views/settings/index.tsx:224
|
||||
msgid "Language"
|
||||
msgstr "Langue"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:332
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:67
|
||||
msgid "Launch offer"
|
||||
msgstr "Offre de lancement"
|
||||
|
||||
#: src/views/members/index.tsx:191
|
||||
msgid "Launch offer: Get unlimited members with Pro"
|
||||
msgstr "Offre de lancement : obtenez des membres illimités avec Pro"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:99
|
||||
msgid "Launch offer: unlimited seats for just $29/month with Pro"
|
||||
msgstr "Offre de lancement : sièges illimités pour seulement 29 $/mois avec Pro"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:83
|
||||
msgid "Learning"
|
||||
msgstr "Apprentissage"
|
||||
@@ -1067,12 +1093,12 @@ msgstr "Priorité moyenne"
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:357
|
||||
#: src/views/card/index.tsx:125
|
||||
#: src/views/members/index.tsx:171
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Membres"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/members/index.tsx:167
|
||||
#: src/views/members/index.tsx:173
|
||||
msgid "Members | {0}"
|
||||
msgstr "Membres | {0}"
|
||||
|
||||
@@ -1080,7 +1106,7 @@ msgstr "Membres | {0}"
|
||||
msgid "Monthly"
|
||||
msgstr "Mensuel"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:93
|
||||
msgid "monthly billing"
|
||||
msgstr "facturation mensuelle"
|
||||
|
||||
@@ -1144,7 +1170,7 @@ msgstr "Le nouveau mot de passe doit être différent du mot de passe actuel"
|
||||
msgid "New Ticket"
|
||||
msgstr "Nouveau ticket"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:65
|
||||
#: src/components/NewWorkspaceForm.tsx:240
|
||||
msgid "New workspace"
|
||||
msgstr "Nouvel espace de travail"
|
||||
|
||||
@@ -1180,11 +1206,11 @@ msgstr "Offre"
|
||||
msgid "Onboarding"
|
||||
msgstr "Intégration"
|
||||
|
||||
#: src/views/settings/index.tsx:312
|
||||
#: src/views/settings/index.tsx:349
|
||||
msgid "Once you delete your account, there is no going back. This action cannot be undone."
|
||||
msgstr "Une fois que vous supprimez votre compte, il n'y a pas de retour possible. Cette action ne peut pas être annulée."
|
||||
|
||||
#: src/views/settings/index.tsx:275
|
||||
#: src/views/settings/index.tsx:312
|
||||
msgid "Once you delete your workspace, there is no going back. This action cannot be undone."
|
||||
msgstr "Une fois que vous supprimez votre espace de travail, il n'y a pas de retour possible. Cette action ne peut pas être annulée."
|
||||
|
||||
@@ -1216,11 +1242,11 @@ msgstr "Le mot de passe doit comporter au moins 8 caractères"
|
||||
msgid "Passwords do not match"
|
||||
msgstr "Les mots de passe ne correspondent pas"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:96
|
||||
#: src/views/home/components/Pricing.tsx:102
|
||||
msgid "Payment frequency"
|
||||
msgstr "Fréquence de paiement"
|
||||
|
||||
#: src/views/members/index.tsx:128
|
||||
#: src/views/members/index.tsx:134
|
||||
msgid "Pending"
|
||||
msgstr "En attente"
|
||||
|
||||
@@ -1259,7 +1285,7 @@ msgstr "Veuillez sélectionner un fichier à télécharger."
|
||||
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:42
|
||||
#: src/components/NewWorkspaceForm.tsx:155
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
@@ -1282,8 +1308,8 @@ msgstr "Veuillez sélectionner un fichier à télécharger."
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:173
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:83
|
||||
#: src/views/members/components/InviteMemberForm.tsx:133
|
||||
#: src/views/members/components/InviteMemberForm.tsx:78
|
||||
#: src/views/members/components/InviteMemberForm.tsx:131
|
||||
#: src/views/settings/components/Avatar.tsx:40
|
||||
#: src/views/settings/components/Avatar.tsx:98
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
|
||||
@@ -1292,6 +1318,7 @@ msgstr "Veuillez sélectionner un fichier à télécharger."
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:62
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:57
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:74
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:42
|
||||
msgid "Please try again later, or contact customer support."
|
||||
msgstr "Veuillez réessayer plus tard ou contacter le service client."
|
||||
|
||||
@@ -1302,6 +1329,7 @@ msgid "Pricing"
|
||||
msgstr "Tarifs"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:56
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:91
|
||||
msgid "Priority email support"
|
||||
msgstr "Support par e-mail prioritaire"
|
||||
|
||||
@@ -1313,11 +1341,19 @@ msgstr "Politique de confidentialité"
|
||||
msgid "Private"
|
||||
msgstr "Privé"
|
||||
|
||||
#: src/views/members/index.tsx:205
|
||||
msgid "Pro Plan"
|
||||
msgstr "Plan Pro"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
msgid "Pro Plan ∞"
|
||||
msgstr "Plan Pro ∞"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:26
|
||||
msgid "Profile image updated"
|
||||
msgstr "Image de profil mise à jour"
|
||||
|
||||
#: src/views/settings/index.tsx:146
|
||||
#: src/views/settings/index.tsx:171
|
||||
msgid "Profile picture"
|
||||
msgstr "Photo de profil"
|
||||
|
||||
@@ -1353,7 +1389,7 @@ msgstr "À distance"
|
||||
msgid "Remove"
|
||||
msgstr "Supprimer"
|
||||
|
||||
#: src/views/members/index.tsx:142
|
||||
#: src/views/members/index.tsx:148
|
||||
msgid "Remove member"
|
||||
msgstr "Supprimer le membre"
|
||||
|
||||
@@ -1409,7 +1445,7 @@ msgstr "Révoquer"
|
||||
msgid "Roadmap"
|
||||
msgstr "Feuille de route"
|
||||
|
||||
#: src/views/members/index.tsx:215
|
||||
#: src/views/members/index.tsx:243
|
||||
msgid "Role"
|
||||
msgstr "Rôle"
|
||||
|
||||
@@ -1458,12 +1494,12 @@ msgid "Senior"
|
||||
msgstr "Senior"
|
||||
|
||||
#: src/components/SideNavigation.tsx:78
|
||||
#: src/views/settings/index.tsx:140
|
||||
#: src/views/settings/index.tsx:165
|
||||
msgid "Settings"
|
||||
msgstr "Paramètres"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/settings/index.tsx:136
|
||||
#: src/views/settings/index.tsx:161
|
||||
msgid "Settings | {0}"
|
||||
msgstr "Paramètres | {0}"
|
||||
|
||||
@@ -1514,6 +1550,10 @@ msgstr "Étoile sur Github"
|
||||
msgid "Success"
|
||||
msgstr "Succès"
|
||||
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:55
|
||||
msgid "Supercharge your workspace for just $29/month. Here's what you'll get:"
|
||||
msgstr "Optimisez votre espace de travail pour seulement 29 $/mois. Voici ce que vous obtiendrez :"
|
||||
|
||||
#: src/components/UserMenu.tsx:180
|
||||
msgid "Support"
|
||||
msgstr "Assistance"
|
||||
@@ -1526,8 +1566,8 @@ msgstr "Soutenir le développement du projet"
|
||||
msgid "System"
|
||||
msgstr "Système"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:183
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
#: src/views/members/index.tsx:207
|
||||
msgid "Team Plan"
|
||||
msgstr "Forfait d'équipe"
|
||||
|
||||
@@ -1595,6 +1635,14 @@ msgstr "Cela entraînera la suppression définitive de toutes les données assoc
|
||||
msgid "This will result in the permanent deletion of all data associated with your account."
|
||||
msgstr "Cela entraînera la suppression définitive de toutes les données associées à votre compte."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:284
|
||||
msgid "This workspace URL has already been taken"
|
||||
msgstr "Cette URL d'espace de travail est déjà prise"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:286
|
||||
msgid "This workspace URL is reserved"
|
||||
msgstr "Cette URL d'espace de travail est réservée"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:123
|
||||
msgid "This workspace username has already been taken"
|
||||
msgstr "Ce nom d'utilisateur d'espace de travail est déjà pris"
|
||||
@@ -1612,7 +1660,7 @@ msgstr "Basculer le menu"
|
||||
msgid "Track all card changes with detailed activity history."
|
||||
msgstr "Suivez tous les changements de cartes avec un historique d'activité détaillé."
|
||||
|
||||
#: src/views/settings/index.tsx:94
|
||||
#: src/views/settings/index.tsx:119
|
||||
msgid "Trello disconnected"
|
||||
msgstr "Trello déconnecté"
|
||||
|
||||
@@ -1644,7 +1692,7 @@ msgstr "Impossible de créer la liste de contrôle"
|
||||
msgid "Unable to create list"
|
||||
msgstr "Impossible de créer une liste"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:154
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Impossible de créer l'espace de travail"
|
||||
|
||||
@@ -1743,6 +1791,11 @@ msgstr "Commentaires illimités"
|
||||
msgid "Unlimited lists"
|
||||
msgstr "Listes illimitées"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:329
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:64
|
||||
msgid "Unlimited members"
|
||||
msgstr "Membres illimités"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
|
||||
@@ -1772,11 +1825,20 @@ msgstr "a mis à jour le titre"
|
||||
msgid "updated the title to <0>{0}</0>"
|
||||
msgstr "a mis à jour le titre en <0>{0}</0>"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:52
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:109
|
||||
msgid "Upgrade"
|
||||
msgstr "Mettre à niveau"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:222
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:52
|
||||
#: src/views/settings/index.tsx:216
|
||||
msgid "Upgrade to Pro"
|
||||
msgstr "Passer à Pro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:369
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Passer à Pro (29 $/mois)"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:224
|
||||
msgid "Upgrade to Team Plan"
|
||||
msgstr "Passer au forfait d'équipe"
|
||||
|
||||
@@ -1785,14 +1847,17 @@ msgstr "Passer au forfait d'équipe"
|
||||
msgid "Urgent"
|
||||
msgstr "Urgent"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:35
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:36
|
||||
msgid "URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "L'URL ne peut contenir que des lettres, des chiffres et des traits d'union"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:33
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:34
|
||||
msgid "URL cannot exceed 24 characters"
|
||||
msgstr "L'URL ne peut pas dépasser 24 caractères"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:31
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:32
|
||||
msgid "URL must be at least 3 characters long"
|
||||
msgstr "L'URL doit comporter au moins 3 caractères"
|
||||
@@ -1801,11 +1866,11 @@ msgstr "L'URL doit comporter au moins 3 caractères"
|
||||
msgid "Use template"
|
||||
msgstr "Utiliser le modèle"
|
||||
|
||||
#: src/views/members/index.tsx:209
|
||||
#: src/views/members/index.tsx:237
|
||||
msgid "User"
|
||||
msgstr "Utilisateur"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
#: src/views/members/components/InviteMemberForm.tsx:72
|
||||
msgid "User is already a member of this workspace"
|
||||
msgstr "L'utilisateur est déjà membre de cet espace de travail"
|
||||
|
||||
@@ -1813,11 +1878,11 @@ msgstr "L'utilisateur est déjà membre de cet espace de travail"
|
||||
msgid "Video"
|
||||
msgstr "Vidéo"
|
||||
|
||||
#: src/views/settings/index.tsx:262
|
||||
#: src/views/settings/index.tsx:299
|
||||
msgid "View and manage your API keys."
|
||||
msgstr "Consultez et gérez vos clés API."
|
||||
|
||||
#: src/views/settings/index.tsx:201
|
||||
#: src/views/settings/index.tsx:238
|
||||
msgid "View and manage your billing and subscription."
|
||||
msgstr "Consultez et gérez votre facturation et votre abonnement."
|
||||
|
||||
@@ -1873,11 +1938,15 @@ msgstr "Pourquoi créer un Trello open source ?"
|
||||
msgid "Workspace"
|
||||
msgstr "Espace de travail"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:143
|
||||
msgid "Workspace created successfully. You can upgrade later in settings."
|
||||
msgstr "Espace de travail créé avec succès. Vous pourrez effectuer la mise à niveau ultérieurement dans les paramètres."
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:26
|
||||
msgid "Workspace deleted"
|
||||
msgstr "Espace de travail supprimé"
|
||||
|
||||
#: src/views/settings/index.tsx:177
|
||||
#: src/views/settings/index.tsx:202
|
||||
msgid "Workspace description"
|
||||
msgstr "Description de l'espace de travail"
|
||||
|
||||
@@ -1898,8 +1967,8 @@ msgstr "Description de l'espace de travail mise à jour"
|
||||
msgid "Workspace members"
|
||||
msgstr "Membres de l'espace de travail"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:81
|
||||
#: src/views/settings/index.tsx:158
|
||||
#: src/components/NewWorkspaceForm.tsx:259
|
||||
#: src/views/settings/index.tsx:183
|
||||
msgid "Workspace name"
|
||||
msgstr "Nom de l'espace de travail"
|
||||
|
||||
@@ -1907,6 +1976,10 @@ msgstr "Nom de l'espace de travail"
|
||||
msgid "Workspace name cannot exceed 24 characters"
|
||||
msgstr "Le nom de l'espace de travail ne peut pas dépasser 24 caractères"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:27
|
||||
msgid "Workspace name is required"
|
||||
msgstr "Le nom de l'espace de travail est requis"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:14
|
||||
msgid "Workspace name must be at least 3 characters long"
|
||||
msgstr "Le nom de l'espace de travail doit comporter au moins 3 caractères"
|
||||
@@ -1919,10 +1992,14 @@ msgstr "Nom de l'espace de travail mis à jour"
|
||||
msgid "Workspace slug updated"
|
||||
msgstr "Slug de l'espace de travail mis à jour"
|
||||
|
||||
#: src/views/settings/index.tsx:167
|
||||
#: src/views/settings/index.tsx:192
|
||||
msgid "Workspace URL"
|
||||
msgstr "URL de l'espace de travail"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:273
|
||||
msgid "workspace-url"
|
||||
msgstr "workspace-url"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:30
|
||||
msgid "Writing"
|
||||
msgstr "Écriture"
|
||||
@@ -1935,7 +2012,7 @@ msgstr "Annuel"
|
||||
msgid "Yes, we offer an forever free plan for individual use. No restrictions, no paywalls, no limits."
|
||||
msgstr "Oui, nous proposons un plan gratuit à vie pour un usage individuel. Aucune restriction, aucun paywall, aucune limite."
|
||||
|
||||
#: src/views/settings/index.tsx:294
|
||||
#: src/views/settings/index.tsx:331
|
||||
msgid "You are about to change your password."
|
||||
msgstr "Vous êtes sur le point de modifier votre mot de passe."
|
||||
|
||||
@@ -1959,6 +2036,10 @@ msgstr "Vous vous êtes connecté avec succès."
|
||||
msgid "You have been signed up successfully."
|
||||
msgstr "Vous vous êtes inscrit avec succès."
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
msgid "You have unlimited seats with your Pro Plan. There is no additional charge for new members!"
|
||||
msgstr "Vous disposez de places illimitées avec votre Plan Pro. Il n'y a pas de frais supplémentaires pour les nouveaux membres !"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:28
|
||||
msgid "Your account has been deleted."
|
||||
msgstr "Votre compte a été supprimé."
|
||||
@@ -1979,11 +2060,11 @@ msgstr "Votre mot de passe a été modifié."
|
||||
msgid "Your profile image has been updated."
|
||||
msgstr "Votre image de profil a été mise à jour."
|
||||
|
||||
#: src/views/settings/index.tsx:95
|
||||
#: src/views/settings/index.tsx:120
|
||||
msgid "Your Trello account has been disconnected."
|
||||
msgstr "Votre compte Trello a été déconnecté."
|
||||
|
||||
#: src/views/settings/index.tsx:244
|
||||
#: src/views/settings/index.tsx:281
|
||||
msgid "Your Trello account is connected."
|
||||
msgstr "Votre compte Trello est connecté."
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -36,12 +36,12 @@ msgstr "{0} etichette"
|
||||
msgid "{boardCount, plural, one {Import board (1)} other {Import boards ({boardCount})}}"
|
||||
msgstr "{boardCount, plural, one {Importa bacheca (1)} other {Importa bacheche ({boardCount})}}"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:91
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$10/month"
|
||||
msgstr "$10/mese"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$8/month"
|
||||
msgstr "$8/mese"
|
||||
|
||||
@@ -97,7 +97,7 @@ msgid "Add label"
|
||||
msgstr "Aggiungi etichetta"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:130
|
||||
#: src/views/members/components/InviteMemberForm.tsx:149
|
||||
#: src/views/members/components/InviteMemberForm.tsx:147
|
||||
msgid "Add member"
|
||||
msgstr "Aggiungi membro"
|
||||
|
||||
@@ -132,7 +132,7 @@ msgstr "ha aggiunto l'elemento <0>{0}</0> alla checklist"
|
||||
msgid "added label <0>{0}</0>"
|
||||
msgstr "ha aggiunto l'etichetta <0>{0}</0>"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
#: src/views/members/components/InviteMemberForm.tsx:187
|
||||
msgid "Adding a new member will cost an additional {price} ({billingType}) per seat."
|
||||
msgstr "L'aggiunta di un nuovo membro costerà un supplemento di {price} ({billingType}) per posto."
|
||||
|
||||
@@ -148,7 +148,7 @@ msgstr "Tutti i sistemi operativi"
|
||||
msgid "Already have an account? <0><1>Sign in</1></0>"
|
||||
msgstr "Hai già un account? <0><1>Accedi</1></0>"
|
||||
|
||||
#: src/views/settings/index.tsx:102
|
||||
#: src/views/settings/index.tsx:127
|
||||
msgid "An error occurred while disconnecting your Trello account."
|
||||
msgstr "Si è verificato un errore durante la disconnessione del tuo account Trello."
|
||||
|
||||
@@ -156,7 +156,7 @@ msgstr "Si è verificato un errore durante la disconnessione del tuo account Tre
|
||||
msgid "An unexpected error occurred. Please try again later."
|
||||
msgstr "Si è verificato un errore imprevisto. Riprova più tardi."
|
||||
|
||||
#: src/views/settings/index.tsx:259
|
||||
#: src/views/settings/index.tsx:296
|
||||
msgid "API keys"
|
||||
msgstr "Chiavi API"
|
||||
|
||||
@@ -218,20 +218,20 @@ msgstr "Backlog"
|
||||
msgid "Basic Kanban"
|
||||
msgstr "Kanban base"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed annually"
|
||||
msgstr "fatturato annualmente"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed monthly"
|
||||
msgstr "fatturato mensilmente"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
#: src/views/settings/index.tsx:198
|
||||
#: src/views/settings/index.tsx:235
|
||||
msgid "Billing"
|
||||
msgstr "Fatturazione"
|
||||
|
||||
#: src/views/settings/index.tsx:208
|
||||
#: src/views/settings/index.tsx:245
|
||||
msgid "Billing portal"
|
||||
msgstr "Portale di fatturazione"
|
||||
|
||||
@@ -243,6 +243,11 @@ msgstr "Post del blog"
|
||||
msgid "Board"
|
||||
msgstr "Bacheca"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:346
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:81
|
||||
msgid "Board analytics"
|
||||
msgstr "Analisi della bacheca"
|
||||
|
||||
#: src/views/boards/components/NewBoardForm.tsx:21
|
||||
msgid "Board name cannot exceed 100 characters"
|
||||
msgstr "Il nome della bacheca non può superare i 100 caratteri"
|
||||
@@ -309,9 +314,9 @@ msgstr "Segnalazione bug"
|
||||
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:168
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:50
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:88
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:98
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:104
|
||||
msgid "Cancel"
|
||||
msgstr "Annulla"
|
||||
|
||||
@@ -325,12 +330,12 @@ msgstr "Titolo della carta"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:109
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:178
|
||||
#: src/views/settings/index.tsx:291
|
||||
#: src/views/settings/index.tsx:301
|
||||
#: src/views/settings/index.tsx:328
|
||||
#: src/views/settings/index.tsx:338
|
||||
msgid "Change Password"
|
||||
msgstr "Cambia password"
|
||||
|
||||
#: src/views/settings/index.tsx:190
|
||||
#: src/views/settings/index.tsx:227
|
||||
msgid "Change the language of the app."
|
||||
msgstr "Cambia la lingua dell'app."
|
||||
|
||||
@@ -360,7 +365,9 @@ msgstr "Revisione del codice"
|
||||
msgid "Collaborate seamlessly with your team."
|
||||
msgstr "Collabora senza problemi con il tuo team."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:349
|
||||
#: src/views/home/components/Features.tsx:66
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:84
|
||||
msgid "Coming soon"
|
||||
msgstr "Prossimamente"
|
||||
|
||||
@@ -389,16 +396,12 @@ msgstr "ha completato un elemento della checklist"
|
||||
msgid "completed checklist item <0>{0}</0>"
|
||||
msgstr "ha completato l'elemento <0>{0}</0> della checklist"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:42
|
||||
msgid "Confirm URL change"
|
||||
msgstr "Conferma modifica URL"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:150
|
||||
msgid "Confirm your new password"
|
||||
msgstr "Conferma la tua nuova password"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:157
|
||||
#: src/views/settings/index.tsx:235
|
||||
#: src/views/settings/index.tsx:272
|
||||
msgid "Connect Trello"
|
||||
msgstr "Connetti Trello"
|
||||
|
||||
@@ -406,7 +409,7 @@ msgstr "Connetti Trello"
|
||||
msgid "Connect your favorite tools to streamline your workflow."
|
||||
msgstr "Connetti i tuoi strumenti preferiti per semplificare il tuo flusso di lavoro."
|
||||
|
||||
#: src/views/settings/index.tsx:222
|
||||
#: src/views/settings/index.tsx:259
|
||||
msgid "Connect your Trello account to import boards."
|
||||
msgstr "Connetti il tuo account Trello per importare le bacheche."
|
||||
|
||||
@@ -478,7 +481,7 @@ msgstr "Crea nuova etichetta"
|
||||
msgid "Create new list"
|
||||
msgstr "Crea nuova lista"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:94
|
||||
#: src/components/NewWorkspaceForm.tsx:384
|
||||
#: src/components/WorkspaceMenu.tsx:116
|
||||
msgid "Create workspace"
|
||||
msgstr "Crea spazio di lavoro"
|
||||
@@ -499,9 +502,14 @@ msgstr "La password attuale è obbligatoria"
|
||||
msgid "Custom domain"
|
||||
msgstr "Dominio personalizzato"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:45
|
||||
msgid "Custom URLs are a premium feature. You'll be directed to upgrade your account."
|
||||
msgstr "Gli URL personalizzati sono una funzionalità premium. Sarai indirizzato all'aggiornamento del tuo account."
|
||||
#: src/components/NewWorkspaceForm.tsx:315
|
||||
msgid "Custom URLs require upgrading to a Pro plan"
|
||||
msgstr "Gli URL personalizzati richiedono l'aggiornamento a un piano Pro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:339
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:74
|
||||
msgid "Custom workspace URL"
|
||||
msgstr "URL personalizzato dell'area di lavoro"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:41
|
||||
msgid "Customer Support"
|
||||
@@ -520,8 +528,8 @@ msgid "Delete"
|
||||
msgstr "Elimina"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:96
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:319
|
||||
#: src/views/settings/index.tsx:346
|
||||
#: src/views/settings/index.tsx:356
|
||||
msgid "Delete account"
|
||||
msgstr "Elimina account"
|
||||
|
||||
@@ -542,8 +550,8 @@ msgid "Delete list"
|
||||
msgstr "Elimina lista"
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:106
|
||||
#: src/views/settings/index.tsx:272
|
||||
#: src/views/settings/index.tsx:283
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:320
|
||||
msgid "Delete workspace"
|
||||
msgstr "Elimina spazio di lavoro"
|
||||
|
||||
@@ -569,7 +577,7 @@ msgstr "ha eliminato l'elemento <0>{0}</0> della checklist"
|
||||
msgid "Design"
|
||||
msgstr "Design"
|
||||
|
||||
#: src/views/settings/index.tsx:250
|
||||
#: src/views/settings/index.tsx:287
|
||||
msgid "Disconnect Trello"
|
||||
msgstr "Disconnetti Trello"
|
||||
|
||||
@@ -577,7 +585,7 @@ msgstr "Disconnetti Trello"
|
||||
msgid "Discuss and collaborate on cards."
|
||||
msgstr "Discuti e collabora sulle schede."
|
||||
|
||||
#: src/views/settings/index.tsx:151
|
||||
#: src/views/settings/index.tsx:176
|
||||
msgid "Display name"
|
||||
msgstr "Nome visualizzato"
|
||||
|
||||
@@ -647,7 +655,7 @@ msgstr "Modifica"
|
||||
msgid "email"
|
||||
msgstr "email"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:163
|
||||
#: src/views/members/components/InviteMemberForm.tsx:161
|
||||
msgid "Email"
|
||||
msgstr "Email"
|
||||
|
||||
@@ -695,12 +703,12 @@ msgstr "Errore durante l'eliminazione dell'etichetta"
|
||||
msgid "Error deleting workspace"
|
||||
msgstr "Errore durante l'eliminazione dell'area di lavoro"
|
||||
|
||||
#: src/views/settings/index.tsx:101
|
||||
#: src/views/settings/index.tsx:126
|
||||
msgid "Error disconnecting Trello"
|
||||
msgstr "Errore durante la disconnessione da Trello"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:76
|
||||
#: src/views/members/components/InviteMemberForm.tsx:82
|
||||
#: src/views/members/components/InviteMemberForm.tsx:71
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
msgid "Error inviting member"
|
||||
msgstr "Errore durante l'invito del membro"
|
||||
|
||||
@@ -724,10 +732,15 @@ msgstr "Errore durante l'aggiornamento del nome dell'area di lavoro"
|
||||
msgid "Error updating workspace URL"
|
||||
msgstr "Errore durante l'aggiornamento dell'URL dell'area di lavoro"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:132
|
||||
#: src/views/members/components/InviteMemberForm.tsx:130
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:41
|
||||
msgid "Error upgrading subscription"
|
||||
msgstr "Errore nell'aggiornamento dell'abbonamento"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:142
|
||||
msgid "Error upgrading to Pro"
|
||||
msgstr "Errore durante l'aggiornamento a Pro"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:56
|
||||
#: src/views/settings/components/Avatar.tsx:97
|
||||
msgid "Error uploading profile image"
|
||||
@@ -794,8 +807,8 @@ msgstr "Per la sostenibilità a lungo termine, riconosciamo che tutti i buoni pr
|
||||
msgid "Free"
|
||||
msgstr "Gratuito"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:192
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:193
|
||||
#: src/views/members/index.tsx:208
|
||||
msgid "Free Plan"
|
||||
msgstr "Piano gratuito"
|
||||
|
||||
@@ -950,24 +963,24 @@ msgstr "Integrazioni"
|
||||
msgid "Interviewing"
|
||||
msgstr "Colloquio"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:45
|
||||
#: src/views/members/components/InviteMemberForm.tsx:40
|
||||
msgid "Invalid email address"
|
||||
msgstr "Indirizzo email non valido"
|
||||
|
||||
#: src/views/members/index.tsx:193
|
||||
#: src/views/members/index.tsx:221
|
||||
msgid "Invite"
|
||||
msgstr "Invita"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:207
|
||||
#: src/views/members/components/InviteMemberForm.tsx:208
|
||||
msgid "Invite another"
|
||||
msgstr "Invita un altro"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:112
|
||||
#: src/views/members/components/InviteMemberForm.tsx:231
|
||||
#: src/views/members/components/InviteMemberForm.tsx:233
|
||||
msgid "Invite member"
|
||||
msgstr "Invita membro"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:195
|
||||
#: src/views/members/components/InviteMemberForm.tsx:196
|
||||
msgid "Inviting members requires a Team Plan. You'll be redirected to upgrade your workspace."
|
||||
msgstr "L'invito di membri richiede un Piano Team. Sarai reindirizzato per aggiornare il tuo spazio di lavoro."
|
||||
|
||||
@@ -998,10 +1011,23 @@ msgstr "Etichette"
|
||||
msgid "Labels & Filters"
|
||||
msgstr "Etichette & Filtri"
|
||||
|
||||
#: src/views/settings/index.tsx:187
|
||||
#: src/views/settings/index.tsx:224
|
||||
msgid "Language"
|
||||
msgstr "Lingua"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:332
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:67
|
||||
msgid "Launch offer"
|
||||
msgstr "Offerta di lancio"
|
||||
|
||||
#: src/views/members/index.tsx:191
|
||||
msgid "Launch offer: Get unlimited members with Pro"
|
||||
msgstr "Offerta di lancio: ottieni membri illimitati con Pro"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:99
|
||||
msgid "Launch offer: unlimited seats for just $29/month with Pro"
|
||||
msgstr "Offerta di lancio: posti illimitati a soli $29/mese con Pro"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:83
|
||||
msgid "Learning"
|
||||
msgstr "Apprendimento"
|
||||
@@ -1067,12 +1093,12 @@ msgstr "Media priorità"
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:357
|
||||
#: src/views/card/index.tsx:125
|
||||
#: src/views/members/index.tsx:171
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Membri"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/members/index.tsx:167
|
||||
#: src/views/members/index.tsx:173
|
||||
msgid "Members | {0}"
|
||||
msgstr "Membri | {0}"
|
||||
|
||||
@@ -1080,7 +1106,7 @@ msgstr "Membri | {0}"
|
||||
msgid "Monthly"
|
||||
msgstr "Mensile"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:93
|
||||
msgid "monthly billing"
|
||||
msgstr "fatturazione mensile"
|
||||
|
||||
@@ -1144,7 +1170,7 @@ msgstr "La nuova password deve essere diversa dalla password attuale"
|
||||
msgid "New Ticket"
|
||||
msgstr "Nuovo ticket"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:65
|
||||
#: src/components/NewWorkspaceForm.tsx:240
|
||||
msgid "New workspace"
|
||||
msgstr "Nuovo spazio di lavoro"
|
||||
|
||||
@@ -1180,11 +1206,11 @@ msgstr "Offerta"
|
||||
msgid "Onboarding"
|
||||
msgstr "Inserimento"
|
||||
|
||||
#: src/views/settings/index.tsx:312
|
||||
#: src/views/settings/index.tsx:349
|
||||
msgid "Once you delete your account, there is no going back. This action cannot be undone."
|
||||
msgstr "Una volta eliminato il tuo account, non si può tornare indietro. Questa azione non può essere annullata."
|
||||
|
||||
#: src/views/settings/index.tsx:275
|
||||
#: src/views/settings/index.tsx:312
|
||||
msgid "Once you delete your workspace, there is no going back. This action cannot be undone."
|
||||
msgstr "Una volta eliminata l'area di lavoro, non si può tornare indietro. Questa azione non può essere annullata."
|
||||
|
||||
@@ -1216,11 +1242,11 @@ msgstr "La password deve contenere almeno 8 caratteri"
|
||||
msgid "Passwords do not match"
|
||||
msgstr "Le password non corrispondono"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:96
|
||||
#: src/views/home/components/Pricing.tsx:102
|
||||
msgid "Payment frequency"
|
||||
msgstr "Frequenza di pagamento"
|
||||
|
||||
#: src/views/members/index.tsx:128
|
||||
#: src/views/members/index.tsx:134
|
||||
msgid "Pending"
|
||||
msgstr "In attesa"
|
||||
|
||||
@@ -1259,7 +1285,7 @@ msgstr "Seleziona un file da caricare."
|
||||
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:42
|
||||
#: src/components/NewWorkspaceForm.tsx:155
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
@@ -1282,8 +1308,8 @@ msgstr "Seleziona un file da caricare."
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:173
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:83
|
||||
#: src/views/members/components/InviteMemberForm.tsx:133
|
||||
#: src/views/members/components/InviteMemberForm.tsx:78
|
||||
#: src/views/members/components/InviteMemberForm.tsx:131
|
||||
#: src/views/settings/components/Avatar.tsx:40
|
||||
#: src/views/settings/components/Avatar.tsx:98
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
|
||||
@@ -1292,6 +1318,7 @@ msgstr "Seleziona un file da caricare."
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:62
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:57
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:74
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:42
|
||||
msgid "Please try again later, or contact customer support."
|
||||
msgstr "Riprova più tardi o contatta l'assistenza clienti."
|
||||
|
||||
@@ -1302,6 +1329,7 @@ msgid "Pricing"
|
||||
msgstr "Prezzi"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:56
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:91
|
||||
msgid "Priority email support"
|
||||
msgstr "Supporto email prioritario"
|
||||
|
||||
@@ -1313,11 +1341,19 @@ msgstr "Informativa sulla privacy"
|
||||
msgid "Private"
|
||||
msgstr "Privato"
|
||||
|
||||
#: src/views/members/index.tsx:205
|
||||
msgid "Pro Plan"
|
||||
msgstr "Piano Pro"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
msgid "Pro Plan ∞"
|
||||
msgstr "Piano Pro ∞"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:26
|
||||
msgid "Profile image updated"
|
||||
msgstr "Immagine del profilo aggiornata"
|
||||
|
||||
#: src/views/settings/index.tsx:146
|
||||
#: src/views/settings/index.tsx:171
|
||||
msgid "Profile picture"
|
||||
msgstr "Immagine del profilo"
|
||||
|
||||
@@ -1353,7 +1389,7 @@ msgstr "Remoto"
|
||||
msgid "Remove"
|
||||
msgstr "Rimuovi"
|
||||
|
||||
#: src/views/members/index.tsx:142
|
||||
#: src/views/members/index.tsx:148
|
||||
msgid "Remove member"
|
||||
msgstr "Rimuovi membro"
|
||||
|
||||
@@ -1409,7 +1445,7 @@ msgstr "Revoca"
|
||||
msgid "Roadmap"
|
||||
msgstr "Roadmap"
|
||||
|
||||
#: src/views/members/index.tsx:215
|
||||
#: src/views/members/index.tsx:243
|
||||
msgid "Role"
|
||||
msgstr "Ruolo"
|
||||
|
||||
@@ -1458,12 +1494,12 @@ msgid "Senior"
|
||||
msgstr "Senior"
|
||||
|
||||
#: src/components/SideNavigation.tsx:78
|
||||
#: src/views/settings/index.tsx:140
|
||||
#: src/views/settings/index.tsx:165
|
||||
msgid "Settings"
|
||||
msgstr "Impostazioni"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/settings/index.tsx:136
|
||||
#: src/views/settings/index.tsx:161
|
||||
msgid "Settings | {0}"
|
||||
msgstr "Impostazioni | {0}"
|
||||
|
||||
@@ -1514,6 +1550,10 @@ msgstr "Metti una stella su Github"
|
||||
msgid "Success"
|
||||
msgstr "Operazione riuscita"
|
||||
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:55
|
||||
msgid "Supercharge your workspace for just $29/month. Here's what you'll get:"
|
||||
msgstr "Potenzia la tua area di lavoro per soli $29/mese. Ecco cosa otterrai:"
|
||||
|
||||
#: src/components/UserMenu.tsx:180
|
||||
msgid "Support"
|
||||
msgstr "Supporto"
|
||||
@@ -1526,8 +1566,8 @@ msgstr "Sostieni lo sviluppo del progetto"
|
||||
msgid "System"
|
||||
msgstr "Sistema"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:183
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
#: src/views/members/index.tsx:207
|
||||
msgid "Team Plan"
|
||||
msgstr "Piano Team"
|
||||
|
||||
@@ -1595,6 +1635,14 @@ msgstr "Questo comporterà l'eliminazione permanente di tutti i dati associati a
|
||||
msgid "This will result in the permanent deletion of all data associated with your account."
|
||||
msgstr "Questo comporterà l'eliminazione permanente di tutti i dati associati al tuo account."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:284
|
||||
msgid "This workspace URL has already been taken"
|
||||
msgstr "Questo URL dello spazio di lavoro è già stato utilizzato"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:286
|
||||
msgid "This workspace URL is reserved"
|
||||
msgstr "Questo URL dello spazio di lavoro è riservato"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:123
|
||||
msgid "This workspace username has already been taken"
|
||||
msgstr "Questo nome utente dell'area di lavoro è già stato utilizzato"
|
||||
@@ -1612,7 +1660,7 @@ msgstr "Attiva/disattiva menu"
|
||||
msgid "Track all card changes with detailed activity history."
|
||||
msgstr "Tieni traccia di tutte le modifiche alle schede con una cronologia dettagliata delle attività."
|
||||
|
||||
#: src/views/settings/index.tsx:94
|
||||
#: src/views/settings/index.tsx:119
|
||||
msgid "Trello disconnected"
|
||||
msgstr "Trello disconnesso"
|
||||
|
||||
@@ -1644,7 +1692,7 @@ msgstr "Impossibile creare la checklist"
|
||||
msgid "Unable to create list"
|
||||
msgstr "Impossibile creare la lista"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:154
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Impossibile creare lo spazio di lavoro"
|
||||
|
||||
@@ -1743,6 +1791,11 @@ msgstr "Commenti illimitati"
|
||||
msgid "Unlimited lists"
|
||||
msgstr "Liste illimitate"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:329
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:64
|
||||
msgid "Unlimited members"
|
||||
msgstr "Membri illimitati"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
|
||||
@@ -1772,11 +1825,20 @@ msgstr "ha aggiornato il titolo"
|
||||
msgid "updated the title to <0>{0}</0>"
|
||||
msgstr "ha aggiornato il titolo in <0>{0}</0>"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:52
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:109
|
||||
msgid "Upgrade"
|
||||
msgstr "Aggiorna"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:222
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:52
|
||||
#: src/views/settings/index.tsx:216
|
||||
msgid "Upgrade to Pro"
|
||||
msgstr "Passa a Pro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:369
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Passa a Pro ($29/mese)"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:224
|
||||
msgid "Upgrade to Team Plan"
|
||||
msgstr "Passa al Piano Team"
|
||||
|
||||
@@ -1785,14 +1847,17 @@ msgstr "Passa al Piano Team"
|
||||
msgid "Urgent"
|
||||
msgstr "Urgente"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:35
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:36
|
||||
msgid "URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "L'URL può contenere solo lettere, numeri e trattini"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:33
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:34
|
||||
msgid "URL cannot exceed 24 characters"
|
||||
msgstr "L'URL non può superare i 24 caratteri"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:31
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:32
|
||||
msgid "URL must be at least 3 characters long"
|
||||
msgstr "L'URL deve contenere almeno 3 caratteri"
|
||||
@@ -1801,11 +1866,11 @@ msgstr "L'URL deve contenere almeno 3 caratteri"
|
||||
msgid "Use template"
|
||||
msgstr "Usa template"
|
||||
|
||||
#: src/views/members/index.tsx:209
|
||||
#: src/views/members/index.tsx:237
|
||||
msgid "User"
|
||||
msgstr "Utente"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
#: src/views/members/components/InviteMemberForm.tsx:72
|
||||
msgid "User is already a member of this workspace"
|
||||
msgstr "L'utente è già membro di questo spazio di lavoro"
|
||||
|
||||
@@ -1813,11 +1878,11 @@ msgstr "L'utente è già membro di questo spazio di lavoro"
|
||||
msgid "Video"
|
||||
msgstr "Video"
|
||||
|
||||
#: src/views/settings/index.tsx:262
|
||||
#: src/views/settings/index.tsx:299
|
||||
msgid "View and manage your API keys."
|
||||
msgstr "Visualizza e gestisci le tue chiavi API."
|
||||
|
||||
#: src/views/settings/index.tsx:201
|
||||
#: src/views/settings/index.tsx:238
|
||||
msgid "View and manage your billing and subscription."
|
||||
msgstr "Visualizza e gestisci la tua fatturazione e abbonamento."
|
||||
|
||||
@@ -1873,11 +1938,15 @@ msgstr "Perché creare un Trello open source?"
|
||||
msgid "Workspace"
|
||||
msgstr "Spazio di lavoro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:143
|
||||
msgid "Workspace created successfully. You can upgrade later in settings."
|
||||
msgstr "Spazio di lavoro creato con successo. Puoi effettuare l'aggiornamento più tardi nelle impostazioni."
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:26
|
||||
msgid "Workspace deleted"
|
||||
msgstr "Spazio di lavoro eliminato"
|
||||
|
||||
#: src/views/settings/index.tsx:177
|
||||
#: src/views/settings/index.tsx:202
|
||||
msgid "Workspace description"
|
||||
msgstr "Descrizione dello spazio di lavoro"
|
||||
|
||||
@@ -1898,8 +1967,8 @@ msgstr "Descrizione dell'area di lavoro aggiornata"
|
||||
msgid "Workspace members"
|
||||
msgstr "Membri del workspace"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:81
|
||||
#: src/views/settings/index.tsx:158
|
||||
#: src/components/NewWorkspaceForm.tsx:259
|
||||
#: src/views/settings/index.tsx:183
|
||||
msgid "Workspace name"
|
||||
msgstr "Nome dello spazio di lavoro"
|
||||
|
||||
@@ -1907,6 +1976,10 @@ msgstr "Nome dello spazio di lavoro"
|
||||
msgid "Workspace name cannot exceed 24 characters"
|
||||
msgstr "Il nome dello spazio di lavoro non può superare i 24 caratteri"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:27
|
||||
msgid "Workspace name is required"
|
||||
msgstr "Il nome dello spazio di lavoro è obbligatorio"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:14
|
||||
msgid "Workspace name must be at least 3 characters long"
|
||||
msgstr "Il nome dello spazio di lavoro deve contenere almeno 3 caratteri"
|
||||
@@ -1919,10 +1992,14 @@ msgstr "Nome dello spazio di lavoro aggiornato"
|
||||
msgid "Workspace slug updated"
|
||||
msgstr "Slug dell'area di lavoro aggiornato"
|
||||
|
||||
#: src/views/settings/index.tsx:167
|
||||
#: src/views/settings/index.tsx:192
|
||||
msgid "Workspace URL"
|
||||
msgstr "URL dello spazio di lavoro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:273
|
||||
msgid "workspace-url"
|
||||
msgstr "workspace-url"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:30
|
||||
msgid "Writing"
|
||||
msgstr "Scrittura"
|
||||
@@ -1935,7 +2012,7 @@ msgstr "Annuale"
|
||||
msgid "Yes, we offer an forever free plan for individual use. No restrictions, no paywalls, no limits."
|
||||
msgstr "Sì, offriamo un piano gratuito per sempre per uso individuale. Nessuna restrizione, nessun paywall, nessun limite."
|
||||
|
||||
#: src/views/settings/index.tsx:294
|
||||
#: src/views/settings/index.tsx:331
|
||||
msgid "You are about to change your password."
|
||||
msgstr "Stai per cambiare la tua password."
|
||||
|
||||
@@ -1959,6 +2036,10 @@ msgstr "Hai effettuato l'accesso con successo."
|
||||
msgid "You have been signed up successfully."
|
||||
msgstr "Ti sei registrato con successo."
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
msgid "You have unlimited seats with your Pro Plan. There is no additional charge for new members!"
|
||||
msgstr "Hai posti illimitati con il tuo Piano Pro. Non ci sono costi aggiuntivi per i nuovi membri!"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:28
|
||||
msgid "Your account has been deleted."
|
||||
msgstr "Il tuo account è stato eliminato."
|
||||
@@ -1979,11 +2060,11 @@ msgstr "La tua password è stata modificata."
|
||||
msgid "Your profile image has been updated."
|
||||
msgstr "La tua immagine del profilo è stata aggiornata."
|
||||
|
||||
#: src/views/settings/index.tsx:95
|
||||
#: src/views/settings/index.tsx:120
|
||||
msgid "Your Trello account has been disconnected."
|
||||
msgstr "Il tuo account Trello è stato disconnesso."
|
||||
|
||||
#: src/views/settings/index.tsx:244
|
||||
#: src/views/settings/index.tsx:281
|
||||
msgid "Your Trello account is connected."
|
||||
msgstr "Il tuo account Trello è connesso."
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -36,12 +36,12 @@ msgstr "{0} labels"
|
||||
msgid "{boardCount, plural, one {Import board (1)} other {Import boards ({boardCount})}}"
|
||||
msgstr "{boardCount, plural, one {Bord importeren (1)} other {Borden importeren ({boardCount})}}"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:91
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$10/month"
|
||||
msgstr "$10/maand"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:106
|
||||
#: src/views/members/components/InviteMemberForm.tsx:104
|
||||
msgid "$8/month"
|
||||
msgstr "$8/maand"
|
||||
|
||||
@@ -97,7 +97,7 @@ msgid "Add label"
|
||||
msgstr "Label toevoegen"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:130
|
||||
#: src/views/members/components/InviteMemberForm.tsx:149
|
||||
#: src/views/members/components/InviteMemberForm.tsx:147
|
||||
msgid "Add member"
|
||||
msgstr "Lid toevoegen"
|
||||
|
||||
@@ -132,7 +132,7 @@ msgstr "heeft checklistitem <0>{0}</0> toegevoegd"
|
||||
msgid "added label <0>{0}</0>"
|
||||
msgstr "heeft label <0>{0}</0> toegevoegd"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
#: src/views/members/components/InviteMemberForm.tsx:187
|
||||
msgid "Adding a new member will cost an additional {price} ({billingType}) per seat."
|
||||
msgstr "Het toevoegen van een nieuw lid kost een extra {price} ({billingType}) per plaats."
|
||||
|
||||
@@ -148,7 +148,7 @@ msgstr "Alle systemen operationeel"
|
||||
msgid "Already have an account? <0><1>Sign in</1></0>"
|
||||
msgstr "Heb je al een account? <0><1>Log in</1></0>"
|
||||
|
||||
#: src/views/settings/index.tsx:102
|
||||
#: src/views/settings/index.tsx:127
|
||||
msgid "An error occurred while disconnecting your Trello account."
|
||||
msgstr "Er is een fout opgetreden bij het verbreken van de verbinding met je Trello-account."
|
||||
|
||||
@@ -156,7 +156,7 @@ msgstr "Er is een fout opgetreden bij het verbreken van de verbinding met je Tre
|
||||
msgid "An unexpected error occurred. Please try again later."
|
||||
msgstr "Er is een onverwachte fout opgetreden. Probeer het later opnieuw."
|
||||
|
||||
#: src/views/settings/index.tsx:259
|
||||
#: src/views/settings/index.tsx:296
|
||||
msgid "API keys"
|
||||
msgstr "API-sleutels"
|
||||
|
||||
@@ -218,20 +218,20 @@ msgstr "Backlog"
|
||||
msgid "Basic Kanban"
|
||||
msgstr "Basis kanban"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed annually"
|
||||
msgstr "jaarlijks gefactureerd"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:107
|
||||
#: src/views/members/components/InviteMemberForm.tsx:105
|
||||
msgid "billed monthly"
|
||||
msgstr "maandelijks gefactureerd"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:55
|
||||
#: src/views/settings/index.tsx:198
|
||||
#: src/views/settings/index.tsx:235
|
||||
msgid "Billing"
|
||||
msgstr "Facturering"
|
||||
|
||||
#: src/views/settings/index.tsx:208
|
||||
#: src/views/settings/index.tsx:245
|
||||
msgid "Billing portal"
|
||||
msgstr "Factureringsportaal"
|
||||
|
||||
@@ -243,6 +243,11 @@ msgstr "Blogbericht"
|
||||
msgid "Board"
|
||||
msgstr "Bord"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:346
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:81
|
||||
msgid "Board analytics"
|
||||
msgstr "Bordanalyses"
|
||||
|
||||
#: src/views/boards/components/NewBoardForm.tsx:21
|
||||
msgid "Board name cannot exceed 100 characters"
|
||||
msgstr "Bordnaam mag niet langer zijn dan 100 tekens"
|
||||
@@ -309,9 +314,9 @@ msgstr "Bugrapport"
|
||||
#: src/views/card/components/DeleteCommentConfirmation.tsx:76
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:55
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:168
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:50
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:88
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:98
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:104
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleren"
|
||||
|
||||
@@ -325,12 +330,12 @@ msgstr "Kaarttitel"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:109
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:178
|
||||
#: src/views/settings/index.tsx:291
|
||||
#: src/views/settings/index.tsx:301
|
||||
#: src/views/settings/index.tsx:328
|
||||
#: src/views/settings/index.tsx:338
|
||||
msgid "Change Password"
|
||||
msgstr "Wachtwoord wijzigen"
|
||||
|
||||
#: src/views/settings/index.tsx:190
|
||||
#: src/views/settings/index.tsx:227
|
||||
msgid "Change the language of the app."
|
||||
msgstr "Wijzig de taal van de app."
|
||||
|
||||
@@ -360,7 +365,9 @@ msgstr "Code review"
|
||||
msgid "Collaborate seamlessly with your team."
|
||||
msgstr "Werk naadloos samen met je team."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:349
|
||||
#: src/views/home/components/Features.tsx:66
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:84
|
||||
msgid "Coming soon"
|
||||
msgstr "Binnenkort beschikbaar"
|
||||
|
||||
@@ -389,16 +396,12 @@ msgstr "heeft een checklistitem voltooid"
|
||||
msgid "completed checklist item <0>{0}</0>"
|
||||
msgstr "heeft checklistitem <0>{0}</0> voltooid"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:42
|
||||
msgid "Confirm URL change"
|
||||
msgstr "URL-wijziging bevestigen"
|
||||
|
||||
#: src/views/settings/components/ChangePasswordConfirmation.tsx:150
|
||||
msgid "Confirm your new password"
|
||||
msgstr "Bevestig je nieuwe wachtwoord"
|
||||
|
||||
#: src/views/boards/components/ImportBoardsForm.tsx:157
|
||||
#: src/views/settings/index.tsx:235
|
||||
#: src/views/settings/index.tsx:272
|
||||
msgid "Connect Trello"
|
||||
msgstr "Verbind Trello"
|
||||
|
||||
@@ -406,7 +409,7 @@ msgstr "Verbind Trello"
|
||||
msgid "Connect your favorite tools to streamline your workflow."
|
||||
msgstr "Verbind je favoriete tools om je werkstroom te stroomlijnen."
|
||||
|
||||
#: src/views/settings/index.tsx:222
|
||||
#: src/views/settings/index.tsx:259
|
||||
msgid "Connect your Trello account to import boards."
|
||||
msgstr "Verbind je Trello-account om borden te importeren."
|
||||
|
||||
@@ -478,7 +481,7 @@ msgstr "Maak nieuw label"
|
||||
msgid "Create new list"
|
||||
msgstr "Maak nieuwe lijst"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:94
|
||||
#: src/components/NewWorkspaceForm.tsx:384
|
||||
#: src/components/WorkspaceMenu.tsx:116
|
||||
msgid "Create workspace"
|
||||
msgstr "Werkruimte maken"
|
||||
@@ -499,9 +502,14 @@ msgstr "Huidig wachtwoord is vereist"
|
||||
msgid "Custom domain"
|
||||
msgstr "Aangepast domein"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:45
|
||||
msgid "Custom URLs are a premium feature. You'll be directed to upgrade your account."
|
||||
msgstr "Aangepaste URL's zijn een premium functie. Je wordt doorgestuurd om je account te upgraden."
|
||||
#: src/components/NewWorkspaceForm.tsx:315
|
||||
msgid "Custom URLs require upgrading to a Pro plan"
|
||||
msgstr "Aangepaste URL's vereisen een upgrade naar een Pro-abonnement"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:339
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:74
|
||||
msgid "Custom workspace URL"
|
||||
msgstr "Aangepaste werkruimte-URL"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:41
|
||||
msgid "Customer Support"
|
||||
@@ -520,8 +528,8 @@ msgid "Delete"
|
||||
msgstr "Verwijderen"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:96
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:319
|
||||
#: src/views/settings/index.tsx:346
|
||||
#: src/views/settings/index.tsx:356
|
||||
msgid "Delete account"
|
||||
msgstr "Account verwijderen"
|
||||
|
||||
@@ -542,8 +550,8 @@ msgid "Delete list"
|
||||
msgstr "Lijst verwijderen"
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:106
|
||||
#: src/views/settings/index.tsx:272
|
||||
#: src/views/settings/index.tsx:283
|
||||
#: src/views/settings/index.tsx:309
|
||||
#: src/views/settings/index.tsx:320
|
||||
msgid "Delete workspace"
|
||||
msgstr "Werkruimte verwijderen"
|
||||
|
||||
@@ -569,7 +577,7 @@ msgstr "heeft checklistitem <0>{0}</0> verwijderd"
|
||||
msgid "Design"
|
||||
msgstr "Ontwerp"
|
||||
|
||||
#: src/views/settings/index.tsx:250
|
||||
#: src/views/settings/index.tsx:287
|
||||
msgid "Disconnect Trello"
|
||||
msgstr "Trello ontkoppelen"
|
||||
|
||||
@@ -577,7 +585,7 @@ msgstr "Trello ontkoppelen"
|
||||
msgid "Discuss and collaborate on cards."
|
||||
msgstr "Bespreek en werk samen aan kaarten."
|
||||
|
||||
#: src/views/settings/index.tsx:151
|
||||
#: src/views/settings/index.tsx:176
|
||||
msgid "Display name"
|
||||
msgstr "Weergavenaam"
|
||||
|
||||
@@ -647,7 +655,7 @@ msgstr "Bewerken"
|
||||
msgid "email"
|
||||
msgstr "e-mail"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:163
|
||||
#: src/views/members/components/InviteMemberForm.tsx:161
|
||||
msgid "Email"
|
||||
msgstr "E-mail"
|
||||
|
||||
@@ -695,12 +703,12 @@ msgstr "Fout bij het verwijderen van label"
|
||||
msgid "Error deleting workspace"
|
||||
msgstr "Fout bij verwijderen werkruimte"
|
||||
|
||||
#: src/views/settings/index.tsx:101
|
||||
#: src/views/settings/index.tsx:126
|
||||
msgid "Error disconnecting Trello"
|
||||
msgstr "Fout bij ontkoppelen van Trello"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:76
|
||||
#: src/views/members/components/InviteMemberForm.tsx:82
|
||||
#: src/views/members/components/InviteMemberForm.tsx:71
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
msgid "Error inviting member"
|
||||
msgstr "Fout bij het uitnodigen van lid"
|
||||
|
||||
@@ -724,10 +732,15 @@ msgstr "Fout bij bijwerken naam werkruimte"
|
||||
msgid "Error updating workspace URL"
|
||||
msgstr "Fout bij het bijwerken van werkruimte-URL"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:132
|
||||
#: src/views/members/components/InviteMemberForm.tsx:130
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:41
|
||||
msgid "Error upgrading subscription"
|
||||
msgstr "Fout bij het upgraden van abonnement"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:142
|
||||
msgid "Error upgrading to Pro"
|
||||
msgstr "Fout bij upgraden naar Pro"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:56
|
||||
#: src/views/settings/components/Avatar.tsx:97
|
||||
msgid "Error uploading profile image"
|
||||
@@ -794,8 +807,8 @@ msgstr "Voor duurzaamheid op lange termijn erkennen we dat alle goede open sourc
|
||||
msgid "Free"
|
||||
msgstr "Gratis"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:192
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:193
|
||||
#: src/views/members/index.tsx:208
|
||||
msgid "Free Plan"
|
||||
msgstr "Gratis plan"
|
||||
|
||||
@@ -950,24 +963,24 @@ msgstr "Integraties"
|
||||
msgid "Interviewing"
|
||||
msgstr "Interviewen"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:45
|
||||
#: src/views/members/components/InviteMemberForm.tsx:40
|
||||
msgid "Invalid email address"
|
||||
msgstr "Ongeldig e-mailadres"
|
||||
|
||||
#: src/views/members/index.tsx:193
|
||||
#: src/views/members/index.tsx:221
|
||||
msgid "Invite"
|
||||
msgstr "Uitnodigen"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:207
|
||||
#: src/views/members/components/InviteMemberForm.tsx:208
|
||||
msgid "Invite another"
|
||||
msgstr "Nog iemand uitnodigen"
|
||||
|
||||
#: src/views/card/components/MemberSelector.tsx:112
|
||||
#: src/views/members/components/InviteMemberForm.tsx:231
|
||||
#: src/views/members/components/InviteMemberForm.tsx:233
|
||||
msgid "Invite member"
|
||||
msgstr "Lid uitnodigen"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:195
|
||||
#: src/views/members/components/InviteMemberForm.tsx:196
|
||||
msgid "Inviting members requires a Team Plan. You'll be redirected to upgrade your workspace."
|
||||
msgstr "Voor het uitnodigen van leden is een teamplan vereist. Je wordt doorgestuurd om je werkruimte te upgraden."
|
||||
|
||||
@@ -998,10 +1011,23 @@ msgstr "Labels"
|
||||
msgid "Labels & Filters"
|
||||
msgstr "Labels & filters"
|
||||
|
||||
#: src/views/settings/index.tsx:187
|
||||
#: src/views/settings/index.tsx:224
|
||||
msgid "Language"
|
||||
msgstr "Taal"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:332
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:67
|
||||
msgid "Launch offer"
|
||||
msgstr "Introductieaanbieding"
|
||||
|
||||
#: src/views/members/index.tsx:191
|
||||
msgid "Launch offer: Get unlimited members with Pro"
|
||||
msgstr "Lanceringsaanbieding: krijg onbeperkt aantal leden met Pro"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:99
|
||||
msgid "Launch offer: unlimited seats for just $29/month with Pro"
|
||||
msgstr "Introductieaanbieding: onbeperkt aantal gebruikers voor slechts $29/maand met Pro"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:83
|
||||
msgid "Learning"
|
||||
msgstr "Leren"
|
||||
@@ -1067,12 +1093,12 @@ msgstr "Gemiddelde prioriteit"
|
||||
#: src/views/board/components/Filters.tsx:93
|
||||
#: src/views/board/components/NewCardForm.tsx:357
|
||||
#: src/views/card/index.tsx:125
|
||||
#: src/views/members/index.tsx:171
|
||||
#: src/views/members/index.tsx:178
|
||||
msgid "Members"
|
||||
msgstr "Leden"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/members/index.tsx:167
|
||||
#: src/views/members/index.tsx:173
|
||||
msgid "Members | {0}"
|
||||
msgstr "Leden | {0}"
|
||||
|
||||
@@ -1080,7 +1106,7 @@ msgstr "Leden | {0}"
|
||||
msgid "Monthly"
|
||||
msgstr "Maandelijks"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:92
|
||||
#: src/views/members/components/InviteMemberForm.tsx:93
|
||||
msgid "monthly billing"
|
||||
msgstr "maandelijkse facturering"
|
||||
|
||||
@@ -1144,7 +1170,7 @@ msgstr "Nieuw wachtwoord moet verschillen van het huidige wachtwoord"
|
||||
msgid "New Ticket"
|
||||
msgstr "Nieuw ticket"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:65
|
||||
#: src/components/NewWorkspaceForm.tsx:240
|
||||
msgid "New workspace"
|
||||
msgstr "Nieuwe werkruimte"
|
||||
|
||||
@@ -1180,11 +1206,11 @@ msgstr "Aanbod"
|
||||
msgid "Onboarding"
|
||||
msgstr "Inwerktraject"
|
||||
|
||||
#: src/views/settings/index.tsx:312
|
||||
#: src/views/settings/index.tsx:349
|
||||
msgid "Once you delete your account, there is no going back. This action cannot be undone."
|
||||
msgstr "Zodra je je account verwijdert, is er geen weg terug. Deze actie kan niet ongedaan worden gemaakt."
|
||||
|
||||
#: src/views/settings/index.tsx:275
|
||||
#: src/views/settings/index.tsx:312
|
||||
msgid "Once you delete your workspace, there is no going back. This action cannot be undone."
|
||||
msgstr "Zodra je je werkruimte verwijdert, is er geen weg terug. Deze actie kan niet ongedaan worden gemaakt."
|
||||
|
||||
@@ -1216,11 +1242,11 @@ msgstr "Wachtwoord moet minimaal 8 tekens bevatten"
|
||||
msgid "Passwords do not match"
|
||||
msgstr "Wachtwoorden komen niet overeen"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:96
|
||||
#: src/views/home/components/Pricing.tsx:102
|
||||
msgid "Payment frequency"
|
||||
msgstr "Betalingsfrequentie"
|
||||
|
||||
#: src/views/members/index.tsx:128
|
||||
#: src/views/members/index.tsx:134
|
||||
msgid "Pending"
|
||||
msgstr "In behandeling"
|
||||
|
||||
@@ -1259,7 +1285,7 @@ msgstr "Selecteer een bestand om te uploaden."
|
||||
|
||||
#: src/components/DeleteLabelConfirmation.tsx:26
|
||||
#: src/components/FeedbackModal.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:42
|
||||
#: src/components/NewWorkspaceForm.tsx:155
|
||||
#: src/views/board/components/NewCardForm.tsx:174
|
||||
#: src/views/board/components/NewListForm.tsx:78
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:72
|
||||
@@ -1282,8 +1308,8 @@ msgstr "Selecteer een bestand om te uploaden."
|
||||
#: src/views/card/components/NewCommentForm.tsx:31
|
||||
#: src/views/card/index.tsx:173
|
||||
#: src/views/members/components/DeleteMemberConfirmation.tsx:28
|
||||
#: src/views/members/components/InviteMemberForm.tsx:83
|
||||
#: src/views/members/components/InviteMemberForm.tsx:133
|
||||
#: src/views/members/components/InviteMemberForm.tsx:78
|
||||
#: src/views/members/components/InviteMemberForm.tsx:131
|
||||
#: src/views/settings/components/Avatar.tsx:40
|
||||
#: src/views/settings/components/Avatar.tsx:98
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:40
|
||||
@@ -1292,6 +1318,7 @@ msgstr "Selecteer een bestand om te uploaden."
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:62
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:57
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:74
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:42
|
||||
msgid "Please try again later, or contact customer support."
|
||||
msgstr "Probeer het later opnieuw of neem contact op met de klantenservice."
|
||||
|
||||
@@ -1302,6 +1329,7 @@ msgid "Pricing"
|
||||
msgstr "Prijzen"
|
||||
|
||||
#: src/views/home/components/Pricing.tsx:56
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:91
|
||||
msgid "Priority email support"
|
||||
msgstr "Prioriteit e-mailondersteuning"
|
||||
|
||||
@@ -1313,11 +1341,19 @@ msgstr "Privacybeleid"
|
||||
msgid "Private"
|
||||
msgstr "Privé"
|
||||
|
||||
#: src/views/members/index.tsx:205
|
||||
msgid "Pro Plan"
|
||||
msgstr "Pro Plan"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
msgid "Pro Plan ∞"
|
||||
msgstr "Pro Plan ∞"
|
||||
|
||||
#: src/views/settings/components/Avatar.tsx:26
|
||||
msgid "Profile image updated"
|
||||
msgstr "Profielafbeelding bijgewerkt"
|
||||
|
||||
#: src/views/settings/index.tsx:146
|
||||
#: src/views/settings/index.tsx:171
|
||||
msgid "Profile picture"
|
||||
msgstr "Profielfoto"
|
||||
|
||||
@@ -1353,7 +1389,7 @@ msgstr "Op afstand"
|
||||
msgid "Remove"
|
||||
msgstr "Verwijderen"
|
||||
|
||||
#: src/views/members/index.tsx:142
|
||||
#: src/views/members/index.tsx:148
|
||||
msgid "Remove member"
|
||||
msgstr "Lid verwijderen"
|
||||
|
||||
@@ -1409,7 +1445,7 @@ msgstr "Intrekken"
|
||||
msgid "Roadmap"
|
||||
msgstr "Roadmap"
|
||||
|
||||
#: src/views/members/index.tsx:215
|
||||
#: src/views/members/index.tsx:243
|
||||
msgid "Role"
|
||||
msgstr "Rol"
|
||||
|
||||
@@ -1458,12 +1494,12 @@ msgid "Senior"
|
||||
msgstr "Senior"
|
||||
|
||||
#: src/components/SideNavigation.tsx:78
|
||||
#: src/views/settings/index.tsx:140
|
||||
#: src/views/settings/index.tsx:165
|
||||
msgid "Settings"
|
||||
msgstr "Instellingen"
|
||||
|
||||
#. placeholder {0}: workspace.name ?? "Workspace"
|
||||
#: src/views/settings/index.tsx:136
|
||||
#: src/views/settings/index.tsx:161
|
||||
msgid "Settings | {0}"
|
||||
msgstr "Instellingen | {0}"
|
||||
|
||||
@@ -1514,6 +1550,10 @@ msgstr "Star op Github"
|
||||
msgid "Success"
|
||||
msgstr "Geslaagd"
|
||||
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:55
|
||||
msgid "Supercharge your workspace for just $29/month. Here's what you'll get:"
|
||||
msgstr "Geef je werkruimte een boost voor slechts $29/maand. Dit krijg je:"
|
||||
|
||||
#: src/components/UserMenu.tsx:180
|
||||
msgid "Support"
|
||||
msgstr "Ondersteuning"
|
||||
@@ -1526,8 +1566,8 @@ msgstr "Ondersteun de ontwikkeling van het project"
|
||||
msgid "System"
|
||||
msgstr "Systeem"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:183
|
||||
#: src/views/members/index.tsx:184
|
||||
#: src/views/members/components/InviteMemberForm.tsx:182
|
||||
#: src/views/members/index.tsx:207
|
||||
msgid "Team Plan"
|
||||
msgstr "Teamplan"
|
||||
|
||||
@@ -1595,6 +1635,14 @@ msgstr "Dit zal resulteren in het permanent verwijderen van alle gegevens die aa
|
||||
msgid "This will result in the permanent deletion of all data associated with your account."
|
||||
msgstr "Dit zal resulteren in het permanent verwijderen van alle gegevens die aan je account zijn gekoppeld."
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:284
|
||||
msgid "This workspace URL has already been taken"
|
||||
msgstr "Deze werkruimte-URL is al in gebruik"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:286
|
||||
msgid "This workspace URL is reserved"
|
||||
msgstr "Deze werkruimte-URL is gereserveerd"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:123
|
||||
msgid "This workspace username has already been taken"
|
||||
msgstr "Deze werkruimtegebruikersnaam is al in gebruik"
|
||||
@@ -1612,7 +1660,7 @@ msgstr "Menu in-/uitschakelen"
|
||||
msgid "Track all card changes with detailed activity history."
|
||||
msgstr "Volg alle kaartwijzigingen met gedetailleerde activiteitengeschiedenis."
|
||||
|
||||
#: src/views/settings/index.tsx:94
|
||||
#: src/views/settings/index.tsx:119
|
||||
msgid "Trello disconnected"
|
||||
msgstr "Trello ontkoppeld"
|
||||
|
||||
@@ -1644,7 +1692,7 @@ msgstr "Kan checklist niet maken"
|
||||
msgid "Unable to create list"
|
||||
msgstr "Kan geen lijst maken"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:41
|
||||
#: src/components/NewWorkspaceForm.tsx:154
|
||||
msgid "Unable to create workspace"
|
||||
msgstr "Kan werkruimte niet aanmaken"
|
||||
|
||||
@@ -1743,6 +1791,11 @@ msgstr "Onbeperkt aantal opmerkingen"
|
||||
msgid "Unlimited lists"
|
||||
msgstr "Onbeperkt aantal lijsten"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:329
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:64
|
||||
msgid "Unlimited members"
|
||||
msgstr "Onbeperkt aantal leden"
|
||||
|
||||
#: src/views/board/components/UpdateBoardSlugForm.tsx:174
|
||||
#: src/views/settings/components/UpdateDisplayNameForm.tsx:79
|
||||
#: src/views/settings/components/UpdateWorkspaceDescriptionForm.tsx:90
|
||||
@@ -1772,11 +1825,20 @@ msgstr "titel bijgewerkt"
|
||||
msgid "updated the title to <0>{0}</0>"
|
||||
msgstr "titel bijgewerkt naar <0>{0}</0>"
|
||||
|
||||
#: src/views/settings/components/CustomURLConfirmation.tsx:52
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:109
|
||||
msgid "Upgrade"
|
||||
msgstr "Upgraden"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:222
|
||||
#: src/views/settings/components/UpgradeToProConfirmation.tsx:52
|
||||
#: src/views/settings/index.tsx:216
|
||||
msgid "Upgrade to Pro"
|
||||
msgstr "Upgraden naar Pro"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:369
|
||||
msgid "Upgrade to Pro ($29/month)"
|
||||
msgstr "Upgrade naar Pro ($29/maand)"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:224
|
||||
msgid "Upgrade to Team Plan"
|
||||
msgstr "Upgraden naar teamplan"
|
||||
|
||||
@@ -1785,14 +1847,17 @@ msgstr "Upgraden naar teamplan"
|
||||
msgid "Urgent"
|
||||
msgstr "Urgent"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:35
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:36
|
||||
msgid "URL can only contain letters, numbers, and hyphens"
|
||||
msgstr "URL kan alleen letters, cijfers en koppeltekens bevatten"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:33
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:34
|
||||
msgid "URL cannot exceed 24 characters"
|
||||
msgstr "URL mag niet langer zijn dan 24 tekens"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:31
|
||||
#: src/views/settings/components/UpdateWorkspaceUrlForm.tsx:32
|
||||
msgid "URL must be at least 3 characters long"
|
||||
msgstr "URL moet minimaal 3 tekens lang zijn"
|
||||
@@ -1801,11 +1866,11 @@ msgstr "URL moet minimaal 3 tekens lang zijn"
|
||||
msgid "Use template"
|
||||
msgstr "Sjabloon gebruiken"
|
||||
|
||||
#: src/views/members/index.tsx:209
|
||||
#: src/views/members/index.tsx:237
|
||||
msgid "User"
|
||||
msgstr "Gebruiker"
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:77
|
||||
#: src/views/members/components/InviteMemberForm.tsx:72
|
||||
msgid "User is already a member of this workspace"
|
||||
msgstr "Gebruiker is al lid van deze werkruimte"
|
||||
|
||||
@@ -1813,11 +1878,11 @@ msgstr "Gebruiker is al lid van deze werkruimte"
|
||||
msgid "Video"
|
||||
msgstr "Video"
|
||||
|
||||
#: src/views/settings/index.tsx:262
|
||||
#: src/views/settings/index.tsx:299
|
||||
msgid "View and manage your API keys."
|
||||
msgstr "Bekijk en beheer je API-sleutels."
|
||||
|
||||
#: src/views/settings/index.tsx:201
|
||||
#: src/views/settings/index.tsx:238
|
||||
msgid "View and manage your billing and subscription."
|
||||
msgstr "Bekijk en beheer je facturering en abonnement."
|
||||
|
||||
@@ -1873,11 +1938,15 @@ msgstr "Waarom een open source Trello maken?"
|
||||
msgid "Workspace"
|
||||
msgstr "Werkruimte"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:143
|
||||
msgid "Workspace created successfully. You can upgrade later in settings."
|
||||
msgstr "Werkruimte succesvol aangemaakt. Je kunt later upgraden in de instellingen."
|
||||
|
||||
#: src/views/settings/components/DeleteWorkspaceConfirmation.tsx:26
|
||||
msgid "Workspace deleted"
|
||||
msgstr "Werkruimte verwijderd"
|
||||
|
||||
#: src/views/settings/index.tsx:177
|
||||
#: src/views/settings/index.tsx:202
|
||||
msgid "Workspace description"
|
||||
msgstr "Werkruimte beschrijving"
|
||||
|
||||
@@ -1898,8 +1967,8 @@ msgstr "Werkruimtebeschrijving bijgewerkt"
|
||||
msgid "Workspace members"
|
||||
msgstr "Werkruimteleden"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:81
|
||||
#: src/views/settings/index.tsx:158
|
||||
#: src/components/NewWorkspaceForm.tsx:259
|
||||
#: src/views/settings/index.tsx:183
|
||||
msgid "Workspace name"
|
||||
msgstr "Naam werkruimte"
|
||||
|
||||
@@ -1907,6 +1976,10 @@ msgstr "Naam werkruimte"
|
||||
msgid "Workspace name cannot exceed 24 characters"
|
||||
msgstr "Werkruimtenaam mag niet langer zijn dan 24 tekens"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:27
|
||||
msgid "Workspace name is required"
|
||||
msgstr "Naam van werkruimte is verplicht"
|
||||
|
||||
#: src/views/settings/components/UpdateWorkspaceNameForm.tsx:14
|
||||
msgid "Workspace name must be at least 3 characters long"
|
||||
msgstr "Werkruimtenaam moet minimaal 3 tekens lang zijn"
|
||||
@@ -1919,10 +1992,14 @@ msgstr "Werkruimtenaam bijgewerkt"
|
||||
msgid "Workspace slug updated"
|
||||
msgstr "Werkruimte-slug bijgewerkt"
|
||||
|
||||
#: src/views/settings/index.tsx:167
|
||||
#: src/views/settings/index.tsx:192
|
||||
msgid "Workspace URL"
|
||||
msgstr "Werkruimte URL"
|
||||
|
||||
#: src/components/NewWorkspaceForm.tsx:273
|
||||
msgid "workspace-url"
|
||||
msgstr "werkruimte-url"
|
||||
|
||||
#: src/views/boards/components/TemplateBoards.tsx:30
|
||||
msgid "Writing"
|
||||
msgstr "Schrijven"
|
||||
@@ -1935,7 +2012,7 @@ msgstr "Jaarlijks"
|
||||
msgid "Yes, we offer an forever free plan for individual use. No restrictions, no paywalls, no limits."
|
||||
msgstr "Ja, we bieden een voor altijd gratis plan voor individueel gebruik. Geen beperkingen, geen betaalmuren, geen limieten."
|
||||
|
||||
#: src/views/settings/index.tsx:294
|
||||
#: src/views/settings/index.tsx:331
|
||||
msgid "You are about to change your password."
|
||||
msgstr "Je staat op het punt je wachtwoord te wijzigen."
|
||||
|
||||
@@ -1959,6 +2036,10 @@ msgstr "Je bent succesvol ingelogd."
|
||||
msgid "You have been signed up successfully."
|
||||
msgstr "Je bent succesvol geregistreerd."
|
||||
|
||||
#: src/views/members/components/InviteMemberForm.tsx:186
|
||||
msgid "You have unlimited seats with your Pro Plan. There is no additional charge for new members!"
|
||||
msgstr "Je hebt onbeperkte plaatsen met je Pro Plan. Er zijn geen extra kosten voor nieuwe leden!"
|
||||
|
||||
#: src/views/settings/components/DeleteAccountConfirmation.tsx:28
|
||||
msgid "Your account has been deleted."
|
||||
msgstr "Je account is verwijderd."
|
||||
@@ -1979,11 +2060,11 @@ msgstr "Je wachtwoord is gewijzigd."
|
||||
msgid "Your profile image has been updated."
|
||||
msgstr "Je profielafbeelding is bijgewerkt."
|
||||
|
||||
#: src/views/settings/index.tsx:95
|
||||
#: src/views/settings/index.tsx:120
|
||||
msgid "Your Trello account has been disconnected."
|
||||
msgstr "Je Trello-account is ontkoppeld."
|
||||
|
||||
#: src/views/settings/index.tsx:244
|
||||
#: src/views/settings/index.tsx:281
|
||||
msgid "Your Trello account is connected."
|
||||
msgstr "Je Trello-account is verbonden."
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -3,6 +3,7 @@ import { env } from "next-runtime-env";
|
||||
import { z } from "zod";
|
||||
|
||||
import { createNextApiContext } from "@kan/api/trpc";
|
||||
import * as subscriptionRepo from "@kan/db/repository/subscription.repo";
|
||||
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
import { createStripeClient } from "@kan/stripe";
|
||||
|
||||
@@ -40,17 +41,22 @@ export default async function handler(
|
||||
const body = req.body as CheckoutSessionRequest;
|
||||
const { successUrl, cancelUrl, slug, workspacePublicId } = body;
|
||||
|
||||
if (!successUrl || !cancelUrl || !slug || !workspacePublicId) {
|
||||
if (!successUrl || !cancelUrl || !workspacePublicId) {
|
||||
return res.status(400).json({ error: "Missing required fields" });
|
||||
}
|
||||
|
||||
const slugResult = workspaceSlugSchema.safeParse(slug);
|
||||
if (slug) {
|
||||
const slugResult = workspaceSlugSchema.safeParse(slug);
|
||||
|
||||
if (!slugResult.success) {
|
||||
return new Response(JSON.stringify({ error: "Invalid workspace slug" }), {
|
||||
status: 400,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
if (!slugResult.success) {
|
||||
return new Response(
|
||||
JSON.stringify({ error: "Invalid workspace slug" }),
|
||||
{
|
||||
status: 400,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const workspace = await workspaceRepo.getAllByUserId(db, user.id);
|
||||
@@ -66,20 +72,37 @@ export default async function handler(
|
||||
});
|
||||
}
|
||||
|
||||
const subscription = await subscriptionRepo.create(db, {
|
||||
plan: "pro",
|
||||
referenceId: workspacePublicId,
|
||||
userId: user.id,
|
||||
stripeCustomerId: user.stripeCustomerId ?? "",
|
||||
status: "incomplete",
|
||||
});
|
||||
|
||||
const subscriptionId = subscription?.id;
|
||||
|
||||
if (!subscriptionId) {
|
||||
return res.status(500).json({ error: "Error creating subscription" });
|
||||
}
|
||||
|
||||
const session = await stripe.checkout.sessions.create({
|
||||
mode: "subscription",
|
||||
line_items: [
|
||||
{
|
||||
price: process.env.STRIPE_PRO_PLAN_PRICE_ID,
|
||||
price: process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID,
|
||||
quantity: 1,
|
||||
},
|
||||
],
|
||||
success_url: `${env("NEXT_PUBLIC_BASE_URL")}${successUrl}`,
|
||||
cancel_url: `${env("NEXT_PUBLIC_BASE_URL")}${cancelUrl}`,
|
||||
client_reference_id: workspacePublicId,
|
||||
customer: user.stripeCustomerId ?? undefined,
|
||||
metadata: {
|
||||
workspaceSlug: slug,
|
||||
...(slug && { workspaceSlug: slug }),
|
||||
workspacePublicId,
|
||||
userId: user.id,
|
||||
subscriptionId,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ export default async function handler(
|
||||
const event = stripe.webhooks.constructEvent(
|
||||
rawBody,
|
||||
sig,
|
||||
process.env.STRIPE_WEBHOOK_SECRET!,
|
||||
process.env.STRIPE_WEBHOOK_SECRET_LEGACY!,
|
||||
);
|
||||
|
||||
const { db } = await createNextApiContext(req);
|
||||
@@ -47,9 +47,9 @@ export default async function handler(
|
||||
|
||||
const metaData = checkoutSession.metadata;
|
||||
|
||||
if (metaData?.workspacePublicId && metaData.workspaceSlug) {
|
||||
if (metaData?.workspacePublicId) {
|
||||
await workspaceRepo.update(db, metaData.workspacePublicId, {
|
||||
slug: metaData.workspaceSlug,
|
||||
...(metaData.workspaceSlug && { slug: metaData.workspaceSlug }),
|
||||
plan: "pro",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createContext, useContext, useState } from "react";
|
||||
import { createContext, useCallback, useContext, useState } from "react";
|
||||
|
||||
interface ModalState {
|
||||
contentType: string;
|
||||
@@ -42,57 +42,59 @@ export const ModalProvider: React.FC<Props> = ({ children }) => {
|
||||
const entityId = currentModal?.entityId || "";
|
||||
const entityLabel = currentModal?.entityLabel || "";
|
||||
|
||||
const openModal = (
|
||||
contentType: string,
|
||||
entityId?: string,
|
||||
entityLabel?: string,
|
||||
) => {
|
||||
const newModal: ModalState = { contentType, entityId, entityLabel };
|
||||
setModalStack((prev) => [...prev, newModal]);
|
||||
};
|
||||
const openModal = useCallback(
|
||||
(contentType: string, entityId?: string, entityLabel?: string) => {
|
||||
const newModal: ModalState = { contentType, entityId, entityLabel };
|
||||
setModalStack((prev) => [...prev, newModal]);
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const closeModal = () => {
|
||||
const closeModal = useCallback(() => {
|
||||
setModalStack((prev) => {
|
||||
if (prev.length <= 1) {
|
||||
return [];
|
||||
}
|
||||
return prev.slice(0, -1);
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
const closeModals = (count: number) => {
|
||||
setModalStack(prev => {
|
||||
const closeModals = useCallback((count: number) => {
|
||||
setModalStack((prev) => {
|
||||
const newLength = Math.max(0, prev.length - count);
|
||||
return prev.slice(0, newLength);
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
const clearAllModals = () => {
|
||||
const clearAllModals = useCallback(() => {
|
||||
setModalStack([]);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const setModalState = (modalType: string, state: any) => {
|
||||
const setModalState = useCallback((modalType: string, state: any) => {
|
||||
setModalStates((prev) => ({
|
||||
...prev,
|
||||
[modalType]: state,
|
||||
}));
|
||||
};
|
||||
}, []);
|
||||
|
||||
const getModalState = (modalType: string) => {
|
||||
return modalStates[modalType];
|
||||
};
|
||||
const getModalState = useCallback(
|
||||
(modalType: string) => {
|
||||
return modalStates[modalType];
|
||||
},
|
||||
[modalStates],
|
||||
);
|
||||
|
||||
const clearModalState = (modalType: string) => {
|
||||
const clearModalState = useCallback((modalType: string) => {
|
||||
setModalStates((prev) => {
|
||||
const newStates = { ...prev };
|
||||
delete newStates[modalType];
|
||||
return newStates;
|
||||
});
|
||||
};
|
||||
}, []);
|
||||
|
||||
const clearAllModalStates = () => {
|
||||
const clearAllModalStates = useCallback(() => {
|
||||
setModalStates({});
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<ModalContext.Provider
|
||||
|
||||
@@ -47,12 +47,16 @@ export const WorkspaceProvider: React.FC<{ children: ReactNode }> = ({
|
||||
const [hasLoaded, setHasLoaded] = useState(false);
|
||||
|
||||
const { data, isLoading } = api.workspace.all.useQuery();
|
||||
const utils = api.useUtils();
|
||||
|
||||
const switchWorkspace = (_workspace: Workspace) => {
|
||||
localStorage.setItem("workspacePublicId", _workspace.publicId);
|
||||
|
||||
setWorkspace(_workspace);
|
||||
|
||||
// Refetch workspace data to ensure availableWorkspaces is up to date
|
||||
void utils.workspace.all.refetch();
|
||||
|
||||
router.push(`/boards`);
|
||||
};
|
||||
|
||||
@@ -66,21 +70,15 @@ export const WorkspaceProvider: React.FC<{ children: ReactNode }> = ({
|
||||
localStorage.getItem("workspacePublicId");
|
||||
|
||||
if (data.length) {
|
||||
const workspaces = data
|
||||
.map(({ workspace, role }) => {
|
||||
if (!workspace) return;
|
||||
|
||||
return {
|
||||
role,
|
||||
publicId: workspace.publicId,
|
||||
name: workspace.name,
|
||||
slug: workspace.slug,
|
||||
description: workspace.description,
|
||||
plan: workspace.plan,
|
||||
hasLoaded: true,
|
||||
};
|
||||
})
|
||||
.filter((workspace) => workspace !== null) as Workspace[];
|
||||
const workspaces = data.map(({ workspace, role }) => ({
|
||||
role,
|
||||
publicId: workspace.publicId,
|
||||
name: workspace.name,
|
||||
slug: workspace.slug,
|
||||
description: workspace.description,
|
||||
plan: workspace.plan,
|
||||
hasLoaded: true,
|
||||
})) as Workspace[];
|
||||
|
||||
if (workspaces.length) setAvailableWorkspaces(workspaces);
|
||||
}
|
||||
@@ -116,7 +114,7 @@ export const WorkspaceProvider: React.FC<{ children: ReactNode }> = ({
|
||||
role: primaryWorkspaceRole,
|
||||
});
|
||||
}
|
||||
}, [data]);
|
||||
}, [data, isLoading]);
|
||||
|
||||
return (
|
||||
<WorkspaceContext.Provider
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useEffect } from "react";
|
||||
import { HiArrowDownTray, HiOutlinePlusSmall } from "react-icons/hi2";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
@@ -14,9 +15,13 @@ import { NewBoardForm } from "./components/NewBoardForm";
|
||||
|
||||
export default function BoardsPage() {
|
||||
const { openModal, modalContentType, isOpen } = useModal();
|
||||
const { workspace, hasLoaded } = useWorkspace();
|
||||
const { availableWorkspaces, workspace, hasLoaded } = useWorkspace();
|
||||
|
||||
if (hasLoaded && !workspace.publicId) openModal("NEW_WORKSPACE");
|
||||
useEffect(() => {
|
||||
if (hasLoaded && availableWorkspaces.length === 0) {
|
||||
openModal("NEW_WORKSPACE");
|
||||
}
|
||||
}, [hasLoaded, availableWorkspaces.length, openModal]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Menu } from "@headlessui/react";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { HiMiniPlus } from "react-icons/hi2";
|
||||
|
||||
@@ -101,22 +100,19 @@ export default function LabelSelector({
|
||||
{selectedLabels.length ? (
|
||||
<div className="flex flex-wrap gap-x-0.5">
|
||||
{selectedLabels.map((label) => (
|
||||
<Menu.Button key={label.key}>
|
||||
<Badge value={label.value} iconLeft={label.leftIcon} />
|
||||
</Menu.Button>
|
||||
))}
|
||||
<Menu.Button>
|
||||
<Badge
|
||||
value={t`Add label`}
|
||||
iconLeft={<HiMiniPlus size={14} />}
|
||||
key={label.key}
|
||||
value={label.value}
|
||||
iconLeft={label.leftIcon}
|
||||
/>
|
||||
</Menu.Button>
|
||||
))}
|
||||
<Badge value={t`Add label`} iconLeft={<HiMiniPlus size={14} />} />
|
||||
</div>
|
||||
) : (
|
||||
<Menu.Button className="flex h-full w-full items-center rounded-[5px] border-[1px] border-light-50 pl-2 text-left text-sm text-neutral-900 hover:border-light-300 hover:bg-light-200 dark:border-dark-50 dark:text-dark-1000 dark:hover:border-dark-200 dark:hover:bg-dark-100">
|
||||
<div className="flex h-full w-full items-center rounded-[5px] border-[1px] border-light-50 pl-2 text-left text-sm text-neutral-900 hover:border-light-300 hover:bg-light-200 dark:border-dark-50 dark:text-dark-1000 dark:hover:border-dark-200 dark:hover:bg-dark-100">
|
||||
<HiMiniPlus size={22} className="pr-2" />
|
||||
{t`Add label`}
|
||||
</Menu.Button>
|
||||
</div>
|
||||
)}
|
||||
</CheckboxDropdown>
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { Menu } from "@headlessui/react";
|
||||
import { t } from "@lingui/core/macro";
|
||||
|
||||
import CheckboxDropdown from "~/components/CheckboxDropdown";
|
||||
@@ -79,9 +78,9 @@ export default function ListSelector({
|
||||
}}
|
||||
asChild
|
||||
>
|
||||
<Menu.Button className="flex h-full w-full items-center rounded-[5px] border-[1px] border-light-50 py-1 pl-2 text-left text-sm text-neutral-900 hover:border-light-300 hover:bg-light-200 dark:border-dark-50 dark:text-dark-1000 dark:hover:border-dark-200 dark:hover:bg-dark-100">
|
||||
<div className="flex h-full w-full items-center rounded-[5px] border-[1px] border-light-50 py-1 pl-2 text-left text-sm text-neutral-900 hover:border-light-300 hover:bg-light-200 dark:border-dark-50 dark:text-dark-1000 dark:hover:border-dark-200 dark:hover:bg-dark-100">
|
||||
{selectedList?.value}
|
||||
</Menu.Button>
|
||||
</div>
|
||||
</CheckboxDropdown>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { useRouter } from "next/router";
|
||||
import { Menu } from "@headlessui/react";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { HiMiniPlus } from "react-icons/hi2";
|
||||
|
||||
@@ -112,11 +111,12 @@ export default function MemberSelector({
|
||||
createNewItemLabel={t`Invite member`}
|
||||
asChild
|
||||
>
|
||||
<Menu.Button className="flex h-full w-full items-center rounded-[5px] border-[1px] border-light-50 py-1 pl-2 text-left text-sm text-neutral-900 hover:border-light-300 hover:bg-light-200 dark:border-dark-50 dark:text-dark-1000 dark:hover:border-dark-200 dark:hover:bg-dark-100">
|
||||
<div className="flex h-full w-full items-center rounded-[5px] border-[1px] border-light-50 py-1 pl-2 text-left text-sm text-neutral-900 hover:border-light-300 hover:bg-light-200 dark:border-dark-50 dark:text-dark-1000 dark:hover:border-dark-200 dark:hover:bg-dark-100">
|
||||
{selectedMembers.length ? (
|
||||
<div className="isolate flex justify-end -space-x-1 overflow-hidden">
|
||||
{selectedMembers.map(({ value, imageUrl }) => (
|
||||
<Avatar
|
||||
key={value}
|
||||
size="sm"
|
||||
name={value}
|
||||
imageUrl={imageUrl}
|
||||
@@ -130,7 +130,7 @@ export default function MemberSelector({
|
||||
{t`Add member`}
|
||||
</>
|
||||
)}
|
||||
</Menu.Button>
|
||||
</div>
|
||||
</CheckboxDropdown>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import PatternedBackground from "~/components/PatternedBackground";
|
||||
import { useTheme } from "next-themes";
|
||||
|
||||
import { authClient } from "@kan/auth/client";
|
||||
|
||||
import PatternedBackground from "~/components/PatternedBackground";
|
||||
import Footer from "./Footer";
|
||||
import Header from "./Header";
|
||||
import { authClient } from "@kan/auth/client";
|
||||
|
||||
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
const { theme } = useTheme();
|
||||
@@ -18,6 +20,7 @@ export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
<style jsx global>{`
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
overflow: auto;
|
||||
background-color: ${!isDarkMode ? "hsl(0deg 0% 97.3%)" : "#161616"};
|
||||
}
|
||||
`}</style>
|
||||
|
||||
@@ -2,7 +2,7 @@ import Link from "next/link";
|
||||
import { Radio, RadioGroup } from "@headlessui/react";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { useState } from "react";
|
||||
import { HiCheckCircle } from "react-icons/hi2";
|
||||
import { HiBolt, HiCheckCircle } from "react-icons/hi2";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
type Frequency = "monthly" | "annually";
|
||||
@@ -92,7 +92,13 @@ const Pricing = () => {
|
||||
{t`Get started for free, with no usage limits. For collaboration, upgrade to a plan that fits the size of your team.`}
|
||||
</p>
|
||||
|
||||
<div className="mt-16 flex justify-center">
|
||||
<div className="mt-12 flex flex-col items-center justify-center">
|
||||
<div className="mb-4 flex items-center gap-2 rounded-full border bg-white px-4 py-1.5 text-center text-xs font-bold text-gray-800 dark:border-dark-300 dark:bg-white dark:text-gray-800 lg:text-sm">
|
||||
<HiBolt />
|
||||
<p>
|
||||
{t`Launch offer: unlimited seats for just $29/month with Pro`}
|
||||
</p>
|
||||
</div>
|
||||
<fieldset aria-label={t`Payment frequency`}>
|
||||
<RadioGroup
|
||||
value={frequency}
|
||||
@@ -165,7 +171,7 @@ const Pricing = () => {
|
||||
!tier.showPrice && "opacity-0",
|
||||
)}
|
||||
>
|
||||
{tier.price[frequency?.value || "monthly"]}
|
||||
{tier.price[frequency?.value ?? "monthly"]}
|
||||
</span>
|
||||
{tier.showPriceSuffix && (
|
||||
<span className="text-sm/6 font-semibold text-light-50 dark:text-dark-900">
|
||||
|
||||
@@ -7,7 +7,9 @@ import { HiXMark } from "react-icons/hi2";
|
||||
import { z } from "zod";
|
||||
|
||||
import type { InviteMemberInput } from "@kan/api/types";
|
||||
import type { Subscription } from "@kan/shared/utils";
|
||||
import { authClient } from "@kan/auth/client";
|
||||
import { getSubscriptionByPlan } from "@kan/shared/utils";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import Input from "~/components/Input";
|
||||
@@ -19,20 +21,13 @@ import { api } from "~/utils/api";
|
||||
|
||||
export function InviteMemberForm({
|
||||
numberOfMembers,
|
||||
activeTeamSubscription,
|
||||
subscriptions,
|
||||
unlimitedSeats,
|
||||
userId,
|
||||
}: {
|
||||
numberOfMembers: number;
|
||||
activeTeamSubscription:
|
||||
| {
|
||||
id: number | null;
|
||||
plan: string;
|
||||
status: string;
|
||||
seats: number | null;
|
||||
periodStart: Date | null;
|
||||
periodEnd: Date | null;
|
||||
}
|
||||
| undefined;
|
||||
subscriptions: Subscription[] | undefined;
|
||||
unlimitedSeats: boolean;
|
||||
userId: string | undefined;
|
||||
}) {
|
||||
const utils = api.useUtils();
|
||||
@@ -87,16 +82,19 @@ export function InviteMemberForm({
|
||||
},
|
||||
});
|
||||
|
||||
const teamSubscription = getSubscriptionByPlan(subscriptions, "team");
|
||||
const proSubscription = getSubscriptionByPlan(subscriptions, "pro");
|
||||
|
||||
const hasTeamSubscription = !!teamSubscription;
|
||||
const hasProSubscription = !!proSubscription;
|
||||
|
||||
let isYearly = false;
|
||||
let price = t`$10/month`;
|
||||
let billingType = t`monthly billing`;
|
||||
|
||||
if (
|
||||
activeTeamSubscription?.periodStart &&
|
||||
activeTeamSubscription?.periodEnd
|
||||
) {
|
||||
const periodStartDate = new Date(activeTeamSubscription.periodStart);
|
||||
const periodEndDate = new Date(activeTeamSubscription.periodEnd);
|
||||
if (teamSubscription?.periodStart && teamSubscription?.periodEnd) {
|
||||
const periodStartDate = new Date(teamSubscription.periodStart);
|
||||
const periodEndDate = new Date(teamSubscription.periodEnd);
|
||||
const diffInDays = Math.round(
|
||||
(periodEndDate.getTime() - periodStartDate.getTime()) /
|
||||
(1000 * 60 * 60 * 24),
|
||||
@@ -163,7 +161,8 @@ export function InviteMemberForm({
|
||||
placeholder={t`Email`}
|
||||
disabled={
|
||||
env("NEXT_PUBLIC_KAN_ENV") === "cloud" &&
|
||||
!activeTeamSubscription?.id
|
||||
!hasTeamSubscription &&
|
||||
!hasProSubscription
|
||||
}
|
||||
{...register("email", { required: true })}
|
||||
onKeyDown={async (e) => {
|
||||
@@ -177,13 +176,15 @@ export function InviteMemberForm({
|
||||
|
||||
{env("NEXT_PUBLIC_KAN_ENV") === "cloud" && (
|
||||
<div className="mt-3 rounded-md bg-light-100 p-3 text-xs text-light-900 dark:bg-dark-200 dark:text-dark-900">
|
||||
{activeTeamSubscription?.id ? (
|
||||
{hasTeamSubscription || hasProSubscription ? (
|
||||
<div>
|
||||
<span className="font-medium text-emerald-500 dark:text-emerald-400">
|
||||
{t`Team Plan`}
|
||||
{hasTeamSubscription ? t`Team Plan` : t`Pro Plan ∞`}
|
||||
</span>
|
||||
<p className="mt-1">
|
||||
{t`Adding a new member will cost an additional ${price} (${billingType}) per seat.`}
|
||||
{unlimitedSeats
|
||||
? t`You have unlimited seats with your Pro Plan. There is no additional charge for new members!`
|
||||
: t`Adding a new member will cost an additional ${price} (${billingType}) per seat.`}
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
@@ -201,7 +202,7 @@ export function InviteMemberForm({
|
||||
</div>
|
||||
|
||||
<div className="mt-12 flex items-center justify-end border-t border-light-600 px-5 pb-5 pt-5 dark:border-dark-600">
|
||||
{activeTeamSubscription?.id &&
|
||||
{(hasTeamSubscription || hasProSubscription) &&
|
||||
env("NEXT_PUBLIC_KAN_ENV") === "cloud" && (
|
||||
<Toggle
|
||||
label={t`Invite another`}
|
||||
@@ -213,7 +214,8 @@ export function InviteMemberForm({
|
||||
)}
|
||||
<div>
|
||||
{env("NEXT_PUBLIC_KAN_ENV") === "cloud" &&
|
||||
!activeTeamSubscription?.id ? (
|
||||
!hasTeamSubscription &&
|
||||
!hasProSubscription ? (
|
||||
<Button
|
||||
type="button"
|
||||
onClick={handleUpgrade}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import Link from "next/link";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { HiEllipsisHorizontal, HiOutlinePlusSmall } from "react-icons/hi2";
|
||||
import { env } from "next-runtime-env";
|
||||
import {
|
||||
HiBolt,
|
||||
HiEllipsisHorizontal,
|
||||
HiOutlinePlusSmall,
|
||||
} from "react-icons/hi2";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import type { Subscription } from "@kan/shared/utils";
|
||||
import { authClient } from "@kan/auth/client";
|
||||
import { getSubscriptionByPlan, hasUnlimitedSeats } from "@kan/shared/utils";
|
||||
|
||||
import Avatar from "~/components/Avatar";
|
||||
import Button from "~/components/Button";
|
||||
@@ -11,7 +19,6 @@ import FeedbackModal from "~/components/FeedbackModal";
|
||||
import Modal from "~/components/modal";
|
||||
import { NewWorkspaceForm } from "~/components/NewWorkspaceForm";
|
||||
import { PageHead } from "~/components/PageHead";
|
||||
import { env } from "~/env";
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { useWorkspace } from "~/providers/workspace";
|
||||
import { api } from "~/utils/api";
|
||||
@@ -30,13 +37,12 @@ export default function MembersPage() {
|
||||
|
||||
const { data: session } = authClient.useSession();
|
||||
|
||||
const subscription = data?.subscriptions;
|
||||
const subscriptions = data?.subscriptions as Subscription[] | undefined;
|
||||
|
||||
const activeTeamSubscription = subscription?.find(
|
||||
(sub: any) =>
|
||||
sub.status === "active" ||
|
||||
(sub.status === "trialing" && sub.plan === "team"),
|
||||
);
|
||||
const teamSubscription = getSubscriptionByPlan(subscriptions, "team");
|
||||
const proSubscription = getSubscriptionByPlan(subscriptions, "pro");
|
||||
|
||||
const unlimitedSeats = hasUnlimitedSeats(subscriptions);
|
||||
|
||||
const TableRow = ({
|
||||
memberPublicId,
|
||||
@@ -167,23 +173,45 @@ export default function MembersPage() {
|
||||
<PageHead title={t`Members | ${workspace.name ?? "Workspace"}`} />
|
||||
<div className="m-auto h-full max-w-[1100px] p-6 px-5 md:px-28 md:py-12">
|
||||
<div className="mb-8 flex w-full justify-between">
|
||||
<h1 className="font-bold tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
|
||||
{t`Members`}
|
||||
</h1>
|
||||
<div className="flex items-center gap-3">
|
||||
{env.NEXT_PUBLIC_KAN_ENV === "cloud" && (
|
||||
<div
|
||||
className={twMerge(
|
||||
"flex items-center rounded-full border px-3 py-1 text-center text-xs",
|
||||
activeTeamSubscription
|
||||
? "border-emerald-300 bg-emerald-50 text-emerald-400 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400"
|
||||
: "border-light-300 bg-light-50 text-light-1000 dark:border-dark-300 dark:bg-dark-50 dark:text-dark-900",
|
||||
<h1 className="font-bold tracking-tight text-neutral-900 dark:text-dark-1000 sm:text-[1.2rem]">
|
||||
{t`Members`}
|
||||
</h1>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
{env("NEXT_PUBLIC_KAN_ENV") === "cloud" && (
|
||||
<>
|
||||
{!proSubscription && (
|
||||
<Link
|
||||
href="/settings?upgrade=pro"
|
||||
className="hidden items-center rounded-full border border-emerald-300 bg-emerald-50 px-3 py-1 text-center text-xs text-emerald-400 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400 lg:flex"
|
||||
>
|
||||
<HiBolt />
|
||||
<span className="ml-1 font-medium">
|
||||
{t`Launch offer: Get unlimited members with Pro`}
|
||||
</span>
|
||||
</Link>
|
||||
)}
|
||||
>
|
||||
<span className="font-medium">
|
||||
{activeTeamSubscription ? t`Team Plan` : t`Free Plan`}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
className={twMerge(
|
||||
"flex items-center rounded-full border px-3 py-1 text-center text-xs",
|
||||
teamSubscription || proSubscription
|
||||
? "border-emerald-300 bg-emerald-50 text-emerald-400 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400"
|
||||
: "border-light-300 bg-light-50 text-light-1000 dark:border-dark-300 dark:bg-dark-50 dark:text-dark-900",
|
||||
)}
|
||||
>
|
||||
<span className="font-medium">
|
||||
{proSubscription
|
||||
? t`Pro Plan`
|
||||
: teamSubscription
|
||||
? t`Team Plan`
|
||||
: t`Free Plan`}
|
||||
{proSubscription && unlimitedSeats && (
|
||||
<span className="ml-1 text-xs">∞</span>
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
onClick={() => openModal("INVITE_MEMBER")}
|
||||
@@ -268,7 +296,8 @@ export default function MembersPage() {
|
||||
<InviteMemberForm
|
||||
userId={session?.user.id}
|
||||
numberOfMembers={data?.members.length ?? 1}
|
||||
activeTeamSubscription={activeTeamSubscription}
|
||||
subscriptions={subscriptions}
|
||||
unlimitedSeats={unlimitedSeats}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import { useModal } from "~/providers/modal";
|
||||
|
||||
export function CustomURLConfirmation({
|
||||
workspacePublicId,
|
||||
}: {
|
||||
workspacePublicId: string;
|
||||
}) {
|
||||
const { closeModal, entityId } = useModal();
|
||||
|
||||
const handleUpgrade = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/stripe/create_checkout_session", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
slug: entityId,
|
||||
workspacePublicId: workspacePublicId,
|
||||
cancelUrl: "/settings",
|
||||
successUrl: "/settings",
|
||||
}),
|
||||
});
|
||||
|
||||
const { url } = (await response.json()) as { url: string };
|
||||
|
||||
if (url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error creating checkout session:", error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-5">
|
||||
<div className="flex w-full flex-col justify-between pb-4">
|
||||
<h2 className="text-md pb-4 font-medium text-neutral-900 dark:text-dark-1000">
|
||||
{t`Confirm URL change`}
|
||||
</h2>
|
||||
<p className="text-sm font-medium text-light-900 dark:text-dark-900">
|
||||
{t`Custom URLs are a premium feature. You'll be directed to upgrade your account.`}
|
||||
</p>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end space-x-2 sm:mt-6">
|
||||
<Button onClick={() => closeModal()} variant="secondary">
|
||||
{t`Cancel`}
|
||||
</Button>
|
||||
<Button onClick={handleUpgrade}>{t`Upgrade`}</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -98,7 +98,7 @@ const UpdateWorkspaceUrlForm = ({
|
||||
if (!isWorkspaceSlugAvailable?.isAvailable) return;
|
||||
|
||||
if (workspacePlan !== "pro" && env("NEXT_PUBLIC_KAN_ENV") === "cloud")
|
||||
return openModal("UPDATE_WORKSPACE_URL", data.slug);
|
||||
return openModal("UPGRADE_TO_PRO", data.slug);
|
||||
|
||||
updateWorkspaceSlug.mutate({
|
||||
workspacePublicId,
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { HiBolt, HiCheckBadge } from "react-icons/hi2";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import { useModal } from "~/providers/modal";
|
||||
import { usePopup } from "~/providers/popup";
|
||||
|
||||
export function UpgradeToProConfirmation({
|
||||
workspacePublicId,
|
||||
}: {
|
||||
userId: string;
|
||||
workspacePublicId: string;
|
||||
}) {
|
||||
const { closeModal, entityId } = useModal();
|
||||
const { showPopup } = usePopup();
|
||||
|
||||
const handleUpgrade = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/stripe/create_checkout_session", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
...(entityId && { slug: entityId }),
|
||||
workspacePublicId: workspacePublicId,
|
||||
cancelUrl: "/settings",
|
||||
successUrl: "/settings",
|
||||
}),
|
||||
});
|
||||
|
||||
const { url } = (await response.json()) as { url: string };
|
||||
|
||||
if (url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error creating checkout session:", error);
|
||||
|
||||
showPopup({
|
||||
header: t`Error upgrading subscription`,
|
||||
message: t`Please try again later, or contact customer support.`,
|
||||
icon: "error",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-5">
|
||||
<div className="flex w-full flex-col justify-between pb-4">
|
||||
<h2 className="text-md pb-4 font-bold text-neutral-900 dark:text-dark-1000">
|
||||
{t`Upgrade to Pro`}
|
||||
</h2>
|
||||
<p className="mb-4 text-sm font-medium text-light-900 dark:text-dark-900">
|
||||
{t`Supercharge your workspace for just $29/month. Here's what you'll get:`}
|
||||
</p>
|
||||
|
||||
<div className="rounded-md bg-light-100 p-3 text-xs text-light-900 dark:bg-dark-200 dark:text-dark-900">
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center space-x-3">
|
||||
<HiCheckBadge className="h-5 w-5 flex-shrink-0 text-light-1000 dark:text-dark-950" />
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="text-sm text-neutral-900 dark:text-dark-1000">
|
||||
{t`Unlimited members`}
|
||||
</span>
|
||||
<span className="inline-flex items-center rounded-full bg-emerald-500/10 px-2 py-0.5 text-[10px] font-medium text-emerald-600 ring-1 ring-inset ring-emerald-500/20 dark:text-emerald-400 sm:text-[10px]">
|
||||
{t`Launch offer`}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<HiCheckBadge className="h-5 w-5 flex-shrink-0 text-light-1000 dark:text-dark-950" />
|
||||
<span className="text-sm text-neutral-900 dark:text-dark-1000">
|
||||
{t`Custom workspace URL`}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<HiCheckBadge className="h-5 w-5 flex-shrink-0 text-light-1000 dark:text-dark-950" />
|
||||
<div className="flex items-center space-x-2">
|
||||
<span className="text-xs text-neutral-900 dark:text-dark-1000">
|
||||
{t`Board analytics`}
|
||||
</span>
|
||||
<span className="inline-flex items-center rounded-full bg-gray-500/10 px-2 py-0.5 text-[10px] font-medium text-gray-600 ring-1 ring-inset ring-gray-500/20 dark:text-gray-400 sm:text-[10px]">
|
||||
{t`Coming soon`}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center space-x-3">
|
||||
<HiCheckBadge className="h-5 w-5 flex-shrink-0 text-light-1000 dark:text-dark-950" />
|
||||
<span className="text-sm text-neutral-900 dark:text-dark-1000">
|
||||
{t`Priority email support`}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-5 flex justify-end space-x-2 sm:mt-6">
|
||||
<Button
|
||||
onClick={() => {
|
||||
closeModal();
|
||||
}}
|
||||
variant="secondary"
|
||||
>
|
||||
{t`Cancel`}
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleUpgrade}
|
||||
iconRight={<HiBolt />}
|
||||
>{t`Upgrade`}</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,8 +1,11 @@
|
||||
import { useRouter } from "next/router";
|
||||
import { t } from "@lingui/core/macro";
|
||||
import { env } from "next-runtime-env";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { HiMiniArrowTopRightOnSquare } from "react-icons/hi2";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { HiBolt, HiMiniArrowTopRightOnSquare } from "react-icons/hi2";
|
||||
|
||||
import type { Subscription } from "@kan/shared/utils";
|
||||
import { hasActiveSubscription } from "@kan/shared/utils";
|
||||
|
||||
import Button from "~/components/Button";
|
||||
import FeedbackModal from "~/components/FeedbackModal";
|
||||
@@ -17,13 +20,13 @@ import { api } from "~/utils/api";
|
||||
import Avatar from "./components/Avatar";
|
||||
import { ChangePasswordFormConfirmation } from "./components/ChangePasswordConfirmation";
|
||||
import CreateAPIKeyForm from "./components/CreateAPIKeyForm";
|
||||
import { CustomURLConfirmation } from "./components/CustomURLConfirmation";
|
||||
import { DeleteAccountConfirmation } from "./components/DeleteAccountConfirmation";
|
||||
import { DeleteWorkspaceConfirmation } from "./components/DeleteWorkspaceConfirmation";
|
||||
import UpdateDisplayNameForm from "./components/UpdateDisplayNameForm";
|
||||
import UpdateWorkspaceDescriptionForm from "./components/UpdateWorkspaceDescriptionForm";
|
||||
import UpdateWorkspaceNameForm from "./components/UpdateWorkspaceNameForm";
|
||||
import UpdateWorkspaceUrlForm from "./components/UpdateWorkspaceUrlForm";
|
||||
import { UpgradeToProConfirmation } from "./components/UpgradeToProConfirmation";
|
||||
|
||||
export default function SettingsPage() {
|
||||
const { modalContentType, openModal, isOpen } = useModal();
|
||||
@@ -33,10 +36,19 @@ export default function SettingsPage() {
|
||||
const router = useRouter();
|
||||
const workspaceUrlSectionRef = useRef<HTMLDivElement>(null);
|
||||
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
||||
const [hasOpenedUpgradeModal, setHasOpenedUpgradeModal] = useState(false);
|
||||
const isCredentialsEnabled =
|
||||
env("NEXT_PUBLIC_ALLOW_CREDENTIALS")?.toLowerCase() === "true";
|
||||
const { data } = api.user.getUser.useQuery();
|
||||
|
||||
const { data: workspaceData } = api.workspace.byId.useQuery({
|
||||
workspacePublicId: workspace.publicId,
|
||||
});
|
||||
|
||||
const subscriptions = workspaceData?.subscriptions as
|
||||
| Subscription[]
|
||||
| undefined;
|
||||
|
||||
const {
|
||||
data: integrations,
|
||||
refetch: refetchIntegrations,
|
||||
@@ -84,6 +96,19 @@ export default function SettingsPage() {
|
||||
}
|
||||
}, [router.query.edit]);
|
||||
|
||||
// Open upgrade modal if upgrade=pro is in URL params
|
||||
useEffect(() => {
|
||||
if (
|
||||
router.query.upgrade === "pro" &&
|
||||
env("NEXT_PUBLIC_KAN_ENV") === "cloud" &&
|
||||
!hasActiveSubscription(subscriptions, "pro") &&
|
||||
!hasOpenedUpgradeModal
|
||||
) {
|
||||
openModal("UPGRADE_TO_PRO");
|
||||
setHasOpenedUpgradeModal(true);
|
||||
}
|
||||
}, [router.query.upgrade, subscriptions, openModal, hasOpenedUpgradeModal]);
|
||||
|
||||
const { mutateAsync: disconnectTrello } =
|
||||
api.integration.disconnect.useMutation({
|
||||
onSuccess: () => {
|
||||
@@ -180,6 +205,18 @@ export default function SettingsPage() {
|
||||
workspacePublicId={workspace.publicId}
|
||||
workspaceDescription={workspace.description ?? ""}
|
||||
/>
|
||||
|
||||
{env("NEXT_PUBLIC_KAN_ENV") === "cloud" &&
|
||||
!hasActiveSubscription(subscriptions, "pro") && (
|
||||
<div className="mt-8">
|
||||
<Button
|
||||
onClick={() => openModal("UPGRADE_TO_PRO")}
|
||||
iconRight={<HiBolt />}
|
||||
>
|
||||
{t`Upgrade to Pro`}
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="mb-8 border-t border-light-300 dark:border-dark-300">
|
||||
@@ -346,9 +383,12 @@ export default function SettingsPage() {
|
||||
|
||||
<Modal
|
||||
modalSize="sm"
|
||||
isVisible={isOpen && modalContentType === "UPDATE_WORKSPACE_URL"}
|
||||
isVisible={isOpen && modalContentType === "UPGRADE_TO_PRO"}
|
||||
>
|
||||
<CustomURLConfirmation workspacePublicId={workspace.publicId} />
|
||||
<UpgradeToProConfirmation
|
||||
userId={data?.id ?? ""}
|
||||
workspacePublicId={workspace.publicId}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
<Modal
|
||||
|
||||
@@ -22,6 +22,11 @@ services:
|
||||
# Stripe
|
||||
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
|
||||
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
|
||||
- STRIPE_WEBHOOK_SECRET_LEGACY=${STRIPE_WEBHOOK_SECRET_LEGACY}
|
||||
- STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID=${STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID}
|
||||
- STRIPE_TEAM_PLAN_YEARLY_PRICE_ID=${STRIPE_TEAM_PLAN_YEARLY_PRICE_ID}
|
||||
- STRIPE_PRO_PLAN_MONTHLY_PRICE_ID=${STRIPE_PRO_PLAN_MONTHLY_PRICE_ID}
|
||||
- STRIPE_PRO_PLAN_YEARLY_PRICE_ID=${STRIPE_PRO_PLAN_YEARLY_PRICE_ID}
|
||||
|
||||
# Email
|
||||
- SMTP_HOST=${SMTP_HOST}
|
||||
|
||||
@@ -2,8 +2,10 @@ import { TRPCError } from "@trpc/server";
|
||||
import { z } from "zod";
|
||||
|
||||
import * as memberRepo from "@kan/db/repository/member.repo";
|
||||
import * as subscriptionRepo from "@kan/db/repository/subscription.repo";
|
||||
import * as userRepo from "@kan/db/repository/user.repo";
|
||||
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
import { getSubscriptionByPlan, hasUnlimitedSeats } from "@kan/shared/utils";
|
||||
import { updateSubscriptionSeats } from "@kan/stripe";
|
||||
|
||||
import { createTRPCRouter, protectedProcedure } from "../trpc";
|
||||
@@ -62,29 +64,34 @@ export const memberRouter = createTRPCRouter({
|
||||
}
|
||||
|
||||
if (process.env.NEXT_PUBLIC_KAN_ENV === "cloud") {
|
||||
const subscriptions = await ctx.auth.api.listActiveSubscriptions({
|
||||
workspacePublicId: workspace.publicId,
|
||||
});
|
||||
|
||||
// get the active subscription
|
||||
const activeSubscription = subscriptions.find(
|
||||
(sub) =>
|
||||
sub.status === "active" ||
|
||||
(sub.status === "trialing" && sub.plan === "team"),
|
||||
const subscriptions = await subscriptionRepo.getByReferenceId(
|
||||
ctx.db,
|
||||
workspace.publicId,
|
||||
);
|
||||
|
||||
if (!activeSubscription) {
|
||||
// get the active subscriptions
|
||||
const activeTeamSubscription = getSubscriptionByPlan(
|
||||
subscriptions,
|
||||
"team",
|
||||
);
|
||||
const activeProSubscription = getSubscriptionByPlan(
|
||||
subscriptions,
|
||||
"pro",
|
||||
);
|
||||
const unlimitedSeats = hasUnlimitedSeats(subscriptions);
|
||||
|
||||
if (!activeTeamSubscription && !activeProSubscription) {
|
||||
throw new TRPCError({
|
||||
message: `Workspace with public ID ${workspace.publicId} does not have an active subscription`,
|
||||
code: "NOT_FOUND",
|
||||
});
|
||||
}
|
||||
|
||||
// Update the Stripe subscription to add a seat with immediate proration
|
||||
if (activeSubscription.stripeSubscriptionId) {
|
||||
// Update the Stripe subscription
|
||||
if (activeTeamSubscription?.stripeSubscriptionId && !unlimitedSeats) {
|
||||
try {
|
||||
await updateSubscriptionSeats(
|
||||
activeSubscription.stripeSubscriptionId,
|
||||
activeTeamSubscription.stripeSubscriptionId,
|
||||
1,
|
||||
);
|
||||
} catch (error) {
|
||||
@@ -204,22 +211,23 @@ export const memberRouter = createTRPCRouter({
|
||||
|
||||
// Handle subscription seat decrement for cloud environment
|
||||
if (process.env.NEXT_PUBLIC_KAN_ENV === "cloud") {
|
||||
const subscriptions = await ctx.auth.api.listActiveSubscriptions({
|
||||
workspacePublicId: workspace.publicId,
|
||||
});
|
||||
|
||||
// get the active subscription
|
||||
const activeSubscription = subscriptions.find(
|
||||
(sub) =>
|
||||
sub.status === "active" ||
|
||||
(sub.status === "trialing" && sub.plan === "team"),
|
||||
const subscriptions = await subscriptionRepo.getByReferenceId(
|
||||
ctx.db,
|
||||
workspace.publicId,
|
||||
);
|
||||
|
||||
// get the active subscriptions
|
||||
const activeTeamSubscription = getSubscriptionByPlan(
|
||||
subscriptions,
|
||||
"team",
|
||||
);
|
||||
const unlimitedSeats = hasUnlimitedSeats(subscriptions);
|
||||
|
||||
// Only decrease seats if there's an active subscription and stripeSubscriptionId
|
||||
if (activeSubscription?.stripeSubscriptionId) {
|
||||
if (activeTeamSubscription?.stripeSubscriptionId && !unlimitedSeats) {
|
||||
try {
|
||||
await updateSubscriptionSeats(
|
||||
activeSubscription.stripeSubscriptionId,
|
||||
activeTeamSubscription.stripeSubscriptionId,
|
||||
-1,
|
||||
);
|
||||
} catch (error) {
|
||||
|
||||
@@ -140,6 +140,12 @@ export const workspaceRouter = createTRPCRouter({
|
||||
.input(
|
||||
z.object({
|
||||
name: z.string().min(1),
|
||||
slug: z
|
||||
.string()
|
||||
.min(3)
|
||||
.max(24)
|
||||
.regex(/^(?![-]+$)[a-zA-Z0-9-]+$/)
|
||||
.optional(),
|
||||
}),
|
||||
)
|
||||
.output(z.custom<Awaited<ReturnType<typeof workspaceRepo.create>>>())
|
||||
@@ -153,12 +159,43 @@ export const workspaceRouter = createTRPCRouter({
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
// Check if slug is provided in cloud environment
|
||||
if (input.slug && env("NEXT_PUBLIC_KAN_ENV") === "cloud") {
|
||||
throw new TRPCError({
|
||||
message: "Custom URLs are only available for Pro workspaces",
|
||||
code: "BAD_REQUEST",
|
||||
});
|
||||
}
|
||||
|
||||
const workspacePublicId = generateUID();
|
||||
const workspaceSlug = input.slug ?? workspacePublicId;
|
||||
|
||||
if (input.slug) {
|
||||
const reservedOrPremiumWorkspaceSlug =
|
||||
await workspaceSlugRepo.getWorkspaceSlug(ctx.db, input.slug);
|
||||
|
||||
const isWorkspaceSlugAvailable =
|
||||
await workspaceRepo.isWorkspaceSlugAvailable(ctx.db, input.slug);
|
||||
|
||||
if (reservedOrPremiumWorkspaceSlug) {
|
||||
throw new TRPCError({
|
||||
message: `Workspace slug '${input.slug}' is reserved or premium`,
|
||||
code: "BAD_REQUEST",
|
||||
});
|
||||
}
|
||||
|
||||
if (!isWorkspaceSlugAvailable) {
|
||||
throw new TRPCError({
|
||||
message: `Workspace slug '${input.slug}' is already taken`,
|
||||
code: "BAD_REQUEST",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const result = await workspaceRepo.create(ctx.db, {
|
||||
publicId: workspacePublicId,
|
||||
name: input.name,
|
||||
slug: workspacePublicId,
|
||||
slug: workspaceSlug,
|
||||
createdBy: userId,
|
||||
createdByEmail: userEmail,
|
||||
});
|
||||
@@ -334,6 +371,14 @@ export const workspaceRouter = createTRPCRouter({
|
||||
}),
|
||||
)
|
||||
.query(async ({ ctx, input }) => {
|
||||
const userId = ctx.user?.id;
|
||||
|
||||
if (!userId)
|
||||
throw new TRPCError({
|
||||
message: `User not authenticated`,
|
||||
code: "UNAUTHORIZED",
|
||||
});
|
||||
|
||||
const slug = input.workspaceSlug.toLowerCase();
|
||||
// check slug is not reserved
|
||||
const workspaceSlug = await workspaceSlugRepo.getWorkspaceSlug(
|
||||
@@ -345,6 +390,19 @@ export const workspaceRouter = createTRPCRouter({
|
||||
const isWorkspaceSlugAvailable =
|
||||
await workspaceRepo.isWorkspaceSlugAvailable(ctx.db, slug);
|
||||
|
||||
const isAvailable =
|
||||
isWorkspaceSlugAvailable && workspaceSlug?.type !== "reserved";
|
||||
const isReserved = workspaceSlug?.type === "reserved";
|
||||
|
||||
if (env("NEXT_PUBLIC_KAN_ENV") === "cloud") {
|
||||
await workspaceSlugRepo.createWorkspaceSlugCheck(ctx.db, {
|
||||
slug,
|
||||
userId,
|
||||
available: isAvailable,
|
||||
reserved: isReserved,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
isAvailable:
|
||||
isWorkspaceSlugAvailable && workspaceSlug?.type !== "reserved",
|
||||
|
||||
@@ -10,6 +10,7 @@ import { env } from "next-runtime-env";
|
||||
|
||||
import type { dbClient } from "@kan/db/client";
|
||||
import * as memberRepo from "@kan/db/repository/member.repo";
|
||||
import * as subscriptionRepo from "@kan/db/repository/subscription.repo";
|
||||
import * as userRepo from "@kan/db/repository/user.repo";
|
||||
import * as workspaceRepo from "@kan/db/repository/workspace.repo";
|
||||
import * as schema from "@kan/db/schema";
|
||||
@@ -114,13 +115,13 @@ async function downloadImage(url: string): Promise<Buffer> {
|
||||
export const initAuth = (db: dbClient) => {
|
||||
return betterAuth({
|
||||
secret: process.env.BETTER_AUTH_SECRET!,
|
||||
baseURL: process.env.NEXT_PUBLIC_BASE_URL!,
|
||||
baseURL: env("NEXT_PUBLIC_BASE_URL"),
|
||||
trustedOrigins: process.env.BETTER_AUTH_TRUSTED_ORIGINS
|
||||
? [
|
||||
process.env.NEXT_PUBLIC_BASE_URL!,
|
||||
env("NEXT_PUBLIC_BASE_URL") ?? "",
|
||||
...process.env.BETTER_AUTH_TRUSTED_ORIGINS.split(","),
|
||||
]
|
||||
: [process.env.NEXT_PUBLIC_BASE_URL!],
|
||||
: [env("NEXT_PUBLIC_BASE_URL") ?? ""],
|
||||
database: drizzleAdapter(db, {
|
||||
provider: "pg",
|
||||
schema: {
|
||||
@@ -196,6 +197,31 @@ export const initAuth = (db: dbClient) => {
|
||||
|
||||
return isUserInWorkspace;
|
||||
},
|
||||
getCheckoutSessionParams: () => {
|
||||
return {
|
||||
params: {
|
||||
allow_promotion_codes: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
onSubscriptionComplete: async ({
|
||||
subscription,
|
||||
stripeSubscription,
|
||||
}) => {
|
||||
// Set unlimited seats to true for pro plans
|
||||
if (subscription.plan === "pro") {
|
||||
await subscriptionRepo.updateByStripeSubscriptionId(
|
||||
db,
|
||||
stripeSubscription.id,
|
||||
{
|
||||
unlimitedSeats: true,
|
||||
},
|
||||
);
|
||||
console.log(
|
||||
`Pro subscription ${stripeSubscription.id} activated with unlimited seats`,
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
}),
|
||||
]
|
||||
@@ -317,37 +343,17 @@ export const initAuth = (db: dbClient) => {
|
||||
},
|
||||
hooks: {
|
||||
after: createAuthMiddleware(async (ctx) => {
|
||||
if (ctx.path.startsWith("/get-session")) {
|
||||
const user = ctx.context.session?.user;
|
||||
|
||||
if (
|
||||
env("NEXT_PUBLIC_KAN_ENV") === "cloud" &&
|
||||
user &&
|
||||
!user.stripeCustomerId
|
||||
) {
|
||||
const stripe = createStripeClient();
|
||||
const stripeCustomer = await stripe.customers.create({
|
||||
email: user.email,
|
||||
metadata: {
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
await userRepo.update(db, user.id, {
|
||||
stripeCustomerId: stripeCustomer.id,
|
||||
});
|
||||
}
|
||||
} else if (
|
||||
if (
|
||||
ctx.path === "/magic-link/verify" &&
|
||||
(ctx.query?.callbackURL as string | undefined)?.includes(
|
||||
"type=invite",
|
||||
) &&
|
||||
ctx.query?.memberPublicId
|
||||
)
|
||||
) {
|
||||
const userId = ctx.context.newSession?.session.userId;
|
||||
const memberPublicId = ctx.query.memberPublicId as string;
|
||||
const callbackURL = ctx.query?.callbackURL as string | undefined;
|
||||
const memberPublicId = callbackURL?.split("memberPublicId=")[1];
|
||||
|
||||
if (userId) {
|
||||
if (userId && memberPublicId) {
|
||||
const member = await memberRepo.getByPublicId(db, memberPublicId);
|
||||
|
||||
if (member?.id) {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "subscription" ADD COLUMN "unlimitedSeats" boolean DEFAULT false NOT NULL;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "subscription" ALTER COLUMN "referenceId" DROP NOT NULL;
|
||||
@@ -0,0 +1,22 @@
|
||||
CREATE TABLE IF NOT EXISTS "workspace_slug_checks" (
|
||||
"id" bigserial PRIMARY KEY NOT NULL,
|
||||
"slug" varchar(255) NOT NULL,
|
||||
"available" boolean NOT NULL,
|
||||
"reserved" boolean NOT NULL,
|
||||
"workspaceId" bigint,
|
||||
"createdBy" uuid,
|
||||
"createdAt" timestamp DEFAULT now() NOT NULL
|
||||
);
|
||||
--> statement-breakpoint
|
||||
ALTER TABLE "workspace_slug_checks" ENABLE ROW LEVEL SECURITY;--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "workspace_slug_checks" ADD CONSTRAINT "workspace_slug_checks_workspaceId_workspace_id_fk" FOREIGN KEY ("workspaceId") REFERENCES "public"."workspace"("id") ON DELETE no action ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "workspace_slug_checks" ADD CONSTRAINT "workspace_slug_checks_createdBy_user_id_fk" FOREIGN KEY ("createdBy") REFERENCES "public"."user"("id") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
@@ -0,0 +1,7 @@
|
||||
ALTER TABLE "subscription" DROP CONSTRAINT "subscription_referenceId_workspace_publicId_fk";
|
||||
--> statement-breakpoint
|
||||
DO $$ BEGIN
|
||||
ALTER TABLE "subscription" ADD CONSTRAINT "subscription_referenceId_workspace_publicId_fk" FOREIGN KEY ("referenceId") REFERENCES "public"."workspace"("publicId") ON DELETE set null ON UPDATE no action;
|
||||
EXCEPTION
|
||||
WHEN duplicate_object THEN null;
|
||||
END $$;
|
||||
2543
packages/db/migrations/meta/20250907185512_snapshot.json
Normal file
2543
packages/db/migrations/meta/20250907185512_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2543
packages/db/migrations/meta/20250910195058_snapshot.json
Normal file
2543
packages/db/migrations/meta/20250910195058_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2626
packages/db/migrations/meta/20250910200416_snapshot.json
Normal file
2626
packages/db/migrations/meta/20250910200416_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
2626
packages/db/migrations/meta/20250910202358_snapshot.json
Normal file
2626
packages/db/migrations/meta/20250910202358_snapshot.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -71,6 +71,34 @@
|
||||
"when": 1756803246096,
|
||||
"tag": "20250902085406_AddSubscriptions",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 10,
|
||||
"version": "7",
|
||||
"when": 1757271312974,
|
||||
"tag": "20250907185512_AddUnlimitedSeatsToSubscription",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 11,
|
||||
"version": "7",
|
||||
"when": 1757533858687,
|
||||
"tag": "20250910195058_RemoveNotNullConstraintFromReferenceIdOnSubsriptions",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 12,
|
||||
"version": "7",
|
||||
"when": 1757534656098,
|
||||
"tag": "20250910200416_AddWorkspaceSlugChecks",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 13,
|
||||
"version": "7",
|
||||
"when": 1757535838766,
|
||||
"tag": "20250910202358_AddCascadeSetNullToReferenceIdOnSubsriptions",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
91
packages/db/src/repository/subscription.repo.ts
Normal file
91
packages/db/src/repository/subscription.repo.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
import type { dbClient } from "@kan/db/client";
|
||||
import { subscription } from "@kan/db/schema";
|
||||
|
||||
export const updateById = async (
|
||||
db: dbClient,
|
||||
subscriptionId: number,
|
||||
updates: {
|
||||
unlimitedSeats?: boolean;
|
||||
status?: string;
|
||||
seats?: number | null;
|
||||
periodStart?: Date | null;
|
||||
periodEnd?: Date | null;
|
||||
cancelAtPeriodEnd?: boolean | null;
|
||||
},
|
||||
) => {
|
||||
const [result] = await db
|
||||
.update(subscription)
|
||||
.set({
|
||||
...updates,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(subscription.id, subscriptionId))
|
||||
.returning({
|
||||
id: subscription.id,
|
||||
plan: subscription.plan,
|
||||
status: subscription.status,
|
||||
unlimitedSeats: subscription.unlimitedSeats,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const updateByStripeSubscriptionId = async (
|
||||
db: dbClient,
|
||||
stripeSubscriptionId: string,
|
||||
updates: {
|
||||
unlimitedSeats?: boolean;
|
||||
status?: string;
|
||||
seats?: number | null;
|
||||
periodStart?: Date | null;
|
||||
periodEnd?: Date | null;
|
||||
cancelAtPeriodEnd?: boolean | null;
|
||||
},
|
||||
) => {
|
||||
const [result] = await db
|
||||
.update(subscription)
|
||||
.set({
|
||||
...updates,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(subscription.stripeSubscriptionId, stripeSubscriptionId))
|
||||
.returning({
|
||||
id: subscription.id,
|
||||
plan: subscription.plan,
|
||||
status: subscription.status,
|
||||
unlimitedSeats: subscription.unlimitedSeats,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const getByStripeSubscriptionId = async (
|
||||
db: dbClient,
|
||||
stripeSubscriptionId: string,
|
||||
) => {
|
||||
return await db.query.subscription.findFirst({
|
||||
where: eq(subscription.stripeSubscriptionId, stripeSubscriptionId),
|
||||
});
|
||||
};
|
||||
|
||||
export const getByReferenceId = async (db: dbClient, referenceId: string) => {
|
||||
return await db.query.subscription.findMany({
|
||||
where: eq(subscription.referenceId, referenceId),
|
||||
});
|
||||
};
|
||||
|
||||
export const create = async (
|
||||
db: dbClient,
|
||||
data: {
|
||||
plan: string;
|
||||
referenceId: string;
|
||||
userId: string;
|
||||
stripeCustomerId: string;
|
||||
status: string;
|
||||
},
|
||||
) => {
|
||||
const [result] = await db.insert(subscription).values(data).returning();
|
||||
return result;
|
||||
};
|
||||
@@ -127,6 +127,7 @@ export const getByPublicIdWithMembers = (
|
||||
plan: true,
|
||||
status: true,
|
||||
seats: true,
|
||||
unlimitedSeats: true,
|
||||
periodStart: true,
|
||||
periodEnd: true,
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
import type { dbClient } from "@kan/db/client";
|
||||
import { slugs } from "@kan/db/schema";
|
||||
import { slugChecks, slugs } from "@kan/db/schema";
|
||||
|
||||
export const getWorkspaceSlug = (db: dbClient, slug: string) => {
|
||||
return db.query.slugs.findFirst({
|
||||
@@ -12,3 +12,20 @@ export const getWorkspaceSlug = (db: dbClient, slug: string) => {
|
||||
where: eq(slugs.slug, slug),
|
||||
});
|
||||
};
|
||||
|
||||
export const createWorkspaceSlugCheck = (
|
||||
db: dbClient,
|
||||
input: {
|
||||
slug: string;
|
||||
userId: string;
|
||||
available: boolean;
|
||||
reserved: boolean;
|
||||
},
|
||||
) => {
|
||||
return db.insert(slugChecks).values({
|
||||
slug: input.slug,
|
||||
available: input.available,
|
||||
reserved: input.reserved,
|
||||
createdBy: input.userId,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -13,9 +13,10 @@ import { workspaces } from "./workspaces";
|
||||
export const subscription = pgTable("subscription", {
|
||||
id: bigserial("id", { mode: "number" }).primaryKey(),
|
||||
plan: varchar("plan", { length: 255 }).notNull(),
|
||||
referenceId: varchar("referenceId", { length: 12 })
|
||||
.notNull()
|
||||
.references(() => workspaces.publicId),
|
||||
referenceId: varchar("referenceId", { length: 12 }).references(
|
||||
() => workspaces.publicId,
|
||||
{ onDelete: "set null" },
|
||||
),
|
||||
stripeCustomerId: varchar("stripeCustomerId", { length: 255 }),
|
||||
stripeSubscriptionId: varchar("stripeSubscriptionId", { length: 255 }),
|
||||
status: varchar("status", { length: 255 }).notNull(),
|
||||
@@ -23,6 +24,7 @@ export const subscription = pgTable("subscription", {
|
||||
periodEnd: timestamp("periodEnd"),
|
||||
cancelAtPeriodEnd: boolean("cancelAtPeriodEnd"),
|
||||
seats: integer("seats"),
|
||||
unlimitedSeats: boolean("unlimitedSeats").default(false).notNull(),
|
||||
trialStart: timestamp("trialStart"),
|
||||
trialEnd: timestamp("trialEnd"),
|
||||
createdAt: timestamp("createdAt").notNull().defaultNow(),
|
||||
|
||||
@@ -2,6 +2,7 @@ import { relations } from "drizzle-orm";
|
||||
import {
|
||||
bigint,
|
||||
bigserial,
|
||||
boolean,
|
||||
pgEnum,
|
||||
pgTable,
|
||||
text,
|
||||
@@ -103,3 +104,17 @@ export const slugs = pgTable("workspace_slugs", {
|
||||
slug: varchar("slug", { length: 255 }).notNull().unique(),
|
||||
type: slugTypeEnum("type").notNull(),
|
||||
});
|
||||
|
||||
export const slugChecks = pgTable("workspace_slug_checks", {
|
||||
id: bigserial("id", { mode: "number" }).primaryKey(),
|
||||
slug: varchar("slug", { length: 255 }).notNull(),
|
||||
available: boolean("available").notNull(),
|
||||
reserved: boolean("reserved").notNull(),
|
||||
workspaceId: bigint("workspaceId", { mode: "number" }).references(
|
||||
() => workspaces.id,
|
||||
),
|
||||
createdBy: uuid("createdBy").references(() => users.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
createdAt: timestamp("createdAt").defaultNow().notNull(),
|
||||
}).enableRLS();
|
||||
|
||||
@@ -45,14 +45,14 @@ export const sendEmail = async (
|
||||
html,
|
||||
};
|
||||
|
||||
if (cloudMailerClient) {
|
||||
const response = await cloudMailerClient.emails.send({
|
||||
...options,
|
||||
body: html,
|
||||
});
|
||||
// if (cloudMailerClient) {
|
||||
// const response = await cloudMailerClient.emails.send({
|
||||
// ...options,
|
||||
// body: html,
|
||||
// });
|
||||
|
||||
return response;
|
||||
}
|
||||
// return response;
|
||||
// }
|
||||
|
||||
const response = await transporter.sendMail(options);
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./generateUID";
|
||||
export * from "./generateSlug";
|
||||
export * from "./subscriptions";
|
||||
|
||||
57
packages/shared/src/utils/subscriptions.ts
Normal file
57
packages/shared/src/utils/subscriptions.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
export type SubscriptionStatus =
|
||||
| "active"
|
||||
| "trialing"
|
||||
| "past_due"
|
||||
| "canceled"
|
||||
| "unpaid";
|
||||
export type SubscriptionPlan = "team" | "pro";
|
||||
|
||||
export interface Subscription {
|
||||
id: number | null;
|
||||
plan: string;
|
||||
status: string;
|
||||
seats: number | null;
|
||||
unlimitedSeats: boolean;
|
||||
periodStart: Date | null;
|
||||
periodEnd: Date | null;
|
||||
referenceId: string | null;
|
||||
stripeSubscriptionId: string | null;
|
||||
stripeCustomerId: string | null;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export const getActiveSubscriptions = (
|
||||
subscriptions: Subscription[] | undefined,
|
||||
) => {
|
||||
if (!subscriptions) return [];
|
||||
return subscriptions.filter(
|
||||
(sub) => sub.status === "active" || sub.status === "trialing",
|
||||
);
|
||||
};
|
||||
|
||||
export const getSubscriptionByPlan = (
|
||||
subscriptions: Subscription[] | undefined,
|
||||
plan: SubscriptionPlan,
|
||||
) => {
|
||||
if (!subscriptions) return undefined;
|
||||
return subscriptions.find(
|
||||
(sub) =>
|
||||
sub.plan === plan &&
|
||||
(sub.status === "active" || sub.status === "trialing"),
|
||||
);
|
||||
};
|
||||
|
||||
export const hasActiveSubscription = (
|
||||
subscriptions: Subscription[] | undefined,
|
||||
plan: SubscriptionPlan,
|
||||
) => {
|
||||
return getSubscriptionByPlan(subscriptions, plan) !== undefined;
|
||||
};
|
||||
|
||||
export const hasUnlimitedSeats = (
|
||||
subscriptions: Subscription[] | undefined,
|
||||
) => {
|
||||
const activeSubscriptions = getActiveSubscriptions(subscriptions);
|
||||
return activeSubscriptions.some((sub) => sub.unlimitedSeats);
|
||||
};
|
||||
@@ -64,7 +64,7 @@ export const updateSubscriptionSeats = async (
|
||||
quantity: newQuantity,
|
||||
},
|
||||
],
|
||||
proration_behavior: "always_invoice", // Invoice immediately
|
||||
proration_behavior: "create_prorations",
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -99,7 +99,11 @@
|
||||
"NEXT_PUBLIC_WHITE_LABEL_HIDE_POWERED_BY",
|
||||
"STRIPE_SECRET_KEY",
|
||||
"STRIPE_WEBHOOK_SECRET",
|
||||
"STRIPE_PRO_PLAN_PRICE_ID",
|
||||
"STRIPE_WEBHOOK_SECRET_LEGACY",
|
||||
"STRIPE_PRO_PLAN_MONTHLY_PRICE_ID",
|
||||
"STRIPE_PRO_PLAN_YEARLY_PRICE_ID",
|
||||
"STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID",
|
||||
"STRIPE_TEAM_PLAN_YEARLY_PRICE_ID",
|
||||
"NEXT_PUBLIC_STORAGE_DOMAIN",
|
||||
"NEXT_PUBLIC_STORAGE_URL",
|
||||
"NEXT_PUBLIC_AVATAR_BUCKET_NAME",
|
||||
|
||||
Reference in New Issue
Block a user