fix:提交修复6个问题
This commit is contained in:
@@ -1,36 +1,129 @@
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useNavigate, Link } from 'react-router-dom';
|
||||
import type { PartnerLeaderboardPeriod, PartnerLeaderboardResponse } from '@dukang/shared-types';
|
||||
import PageHeader from '@dukang/shared-ui/PageHeader';
|
||||
import { LEADERBOARD_MOCK } from '../lib/leaderboard';
|
||||
import { fetchPartnerLeaderboard } from '../lib/leaderboard';
|
||||
import { usePartnerSession } from '../contexts/PartnerSessionContext';
|
||||
import { isPrimaryAccount } from '../lib/partnerAccess';
|
||||
|
||||
const PERIOD_TABS: { key: PartnerLeaderboardPeriod; label: string }[] = [
|
||||
{ key: 'month', label: '本月' },
|
||||
{ key: 'lastMonth', label: '上月' },
|
||||
{ key: 'total', label: '累计' },
|
||||
];
|
||||
|
||||
function periodStatLabel(period: PartnerLeaderboardPeriod): string {
|
||||
if (period === 'month') return '本月拓店';
|
||||
if (period === 'lastMonth') return '上月拓店';
|
||||
return '累计拓店';
|
||||
}
|
||||
|
||||
function periodSubLabel(period: PartnerLeaderboardPeriod): string {
|
||||
if (period === 'total') return '累计';
|
||||
if (period === 'month') return '本月新增';
|
||||
return '上月新增';
|
||||
}
|
||||
|
||||
export default function LeaderboardPage() {
|
||||
const navigate = useNavigate();
|
||||
const { account } = usePartnerSession();
|
||||
const showStaffFab = isPrimaryAccount(account);
|
||||
const [period, setPeriod] = useState<PartnerLeaderboardPeriod>('month');
|
||||
const [data, setData] = useState<PartnerLeaderboardResponse | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
setLoading(true);
|
||||
setError('');
|
||||
fetchPartnerLeaderboard(period)
|
||||
.then(setData)
|
||||
.catch((e) => {
|
||||
setData(null);
|
||||
setError(e instanceof Error ? e.message : '加载失败');
|
||||
})
|
||||
.finally(() => setLoading(false));
|
||||
}, [period]);
|
||||
|
||||
return (
|
||||
<div className="page-no-tab">
|
||||
<PageHeader title="合伙人贡献榜" onBack={() => navigate('/')} />
|
||||
|
||||
<p className="label-md text-muted" style={{ padding: '0 20px 12px' }}>
|
||||
按拓店数排行,数据每周更新
|
||||
</p>
|
||||
|
||||
<div style={{ padding: '0 20px 24px' }}>
|
||||
{LEADERBOARD_MOCK.map((entry) => (
|
||||
<div key={entry.rank} className="partner-leaderboard-row">
|
||||
<div className="partner-leaderboard-rank">{entry.rank}</div>
|
||||
<div className="partner-leaderboard-info">
|
||||
<p className="headline-md">
|
||||
{entry.name}
|
||||
<span className="label-md text-muted" style={{ marginLeft: 6, fontWeight: 400 }}>({entry.role})</span>
|
||||
</p>
|
||||
<p className="label-md text-muted">累计拓店 {entry.totalStores} 间</p>
|
||||
</div>
|
||||
<div className="partner-leaderboard-stat">
|
||||
<p className="headline-md text-primary">{entry.monthStores} 间</p>
|
||||
<p className="label-md text-muted">本月新增</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="partner-leaderboard-tabs">
|
||||
{PERIOD_TABS.map((tab) => (
|
||||
<button
|
||||
key={tab.key}
|
||||
type="button"
|
||||
className={`partner-leaderboard-tab${period === tab.key ? ' active' : ''}`}
|
||||
onClick={() => setPeriod(tab.key)}
|
||||
>
|
||||
{tab.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="label-md text-muted" style={{ padding: '0 20px 12px' }}>
|
||||
按拓店数排行,数据实时更新
|
||||
</p>
|
||||
|
||||
{loading && <div className="empty">加载中...</div>}
|
||||
{!loading && error && <div className="empty">{error}</div>}
|
||||
|
||||
{!loading && !error && data && (
|
||||
<div style={{ padding: '0 20px 96px' }}>
|
||||
{data.self && (
|
||||
<section className="partner-leaderboard-self-card">
|
||||
<div className="partner-leaderboard-self-main">
|
||||
<div className="partner-leaderboard-self-rank">第 {data.self.rank} 名</div>
|
||||
<div>
|
||||
<p className="headline-md" style={{ color: '#fff' }}>
|
||||
{data.self.name}
|
||||
{data.self.isSelf ? ' (我)' : ''}
|
||||
</p>
|
||||
<p className="label-md" style={{ color: 'rgba(255,255,255,0.8)' }}>{data.self.roleLabel}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="partner-leaderboard-self-stats">
|
||||
<span>{periodStatLabel(period)}: {data.self.periodStores} 间</span>
|
||||
{data.self.beatPercent != null && (
|
||||
<span>击败 {data.self.beatPercent}% 合伙人</span>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<h2 className="headline-md" style={{ margin: '16px 0 12px' }}>实时排行</h2>
|
||||
|
||||
{data.list.length === 0 ? (
|
||||
<div className="empty">暂无排行数据</div>
|
||||
) : (
|
||||
data.list.map((entry) => (
|
||||
<div key={entry.accountId} className="partner-leaderboard-row">
|
||||
<div className="partner-leaderboard-rank">{entry.rank}</div>
|
||||
<div className="partner-leaderboard-info">
|
||||
<p className="headline-md">
|
||||
{entry.name}
|
||||
<span className="label-md text-muted" style={{ marginLeft: 6, fontWeight: 400 }}>
|
||||
({entry.roleLabel})
|
||||
</span>
|
||||
</p>
|
||||
<p className="label-md text-muted">累计拓店 {entry.totalStores} 间</p>
|
||||
</div>
|
||||
<div className="partner-leaderboard-stat">
|
||||
<p className="headline-md text-primary">{entry.periodStores} 间</p>
|
||||
<p className="label-md text-muted">{periodSubLabel(period)}</p>
|
||||
</div>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showStaffFab && (
|
||||
<Link to="/center/staff" className="partner-fab-round" aria-label="子账号管理">
|
||||
<span className="material-symbols-outlined">add</span>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user