feat(challenges): 新增挑战详情页与排行榜及轮播卡片交互
- 重构挑战列表为横向轮播,支持多进行中的挑战 - 新增挑战详情页 /challenges/[id]/index 与排行榜 /challenges/[id]/leaderboard - ChallengeProgressCard 支持小时级剩余时间显示 - 新增 ChallengeRankingItem 组件展示榜单项 - 排行榜支持分页加载、下拉刷新与错误重试 - 挑战卡片新增已结束角标与渐变遮罩 - 加入/退出挑战时展示庆祝动画与错误提示 - 统一背景渐变色与卡片阴影细节
This commit is contained in:
@@ -15,6 +15,8 @@ export type RankingItemDto = {
|
||||
avatar: string | null;
|
||||
metric: string;
|
||||
badge?: string;
|
||||
todayReportedValue?: number;
|
||||
todayTargetValue?: number;
|
||||
};
|
||||
|
||||
export enum ChallengeType {
|
||||
@@ -55,6 +57,13 @@ export type ChallengeDetailDto = ChallengeListItemDto & {
|
||||
userRank?: number;
|
||||
};
|
||||
|
||||
export type ChallengeRankingsDto = {
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
items: RankingItemDto[];
|
||||
};
|
||||
|
||||
export async function listChallenges(): Promise<ChallengeListItemDto[]> {
|
||||
return api.get<ChallengeListItemDto[]>('/challenges');
|
||||
}
|
||||
@@ -75,3 +84,19 @@ export async function reportChallengeProgress(id: string, value?: number): Promi
|
||||
const body = value != null ? { value } : undefined;
|
||||
return api.post<ChallengeProgressDto>(`/challenges/${encodeURIComponent(id)}/progress`, body);
|
||||
}
|
||||
|
||||
export async function getChallengeRankings(
|
||||
id: string,
|
||||
params?: { page?: number; pageSize?: number }
|
||||
): Promise<ChallengeRankingsDto> {
|
||||
const searchParams = new URLSearchParams();
|
||||
if (params?.page) {
|
||||
searchParams.append('page', String(params.page));
|
||||
}
|
||||
if (params?.pageSize) {
|
||||
searchParams.append('pageSize', String(params.pageSize));
|
||||
}
|
||||
const query = searchParams.toString();
|
||||
const url = `/challenges/${encodeURIComponent(id)}/rankings${query ? `?${query}` : ''}`;
|
||||
return api.get<ChallengeRankingsDto>(url);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user