mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 13:00:39 +00:00
4b8cad6d00
- Updated `BackupCenterPage` to support download progress tracking during remote backup downloads. - Modified `ImportPage` to simplify export functionality by removing unnecessary payload handling. - Improved `JwtWarningPage` to utilize a new clipboard utility for copying text with feedback. - Enhanced `PublicSendPage` to show download progress for files being downloaded. - Updated `RecoverTwoFactorPage` to include autocomplete attributes for better user experience. - Refactored `SendsPage` to use the new clipboard utility for copying access URLs. - Enhanced `SettingsPage` to utilize the clipboard utility for copying sensitive information. - Improved `TotpCodesPage` to use the clipboard utility for copying TOTP codes. - Updated `VaultPage` and related components to support download progress for attachments. - Introduced a new `app-notify` module for consistent notification handling across the application. - Created a `clipboard` utility for improved clipboard interactions with user feedback. - Added progress tracking for file downloads in the API layer, enhancing user experience during downloads.
79 lines
2.9 KiB
TypeScript
79 lines
2.9 KiB
TypeScript
import { useState } from 'preact/hooks';
|
|
import { Eye, EyeOff, Send, X } from 'lucide-preact';
|
|
import StandalonePageFrame from '@/components/StandalonePageFrame';
|
|
import { t } from '@/lib/i18n';
|
|
|
|
interface RecoverTwoFactorPageProps {
|
|
values: { email: string; password: string; recoveryCode: string };
|
|
onChange: (next: { email: string; password: string; recoveryCode: string }) => void;
|
|
onSubmit: () => void;
|
|
onCancel: () => void;
|
|
}
|
|
|
|
export default function RecoverTwoFactorPage(props: RecoverTwoFactorPageProps) {
|
|
const [showPassword, setShowPassword] = useState(false);
|
|
|
|
return (
|
|
<div className="auth-page">
|
|
<StandalonePageFrame title={t('txt_recover_two_step_login')}>
|
|
<form
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
props.onSubmit();
|
|
}}
|
|
>
|
|
<p className="muted standalone-muted">{t('txt_use_your_one_time_recovery_code_to_disable_two_step_verification')}</p>
|
|
|
|
<label className="field">
|
|
<span>{t('txt_email')}</span>
|
|
<input
|
|
className="input"
|
|
type="email"
|
|
value={props.values.email}
|
|
autoComplete="username"
|
|
onInput={(e) => props.onChange({ ...props.values, email: (e.currentTarget as HTMLInputElement).value })}
|
|
/>
|
|
</label>
|
|
|
|
<label className="field">
|
|
<span>{t('txt_master_password')}</span>
|
|
<div className="password-wrap">
|
|
<input
|
|
className="input"
|
|
type={showPassword ? 'text' : 'password'}
|
|
value={props.values.password}
|
|
autoComplete="current-password"
|
|
onInput={(e) => props.onChange({ ...props.values, password: (e.currentTarget as HTMLInputElement).value })}
|
|
/>
|
|
<button type="button" className="eye-btn" onClick={() => setShowPassword((v) => !v)}>
|
|
{showPassword ? <EyeOff size={16} /> : <Eye size={16} />}
|
|
</button>
|
|
</div>
|
|
</label>
|
|
|
|
<label className="field">
|
|
<span>{t('txt_recovery_code')}</span>
|
|
<input
|
|
className="input"
|
|
value={props.values.recoveryCode}
|
|
autoComplete="one-time-code"
|
|
onInput={(e) => props.onChange({ ...props.values, recoveryCode: (e.currentTarget as HTMLInputElement).value.toUpperCase() })}
|
|
/>
|
|
</label>
|
|
|
|
<div className="field-grid">
|
|
<button type="submit" className="btn btn-primary">
|
|
<Send size={14} className="btn-icon" />
|
|
{t('txt_submit')}
|
|
</button>
|
|
<button type="button" className="btn btn-secondary" onClick={props.onCancel}>
|
|
<X size={14} className="btn-icon" />
|
|
{t('txt_cancel')}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</StandalonePageFrame>
|
|
</div>
|
|
);
|
|
}
|