47 lines
1.8 KiB
TypeScript
47 lines
1.8 KiB
TypeScript
'use client';
|
||
|
||
import Link from 'next/link';
|
||
import { useEffect, useState } from 'react';
|
||
import AppLogo from './AppLogo';
|
||
import BottomNav from './BottomNav';
|
||
import { apiRequest, ensureLogin } from '../lib/api';
|
||
import type { TestResult } from '../lib/types';
|
||
|
||
export default function Profile() {
|
||
const [results, setResults] = useState<TestResult[]>([]);
|
||
const [linkCode, setLinkCode] = useState('');
|
||
const [error, setError] = useState('');
|
||
useEffect(() => {
|
||
ensureLogin().then(() => apiRequest<TestResult[]>('/api/v1/me/results')).then(setResults).catch((error: Error) => setError(error.message));
|
||
}, []);
|
||
async function createLinkCode() {
|
||
try {
|
||
const data = await apiRequest<{ code: string }>('/api/v1/me/link-code', { method: 'POST' });
|
||
setLinkCode(data.code);
|
||
} catch (error) { setError(error instanceof Error ? error.message : '生成失败'); }
|
||
}
|
||
return (
|
||
<main className="pageShell profilePage">
|
||
<AppLogo title="我的偏爱档案" />
|
||
<section className="linkPanel">
|
||
<h2>连接独立饭类版</h2>
|
||
<p>生成一次性绑定码,在另一个小程序确认后合并历史。</p>
|
||
<button onClick={createLinkCode}>生成 10 分钟绑定码</button>
|
||
{linkCode ? <output>{linkCode}</output> : null}
|
||
</section>
|
||
<h2 className="sectionTitle">做过的测试 · {results.length}</h2>
|
||
{error ? <div className="emptyState">{error}</div> : null}
|
||
<section className="resultList">
|
||
{results.map(result => (
|
||
<Link key={result.id} href={`/results/${result.id}`} className="resultRow">
|
||
<span className="rankBadge">#1</span>
|
||
<span><small>{result.test_title}</small><strong>{result.champion_name}</strong></span>
|
||
<b>→</b>
|
||
</Link>
|
||
))}
|
||
</section>
|
||
<BottomNav />
|
||
</main>
|
||
);
|
||
}
|