Files
digital-pilates/services/challengesApi.ts
richarjiang 31c4e4fafa feat(challenges): 移除进度徽章与副标题并动态计算剩余天数
- 使用 dayjs 实时计算挑战结束剩余天数,替代接口返回的固定值
- 删除 badge、subtitle 字段及相关渲染逻辑,简化 UI
- 注释掉未使用的打卡操作区块,保持界面整洁
2025-09-29 10:25:22 +08:00

65 lines
1.8 KiB
TypeScript

import { api } from './api';
export type ChallengeStatus = 'upcoming' | 'ongoing' | 'expired';
export type ChallengeProgressDto = {
completed: number;
target: number;
remaining: number
};
export type RankingItemDto = {
id: string;
name: string;
avatar: string | null;
metric: string;
badge?: string;
};
export type ChallengeListItemDto = {
id: string;
title: string;
image: string;
periodLabel?: string;
durationLabel: string;
requirementLabel: string;
status: ChallengeStatus;
participantsCount: number;
rankingDescription?: string;
highlightTitle: string;
highlightSubtitle: string;
ctaLabel: string;
progress?: ChallengeProgressDto;
isJoined: boolean;
startAt?: string;
endAt?: string;
minimumCheckInDays: number; // 最小打卡天数
};
export type ChallengeDetailDto = ChallengeListItemDto & {
summary?: string;
rankings: RankingItemDto[];
userRank?: number;
};
export async function listChallenges(): Promise<ChallengeListItemDto[]> {
return api.get<ChallengeListItemDto[]>('/challenges');
}
export async function getChallengeDetail(id: string): Promise<ChallengeDetailDto> {
return api.get<ChallengeDetailDto>(`/challenges/${encodeURIComponent(id)}`);
}
export async function joinChallenge(id: string): Promise<ChallengeProgressDto> {
return api.post<ChallengeProgressDto>(`/challenges/${encodeURIComponent(id)}/join`);
}
export async function leaveChallenge(id: string): Promise<boolean> {
return api.post<boolean>(`/challenges/${encodeURIComponent(id)}/leave`);
}
export async function reportChallengeProgress(id: string, increment?: number): Promise<ChallengeProgressDto> {
const body = increment != null ? { increment } : undefined;
return api.post<ChallengeProgressDto>(`/challenges/${encodeURIComponent(id)}/progress`, body);
}