cherry2250 974961e1bd 이벤트 목록 Mock 데이터 적용 및 Participation API 연동
- 이벤트 목록 페이지에 Mock 데이터 적용 (evt_2025012301 등 4개 이벤트)
- 이벤트 상세 페이지 Analytics API 임시 주석처리 (서버 이슈)
- Participation API 프록시 라우트 URL 구조 수정 (/events/ 제거)
- EventID localStorage 저장 기능 추가
- 상세한 console.log 추가 (생성된 eventId, objective, timestamp)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-30 20:17:09 +09:00

143 lines
3.4 KiB
TypeScript

import axios, { AxiosInstance } from 'axios';
import type {
ParticipationRequest,
ParticipationResponse,
ApiResponse,
PageResponse,
DrawWinnersRequest,
DrawWinnersResponse,
} from '../model/types';
// Use Next.js API proxy to bypass CORS issues
const PARTICIPATION_API_BASE = '/api/participations';
const participationApiClient: AxiosInstance = axios.create({
baseURL: PARTICIPATION_API_BASE,
timeout: 90000,
headers: {
'Content-Type': 'application/json',
},
});
// Request interceptor
participationApiClient.interceptors.request.use(
(config) => {
console.log('🎫 Participation API Request:', {
method: config.method?.toUpperCase(),
url: config.url,
baseURL: config.baseURL,
});
const token = localStorage.getItem('accessToken');
if (token && config.headers) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
(error) => {
console.error('❌ Participation API Request Error:', error);
return Promise.reject(error);
}
);
// Response interceptor
participationApiClient.interceptors.response.use(
(response) => {
console.log('✅ Participation API Response:', {
status: response.status,
url: response.config.url,
});
return response;
},
(error) => {
console.error('❌ Participation API Error:', {
message: error.message,
status: error.response?.status,
url: error.config?.url,
});
return Promise.reject(error);
}
);
/**
* Participation API Service
* 이벤트 참여 관리 API
*/
export const participationApi = {
/**
* 이벤트 참여
*/
participate: async (
eventId: string,
data: ParticipationRequest
): Promise<ApiResponse<ParticipationResponse>> => {
const response = await participationApiClient.post<
ApiResponse<ParticipationResponse>
>(`/${eventId}/participate`, data);
return response.data;
},
/**
* 참여자 목록 조회
*/
getParticipants: async (
eventId: string,
params?: {
storeVisited?: boolean;
page?: number;
size?: number;
sort?: string[];
}
): Promise<ApiResponse<PageResponse<ParticipationResponse>>> => {
const response = await participationApiClient.get<
ApiResponse<PageResponse<ParticipationResponse>>
>(`/${eventId}/participants`, { params });
return response.data;
},
/**
* 특정 참여자 조회
*/
getParticipant: async (
eventId: string,
participantId: string
): Promise<ApiResponse<ParticipationResponse>> => {
const response = await participationApiClient.get<
ApiResponse<ParticipationResponse>
>(`/${eventId}/participants/${participantId}`);
return response.data;
},
/**
* 당첨자 추첨
*/
drawWinners: async (
eventId: string,
data: DrawWinnersRequest
): Promise<ApiResponse<DrawWinnersResponse>> => {
const response = await participationApiClient.post<
ApiResponse<DrawWinnersResponse>
>(`/${eventId}/draw-winners`, data);
return response.data;
},
/**
* 당첨자 목록 조회
*/
getWinners: async (
eventId: string,
params?: {
page?: number;
size?: number;
sort?: string[];
}
): Promise<ApiResponse<PageResponse<ParticipationResponse>>> => {
const response = await participationApiClient.get<
ApiResponse<PageResponse<ParticipationResponse>>
>(`/${eventId}/winners`, { params });
return response.data;
},
};
export default participationApi;