diff --git a/services/frontend/src/pages/Competition/index.tsx b/services/frontend/src/pages/Competition/index.tsx
index 290e979..fe37509 100644
--- a/services/frontend/src/pages/Competition/index.tsx
+++ b/services/frontend/src/pages/Competition/index.tsx
@@ -2,40 +2,57 @@ import { useParams, Link, useNavigate } from "react-router-dom";
import { Button } from "@/components/ui/button";
import { ArrowLeft } from "lucide-react";
import ReactMarkdown from "react-markdown";
-import { mockTasks } from "@/shared/mocks/mocks";
-import { useQuery } from "@tanstack/react-query";
-import { getCompetition } from "@/shared/api/competitions";
+import { useQuery, useMutation } from "@tanstack/react-query";
+import { getCompetition, startCompetition } from "@/shared/api/competitions";
+import { getCompetitionTasks } from "@/shared/api/session";
import { Loading } from "@/components/ui/loading";
const CompetitionPage = () => {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
+ const competitionId = id || "";
- const { data: competition, isLoading } = useQuery({
- queryKey: ["competition", id],
- queryFn: async () => getCompetition(id || ""),
+ const competitionQuery = useQuery({
+ queryKey: ["competition", competitionId],
+ queryFn: () => getCompetition(competitionId),
+ enabled: !!competitionId,
});
- if (isLoading) {
+ const startMutation = useMutation({
+ mutationFn: () => startCompetition(competitionId),
+ onSuccess: async () => {
+ try {
+ const tasks = await getCompetitionTasks(competitionId);
+
+ if (tasks && tasks.length > 0) {
+ navigate(`/competition/${competitionId}/tasks/${tasks[0].id}`);
+ } else {
+ navigate(`/competition/${competitionId}/tasks`);
+ }
+ } catch (error) {
+ console.error("Failed to fetch tasks:", error);
+ navigate(`/competition/${competitionId}/tasks`);
+ }
+ },
+ onError: (error) => {
+ console.error("Failed to start competition:", error);
+ }
+ });
+
+ const handleStart = () => {
+ startMutation.mutate();
+ };
+
+ if (competitionQuery.isLoading) {
return ;
}
- if (!id || !competition) {
+ if (!competitionId || !competitionQuery.data) {
return <>>;
}
- const handleContinue = () => {
- if (competition?.id) {
- if (mockTasks && mockTasks.length > 0) {
- const firstTaskId = mockTasks[0].id;
- navigate(`/competition/${competition.id}/tasks/${firstTaskId}`);
- } else {
- navigate(`/competition/${competition.id}/tasks`);
- }
- }
- };
+ const competition = competitionQuery.data;
- console.log(competition)
return (
{
-
-

-
+ {competition.image_url && (
+
+

+
+ )}
@@ -65,8 +84,12 @@ const CompetitionPage = () => {
-
@@ -75,4 +98,4 @@ const CompetitionPage = () => {
);
};
-export default CompetitionPage;
+export default CompetitionPage;
\ No newline at end of file
diff --git a/services/frontend/src/shared/api/competitions.ts b/services/frontend/src/shared/api/competitions.ts
index 5a5eba0..8c47564 100644
--- a/services/frontend/src/shared/api/competitions.ts
+++ b/services/frontend/src/shared/api/competitions.ts
@@ -12,3 +12,9 @@ export const getCompetitions = async (participating?: boolean) => {
export const getCompetition = async (id: string) => {
return await userFetch
(`/competition/${id}`);
};
+
+export const startCompetition = async (competitionId: string) => {
+ return await userFetch(`/competitions/${competitionId}/start`, {
+ method: 'POST'
+ });
+};
\ No newline at end of file
diff --git a/services/frontend/src/shared/api/session.ts b/services/frontend/src/shared/api/session.ts
index 564e91a..0cc6383 100644
--- a/services/frontend/src/shared/api/session.ts
+++ b/services/frontend/src/shared/api/session.ts
@@ -1,82 +1,29 @@
-import { apiFetch } from './index';
-import { Task, TaskStatus } from '@/shared/types';
+import { userFetch } from ".";
+import { Task } from "../types/task";
-interface ApiTask {
- id: string;
- title: string;
- description: string;
- type: 'input' | 'file' | 'code';
- in_competition_position: number;
- points: number;
- status?: TaskStatus;
-}
-
-/**
- * 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 => {
- try {
- const apiTasks: ApiTask[] = await apiFetch(`/api/v1/competitions/${competitionId}/tasks`);
-
- // 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;
- }
+export const getCompetitionTasks = async (competitionId: string) => {
+ return await userFetch(`/competitions/${competitionId}/tasks`);
};
-/**
- * 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 => {
-// const endpoint = `/api/v1/competitions/${competitionId}/tasks/${taskId}/submit`;
+export const submitTaskSolution = async (
+ competitionId: string,
+ taskId: string,
+ solution: string | File
+) => {
+ const endpoint = `/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);
+ if (typeof solution === 'string') {
+ return await userFetch(endpoint, {
+ method: 'POST',
+ body: { answer: solution }
+ });
+ } else {
+ 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 => {
-// const response = await apiFetch(`/api/v1/competitions/${competitionId}/tasks/${taskId}/status`);
-// return response.status;
-// };
\ No newline at end of file
+ return await userFetch(endpoint, {
+ method: 'POST',
+ body: formData
+ });
+ }
+};
\ No newline at end of file