feat: 发布 v0.5.0 加密存储与匿名同步

This commit is contained in:
2026-06-23 01:48:01 +02:00
parent 81a70137a9
commit e3825c5a4e
20 changed files with 1091 additions and 70 deletions
+80
View File
@@ -0,0 +1,80 @@
'use client';
import { FormEvent, useState } from 'react';
import { useRouter } from 'next/navigation';
import { Cloud, HardDrive, Loader2 } from 'lucide-react';
import { toast } from 'sonner';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { loginAnonymousProfile } from '@/lib/anonymous-client';
export function HomeModeSelector() {
const router = useRouter();
const [codeName, setCodeName] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const startLocal = () => {
router.push('/questionnaire');
};
const startAnonymous = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
setLoading(true);
try {
await loginAnonymousProfile({ codeName: codeName.trim(), password });
toast.success('已进入匿名加密档案');
router.push('/questionnaire');
} catch (error) {
toast.error(error instanceof Error ? error.message : '匿名档案进入失败');
} finally {
setLoading(false);
}
};
return (
<div className="grid gap-3">
<div className="border p-4">
<div className="mb-3 flex items-center gap-2 font-medium">
<HardDrive className="h-4 w-4" />
</div>
<p className="mb-4 text-sm leading-6 text-muted-foreground">
使
</p>
<Button className="w-full" onClick={startLocal}>
</Button>
</div>
<form className="border p-4" onSubmit={startAnonymous}>
<div className="mb-3 flex items-center gap-2 font-medium">
<Cloud className="h-4 w-4" />
</div>
<p className="mb-4 text-sm leading-6 text-muted-foreground">
</p>
<div className="grid gap-2">
<Input
value={codeName}
onChange={(event) => setCodeName(event.target.value)}
placeholder="代号,不填真实姓名"
autoComplete="username"
/>
<Input
value={password}
onChange={(event) => setPassword(event.target.value)}
placeholder="恢复口令"
type="password"
autoComplete="current-password"
/>
<Button className="w-full" disabled={loading || !codeName.trim() || password.length < 4}>
{loading ? <Loader2 className="h-4 w-4 animate-spin" /> : <Cloud className="h-4 w-4" />}
</Button>
</div>
</form>
</div>
);
}