Merge pull request #371 from the-luap/i18n/password-reset-modal
i18n(events): translate PasswordResetModal across 5 locales
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { X, Key, Copy, CheckCircle, Mail, Lock, Eye, EyeOff } from 'lucide-react';
|
import { X, Key, Copy, CheckCircle, Mail, Lock, Eye, EyeOff } from 'lucide-react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Button, Card, Input, PasswordGenerator } from '../common';
|
import { Button, Card, Input, PasswordGenerator } from '../common';
|
||||||
|
|
||||||
interface PasswordResetModalProps {
|
interface PasswordResetModalProps {
|
||||||
@@ -18,6 +19,7 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
onConfirm,
|
onConfirm,
|
||||||
onClose
|
onClose
|
||||||
}) => {
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const [confirmPassword, setConfirmPassword] = useState('');
|
const [confirmPassword, setConfirmPassword] = useState('');
|
||||||
const [showPassword, setShowPassword] = useState(false);
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
@@ -33,10 +35,10 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
// Empty is allowed → server auto-generates. Only validate when typed.
|
// Empty is allowed → server auto-generates. Only validate when typed.
|
||||||
if (password) {
|
if (password) {
|
||||||
if (password.length < 6) {
|
if (password.length < 6) {
|
||||||
next.password = 'Password must be at least 6 characters';
|
next.password = t('events.passwordReset.errorMinLength');
|
||||||
}
|
}
|
||||||
if (password !== confirmPassword) {
|
if (password !== confirmPassword) {
|
||||||
next.confirmPassword = 'Passwords do not match';
|
next.confirmPassword = t('events.passwordReset.errorMismatch');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setErrors(next);
|
setErrors(next);
|
||||||
@@ -52,14 +54,14 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
setResultPassword(result.newPassword);
|
setResultPassword(result.newPassword);
|
||||||
setResultWasGenerated(!supplied);
|
setResultWasGenerated(!supplied);
|
||||||
if (supplied) {
|
if (supplied) {
|
||||||
toast.success('Password reset successfully');
|
toast.success(t('events.passwordReset.toastSuccess'));
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
const serverError = error?.response?.data;
|
const serverError = error?.response?.data;
|
||||||
if (serverError?.error === 'Password does not meet security requirements') {
|
if (serverError?.error === 'Password does not meet security requirements') {
|
||||||
setErrors({ password: serverError.feedback?.join?.(' ') || 'Password does not meet security requirements' });
|
setErrors({ password: serverError.feedback?.join?.(' ') || t('events.passwordReset.errorMinLength') });
|
||||||
} else {
|
} else {
|
||||||
toast.error(serverError?.error || 'Failed to reset password');
|
toast.error(serverError?.error || t('events.passwordReset.toastError'));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
setIsResetting(false);
|
setIsResetting(false);
|
||||||
@@ -70,7 +72,7 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
if (resultPassword) {
|
if (resultPassword) {
|
||||||
await navigator.clipboard.writeText(resultPassword);
|
await navigator.clipboard.writeText(resultPassword);
|
||||||
setCopied(true);
|
setCopied(true);
|
||||||
toast.success('Password copied to clipboard');
|
toast.success(t('events.passwordReset.toastCopied'));
|
||||||
setTimeout(() => setCopied(false), 2000);
|
setTimeout(() => setCopied(false), 2000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -86,7 +88,7 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
<Card className="max-w-md w-full">
|
<Card className="max-w-md w-full">
|
||||||
<div className="flex items-center justify-between mb-4">
|
<div className="flex items-center justify-between mb-4">
|
||||||
<h2 className="text-xl font-semibold text-neutral-900">
|
<h2 className="text-xl font-semibold text-neutral-900">
|
||||||
{resultPassword ? 'New Password' : 'Reset Gallery Password'}
|
{resultPassword ? t('events.passwordReset.newTitle') : t('events.passwordReset.title')}
|
||||||
</h2>
|
</h2>
|
||||||
<button
|
<button
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
@@ -99,22 +101,22 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
{!resultPassword ? (
|
{!resultPassword ? (
|
||||||
<>
|
<>
|
||||||
<p className="text-neutral-600 mb-4">
|
<p className="text-neutral-600 mb-4">
|
||||||
Set a new password for <strong>{eventName}</strong>, or leave both fields empty to have one auto-generated.
|
{t('events.passwordReset.description', { eventName })}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="space-y-4 mb-4">
|
<div className="space-y-4 mb-4">
|
||||||
<div>
|
<div>
|
||||||
<Input
|
<Input
|
||||||
type={showPassword ? 'text' : 'password'}
|
type={showPassword ? 'text' : 'password'}
|
||||||
label="New password"
|
label={t('events.passwordReset.newPasswordLabel')}
|
||||||
placeholder="Leave empty to auto-generate"
|
placeholder={t('events.passwordReset.placeholder')}
|
||||||
value={password}
|
value={password}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setPassword(e.target.value);
|
setPassword(e.target.value);
|
||||||
if (errors.password) setErrors((prev) => ({ ...prev, password: undefined }));
|
if (errors.password) setErrors((prev) => ({ ...prev, password: undefined }));
|
||||||
}}
|
}}
|
||||||
error={errors.password}
|
error={errors.password}
|
||||||
helperText="Use 6+ characters, or leave blank to auto-generate"
|
helperText={t('events.passwordReset.helperText')}
|
||||||
leftIcon={<Lock className="w-5 h-5" />}
|
leftIcon={<Lock className="w-5 h-5" />}
|
||||||
rightIcon={
|
rightIcon={
|
||||||
<button
|
<button
|
||||||
@@ -142,8 +144,8 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
{password.length > 0 && (
|
{password.length > 0 && (
|
||||||
<Input
|
<Input
|
||||||
type={showPassword ? 'text' : 'password'}
|
type={showPassword ? 'text' : 'password'}
|
||||||
label="Confirm password"
|
label={t('events.passwordReset.confirmLabel')}
|
||||||
placeholder="Confirm password"
|
placeholder={t('events.passwordReset.confirmLabel')}
|
||||||
value={confirmPassword}
|
value={confirmPassword}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setConfirmPassword(e.target.value);
|
setConfirmPassword(e.target.value);
|
||||||
@@ -167,11 +169,11 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Mail className="w-4 h-4 text-neutral-500" />
|
<Mail className="w-4 h-4 text-neutral-500" />
|
||||||
<span className="text-sm font-medium text-neutral-700">
|
<span className="text-sm font-medium text-neutral-700">
|
||||||
Send email notification
|
{t('events.passwordReset.sendEmail')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-xs text-neutral-500 mt-1">
|
<p className="text-xs text-neutral-500 mt-1">
|
||||||
Notify the host about the password change
|
{t('events.passwordReset.sendEmailHelp')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
@@ -179,8 +181,7 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
|
|
||||||
<div className="bg-amber-50 border border-amber-200 rounded-lg p-3 mb-6">
|
<div className="bg-amber-50 border border-amber-200 rounded-lg p-3 mb-6">
|
||||||
<p className="text-sm text-amber-800">
|
<p className="text-sm text-amber-800">
|
||||||
<strong>Note:</strong> The old password will no longer work.
|
{t('events.passwordReset.warning')}
|
||||||
Make sure to share the new password with the host.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -191,7 +192,7 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
disabled={isResetting}
|
disabled={isResetting}
|
||||||
className="flex-1"
|
className="flex-1"
|
||||||
>
|
>
|
||||||
Cancel
|
{t('common.cancel')}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="primary"
|
variant="primary"
|
||||||
@@ -201,7 +202,7 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
leftIcon={<Key className="w-4 h-4" />}
|
leftIcon={<Key className="w-4 h-4" />}
|
||||||
className="flex-1"
|
className="flex-1"
|
||||||
>
|
>
|
||||||
Reset Password
|
{t('events.passwordReset.submit')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@@ -210,11 +211,11 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
<div className="bg-green-50 border border-green-200 rounded-lg p-4 mb-6">
|
<div className="bg-green-50 border border-green-200 rounded-lg p-4 mb-6">
|
||||||
<div className="flex items-center gap-3 mb-2">
|
<div className="flex items-center gap-3 mb-2">
|
||||||
<CheckCircle className="w-5 h-5 text-green-600" />
|
<CheckCircle className="w-5 h-5 text-green-600" />
|
||||||
<p className="font-medium text-green-900">Password reset successfully!</p>
|
<p className="font-medium text-green-900">{t('events.passwordReset.successHeading')}</p>
|
||||||
</div>
|
</div>
|
||||||
{sendEmail && (
|
{sendEmail && (
|
||||||
<p className="text-sm text-green-700">
|
<p className="text-sm text-green-700">
|
||||||
An email notification has been sent to the host.
|
{t('events.passwordReset.emailSentNote')}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@@ -223,7 +224,7 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
<>
|
<>
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
<label className="block text-sm font-medium text-neutral-700 mb-2">
|
<label className="block text-sm font-medium text-neutral-700 mb-2">
|
||||||
Auto-generated gallery password
|
{t('events.passwordReset.generatedLabel')}
|
||||||
</label>
|
</label>
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<input
|
<input
|
||||||
@@ -237,14 +238,14 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
onClick={handleCopy}
|
onClick={handleCopy}
|
||||||
leftIcon={copied ? <CheckCircle className="w-4 h-4" /> : <Copy className="w-4 h-4" />}
|
leftIcon={copied ? <CheckCircle className="w-4 h-4" /> : <Copy className="w-4 h-4" />}
|
||||||
>
|
>
|
||||||
{copied ? 'Copied!' : 'Copy'}
|
{copied ? t('events.copied') : t('events.copy')}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-3 mb-6">
|
<div className="bg-blue-50 border border-blue-200 rounded-lg p-3 mb-6">
|
||||||
<p className="text-sm text-blue-800">
|
<p className="text-sm text-blue-800">
|
||||||
<strong>Important:</strong> Save this password securely. It cannot be recovered once you close this window.
|
{t('events.passwordReset.saveSecurelyNote')}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
@@ -255,7 +256,7 @@ export const PasswordResetModal: React.FC<PasswordResetModalProps> = ({
|
|||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
>
|
>
|
||||||
Done
|
{t('events.passwordReset.done')}
|
||||||
</Button>
|
</Button>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -904,6 +904,29 @@
|
|||||||
"confirmPassword": "Passwort bestätigen",
|
"confirmPassword": "Passwort bestätigen",
|
||||||
"showPasswords": "Passwörter anzeigen",
|
"showPasswords": "Passwörter anzeigen",
|
||||||
"newPasswordLabel": "Neues Galerie-Passwort",
|
"newPasswordLabel": "Neues Galerie-Passwort",
|
||||||
|
"passwordReset": {
|
||||||
|
"title": "Galerie-Passwort zurücksetzen",
|
||||||
|
"newTitle": "Neues Passwort",
|
||||||
|
"description": "Lege ein neues Passwort für {{eventName}} fest oder lasse beide Felder leer, um eines automatisch zu erzeugen.",
|
||||||
|
"newPasswordLabel": "Neues Passwort",
|
||||||
|
"placeholder": "Leer lassen für automatische Erzeugung",
|
||||||
|
"helperText": "Mindestens 6 Zeichen verwenden oder leer lassen für automatische Erzeugung",
|
||||||
|
"confirmLabel": "Passwort bestätigen",
|
||||||
|
"sendEmail": "E-Mail-Benachrichtigung senden",
|
||||||
|
"sendEmailHelp": "Den Host über die Passwortänderung informieren",
|
||||||
|
"warning": "Hinweis: Das alte Passwort funktioniert nicht mehr. Stelle sicher, dass du das neue Passwort an den Host weitergibst.",
|
||||||
|
"submit": "Passwort zurücksetzen",
|
||||||
|
"successHeading": "Passwort erfolgreich zurückgesetzt!",
|
||||||
|
"emailSentNote": "Eine E-Mail-Benachrichtigung wurde an den Host gesendet.",
|
||||||
|
"generatedLabel": "Automatisch generiertes Galerie-Passwort",
|
||||||
|
"saveSecurelyNote": "Wichtig: Speichere dieses Passwort sicher. Es kann nicht wiederhergestellt werden, sobald du dieses Fenster schließt.",
|
||||||
|
"done": "Fertig",
|
||||||
|
"toastSuccess": "Passwort erfolgreich zurückgesetzt",
|
||||||
|
"toastError": "Passwort zurücksetzen fehlgeschlagen",
|
||||||
|
"toastCopied": "Passwort in Zwischenablage kopiert",
|
||||||
|
"errorMinLength": "Das Passwort muss mindestens 6 Zeichen lang sein",
|
||||||
|
"errorMismatch": "Passwörter stimmen nicht überein"
|
||||||
|
},
|
||||||
"gallerySettings": "Galerie-Einstellungen",
|
"gallerySettings": "Galerie-Einstellungen",
|
||||||
"colorTheme": "Farbthema",
|
"colorTheme": "Farbthema",
|
||||||
"galleryExpiration": "Galerie-Ablauf",
|
"galleryExpiration": "Galerie-Ablauf",
|
||||||
|
|||||||
@@ -454,6 +454,29 @@
|
|||||||
"confirmPassword": "Confirm Password",
|
"confirmPassword": "Confirm Password",
|
||||||
"showPasswords": "Show passwords",
|
"showPasswords": "Show passwords",
|
||||||
"newPasswordLabel": "New Gallery Password",
|
"newPasswordLabel": "New Gallery Password",
|
||||||
|
"passwordReset": {
|
||||||
|
"title": "Reset Gallery Password",
|
||||||
|
"newTitle": "New Password",
|
||||||
|
"description": "Set a new password for {{eventName}}, or leave both fields empty to have one auto-generated.",
|
||||||
|
"newPasswordLabel": "New password",
|
||||||
|
"placeholder": "Leave empty to auto-generate",
|
||||||
|
"helperText": "Use 6+ characters, or leave blank to auto-generate",
|
||||||
|
"confirmLabel": "Confirm password",
|
||||||
|
"sendEmail": "Send email notification",
|
||||||
|
"sendEmailHelp": "Notify the host about the password change",
|
||||||
|
"warning": "Note: The old password will no longer work. Make sure to share the new password with the host.",
|
||||||
|
"submit": "Reset Password",
|
||||||
|
"successHeading": "Password reset successfully!",
|
||||||
|
"emailSentNote": "An email notification has been sent to the host.",
|
||||||
|
"generatedLabel": "Auto-generated gallery password",
|
||||||
|
"saveSecurelyNote": "Important: Save this password securely. It cannot be recovered once you close this window.",
|
||||||
|
"done": "Done",
|
||||||
|
"toastSuccess": "Password reset successfully",
|
||||||
|
"toastError": "Failed to reset password",
|
||||||
|
"toastCopied": "Password copied to clipboard",
|
||||||
|
"errorMinLength": "Password must be at least 6 characters",
|
||||||
|
"errorMismatch": "Passwords do not match"
|
||||||
|
},
|
||||||
"gallerySettings": "Gallery Settings",
|
"gallerySettings": "Gallery Settings",
|
||||||
"themeAndStyle": "Theme & Style",
|
"themeAndStyle": "Theme & Style",
|
||||||
"colorTheme": "Color Theme",
|
"colorTheme": "Color Theme",
|
||||||
|
|||||||
@@ -448,6 +448,29 @@
|
|||||||
"confirmPassword": "Bevestig wachtwoord",
|
"confirmPassword": "Bevestig wachtwoord",
|
||||||
"showPasswords": "Wachtwoorden tonen",
|
"showPasswords": "Wachtwoorden tonen",
|
||||||
"newPasswordLabel": "Nieuw galerijwachtwoord",
|
"newPasswordLabel": "Nieuw galerijwachtwoord",
|
||||||
|
"passwordReset": {
|
||||||
|
"title": "Galerijwachtwoord opnieuw instellen",
|
||||||
|
"newTitle": "Nieuw wachtwoord",
|
||||||
|
"description": "Stel een nieuw wachtwoord in voor {{eventName}}, of laat beide velden leeg om er automatisch een te laten genereren.",
|
||||||
|
"newPasswordLabel": "Nieuw wachtwoord",
|
||||||
|
"placeholder": "Leeg laten voor automatische generatie",
|
||||||
|
"helperText": "Gebruik 6+ tekens, of laat leeg voor automatische generatie",
|
||||||
|
"confirmLabel": "Wachtwoord bevestigen",
|
||||||
|
"sendEmail": "E-mailmelding versturen",
|
||||||
|
"sendEmailHelp": "Stel de host op de hoogte van de wachtwoordwijziging",
|
||||||
|
"warning": "Let op: Het oude wachtwoord werkt niet meer. Zorg ervoor dat je het nieuwe wachtwoord deelt met de host.",
|
||||||
|
"submit": "Wachtwoord opnieuw instellen",
|
||||||
|
"successHeading": "Wachtwoord succesvol opnieuw ingesteld!",
|
||||||
|
"emailSentNote": "Een e-mailmelding is naar de host gestuurd.",
|
||||||
|
"generatedLabel": "Automatisch gegenereerd galerijwachtwoord",
|
||||||
|
"saveSecurelyNote": "Belangrijk: Sla dit wachtwoord veilig op. Het kan niet worden hersteld nadat je dit venster hebt gesloten.",
|
||||||
|
"done": "Klaar",
|
||||||
|
"toastSuccess": "Wachtwoord succesvol opnieuw ingesteld",
|
||||||
|
"toastError": "Wachtwoord opnieuw instellen mislukt",
|
||||||
|
"toastCopied": "Wachtwoord gekopieerd naar klembord",
|
||||||
|
"errorMinLength": "Wachtwoord moet minimaal 6 tekens bevatten",
|
||||||
|
"errorMismatch": "Wachtwoorden komen niet overeen"
|
||||||
|
},
|
||||||
"gallerySettings": "Galerijinstellingen",
|
"gallerySettings": "Galerijinstellingen",
|
||||||
"themeAndStyle": "Thema & Stijl",
|
"themeAndStyle": "Thema & Stijl",
|
||||||
"colorTheme": "Kleurthema",
|
"colorTheme": "Kleurthema",
|
||||||
|
|||||||
@@ -448,6 +448,29 @@
|
|||||||
"confirmPassword": "Confirmar Senha",
|
"confirmPassword": "Confirmar Senha",
|
||||||
"showPasswords": "Mostrar senhas",
|
"showPasswords": "Mostrar senhas",
|
||||||
"newPasswordLabel": "Nova Senha da Galeria",
|
"newPasswordLabel": "Nova Senha da Galeria",
|
||||||
|
"passwordReset": {
|
||||||
|
"title": "Redefinir Senha da Galeria",
|
||||||
|
"newTitle": "Nova Senha",
|
||||||
|
"description": "Defina uma nova senha para {{eventName}} ou deixe ambos os campos vazios para gerar uma automaticamente.",
|
||||||
|
"newPasswordLabel": "Nova senha",
|
||||||
|
"placeholder": "Deixe em branco para gerar automaticamente",
|
||||||
|
"helperText": "Use 6+ caracteres, ou deixe em branco para gerar automaticamente",
|
||||||
|
"confirmLabel": "Confirmar senha",
|
||||||
|
"sendEmail": "Enviar notificação por e-mail",
|
||||||
|
"sendEmailHelp": "Notifique o anfitrião sobre a alteração de senha",
|
||||||
|
"warning": "Observação: A senha antiga não funcionará mais. Certifique-se de compartilhar a nova senha com o anfitrião.",
|
||||||
|
"submit": "Redefinir Senha",
|
||||||
|
"successHeading": "Senha redefinida com sucesso!",
|
||||||
|
"emailSentNote": "Uma notificação por e-mail foi enviada ao anfitrião.",
|
||||||
|
"generatedLabel": "Senha da galeria gerada automaticamente",
|
||||||
|
"saveSecurelyNote": "Importante: Salve esta senha com segurança. Ela não pode ser recuperada após fechar esta janela.",
|
||||||
|
"done": "Concluído",
|
||||||
|
"toastSuccess": "Senha redefinida com sucesso",
|
||||||
|
"toastError": "Falha ao redefinir senha",
|
||||||
|
"toastCopied": "Senha copiada para a área de transferência",
|
||||||
|
"errorMinLength": "A senha deve ter pelo menos 6 caracteres",
|
||||||
|
"errorMismatch": "As senhas não coincidem"
|
||||||
|
},
|
||||||
"gallerySettings": "Configurações da Galeria",
|
"gallerySettings": "Configurações da Galeria",
|
||||||
"themeAndStyle": "Tema e Estilo",
|
"themeAndStyle": "Tema e Estilo",
|
||||||
"colorTheme": "Tema de Cores",
|
"colorTheme": "Tema de Cores",
|
||||||
|
|||||||
@@ -448,6 +448,29 @@
|
|||||||
"confirmPassword": "Подтвердить пароль",
|
"confirmPassword": "Подтвердить пароль",
|
||||||
"showPasswords": "Показать пароли",
|
"showPasswords": "Показать пароли",
|
||||||
"newPasswordLabel": "Новый пароль галереи",
|
"newPasswordLabel": "Новый пароль галереи",
|
||||||
|
"passwordReset": {
|
||||||
|
"title": "Сбросить пароль галереи",
|
||||||
|
"newTitle": "Новый пароль",
|
||||||
|
"description": "Установите новый пароль для {{eventName}} или оставьте оба поля пустыми, чтобы пароль был сгенерирован автоматически.",
|
||||||
|
"newPasswordLabel": "Новый пароль",
|
||||||
|
"placeholder": "Оставьте пустым для автоматической генерации",
|
||||||
|
"helperText": "Минимум 6 символов или оставьте пустым для автоматической генерации",
|
||||||
|
"confirmLabel": "Подтвердите пароль",
|
||||||
|
"sendEmail": "Отправить уведомление по электронной почте",
|
||||||
|
"sendEmailHelp": "Уведомить хоста об изменении пароля",
|
||||||
|
"warning": "Внимание: Старый пароль больше не будет работать. Обязательно передайте новый пароль хосту.",
|
||||||
|
"submit": "Сбросить пароль",
|
||||||
|
"successHeading": "Пароль успешно сброшен!",
|
||||||
|
"emailSentNote": "Уведомление по электронной почте отправлено хосту.",
|
||||||
|
"generatedLabel": "Автоматически сгенерированный пароль галереи",
|
||||||
|
"saveSecurelyNote": "Важно: Сохраните этот пароль в безопасном месте. Восстановить его после закрытия окна невозможно.",
|
||||||
|
"done": "Готово",
|
||||||
|
"toastSuccess": "Пароль успешно сброшен",
|
||||||
|
"toastError": "Не удалось сбросить пароль",
|
||||||
|
"toastCopied": "Пароль скопирован в буфер обмена",
|
||||||
|
"errorMinLength": "Пароль должен содержать не менее 6 символов",
|
||||||
|
"errorMismatch": "Пароли не совпадают"
|
||||||
|
},
|
||||||
"gallerySettings": "Настройки галереи",
|
"gallerySettings": "Настройки галереи",
|
||||||
"themeAndStyle": "Тема и стиль",
|
"themeAndStyle": "Тема и стиль",
|
||||||
"colorTheme": "Цветовая тема",
|
"colorTheme": "Цветовая тема",
|
||||||
|
|||||||
Reference in New Issue
Block a user