UI - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: дизайн и русификация God Mode

This commit is contained in:
DCCONSTRUCTIONS
2026-04-29 00:38:04 +03:00
parent 5d336039ba
commit 7f47b85c36
57 changed files with 1104 additions and 588 deletions
@@ -31,7 +31,7 @@ type TEmailSecurityKeys = "EMAIL_USE_TLS" | "EMAIL_USE_SSL" | "NONE";
const EMAIL_SECURITY_OPTIONS: { [key in TEmailSecurityKeys]: string } = {
EMAIL_USE_TLS: "TLS",
EMAIL_USE_SSL: "SSL",
NONE: "No email security",
NONE: "Без шифрования",
};
export function InstanceEmailForm(props: IInstanceEmailForm) {
@@ -63,7 +63,7 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
{
key: "EMAIL_HOST",
type: "text",
label: "Host",
label: "Хост",
placeholder: "email.google.com",
error: Boolean(errors.EMAIL_HOST),
required: true,
@@ -71,7 +71,7 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
{
key: "EMAIL_PORT",
type: "text",
label: "Port",
label: "Порт",
placeholder: "8080",
error: Boolean(errors.EMAIL_PORT),
required: true,
@@ -79,9 +79,9 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
{
key: "EMAIL_FROM",
type: "text",
label: "Sender's email address",
label: "Email отправителя",
description:
"This is the email address your users will see when getting emails from this instance. You will need to verify this address.",
"Этот адрес будут видеть пользователи в письмах от инстанса. Адрес нужно подтвердить на стороне SMTP.",
placeholder: "no-reply@projectplane.so",
error: Boolean(errors.EMAIL_FROM),
required: true,
@@ -92,7 +92,7 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
{
key: "EMAIL_HOST_USER",
type: "text",
label: "Username",
label: "Имя пользователя",
placeholder: "getitdone@projectplane.so",
error: Boolean(errors.EMAIL_HOST_USER),
required: false,
@@ -100,8 +100,8 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
{
key: "EMAIL_HOST_PASSWORD",
type: "password",
label: "Password",
placeholder: "Password",
label: "Пароль",
placeholder: "Пароль",
error: Boolean(errors.EMAIL_HOST_PASSWORD),
required: false,
},
@@ -114,8 +114,8 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
.then(() =>
setToast({
type: TOAST_TYPE.SUCCESS,
title: "Success",
message: "Email Settings updated successfully",
title: "Сохранено",
message: "Настройки почты обновлены",
})
)
.catch((err) => console.error(err));
@@ -163,12 +163,12 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
/>
))}
<div className="flex flex-col gap-1">
<h4 className="text-13 text-tertiary">Email security</h4>
<h4 className="text-13 text-tertiary">Защита соединения</h4>
<CustomSelect
value={emailSecurityKey}
label={EMAIL_SECURITY_OPTIONS[emailSecurityKey]}
onChange={handleEmailSecurityChange}
buttonClassName="rounded-md border-subtle"
buttonClassName="nodedc-settings-select rounded-md border-subtle"
input
>
{Object.entries(EMAIL_SECURITY_OPTIONS).map(([key, value]) => (
@@ -183,9 +183,9 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
<div className="flex w-full max-w-xl flex-col gap-y-10 px-1">
<div className="mr-8 flex items-center gap-10 pt-4">
<div className="grow">
<div className="text-13 font-medium text-primary">Authentication</div>
<div className="text-13 font-medium text-primary">Аутентификация</div>
<div className="text-11 font-regular text-tertiary">
This is optional, but we recommend setting up a username and a password for your SMTP server.
Необязательно, но для SMTP-сервера обычно нужны имя пользователя и пароль.
</div>
</div>
</div>
@@ -215,7 +215,7 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
loading={isSubmitting}
disabled={!isValid || !isDirty}
>
{isSubmitting ? "Saving" : "Save changes"}
{isSubmitting ? "Сохранение" : "Сохранить изменения"}
</Button>
<Button
variant="secondary"
@@ -224,7 +224,7 @@ export function InstanceEmailForm(props: IInstanceEmailForm) {
loading={isSubmitting}
disabled={!isValid}
>
Send test email
Отправить тестовое письмо
</Button>
</div>
</div>
@@ -34,14 +34,14 @@ const InstanceEmailPage = observer(function InstanceEmailPage(_props: Route.Comp
await disableEmail();
setIsSMTPEnabled(false);
setToast({
title: "Email feature disabled",
message: "Email feature has been disabled",
title: "Почта отключена",
message: "Отправка писем через SMTP отключена",
type: TOAST_TYPE.SUCCESS,
});
} catch (_error) {
setToast({
title: "Error disabling email",
message: "Failed to disable email feature. Please try again.",
title: "Не удалось отключить почту",
message: "Повторите попытку.",
type: TOAST_TYPE.ERROR,
});
} finally {
@@ -60,13 +60,13 @@ const InstanceEmailPage = observer(function InstanceEmailPage(_props: Route.Comp
return (
<PageWrapper
header={{
title: "Secure emails from your own instance",
title: "Письма от вашего инстанса",
description: (
<>
Plane can send useful emails to you and your users from your own instance without talking to the Internet.
NODE.DC может отправлять системные письма пользователям через ваш SMTP-сервер.
<div className="text-13 font-regular text-tertiary">
Set it up below and please test your settings before you save them.&nbsp;
<span className="text-danger-primary">Misconfigs can lead to email bounces and errors.</span>
Заполните параметры ниже и проверьте отправку перед сохранением.&nbsp;
<span className="text-danger-primary">Ошибки в конфигурации приводят к отказам доставки.</span>
</div>
</>
),
@@ -98,6 +98,6 @@ const InstanceEmailPage = observer(function InstanceEmailPage(_props: Route.Comp
);
});
export const meta: Route.MetaFunction = () => [{ title: "Email Settings - God Mode" }];
export const meta: Route.MetaFunction = () => [{ title: "Настройки почты - NODE.DC" }];
export default InstanceEmailPage;
@@ -58,7 +58,7 @@ export function SendTestEmailModal(props: Props) {
setSendEmailStep(ESendEmailSteps.SUCCESS);
})
.catch((error) => {
setError(error?.error || "Failed to send email");
setError(error?.error || "Не удалось отправить письмо");
setSendEmailStep(ESendEmailSteps.FAILED);
})
.finally(() => {
@@ -91,13 +91,13 @@ export function SendTestEmailModal(props: Props) {
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="relative w-full transform rounded-lg bg-surface-1 p-5 px-4 text-left shadow-raised-200 transition-all sm:max-w-xl">
<Dialog.Panel className="nodedc-glass-modal relative w-full transform rounded-[1.75rem] bg-surface-1 p-5 px-4 text-left shadow-raised-200 transition-all sm:max-w-xl">
<h3 className="text-16 leading-6 font-medium text-primary">
{sendEmailStep === ESendEmailSteps.SEND_EMAIL
? "Send test email"
? "Отправить тестовое письмо"
: sendEmailStep === ESendEmailSteps.SUCCESS
? "Email send"
: "Failed"}{" "}
? "Письмо отправлено"
: "Ошибка отправки"}{" "}
</h3>
<div className="pt-6 pb-2">
{sendEmailStep === ESendEmailSteps.SEND_EMAIL && (
@@ -106,28 +106,25 @@ export function SendTestEmailModal(props: Props) {
type="email"
value={receiverEmail}
onChange={(e) => setReceiverEmail(e.target.value)}
placeholder="Receiver email"
className="w-full resize-none text-16"
placeholder="Email получателя"
className="nodedc-settings-input w-full resize-none text-16"
tabIndex={1}
/>
)}
{sendEmailStep === ESendEmailSteps.SUCCESS && (
<div className="flex flex-col gap-y-4 text-13">
<p>
We have sent the test email to {receiverEmail}. Please check your spam folder if you cannot find
it.
</p>
<p>If you still cannot find it, recheck your SMTP configuration and trigger a new test email.</p>
<p>Тестовое письмо отправлено на {receiverEmail}. Если письма нет во входящих, проверьте спам.</p>
<p>Если письмо не пришло, проверьте SMTP-настройки и отправьте тест заново.</p>
</div>
)}
{sendEmailStep === ESendEmailSteps.FAILED && <div className="text-13">{error}</div>}
<div className="mt-5 flex items-center justify-end gap-2">
<Button variant="secondary" size="lg" onClick={handleClose} tabIndex={2}>
{sendEmailStep === ESendEmailSteps.SEND_EMAIL ? "Cancel" : "Close"}
{sendEmailStep === ESendEmailSteps.SEND_EMAIL ? "Отмена" : "Закрыть"}
</Button>
{sendEmailStep === ESendEmailSteps.SEND_EMAIL && (
<Button variant="primary" size="lg" loading={isLoading} onClick={handleSubmit} tabIndex={3}>
{isLoading ? "Sending email" : "Send email"}
{isLoading ? "Отправка" : "Отправить"}
</Button>
)}
</div>