fix(auth): show user agreement before login actions
CI / verify (pull_request) Has been cancelled

Quick login required agreement without a checkbox; move the consent row above CTAs across partner/shop/user/mini login pages so it stays visible on short screens.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-17 10:20:32 +08:00
parent 55e91158b3
commit 14b867a3a5
10 changed files with 235 additions and 117 deletions
+20 -21
View File
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { useNavigate, useSearchParams, Link } from 'react-router-dom';
import AppImage from '@dukang/shared-ui/AppImage';
import type { WechatLoginResult } from '@dukang/shared-types';
@@ -31,6 +31,7 @@ export default function LoginPage() {
const [wxSessionKey, setWxSessionKey] = useState<string | null>(null);
const [bindMode, setBindMode] = useState(false);
const [wxAuthorize, setWxAuthorize] = useState(false);
const agreementRef = useRef<HTMLLabelElement>(null);
const { sendCode, sending, codeCooldown, sentHint, error: smsError, setError: setSmsError, clearMessages } =
useSmsCode();
@@ -73,6 +74,7 @@ export default function LoginPage() {
function ensureAgreed() {
if (!agreed) {
setMsg('请先勾选并同意用户协议');
agreementRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' });
return false;
}
return true;
@@ -194,6 +196,23 @@ export default function LoginPage() {
{displayMsg || sentHint}
</p>
)}
<label className="login-agreement" ref={agreementRef}>
<input
type="checkbox"
checked={agreed}
onChange={(e) => setAgreed(e.target.checked)}
/>
<span>
<Link to="/legal/user-agreement" onClick={(e) => e.stopPropagation()}>
</Link>
<Link to="/legal/privacy-policy" onClick={(e) => e.stopPropagation()}>
</Link>
</span>
</label>
<button
type="button"
className="login-sms-btn"
@@ -219,26 +238,6 @@ export default function LoginPage() {
</>
)}
</main>
<footer className="login-footer">
<label className="login-agreement">
<input
type="checkbox"
checked={agreed}
onChange={(e) => setAgreed(e.target.checked)}
/>
<span>
<Link to="/legal/user-agreement" onClick={(e) => e.stopPropagation()}>
</Link>
<Link to="/legal/privacy-policy" onClick={(e) => e.stopPropagation()}>
</Link>
</span>
</label>
</footer>
</div>
);
}
+4 -3
View File
@@ -1558,8 +1558,9 @@
.login-agreement {
display: flex;
align-items: center;
align-items: flex-start;
gap: 8px;
margin: 12px 0 16px;
font-family: var(--font-label);
font-size: 12px;
font-weight: 500;
@@ -1571,8 +1572,8 @@
.login-agreement input {
margin-top: 0;
width: 16px;
height: 16px;
width: 18px;
height: 18px;
flex-shrink: 0;
accent-color: var(--color-heritage-red);
}