- account settings: sidebar sections (profile, devices, security, invitations, sync and sign-in) instead of one long scroll; inline device rename, confirmations for destructive actions and toast feedback - sign-in/register: split layout with a quiet brand column, text tabs and underlined inputs; registering asks for the password twice and explains that it cannot be recovered - move invitation accept/label helpers into store/invitations so the toast and the settings inbox share them - add the home page zone styles used by the next commit
44 lines
2.3 KiB
TypeScript
44 lines
2.3 KiB
TypeScript
import { navigate } from '@/app/navigation';
|
|
import { errorMessage } from '@/core-bridge/errors';
|
|
import { useAccount } from '@/store/account';
|
|
import { useToast } from '@/store/toast';
|
|
import { Button } from '@/ui/Button';
|
|
import styles from './AccountSettings.module.css';
|
|
|
|
export function SyncSettings() {
|
|
const busy = useAccount((s) => s.busy);
|
|
const remembered = useAccount((s) => s.remembered);
|
|
const sync = useAccount((s) => s.sync);
|
|
const logout = useAccount((s) => s.logout);
|
|
const clearSavedLogin = useAccount((s) => s.clearSavedLogin);
|
|
const toast = useToast.getState().push;
|
|
|
|
async function syncNow() {
|
|
try { await sync(); toast({ kind: 'ok', text: '资源保险库已同步' }); }
|
|
catch (cause) { toast({ kind: 'error', text: `同步失败:${errorMessage(cause)}` }); }
|
|
}
|
|
async function clearSaved() {
|
|
if (!window.confirm('清除本机保存的账号和密码?当前页面仍可使用,刷新后需要重新登录。')) return;
|
|
try { await clearSavedLogin(); toast({ kind: 'ok', text: '已清除本机保存的登录信息' }); }
|
|
catch (cause) { toast({ kind: 'error', text: errorMessage(cause) }); }
|
|
}
|
|
async function signOut() {
|
|
if (!window.confirm('退出登录?')) return;
|
|
await logout();
|
|
navigate('/');
|
|
}
|
|
|
|
return <section className={styles.page} aria-label="同步与登录">
|
|
<h2>同步与登录</h2>
|
|
<div className={styles.group}>
|
|
<div className={styles.groupText}><strong>资源保险库</strong><small>空间与分享的访问凭据在本机加密后同步,换设备登录即可恢复。</small></div>
|
|
<Button disabled={busy} onClick={() => { void syncNow(); }}>{busy ? '同步中…' : '立即同步'}</Button>
|
|
</div>
|
|
<div className={styles.group}>
|
|
<div className={styles.groupText}><strong>本机记住登录</strong><small>{remembered ? '已开启:刷新页面后自动恢复登录。只在自己的设备上使用。' : '未开启:刷新或关闭页面后需要重新登录。'}</small></div>
|
|
{remembered ? <Button disabled={busy} onClick={() => { void clearSaved(); }}>清除本机保存</Button> : null}
|
|
</div>
|
|
<div className={styles.footer}><Button className={styles.danger} variant="ghost" disabled={busy} onClick={() => { void signOut(); }}>退出登录</Button></div>
|
|
</section>;
|
|
}
|