Merge branch 'master' of gitlab.prodcontest.ru:team-15/project

This commit is contained in:
moolcoov
2025-03-02 17:53:28 +03:00
75 changed files with 1596 additions and 965 deletions
@@ -12,3 +12,9 @@ export const getCompetitions = async (participating?: boolean) => {
export const getCompetition = async (id: string) => {
return await userFetch<Competition>(`/competition/${id}`);
};
export const startCompetition = async (competitionId: string) => {
return await userFetch(`/competitions/${competitionId}/start`, {
method: 'POST'
});
};
+33 -78
View File
@@ -1,82 +1,37 @@
import { apiFetch } from './index';
import { Task, TaskStatus } from '@/shared/types';
import { userFetch } from ".";
import { Task, Solution, TaskAttachment } from "../types/task";
interface ApiTask {
id: string;
title: string;
description: string;
type: 'input' | 'file' | 'code';
in_competition_position: number;
points: number;
status?: TaskStatus;
}
export const getCompetitionTasks = async (competitionId: string) => {
return await userFetch<Task[]>(`/competitions/${competitionId}/tasks`);
};
/**
* Fetches tasks for a specific competition
* @param competitionId - The ID of the competition
* @returns Promise with an array of tasks in the application's format
*/
export const getCompetitionTasks = async (competitionId: string): Promise<Task[]> => {
try {
const apiTasks: ApiTask[] = await apiFetch(`/api/v1/competitions/${competitionId}/tasks`);
export const getTaskSolutionHistory = async (competitionId: string, taskId: string) => {
return await userFetch<Solution[]>(`/competitions/${competitionId}/tasks/${taskId}/history`);
};
export const getTaskAttachments = async (competitionId: string, taskId: string) => {
return await userFetch<TaskAttachment[]>(`/competitions/${competitionId}/tasks/${taskId}/attachments`);
};
export const submitTaskSolution = async (
competitionId: string,
taskId: string,
solution: string | File
) => {
const endpoint = `/competitions/${competitionId}/tasks/${taskId}/submit`;
if (typeof solution === 'string') {
return await userFetch(endpoint, {
method: 'POST',
body: { content: solution }
});
} else {
const formData = new FormData();
formData.append('file', solution);
// Transform API tasks to application Task format
return apiTasks.map(apiTask => transformApiTask(apiTask));
} catch (error) {
console.error('Failed to fetch competition tasks:', error);
throw error;
return await userFetch(endpoint, {
method: 'POST',
body: formData
});
}
};
/**
* Transforms an API task to the application's Task format
*/
const transformApiTask = (apiTask: ApiTask): Task => {
return {
id: apiTask.id,
number: String(apiTask.in_competition_position),
status: apiTask.status || TaskStatus.Uncleared,
solutionType: apiTask.type,
description: apiTask.description,
maxScore: apiTask.points
};
};
// export const submitTaskSolution = async (
// competitionId: string,
// taskId: string,
// solution: string | File
// ): Promise<void> => {
// const endpoint = `/api/v1/competitions/${competitionId}/tasks/${taskId}/submit`;
// // Handle different solution types
// if (typeof solution === 'string') {
// // Text or code solution
// await apiFetch(endpoint, {
// method: 'POST',
// body: { answer: solution }
// });
// } else {
// // File solution
// const formData = new FormData();
// formData.append('file', solution);
// await apiFetch(endpoint, {
// method: 'POST',
// body: formData
// });
// }
// };
/**
* Gets the status of a task submission
* This would be used to poll for updates after submission
*/
// export const getTaskSubmissionStatus = async (
// competitionId: string,
// taskId: string
// ): Promise<TaskStatus> => {
// const response = await apiFetch(`/api/v1/competitions/${competitionId}/tasks/${taskId}/status`);
// return response.status;
// };
};