From 8103bfd266eb83532dc59faf7eb33dc16acb27a4 Mon Sep 17 00:00:00 2001 From: MikiVL Date: Tue, 5 May 2026 12:53:24 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=99=BB=E5=BD=95/=E6=B3=A8=E5=86=8C/?= =?UTF-8?q?=E9=82=80=E8=AF=B7=E7=A0=81=E6=BF=80=E6=B4=BB=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/auth/LoginModal.tsx | 137 +++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 src/components/auth/LoginModal.tsx diff --git a/src/components/auth/LoginModal.tsx b/src/components/auth/LoginModal.tsx new file mode 100644 index 0000000..7061a72 --- /dev/null +++ b/src/components/auth/LoginModal.tsx @@ -0,0 +1,137 @@ +import { useState } from 'react' +import { X } from 'lucide-react' +import { apiLogin, apiRegister, apiActivate, setToken } from '../../lib/auth' +import { useAppStore } from '../../stores/appStore' + +type Tab = 'login' | 'register' | 'activate' + +export function LoginModal({ onClose, initialTab }: { onClose: () => void; initialTab?: Tab }) { + const [tab, setTab] = useState(initialTab ?? 'login') + const [username, setUsername] = useState('') + const [password, setPassword] = useState('') + const [code, setCode] = useState('') + const [error, setError] = useState('') + const [loading, setLoading] = useState(false) + const { setCurrentUser, syncFromCloud, currentUser } = useAppStore() + + async function handleSubmit(e: React.FormEvent) { + e.preventDefault() + setError('') + setLoading(true) + try { + if (tab === 'login') { + const { token, user } = await apiLogin(username, password) + setToken(token) + setCurrentUser(user) + if (user.cloudEnabled) await syncFromCloud() + onClose() + } else if (tab === 'register') { + const { token, user } = await apiRegister(username, password) + setToken(token) + setCurrentUser(user) + onClose() + } else { + await apiActivate(code) + setCurrentUser({ ...currentUser!, cloudEnabled: true }) + await syncFromCloud() + onClose() + } + } catch (err: any) { + setError(err.message) + } finally { + setLoading(false) + } + } + + const inputStyle = { + background: 'var(--bg-muted)', + border: '1px solid var(--border)', + color: 'var(--text)', + width: '100%', + padding: '0.5rem 0.75rem', + borderRadius: '0.5rem', + fontSize: '0.875rem', + outline: 'none', + } + + return ( +
+
e.stopPropagation()} + > +
+

+ {tab === 'login' ? '登录' : tab === 'register' ? '注册' : '激活云存储'} +

+ +
+ + {tab !== 'activate' && ( +
+ {(['login', 'register'] as Tab[]).map(t => ( + + ))} +
+ )} + +
+ {tab !== 'activate' ? ( + <> + setUsername(e.target.value)} + autoFocus + /> + setPassword(e.target.value)} + /> + + ) : ( + setCode(e.target.value)} + autoFocus + /> + )} + + {error &&

{error}

} + + +
+
+
+ ) +}