145 lines
5.9 KiB
TypeScript
145 lines
5.9 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import { Link } from 'react-router-dom';
|
|
import { request } from '../lib/api';
|
|
import { usePartnerSession } from '../contexts/PartnerSessionContext';
|
|
import { contactSupport } from '../lib/contact';
|
|
import { isPrimaryAccount } from '../lib/partnerAccess';
|
|
import { toastError } from '../lib/toast';
|
|
|
|
type CenterPageProps = {
|
|
/** 子账号个人中心复用 */
|
|
variant?: 'primary' | 'sub';
|
|
roleLabel?: string;
|
|
};
|
|
|
|
export default function CenterPage({ variant = 'primary', roleLabel }: CenterPageProps) {
|
|
const { account, logout, refresh } = usePartnerSession();
|
|
const isPrimary = variant === 'primary' && isPrimaryAccount(account);
|
|
const [name, setName] = useState(account?.name ?? '');
|
|
const [saving, setSaving] = useState(false);
|
|
|
|
useEffect(() => {
|
|
document.title = isPrimary ? '合伙人中心' : '个人中心';
|
|
}, [isPrimary]);
|
|
|
|
useEffect(() => {
|
|
setName(account?.name ?? '');
|
|
}, [account?.name]);
|
|
|
|
async function handleSave() {
|
|
const trimmed = name.trim();
|
|
if (!trimmed) {
|
|
toastError('请输入姓名');
|
|
return;
|
|
}
|
|
if (trimmed === account?.name) return;
|
|
setSaving(true);
|
|
try {
|
|
await request('PARTNER_H5', '/partner/me', {
|
|
method: 'PUT',
|
|
body: JSON.stringify({ name: trimmed }),
|
|
});
|
|
await refresh();
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
}
|
|
|
|
function handleContactPartner() {
|
|
if (isPrimary) {
|
|
if (!contactSupport()) toastError('暂无客服电话');
|
|
return;
|
|
}
|
|
if (!account?.primaryPhone) {
|
|
toastError('暂无合伙人联系方式');
|
|
return;
|
|
}
|
|
window.location.href = `tel:${account.primaryPhone}`;
|
|
}
|
|
|
|
return (
|
|
<div className="page partner-center-page partner-home--flush-top">
|
|
<section className="partner-profile-card">
|
|
<div className="partner-profile-avatar">
|
|
<span className="material-symbols-outlined">person</span>
|
|
</div>
|
|
<div style={{ flex: 1 }}>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
|
<h2 className="headline-lg" style={{ fontSize: 20 }}>{account?.name || '合伙人'}</h2>
|
|
<span className="partner-role-badge">{roleLabel || (isPrimary ? '城市合伙人' : '拓店员')}</span>
|
|
</div>
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 4, marginTop: 4, color: 'var(--color-subtle-gray)' }}>
|
|
<span className="material-symbols-outlined" style={{ fontSize: 16 }}>location_on</span>
|
|
<span className="body-md">{account?.companyName || '—'}</span>
|
|
</div>
|
|
<p className="label-md text-muted" style={{ marginTop: 4 }}>{account?.phone || ''}</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="partner-menu-section">
|
|
<h3 className="headline-md" style={{ marginBottom: 8 }}>个人信息设置</h3>
|
|
<div className="partner-menu-card" style={{ padding: '16px' }}>
|
|
<label className="partner-form-label" htmlFor="center-name">姓名</label>
|
|
<input
|
|
id="center-name"
|
|
className="partner-form-input"
|
|
value={name}
|
|
onChange={(e) => setName(e.target.value)}
|
|
placeholder="请输入姓名"
|
|
maxLength={32}
|
|
/>
|
|
<label className="partner-form-label" style={{ marginTop: 16 }}>手机号</label>
|
|
<input className="partner-form-input" value={account?.phone ?? ''} readOnly disabled />
|
|
<p className="label-md text-muted" style={{ marginTop: 4 }}>手机号由管理员维护,如需修改请联系总部</p>
|
|
<button
|
|
type="button"
|
|
className="partner-btn-primary"
|
|
style={{ width: '100%', marginTop: 16 }}
|
|
disabled={saving}
|
|
onClick={() => void handleSave()}
|
|
>
|
|
{saving ? '保存中…' : '保存资料'}
|
|
</button>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="partner-menu-section">
|
|
<div className="partner-menu-card">
|
|
<button type="button" className="partner-menu-item" onClick={() => { if (!contactSupport()) toastError('暂无客服电话'); }}>
|
|
<div className="partner-menu-item-left">
|
|
<div className="partner-menu-icon"><span className="material-symbols-outlined">support_agent</span></div>
|
|
<span className="body-md" style={{ fontSize: 16 }}>联系客服</span>
|
|
</div>
|
|
<span className="material-symbols-outlined text-muted">chevron_right</span>
|
|
</button>
|
|
<button type="button" className="partner-menu-item" onClick={handleContactPartner}>
|
|
<div className="partner-menu-item-left">
|
|
<div className="partner-menu-icon"><span className="material-symbols-outlined">call</span></div>
|
|
<span className="body-md" style={{ fontSize: 16 }}>{isPrimary ? '联系总部' : '联系合伙人'}</span>
|
|
</div>
|
|
<span className="material-symbols-outlined text-muted">chevron_right</span>
|
|
</button>
|
|
{isPrimary && (
|
|
<Link to="/center/staff" className="partner-menu-item">
|
|
<div className="partner-menu-item-left">
|
|
<div className="partner-menu-icon"><span className="material-symbols-outlined">group</span></div>
|
|
<span className="body-md" style={{ fontSize: 16 }}>子账号管理</span>
|
|
</div>
|
|
<span className="material-symbols-outlined text-muted">chevron_right</span>
|
|
</Link>
|
|
)}
|
|
</div>
|
|
</section>
|
|
|
|
<button type="button" className="partner-logout-btn" onClick={logout}>
|
|
<span className="material-symbols-outlined">logout</span>
|
|
退出登录
|
|
</button>
|
|
|
|
<div style={{ textAlign: 'center', opacity: 0.3, padding: '32px 0' }}>
|
|
<p className="label-md text-muted">传承千年 · 杜康好客</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|