feat: 培训业务 Web(Vite+React)
- user 端:课程/活动/报名/测评/政策/调研 - 后端已并入 server-core/app/training,/api/* 走 opc.pinesound.cn
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import React from 'react';
|
||||
import { ContentTemplate } from '@/components/templates';
|
||||
import { SectionHead, FieldText, FieldSelect, FieldCheck, Button, Icon } from '@/components/atoms';
|
||||
import AuthGate from '@/components/AuthGate';
|
||||
import { getUser, updateProfile } from '@/services/auth';
|
||||
import { BK_STATUS_OPTIONS, BK_TOPIC_OPTIONS, BK_SOURCE_OPTIONS } from '@/data/booking';
|
||||
import '@/styles/booking.css';
|
||||
|
||||
/* 个人中心:报名资料设置(姓名/状态/主题/来源),报名时自动带入 */
|
||||
export default function Profile() {
|
||||
const [authed, setAuthed] = React.useState(!!getUser());
|
||||
const user = getUser() || {};
|
||||
const [form, setForm] = React.useState({
|
||||
name: user.name || '',
|
||||
status: user.status || '',
|
||||
topics: user.topics || [],
|
||||
source: user.source || ''
|
||||
});
|
||||
const [msg, setMsg] = React.useState('');
|
||||
const [err, setErr] = React.useState('');
|
||||
const [busy, setBusy] = React.useState(false);
|
||||
const set = (k) => (v) => setForm((f) => ({ ...f, [k]: v }));
|
||||
|
||||
const save = async (e) => {
|
||||
e.preventDefault();
|
||||
setErr(''); setMsg(''); setBusy(true);
|
||||
try {
|
||||
const r = await updateProfile({ name: form.name.trim(), status: form.status, topics: form.topics, source: form.source });
|
||||
if (r.ok) { setMsg('已保存,报名时将自动带入。'); }
|
||||
else throw new Error(r.detail || r.error || '保存失败');
|
||||
setAuthed(true); // 若此前未登录,登录卡回来就刷新
|
||||
} catch (ex) {
|
||||
setErr(ex && ex.message ? ex.message : '保存失败,请重试');
|
||||
} finally { setBusy(false); }
|
||||
};
|
||||
|
||||
if (!authed) {
|
||||
return (
|
||||
<ContentTemplate active="profile" kicker="Profile" title="个人中心" desc="完善报名资料,报名活动时自动带入,无需重复填写。">
|
||||
<section className="section">
|
||||
<AuthGate subtitle="登录后可设置并保存报名资料,报名活动自动带入。" onAuthed={() => setAuthed(true)} />
|
||||
{err && <div className="bk-err">{err}</div>}
|
||||
</section>
|
||||
</ContentTemplate>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ContentTemplate active="profile" kicker="Profile" title="个人中心" desc="完善报名资料,报名活动时自动带入,无需重复填写。">
|
||||
<section className="section">
|
||||
<SectionHead no="01" title="报名资料" en="Profile" />
|
||||
<form className="form-card" onSubmit={save}>
|
||||
<FieldText label="姓名 / 称呼" placeholder="怎么称呼你" value={form.name} onChange={set('name')} />
|
||||
<FieldSelect label="你的状态" options={BK_STATUS_OPTIONS} value={form.status} onChange={set('status')} />
|
||||
<FieldCheck label="感兴趣的主题(可多选)" options={BK_TOPIC_OPTIONS} value={form.topics} onChange={set('topics')} />
|
||||
<FieldSelect label="从哪知道我们" options={BK_SOURCE_OPTIONS} value={form.source} onChange={set('source')} />
|
||||
{msg && <div className="bk-ok"><Icon name="check" size="sm" /> {msg}</div>}
|
||||
{err && <div className="bk-err">{err}</div>}
|
||||
<div className="form-actions">
|
||||
<button className="btn btn-cta" type="submit" disabled={busy}>{busy ? '保存中…' : '保存资料'}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
</ContentTemplate>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user