feat: refactor authentication forms to use <form> elements for better submission handling

This commit is contained in:
shuaiplus
2026-03-15 18:26:36 +08:00
parent ca74e55979
commit 588408ff96
4 changed files with 172 additions and 134 deletions
+24 -3
View File
@@ -64,6 +64,12 @@ export default function AuthViews(props: AuthViewsProps) {
return ( return (
<div className="auth-page"> <div className="auth-page">
<StandalonePageFrame title={t('txt_unlock_vault')}> <StandalonePageFrame title={t('txt_unlock_vault')}>
<form
onSubmit={(e) => {
e.preventDefault();
props.onSubmitUnlock();
}}
>
<p className="muted standalone-muted">{props.emailForLock}</p> <p className="muted standalone-muted">{props.emailForLock}</p>
<PasswordField <PasswordField
label={t('txt_master_password')} label={t('txt_master_password')}
@@ -71,7 +77,7 @@ export default function AuthViews(props: AuthViewsProps) {
autoFocus autoFocus
onInput={props.onChangeUnlock} onInput={props.onChangeUnlock}
/> />
<button type="button" className="btn btn-primary full" onClick={props.onSubmitUnlock}> <button type="submit" className="btn btn-primary full">
<Unlock size={16} className="btn-icon" /> <Unlock size={16} className="btn-icon" />
{t('txt_unlock')} {t('txt_unlock')}
</button> </button>
@@ -80,6 +86,7 @@ export default function AuthViews(props: AuthViewsProps) {
<LogOut size={16} className="btn-icon" /> <LogOut size={16} className="btn-icon" />
{t('txt_log_out')} {t('txt_log_out')}
</button> </button>
</form>
</StandalonePageFrame> </StandalonePageFrame>
</div> </div>
); );
@@ -89,6 +96,12 @@ export default function AuthViews(props: AuthViewsProps) {
return ( return (
<div className="auth-page"> <div className="auth-page">
<StandalonePageFrame title={t('txt_create_account')}> <StandalonePageFrame title={t('txt_create_account')}>
<form
onSubmit={(e) => {
e.preventDefault();
props.onSubmitRegister();
}}
>
<label className="field"> <label className="field">
<span>{t('txt_name')}</span> <span>{t('txt_name')}</span>
<input <input
@@ -130,7 +143,7 @@ export default function AuthViews(props: AuthViewsProps) {
} }
/> />
</label> </label>
<button type="button" className="btn btn-primary full" onClick={props.onSubmitRegister}> <button type="submit" className="btn btn-primary full">
<UserPlus size={16} className="btn-icon" /> <UserPlus size={16} className="btn-icon" />
{t('txt_create_account')} {t('txt_create_account')}
</button> </button>
@@ -139,6 +152,7 @@ export default function AuthViews(props: AuthViewsProps) {
<ArrowLeft size={16} className="btn-icon" /> <ArrowLeft size={16} className="btn-icon" />
{t('txt_back_to_login')} {t('txt_back_to_login')}
</button> </button>
</form>
</StandalonePageFrame> </StandalonePageFrame>
</div> </div>
); );
@@ -147,6 +161,12 @@ export default function AuthViews(props: AuthViewsProps) {
return ( return (
<div className="auth-page"> <div className="auth-page">
<StandalonePageFrame title={t('txt_log_in')}> <StandalonePageFrame title={t('txt_log_in')}>
<form
onSubmit={(e) => {
e.preventDefault();
props.onSubmitLogin();
}}
>
<label className="field"> <label className="field">
<span>{t('txt_email')}</span> <span>{t('txt_email')}</span>
<input <input
@@ -162,7 +182,7 @@ export default function AuthViews(props: AuthViewsProps) {
onInput={(v) => props.onChangeLogin({ ...props.loginValues, password: v })} onInput={(v) => props.onChangeLogin({ ...props.loginValues, password: v })}
autoFocus autoFocus
/> />
<button type="button" className="btn btn-primary full" onClick={props.onSubmitLogin}> <button type="submit" className="btn btn-primary full">
<LogIn size={16} className="btn-icon" /> <LogIn size={16} className="btn-icon" />
{t('txt_log_in')} {t('txt_log_in')}
</button> </button>
@@ -171,6 +191,7 @@ export default function AuthViews(props: AuthViewsProps) {
<UserPlus size={16} className="btn-icon" /> <UserPlus size={16} className="btn-icon" />
{t('txt_create_account')} {t('txt_create_account')}
</button> </button>
</form>
</StandalonePageFrame> </StandalonePageFrame>
</div> </div>
); );
+9 -4
View File
@@ -20,14 +20,19 @@ export default function ConfirmDialog(props: ConfirmDialogProps) {
if (!props.open) return null; if (!props.open) return null;
return ( return (
<div className="dialog-mask"> <div className="dialog-mask">
<div className="dialog-card"> <form
className="dialog-card"
onSubmit={(e) => {
e.preventDefault();
props.onConfirm();
}}
>
<h3 className="dialog-title">{props.title}</h3> <h3 className="dialog-title">{props.title}</h3>
<div className="dialog-message">{props.message}</div> <div className="dialog-message">{props.message}</div>
{props.children} {props.children}
<button <button
type="button" type="submit"
className={`btn ${props.danger ? 'btn-danger' : 'btn-primary'} dialog-btn`} className={`btn ${props.danger ? 'btn-danger' : 'btn-primary'} dialog-btn`}
onClick={props.onConfirm}
> >
<Check size={14} className="btn-icon" /> <Check size={14} className="btn-icon" />
{props.confirmText || t('txt_yes')} {props.confirmText || t('txt_yes')}
@@ -37,7 +42,7 @@ export default function ConfirmDialog(props: ConfirmDialogProps) {
{props.cancelText || t('txt_no')} {props.cancelText || t('txt_no')}
</button> </button>
{props.afterActions} {props.afterActions}
</div> </form>
</div> </div>
); );
} }
+8 -3
View File
@@ -92,7 +92,12 @@ export default function PublicSendPage(props: PublicSendPageProps) {
{loading && <p className="muted">{t('txt_loading')}</p>} {loading && <p className="muted">{t('txt_loading')}</p>}
{!loading && needPassword && ( {!loading && needPassword && (
<> <form
onSubmit={(e) => {
e.preventDefault();
void loadSend(password);
}}
>
<label className="field"> <label className="field">
<span>{t('txt_password')}</span> <span>{t('txt_password')}</span>
<div className="password-wrap"> <div className="password-wrap">
@@ -104,10 +109,10 @@ export default function PublicSendPage(props: PublicSendPageProps) {
/> />
</div> </div>
</label> </label>
<button type="button" className="btn btn-primary full" disabled={busy} onClick={() => void loadSend(password)}> <button type="submit" className="btn btn-primary full" disabled={busy}>
<Lock size={14} className="btn-icon" /> {t('txt_unlock_send')} <Lock size={14} className="btn-icon" /> {t('txt_unlock_send')}
</button> </button>
</> </form>
)} )}
{!loading && sendData && ( {!loading && sendData && (
@@ -16,6 +16,12 @@ export default function RecoverTwoFactorPage(props: RecoverTwoFactorPageProps) {
return ( return (
<div className="auth-page"> <div className="auth-page">
<StandalonePageFrame title={t('txt_recover_two_step_login')}> <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> <p className="muted standalone-muted">{t('txt_use_your_one_time_recovery_code_to_disable_two_step_verification')}</p>
<label className="field"> <label className="field">
@@ -53,7 +59,7 @@ export default function RecoverTwoFactorPage(props: RecoverTwoFactorPageProps) {
</label> </label>
<div className="field-grid"> <div className="field-grid">
<button type="button" className="btn btn-primary" onClick={props.onSubmit}> <button type="submit" className="btn btn-primary">
<Send size={14} className="btn-icon" /> <Send size={14} className="btn-icon" />
{t('txt_submit')} {t('txt_submit')}
</button> </button>
@@ -62,6 +68,7 @@ export default function RecoverTwoFactorPage(props: RecoverTwoFactorPageProps) {
{t('txt_cancel')} {t('txt_cancel')}
</button> </button>
</div> </div>
</form>
</StandalonePageFrame> </StandalonePageFrame>
</div> </div>
); );