fix(profile): photo upload no longer wipes saved info; mobile layout polish for profile and resume

This commit is contained in:
root
2026-10-17 13:43:09 +08:00
parent 78bfe188b6
commit 6a97590f90
19 changed files with 71 additions and 70 deletions
+4 -3
View File
@@ -65,9 +65,10 @@ export function ProfilePage() {
setPhotoBusy(true);
try {
const url = await profilePhotoUpload(f);
const next = { ...EMPTY, ...form, photoUrl: url };
setForm(next);
// 以已保存档案为底,只更新 photoUrl —— 避免覆盖其他字段
const next = { ...EMPTY, ...info, photoUrl: url };
await profileUpsert({ info: next });
setForm(prev => ({ ...EMPTY, ...prev, photoUrl: url }));
void qc.invalidateQueries({ queryKey: ['profile'] });
toast('success', '证件照已上传');
} catch (e) { toast('error', (e as Error).message); }
@@ -78,7 +79,7 @@ export function ProfilePage() {
return (
<div className="mx-auto max-w-[880px] px-3 py-4 sm:px-6 sm:py-5">
<div className="mb-4 flex items-center justify-between">
<div className="mb-4 flex flex-wrap items-center justify-between gap-2">
<h2 className="text-[15px] font-semibold text-ink-1">个人信息</h2>
<Button variant="primary" onClick={openEdit}><Pencil size={13} /> 编辑</Button>
</div>
+6 -6
View File
@@ -17,7 +17,7 @@ function Ed({ html, onCommit, className }: { html: string; onCommit: (v: string)
contentEditable
suppressContentEditableWarning
spellCheck={false}
className={'outline-none rounded-sm transition-shadow focus:shadow-[0_0_0_1.5px_rgba(48,86,211,0.5)] cursor-text ' + (className ?? '')}
className={'outline-none break-words rounded-sm transition-shadow focus:shadow-[0_0_0_1.5px_rgba(48,86,211,0.5)] cursor-text ' + (className ?? '')}
dangerouslySetInnerHTML={{ __html: esc }}
onBlur={e => {
const v = (e.currentTarget.textContent ?? '').trim();
@@ -147,11 +147,11 @@ export function ResumePage() {
>
<div
ref={contentRef}
className={'p-8 sm:p-10 resume-tpl-' + cfg.template}
className={'min-w-0 overflow-x-hidden p-5 sm:p-10 resume-tpl-' + cfg.template}
style={{ zoom, '--accent': cfg.accent } as React.CSSProperties}
>
<div className="mb-6 flex items-start justify-between gap-6">
<div>
<div className="mb-6 flex items-start justify-between gap-4 sm:gap-6">
<div className="min-w-0 flex-1">
<h1 className={'text-[26px] font-bold leading-tight ' + (cfg.template === 'tech' ? 'text-[var(--accent)]' : 'text-neutral-900')}>
{profile.name || '姓名'}
</h1>
@@ -174,7 +174,7 @@ export function ResumePage() {
</div>
{sec.kind === 'edu' ? (
<div>
<div className="grid grid-cols-2 gap-x-8 gap-y-1 text-[12.5px]">
<div className="grid grid-cols-1 gap-x-8 gap-y-1 text-[12.5px] sm:grid-cols-2">
{([['学校', 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>
@@ -190,7 +190,7 @@ export function ResumePage() {
)}
</div>
) : sec.kind === 'info' ? (
<div className="grid grid-cols-2 gap-x-8 gap-y-1 text-[12.5px]">
<div className="grid grid-cols-1 gap-x-8 gap-y-1 text-[12.5px] sm:grid-cols-2">
{([['姓名', profile.name], ['性别', profile.gender], ['出生年月', profile.birth], ['民族', profile.nation],
['籍贯', profile.native], ['政治面貌', profile.political], ['班级', profile.className], ['学号', profile.studentId],
['手机', profile.phone], ['邮箱', profile.email]] as [string, string][]).filter(r => r[1]).map(r => (