feat(resume): editable dates (items + education), profile-field quick save, panel independent scroll

This commit is contained in:
root
2026-10-17 13:15:13 +08:00
parent 4f7978b129
commit 603e39d2bd
16 changed files with 71 additions and 64 deletions
+15 -8
View File
@@ -90,6 +90,12 @@ export function ResumePage() {
});
};
const saveProfileField = (key: keyof ProfileInfo, v: string) => {
void profileUpsert({ info: { ...previewProfile, [key]: v } })
.then(() => profileQ.refetch())
.catch(e => toast('error', e.message));
};
// 一页限定
useEffect(() => {
if (!cfg.onePage) { setFitZoom(1); return; }
@@ -169,18 +175,17 @@ export function ResumePage() {
{sec.kind === 'edu' ? (
<div>
<div className="grid grid-cols-2 gap-x-8 gap-y-1 text-[12.5px]">
{([['学校', profile.school], ['专业', profile.major], ['学制', profile.eduLength], ['学历', profile.degree], ['入学', profile.eduStart], ['毕业', profile.eduEnd]] as [string, string | undefined][])
{([['学校', profile.school, 'school'], ['专业', profile.major, 'major'], ['学制', profile.eduLength, 'eduLength'], ['学历', profile.degree, 'degree'], ['入学', profile.eduStart, 'eduStart'], ['毕业', profile.eduEnd, 'eduEnd']] as [string, string | undefined, keyof ProfileInfo][])
.filter(r => r[1]).map(r => (
<div key={r[0]} className="flex gap-2"><span className="w-16 shrink-0 text-neutral-500">{r[0]}</span><span>{r[1]}</span></div>
<div key={r[0]} className="flex gap-2"><span className="w-16 shrink-0 text-neutral-500">{r[0]}</span>
<Ed html={r[1] ?? ''} onCommit={v => saveProfileField(r[2], v)} />
</div>
))}
</div>
{profile.majorCourses && (
<p className="mt-2.5 text-[12.5px] leading-relaxed text-neutral-700">
<b>主修课程:</b>
<Ed html={profile.majorCourses} onCommit={v => {
const next = { ...previewProfile, majorCourses: v };
void profileUpsert({ info: next }).then(() => profileQ.refetch()).catch(e => toast('error', e.message));
}} />
<Ed html={profile.majorCourses} onCommit={v => saveProfileField('majorCourses', v)} />
</p>
)}
</div>
@@ -204,7 +209,9 @@ export function ResumePage() {
<span className="text-[13px] font-semibold text-neutral-900 r-item-title">
<Ed html={it.title} onCommit={v => handleEdit({ secKey: sec.key, field: 'title', value: v, itemIdx, fromRecord: it.fromRecord })} />
</span>
<span className="num shrink-0 text-[11.5px] text-neutral-500">{it.date ?? ''}</span>
<span className="num shrink-0 text-[11.5px] text-neutral-500">
<Ed html={it.date ?? ''} onCommit={v => handleEdit({ secKey: sec.key, field: 'date', value: v, itemIdx, fromRecord: it.fromRecord })} />
</span>
</div>
{it.subtitle && <div className="text-[12px] text-neutral-600">{it.subtitle}</div>}
{it.desc && (
@@ -229,7 +236,7 @@ export function ResumePage() {
{/* 右侧设置面板(手机在下方) */}
{panelOpen && (
<div className="no-print flex flex-col gap-4 lg:sticky lg:top-4 lg:self-start">
<div className="no-print flex flex-col gap-4 lg:sticky lg:top-4 lg:max-h-[calc(100vh-2rem)] lg:self-start lg:overflow-y-auto lg:pr-1">
<Card>
<CardHeader title="模板与风格" />
<CardBody className="flex flex-col gap-3">