diff --git a/plane-src/apps/web/ce/components/projects/external-contours/content-root.tsx b/plane-src/apps/web/ce/components/projects/external-contours/content-root.tsx index 22700c5..3457c32 100644 --- a/plane-src/apps/web/ce/components/projects/external-contours/content-root.tsx +++ b/plane-src/apps/web/ce/components/projects/external-contours/content-root.tsx @@ -90,7 +90,7 @@ export const ExternalContoursContentRoot = observer(function ExternalContoursCon hasDirectTargetAccess={hasDirectTargetAccess} /> - +
@@ -54,13 +54,14 @@ export function ExternalContourDeclineModal(props: Props) { rows={5} disabled={isSubmitting} autoFocus + className="nodedc-modal-input min-h-[8rem] resize-none" />
- -
diff --git a/plane-src/apps/web/ce/components/projects/external-contours/issue-header.tsx b/plane-src/apps/web/ce/components/projects/external-contours/issue-header.tsx index 0141f14..9b3584b 100644 --- a/plane-src/apps/web/ce/components/projects/external-contours/issue-header.tsx +++ b/plane-src/apps/web/ce/components/projects/external-contours/issue-header.tsx @@ -135,7 +135,7 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont onSubmit={(comment) => handleDecision("decline", comment)} /> - +
{issue?.project_id && issue.sequence_id && (

@@ -157,11 +157,11 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
{canReviewClosedRequest && ( <> - - @@ -172,12 +172,18 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont {t("external_contours_page.traceability.source_decision_accepted")} )} - {hasDirectTargetAccess && ( router.push(workItemLink)} target="_self"> - @@ -196,10 +202,10 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
{canReviewClosedRequest && ( <> - - @@ -209,7 +215,7 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont )} {hasDirectTargetAccess && ( router.push(workItemLink)} target="_self"> - diff --git a/plane-src/apps/web/ce/components/projects/external-contours/issue-root.tsx b/plane-src/apps/web/ce/components/projects/external-contours/issue-root.tsx index 7180545..c49be11 100644 --- a/plane-src/apps/web/ce/components/projects/external-contours/issue-root.tsx +++ b/plane-src/apps/web/ce/components/projects/external-contours/issue-root.tsx @@ -139,7 +139,7 @@ export const ExternalContoursIssueMainContent = observer(function ExternalContou if (!hasDirectTargetAccess) { return (
-
+
{isSourceEditable ? ( <> -
+
+
{duplicateIssues.length > 0 && (
-
- -
+ -
+
-
+
-
+
- +
); }); diff --git a/plane-src/apps/web/ce/components/projects/external-contours/list-item.tsx b/plane-src/apps/web/ce/components/projects/external-contours/list-item.tsx index 7ef1ccd..585c338 100644 --- a/plane-src/apps/web/ce/components/projects/external-contours/list-item.tsx +++ b/plane-src/apps/web/ce/components/projects/external-contours/list-item.tsx @@ -42,8 +42,11 @@ export const ExternalContoursListItem = observer(function ExternalContoursListIt if (!request || !issue) return <>; const assigneeDetails = issue.assignee_details?.slice(0, 2) ?? []; - const visibleLabels = issue.label_details?.slice(0, 3) ?? []; const lastUpdatedAt = issue.updated_at || request.updated_at; + const requester = issue.created_by_detail; + const requesterName = + request.requested_by_name || requester?.display_name || t("external_contours_page.mirror.system_actor"); + const contourName = request.target_project_name || issue.project_detail?.name || t("common.none"); return ( -
-
-
- - {issue.project_detail?.identifier || "REQ"}-{issue.sequence_id} - - {issue.project_detail?.name && {issue.project_detail.name}} +
+
+ +
+
{requesterName}
+
{contourName}
+
+
+
+
+ {issue.project_detail?.identifier || "REQ"}-{issue.sequence_id} +
+
{request.has_unread_updates && ( )} -
-
-

{issue.name}

-
-
+
+

+ {issue.name} +

+
+ +
+
+ {assigneeDetails.length > 0 ? ( + assigneeDetails.map((assignee) => ( + + )) + ) : ( + +
{t("external_contours_page.list.unassigned")}
+
+ )} +
+
-
{renderFormattedDate(lastUpdatedAt ?? "")}
+
+ {renderFormattedDate(lastUpdatedAt ?? "")} +
{issue.priority && issue.priority !== "none" && ( @@ -94,32 +130,6 @@ export const ExternalContoursListItem = observer(function ExternalContoursListIt )} - - {visibleLabels.map((label) => ( -
- - {label.name} -
- ))} -
-
- {assigneeDetails.length > 0 ? ( - <> - {assigneeDetails.map((assignee) => ( - - ))} - - ) : ( - -
{t("external_contours_page.list.unassigned")}
-
- )}
diff --git a/plane-src/apps/web/core/components/account/auth-forms/auth-root.tsx b/plane-src/apps/web/core/components/account/auth-forms/auth-root.tsx index e1e089b..ca71de3 100644 --- a/plane-src/apps/web/core/components/account/auth-forms/auth-root.tsx +++ b/plane-src/apps/web/core/components/account/auth-forms/auth-root.tsx @@ -157,7 +157,7 @@ export const AuthRoot = observer(function AuthRoot(props: TAuthRoot) { function AuthContainer({ children }: { children: React.ReactNode }) { return ( -
+
{children}
); diff --git a/plane-src/apps/web/core/components/auth-screens/auth-base.tsx b/plane-src/apps/web/core/components/auth-screens/auth-base.tsx index cc9edba..a32f6ff 100644 --- a/plane-src/apps/web/core/components/auth-screens/auth-base.tsx +++ b/plane-src/apps/web/core/components/auth-screens/auth-base.tsx @@ -15,7 +15,7 @@ type AuthBaseProps = { export function AuthBase({ authType }: AuthBaseProps) { return ( -
+
diff --git a/plane-src/apps/web/core/components/auth-screens/header.tsx b/plane-src/apps/web/core/components/auth-screens/header.tsx index 60980d1..557c40e 100644 --- a/plane-src/apps/web/core/components/auth-screens/header.tsx +++ b/plane-src/apps/web/core/components/auth-screens/header.tsx @@ -73,7 +73,11 @@ export function AuthHeaderBase(props: TAuthHeaderBase) {
- + {additionalAction}
diff --git a/plane-src/apps/web/core/components/core/image-picker-popover.tsx b/plane-src/apps/web/core/components/core/image-picker-popover.tsx index 4cbdc44..5cd4c28 100644 --- a/plane-src/apps/web/core/components/core/image-picker-popover.tsx +++ b/plane-src/apps/web/core/components/core/image-picker-popover.tsx @@ -17,7 +17,7 @@ import { ACCEPTED_COVER_IMAGE_MIME_TYPES_FOR_REACT_DROPZONE, MAX_FILE_SIZE } fro import { useOutsideClickDetector } from "@plane/hooks"; import { useTranslation } from "@plane/i18n"; import { Tabs } from "@plane/propel/tabs"; -import { Button, getButtonStyling } from "@plane/propel/button"; +import { Button } from "@plane/propel/button"; import { TOAST_TYPE, setToast } from "@plane/propel/toast"; import { EFileAssetType } from "@plane/types"; import { Input, Loader } from "@plane/ui"; @@ -204,7 +204,9 @@ export const ImagePickerPopover = observer(function ImagePickerPopover(props: Pr return ( diff --git a/plane-src/apps/web/core/components/instance/not-ready-view.tsx b/plane-src/apps/web/core/components/instance/not-ready-view.tsx index 6594fc6..806b978 100644 --- a/plane-src/apps/web/core/components/instance/not-ready-view.tsx +++ b/plane-src/apps/web/core/components/instance/not-ready-view.tsx @@ -17,39 +17,46 @@ export function InstanceNotReady() { return (
- {/* Background decorations */} - - - {/* Main content */}
- +
-
+
+ + NODE.DC Logo
-

Welcome to NODE.DC

+

NODE.DC готов к запуску

- Set up your instance and create your first workspace to begin managing projects and work. + Завершите настройку инстанса и создайте первое рабочее пространство, чтобы начать работу с + проектами и рабочими элементами.

+ + + + + Служба поддержки +
- - -
diff --git a/plane-src/apps/web/core/components/project/create/header.tsx b/plane-src/apps/web/core/components/project/create/header.tsx index 7e7d84c..90cb78b 100644 --- a/plane-src/apps/web/core/components/project/create/header.tsx +++ b/plane-src/apps/web/core/components/project/create/header.tsx @@ -84,7 +84,7 @@ function ProjectCreateHeader(props: Props) { }} control={control} value={value ?? null} - buttonClassName="nodedc-overlay-button" + buttonClassName="nodedc-overlay-button min-w-[10.5rem]" tabIndex={getIndex("cover_image")} /> )} diff --git a/plane-src/apps/web/core/components/project/form.tsx b/plane-src/apps/web/core/components/project/form.tsx index 1d0cd66..4de357b 100644 --- a/plane-src/apps/web/core/components/project/form.tsx +++ b/plane-src/apps/web/core/components/project/form.tsx @@ -255,7 +255,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) { control={control} onChange={onChange} value={value ?? null} - buttonClassName="nodedc-overlay-button" + buttonClassName="nodedc-overlay-button min-w-[10.5rem]" disabled={!isAdmin} projectId={project.id} /> @@ -436,7 +436,7 @@ export function ProjectDetailsForm(props: IProjectDetailsForm) { type="submit" loading={isLoading} disabled={!isAdmin} - className="nodedc-settings-save-button min-w-[11.5rem]" + className="nodedc-settings-save-button min-w-[11.5rem] !text-[#0b1117] hover:!text-[#0b1117]" > {isLoading ? t("updating") : t("common.update_project")} diff --git a/plane-src/apps/web/core/components/project/project-feature-update.tsx b/plane-src/apps/web/core/components/project/project-feature-update.tsx index 95f8df4..ff83f66 100644 --- a/plane-src/apps/web/core/components/project/project-feature-update.tsx +++ b/plane-src/apps/web/core/components/project/project-feature-update.tsx @@ -57,7 +57,7 @@ export const ProjectFeatureUpdate = observer(function ProjectFeatureUpdate(props {t("open_project")} diff --git a/plane-src/apps/web/styles/globals.css b/plane-src/apps/web/styles/globals.css index c67db14..e5091a4 100644 --- a/plane-src/apps/web/styles/globals.css +++ b/plane-src/apps/web/styles/globals.css @@ -494,6 +494,15 @@ background: color-mix(in srgb, rgb(var(--nodedc-card-active-rgb)) 82%, white) !important; } + .nodedc-modal-primary-button, + .nodedc-modal-primary-button *, + .nodedc-settings-primary-button, + .nodedc-settings-primary-button *, + .nodedc-settings-save-button, + .nodedc-settings-save-button * { + color: #0b1117 !important; + } + .nodedc-modal-danger-button { min-height: 2.75rem; border: 0 !important; @@ -650,18 +659,18 @@ } .nodedc-overlay-button { - min-height: 2.5rem; + min-height: 2.75rem; border: 0 !important; outline: none !important; box-shadow: none !important; - border-radius: 1.05rem !important; + border-radius: 1.25rem !important; background: - linear-gradient(180deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.018) 100%), - rgba(8, 8, 10, 0.58) !important; + linear-gradient(180deg, rgba(255, 255, 255, 0.045) 0%, rgba(255, 255, 255, 0.02) 100%), + rgba(9, 9, 12, 0.72) !important; color: #f5f7fb !important; - padding-inline: 1rem !important; - -webkit-backdrop-filter: blur(18px); - backdrop-filter: blur(18px); + padding-inline: 1.05rem !important; + -webkit-backdrop-filter: blur(22px); + backdrop-filter: blur(22px); transition: background 120ms ease, color 120ms ease, @@ -670,8 +679,8 @@ .nodedc-overlay-button:hover { background: - linear-gradient(180deg, rgba(255, 255, 255, 0.075) 0%, rgba(255, 255, 255, 0.03) 100%), - rgba(8, 8, 10, 0.72) !important; + linear-gradient(180deg, rgba(255, 255, 255, 0.07) 0%, rgba(255, 255, 255, 0.03) 100%), + rgba(9, 9, 12, 0.8) !important; color: #ffffff !important; } @@ -798,17 +807,24 @@ .nodedc-auth-shell { width: 100%; - max-width: 28rem; + max-width: 32rem; border: 0 !important; outline: none !important; - box-shadow: none !important; - border-radius: 1.75rem !important; - padding: 1.75rem !important; + box-shadow: + 0 24px 64px rgba(0, 0, 0, 0.34), + 0 8px 20px rgba(0, 0, 0, 0.18) !important; + border-radius: 1.9rem !important; + padding: 2.2rem !important; background: - linear-gradient(180deg, rgba(255, 255, 255, 0.04) 0%, rgba(255, 255, 255, 0.015) 100%), - rgba(10, 10, 12, 0.82) !important; - -webkit-backdrop-filter: blur(34px); - backdrop-filter: blur(34px); + linear-gradient(180deg, rgba(255, 255, 255, 0.048) 0%, rgba(255, 255, 255, 0.015) 100%), + rgba(9, 9, 12, 0.84) !important; + -webkit-backdrop-filter: blur(40px); + backdrop-filter: blur(40px); + } + + .nodedc-auth-logo-lockup { + color: var(--text-color-primary) !important; + filter: drop-shadow(0 12px 28px rgba(0, 0, 0, 0.2)); } .nodedc-auth-banner { @@ -885,14 +901,16 @@ max-width: 36rem; border: 0 !important; outline: none !important; - box-shadow: none !important; - border-radius: 1.9rem !important; - padding: 2rem !important; + box-shadow: + 0 24px 64px rgba(0, 0, 0, 0.34), + 0 8px 20px rgba(0, 0, 0, 0.18) !important; + border-radius: 1.95rem !important; + padding: 2.15rem !important; background: - linear-gradient(180deg, rgba(255, 255, 255, 0.04) 0%, rgba(255, 255, 255, 0.015) 100%), - rgba(10, 10, 12, 0.82) !important; - -webkit-backdrop-filter: blur(36px); - backdrop-filter: blur(36px); + linear-gradient(180deg, rgba(255, 255, 255, 0.045) 0%, rgba(255, 255, 255, 0.016) 100%), + rgba(9, 9, 12, 0.86) !important; + -webkit-backdrop-filter: blur(40px); + backdrop-filter: blur(40px); } .nodedc-error-link { @@ -955,10 +973,10 @@ .nodedc-external-sidebar-shell { border: 0 !important; background: - linear-gradient(180deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%), - rgba(8, 8, 11, 0.82) !important; - -webkit-backdrop-filter: blur(26px); - backdrop-filter: blur(26px); + linear-gradient(180deg, rgba(255, 255, 255, 0.035) 0%, rgba(255, 255, 255, 0.012) 100%), + rgba(8, 8, 11, 0.86) !important; + -webkit-backdrop-filter: blur(30px); + backdrop-filter: blur(30px); } .nodedc-external-tab { @@ -985,23 +1003,65 @@ .nodedc-external-card { border: 0 !important; outline: none !important; - box-shadow: none !important; - border-radius: 1.9rem !important; - background: rgb(var(--nodedc-card-passive-rgb)) !important; + box-shadow: + 0 12px 28px rgba(0, 0, 0, 0.12), + inset 0 1px 0 rgba(255, 255, 255, 0.018) !important; + border-radius: 2rem !important; + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.018) 0%, rgba(255, 255, 255, 0.006) 100%), + rgb(var(--nodedc-card-passive-rgb)) !important; color: var(--text-color-primary) !important; } .nodedc-external-card[data-active="true"] { background: - linear-gradient(180deg, rgba(255, 255, 255, 0.028) 0%, rgba(255, 255, 255, 0.01) 100%), - rgba(255, 255, 255, 0.04) !important; - box-shadow: inset 0 0 0 1px rgba(var(--nodedc-accent-rgb), 0.3); + linear-gradient(180deg, rgba(255, 255, 255, 0.024) 0%, rgba(255, 255, 255, 0.008) 100%), + rgba(255, 255, 255, 0.035) !important; + box-shadow: + inset 0 0 0 1px rgba(var(--nodedc-accent-rgb), 0.32), + 0 12px 32px rgba(0, 0, 0, 0.16) !important; + } + + .nodedc-external-content-shell { + border: 0 !important; + outline: none !important; + box-shadow: + 0 18px 44px rgba(0, 0, 0, 0.18), + inset 0 1px 0 rgba(255, 255, 255, 0.02) !important; + border-radius: 2rem !important; + background: + linear-gradient(180deg, rgba(255, 255, 255, 0.034) 0%, rgba(255, 255, 255, 0.014) 100%), + rgba(255, 255, 255, 0.03) !important; + -webkit-backdrop-filter: blur(28px); + backdrop-filter: blur(28px); + } + + .nodedc-external-field { + border: 0 !important; + outline: none !important; + box-shadow: none !important; + border-radius: 1.4rem !important; + background: rgba(255, 255, 255, 0.04) !important; + } + + .nodedc-external-field:hover, + .nodedc-external-field:focus-within { + background: rgba(255, 255, 255, 0.055) !important; + } + + .nodedc-external-chip { + border: 0 !important; + outline: none !important; + box-shadow: none !important; + border-radius: 999px !important; + background: rgba(255, 255, 255, 0.06) !important; + color: var(--text-color-primary) !important; } .nodedc-external-panel { border: 0 !important; outline: none !important; - box-shadow: none !important; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.018) !important; border-radius: 1.6rem !important; background: linear-gradient(180deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.012) 100%), @@ -1013,7 +1073,9 @@ .nodedc-external-section { border: 0 !important; outline: none !important; - box-shadow: none !important; + box-shadow: + 0 12px 32px rgba(0, 0, 0, 0.12), + inset 0 1px 0 rgba(255, 255, 255, 0.018) !important; border-radius: 1.5rem !important; background: linear-gradient(180deg, rgba(255, 255, 255, 0.028) 0%, rgba(255, 255, 255, 0.012) 100%), @@ -1030,4 +1092,35 @@ background: rgba(255, 255, 255, 0.035) !important; color: var(--text-color-secondary) !important; } + + .nodedc-external-action-button { + min-height: 2.75rem; + border: 0 !important; + outline: none !important; + box-shadow: none !important; + border-radius: 1.25rem !important; + background: rgba(255, 255, 255, 0.06) !important; + color: var(--text-color-primary) !important; + padding-inline: 1.15rem !important; + } + + .nodedc-external-action-button:hover { + background: rgba(255, 255, 255, 0.1) !important; + } + + .nodedc-external-primary-button { + min-height: 2.75rem; + border: 0 !important; + outline: none !important; + box-shadow: none !important; + border-radius: 1.25rem !important; + background: rgb(var(--nodedc-card-active-rgb)) !important; + color: #0b1117 !important; + padding-inline: 1.2rem !important; + } + + .nodedc-external-primary-button:hover { + background: color-mix(in srgb, rgb(var(--nodedc-card-active-rgb)) 82%, white) !important; + color: #0b1117 !important; + } } diff --git a/plane-src/packages/utils/src/auth.ts b/plane-src/packages/utils/src/auth.ts index fb5689f..9315611 100644 --- a/plane-src/packages/utils/src/auth.ts +++ b/plane-src/packages/utils/src/auth.ts @@ -60,32 +60,32 @@ export type PasswordCriteria = { export const getPasswordCriteria = (password: string): PasswordCriteria[] => [ { key: "length", - label: "Min 8 characters", + label: "Минимум 8 символов", isValid: password.length >= 8, }, { key: "uppercase", - label: "Min 1 upper-case letter", + label: "Минимум 1 заглавная буква", isValid: /[A-Z]/.test(password), }, { key: "lowercase", - label: "Min 1 lower-case letter", + label: "Минимум 1 строчная буква", isValid: /[a-z]/.test(password), }, { key: "number", - label: "Min 1 number", + label: "Минимум 1 цифра", isValid: /[0-9]/.test(password), }, { key: "special", - label: "Min 1 special character", + label: "Минимум 1 спецсимвол", isValid: /[!@#$%^&*()\-_+=\[\]{}|;:'",.<>?/]/.test(password), }, { key: "predictable", - label: "Avoid common or predictable patterns", + label: "Избегайте простых и предсказуемых шаблонов", isValid: password.length >= 8 ? zxcvbn(password).score >= 3 : false, }, ]; @@ -96,218 +96,218 @@ const errorCodeMessages: { } = { // global [EAuthErrorCodes.INSTANCE_NOT_CONFIGURED]: { - title: `Instance not configured`, - message: () => `Instance not configured. Please contact your administrator.`, + title: `Инстанс не настроен`, + message: () => `Инстанс не настроен. Обратитесь к администратору.`, }, [EAuthErrorCodes.SIGNUP_DISABLED]: { - title: `Sign up disabled`, - message: () => `Sign up disabled. Please contact your administrator.`, + title: `Регистрация отключена`, + message: () => `Регистрация отключена. Обратитесь к администратору.`, }, [EAuthErrorCodes.INVALID_PASSWORD]: { - title: `Invalid password`, - message: () => `Invalid password. Please try again.`, + title: `Неверный пароль`, + message: () => `Неверный пароль. Попробуйте снова.`, }, [EAuthErrorCodes.PASSWORD_TOO_WEAK]: { - title: `Password too weak`, + title: `Слишком простой пароль`, message: () => - `Password must include upper-case, lower-case, number, special character, and must not be predictable.`, + `Пароль должен содержать заглавные и строчные буквы, цифру, спецсимвол и не быть предсказуемым.`, }, [EAuthErrorCodes.SMTP_NOT_CONFIGURED]: { - title: `SMTP not configured`, - message: () => `SMTP not configured. Please contact your administrator.`, + title: `SMTP не настроен`, + message: () => `SMTP не настроен. Обратитесь к администратору.`, }, // email check in both sign up and sign in [EAuthErrorCodes.INVALID_EMAIL]: { - title: `Invalid email`, - message: () => `Invalid email. Please try again.`, + title: `Некорректный e-mail`, + message: () => `Некорректный e-mail. Попробуйте снова.`, }, [EAuthErrorCodes.EMAIL_REQUIRED]: { - title: `Email required`, - message: () => `Email required. Please try again.`, + title: `Нужен e-mail`, + message: () => `Укажите e-mail и попробуйте снова.`, }, // sign up [EAuthErrorCodes.USER_ALREADY_EXIST]: { - title: `User already exists`, - message: () => `Your account is already registered. Sign in now.`, + title: `Аккаунт уже существует`, + message: () => `Аккаунт уже зарегистрирован. Выполните вход.`, }, [EAuthErrorCodes.REQUIRED_EMAIL_PASSWORD_SIGN_UP]: { - title: `Email and password required`, - message: () => `Email and password required. Please try again.`, + title: `Нужны e-mail и пароль`, + message: () => `Укажите e-mail и пароль, затем попробуйте снова.`, }, [EAuthErrorCodes.AUTHENTICATION_FAILED_SIGN_UP]: { - title: `Authentication failed`, - message: () => `Authentication failed. Please try again.`, + title: `Не удалось выполнить вход`, + message: () => `Не удалось выполнить вход. Проверьте данные и попробуйте снова.`, }, [EAuthErrorCodes.INVALID_EMAIL_SIGN_UP]: { - title: `Invalid email`, - message: () => `Invalid email. Please try again.`, + title: `Некорректный e-mail`, + message: () => `Некорректный e-mail. Попробуйте снова.`, }, [EAuthErrorCodes.MAGIC_SIGN_UP_EMAIL_CODE_REQUIRED]: { - title: `Email and code required`, - message: () => `Email and code required. Please try again.`, + title: `Нужны e-mail и код`, + message: () => `Укажите e-mail и код подтверждения, затем попробуйте снова.`, }, [EAuthErrorCodes.INVALID_EMAIL_MAGIC_SIGN_UP]: { - title: `Invalid email`, - message: () => `Invalid email. Please try again.`, + title: `Некорректный e-mail`, + message: () => `Некорректный e-mail. Попробуйте снова.`, }, // sign in [EAuthErrorCodes.USER_ACCOUNT_DEACTIVATED]: { - title: `User account deactivated`, - message: () => `User account deactivated. Please contact administrator.`, + title: `Аккаунт деактивирован`, + message: () => `Аккаунт деактивирован. Обратитесь к администратору.`, }, [EAuthErrorCodes.USER_DOES_NOT_EXIST]: { - title: `User does not exist`, - message: () => `No account found. Create one to get started.`, + title: `Аккаунт не найден`, + message: () => `Аккаунт не найден. Создайте новый для начала работы.`, }, [EAuthErrorCodes.REQUIRED_EMAIL_PASSWORD_SIGN_IN]: { - title: `Email and password required`, - message: () => `Email and password required. Please try again.`, + title: `Нужны e-mail и пароль`, + message: () => `Укажите e-mail и пароль, затем попробуйте снова.`, }, [EAuthErrorCodes.AUTHENTICATION_FAILED_SIGN_IN]: { - title: `Authentication failed`, - message: () => `Authentication failed. Please try again.`, + title: `Не удалось выполнить вход`, + message: () => `Не удалось выполнить вход. Проверьте данные и попробуйте снова.`, }, [EAuthErrorCodes.INVALID_EMAIL_SIGN_IN]: { - title: `Invalid email`, - message: () => `Invalid email. Please try again.`, + title: `Некорректный e-mail`, + message: () => `Некорректный e-mail. Попробуйте снова.`, }, [EAuthErrorCodes.MAGIC_SIGN_IN_EMAIL_CODE_REQUIRED]: { - title: `Email and code required`, - message: () => `Email and code required. Please try again.`, + title: `Нужны e-mail и код`, + message: () => `Укажите e-mail и код подтверждения, затем попробуйте снова.`, }, [EAuthErrorCodes.INVALID_EMAIL_MAGIC_SIGN_IN]: { - title: `Invalid email`, - message: () => `Invalid email. Please try again.`, + title: `Некорректный e-mail`, + message: () => `Некорректный e-mail. Попробуйте снова.`, }, // Both Sign in and Sign up [EAuthErrorCodes.INVALID_MAGIC_CODE_SIGN_IN]: { - title: `Authentication failed`, - message: () => `Invalid magic code. Please try again.`, + title: `Неверный код подтверждения`, + message: () => `Неверный код подтверждения. Попробуйте снова.`, }, [EAuthErrorCodes.INVALID_MAGIC_CODE_SIGN_UP]: { - title: `Authentication failed`, - message: () => `Invalid magic code. Please try again.`, + title: `Неверный код подтверждения`, + message: () => `Неверный код подтверждения. Попробуйте снова.`, }, [EAuthErrorCodes.EXPIRED_MAGIC_CODE_SIGN_IN]: { - title: `Expired magic code`, - message: () => `Expired magic code. Please try again.`, + title: `Код подтверждения истёк`, + message: () => `Код подтверждения истёк. Запросите новый и попробуйте снова.`, }, [EAuthErrorCodes.EXPIRED_MAGIC_CODE_SIGN_UP]: { - title: `Expired magic code`, - message: () => `Expired magic code. Please try again.`, + title: `Код подтверждения истёк`, + message: () => `Код подтверждения истёк. Запросите новый и попробуйте снова.`, }, [EAuthErrorCodes.EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_IN]: { - title: `Expired magic code`, - message: () => `Expired magic code. Please try again.`, + title: `Лимит попыток исчерпан`, + message: () => `Лимит попыток ввода кода исчерпан. Запросите новый код.`, }, [EAuthErrorCodes.EMAIL_CODE_ATTEMPT_EXHAUSTED_SIGN_UP]: { - title: `Expired magic code`, - message: () => `Expired magic code. Please try again.`, + title: `Лимит попыток исчерпан`, + message: () => `Лимит попыток ввода кода исчерпан. Запросите новый код.`, }, // Oauth [EAuthErrorCodes.OAUTH_NOT_CONFIGURED]: { - title: `OAuth not configured`, - message: () => `OAuth not configured. Please contact your administrator.`, + title: `OAuth не настроен`, + message: () => `OAuth не настроен. Обратитесь к администратору.`, }, [EAuthErrorCodes.GOOGLE_NOT_CONFIGURED]: { - title: `Google not configured`, - message: () => `Google not configured. Please contact your administrator.`, + title: `Google OAuth не настроен`, + message: () => `Google OAuth не настроен. Обратитесь к администратору.`, }, [EAuthErrorCodes.GITHUB_NOT_CONFIGURED]: { - title: `GitHub not configured`, - message: () => `GitHub not configured. Please contact your administrator.`, + title: `GitHub OAuth не настроен`, + message: () => `GitHub OAuth не настроен. Обратитесь к администратору.`, }, [EAuthErrorCodes.GITLAB_NOT_CONFIGURED]: { - title: `GitLab not configured`, - message: () => `GitLab not configured. Please contact your administrator.`, + title: `GitLab OAuth не настроен`, + message: () => `GitLab OAuth не настроен. Обратитесь к администратору.`, }, [EAuthErrorCodes.GOOGLE_OAUTH_PROVIDER_ERROR]: { - title: `Google OAuth provider error`, - message: () => `Google OAuth provider error. Please try again.`, + title: `Ошибка Google OAuth`, + message: () => `Не удалось авторизоваться через Google. Попробуйте снова.`, }, [EAuthErrorCodes.GITHUB_OAUTH_PROVIDER_ERROR]: { - title: `GitHub OAuth provider error`, - message: () => `GitHub OAuth provider error. Please try again.`, + title: `Ошибка GitHub OAuth`, + message: () => `Не удалось авторизоваться через GitHub. Попробуйте снова.`, }, [EAuthErrorCodes.GITLAB_OAUTH_PROVIDER_ERROR]: { - title: `GitLab OAuth provider error`, - message: () => `GitLab OAuth provider error. Please try again.`, + title: `Ошибка GitLab OAuth`, + message: () => `Не удалось авторизоваться через GitLab. Попробуйте снова.`, }, // Reset Password [EAuthErrorCodes.INVALID_PASSWORD_TOKEN]: { - title: `Invalid password token`, - message: () => `Invalid password token. Please try again.`, + title: `Некорректный токен`, + message: () => `Некорректный токен восстановления. Попробуйте снова.`, }, [EAuthErrorCodes.EXPIRED_PASSWORD_TOKEN]: { - title: `Expired password token`, - message: () => `Expired password token. Please try again.`, + title: `Токен истёк`, + message: () => `Токен восстановления истёк. Запросите новый.`, }, // Change password [EAuthErrorCodes.MISSING_PASSWORD]: { - title: `Password required`, - message: () => `Password required. Please try again.`, + title: `Нужен пароль`, + message: () => `Укажите пароль и попробуйте снова.`, }, [EAuthErrorCodes.INCORRECT_OLD_PASSWORD]: { - title: `Incorrect old password`, - message: () => `Incorrect old password. Please try again.`, + title: `Неверный старый пароль`, + message: () => `Старый пароль указан неверно. Попробуйте снова.`, }, [EAuthErrorCodes.INVALID_NEW_PASSWORD]: { - title: `Invalid new password`, - message: () => `Invalid new password. Please try again.`, + title: `Некорректный новый пароль`, + message: () => `Новый пароль не соответствует требованиям.`, }, // set password [EAuthErrorCodes.PASSWORD_ALREADY_SET]: { - title: `Password already set`, - message: () => `Password already set. Please try again.`, + title: `Пароль уже установлен`, + message: () => `Пароль уже установлен. Выполните вход.`, }, // admin [EAuthErrorCodes.ADMIN_ALREADY_EXIST]: { - title: `Admin already exists`, - message: () => `Admin already exists. Please try again.`, + title: `Администратор уже существует`, + message: () => `Администратор уже существует. Попробуйте снова.`, }, [EAuthErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD_FIRST_NAME]: { - title: `Email, password and first name required`, - message: () => `Email, password and first name required. Please try again.`, + title: `Нужны e-mail, пароль и имя`, + message: () => `Укажите e-mail, пароль и имя, затем попробуйте снова.`, }, [EAuthErrorCodes.INVALID_ADMIN_EMAIL]: { - title: `Invalid admin email`, - message: () => `Invalid admin email. Please try again.`, + title: `Некорректный e-mail администратора`, + message: () => `Некорректный e-mail администратора. Попробуйте снова.`, }, [EAuthErrorCodes.INVALID_ADMIN_PASSWORD]: { - title: `Invalid admin password`, - message: () => `Invalid admin password. Please try again.`, + title: `Некорректный пароль администратора`, + message: () => `Некорректный пароль администратора. Попробуйте снова.`, }, [EAuthErrorCodes.REQUIRED_ADMIN_EMAIL_PASSWORD]: { - title: `Email and password required`, - message: () => `Email and password required. Please try again.`, + title: `Нужны e-mail и пароль`, + message: () => `Укажите e-mail и пароль, затем попробуйте снова.`, }, [EAuthErrorCodes.ADMIN_AUTHENTICATION_FAILED]: { - title: `Authentication failed`, - message: () => `Authentication failed. Please try again.`, + title: `Не удалось выполнить вход`, + message: () => `Не удалось выполнить вход. Проверьте данные и попробуйте снова.`, }, [EAuthErrorCodes.ADMIN_USER_ALREADY_EXIST]: { - title: `Admin user already exists`, - message: () => `Admin user already exists. Sign in now.`, + title: `Администратор уже существует`, + message: () => `Администратор уже существует. Выполните вход.`, }, [EAuthErrorCodes.ADMIN_USER_DOES_NOT_EXIST]: { - title: `Admin user does not exist`, - message: () => `Admin user does not exist. Sign in now.`, + title: `Администратор не найден`, + message: () => `Администратор не найден. Выполните вход.`, }, [EAuthErrorCodes.MAGIC_LINK_LOGIN_DISABLED]: { - title: `Magic link login disabled`, - message: () => `Magic link login is disabled. Please use password to login.`, + title: `Вход по magic link отключён`, + message: () => `Вход по magic link отключён. Используйте пароль.`, }, [EAuthErrorCodes.PASSWORD_LOGIN_DISABLED]: { - title: `Password login disabled`, - message: () => `Password login is disabled. Please use magic link to login.`, + title: `Вход по паролю отключён`, + message: () => `Вход по паролю отключён. Используйте magic link.`, }, [EAuthErrorCodes.ADMIN_USER_DEACTIVATED]: { - title: `Admin user deactivated`, - message: () => `Admin user account has been deactivated. Please contact administrator.`, + title: `Администратор деактивирован`, + message: () => `Аккаунт администратора деактивирован. Обратитесь к администратору.`, }, [EAuthErrorCodes.RATE_LIMIT_EXCEEDED]: { - title: `Rate limit exceeded`, - message: () => `Too many requests. Please try again later.`, + title: `Слишком много запросов`, + message: () => `Слишком много запросов. Повторите попытку позже.`, }, }; @@ -365,8 +365,8 @@ export const authErrorHandler = (errorCode: EAuthErrorCodes, email?: string): TA return { type: EErrorAlertType.BANNER_ALERT, code: errorCode, - title: errorCodeMessages[errorCode]?.title || "Error", - message: errorCodeMessages[errorCode]?.message(email) || "Something went wrong. Please try again.", + title: errorCodeMessages[errorCode]?.title || "Ошибка", + message: errorCodeMessages[errorCode]?.message(email) || "Что-то пошло не так. Попробуйте снова.", }; return undefined;