diff --git a/.prettierignore b/.prettierignore index f9e671f..711d77f 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,5 @@ node_modules/ /dist/ /pnpm-lock.yaml /postcss.config.cjs + +src/components/Languages.tsx diff --git a/src/app/services/submission.ts b/src/app/services/submission.ts new file mode 100644 index 0000000..5fcb548 --- /dev/null +++ b/src/app/services/submission.ts @@ -0,0 +1,38 @@ +import type { Meta, Wrap } from "./base"; +import type { UserProfile } from "./user"; +import type { ProblemInfo } from "./problem"; +import { api } from "./api"; + +export interface SubmissionInfo { + meta: Meta; + problem: ProblemInfo; + user: UserProfile; + language: string; + code: string; +} + +export interface SubmitRequest { + pid: number; + language: string; + code: string; +} + +export interface ReJudgeResponse { + sid: number; +} + +export const submissionApi = api.injectEndpoints({ + endpoints: (builder) => ({ + submit: builder.mutation, SubmitRequest>({ + query: (data: SubmitRequest) => ({ + url: "/submission/create", + method: "POST", + body: data, + }), + invalidatesTags: [{ type: "Status", id: "Search" }], + }), + }), + // TODO: admin endpoints: rejudge +}); + +export const { useSubmitMutation } = submissionApi; diff --git a/src/components/Languages.tsx b/src/components/Languages.tsx new file mode 100644 index 0000000..976a37b --- /dev/null +++ b/src/components/Languages.tsx @@ -0,0 +1,10 @@ +/* eslint-disable prettier/prettier */ +export const LanguageMap: { [lang: string]: { label: string; mode: string; prism: string } } = { + c: { label: "C", mode: "c_cpp", prism: "cpp" }, + cpp: { label: "C++", mode: "c_cpp", prism: "cpp" }, + python3: { label: "Python3", mode: "python", prism: "python" }, + pypy3: { label: "PyPy3", mode: "python", prism: "python" }, + rust: { label: "Rust", mode: "rust", prism: "rust" }, + go: { label: "Go", mode: "golang", prism: "go" }, +}; +/* eslint-enable prettier/prettier */ diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index bec9da5..3eabba0 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -85,7 +85,7 @@ export default function LoginPage() { try { // authSlice will automatically handle the response - await login(formState).unwrap(); + await login(formState); navigate("/"); } catch (err) { const errTyped = err as { status: number | string; data: Wrap }; diff --git a/src/pages/SubmitPage.tsx b/src/pages/SubmitPage.tsx new file mode 100644 index 0000000..1de1ccc --- /dev/null +++ b/src/pages/SubmitPage.tsx @@ -0,0 +1,65 @@ +import { lazy, useEffect, useState } from "react"; +import { Box, Button, Stack, useToast } from "@chakra-ui/react"; +import { useNavigate, useParams } from "react-router-dom"; +import { MdPlayCircleOutline } from "react-icons/md"; + +import { LanguageMap } from "../components/Languages"; +import { useDetailQuery } from "../app/services/problem"; +import { useSubmitMutation } from "../app/services/submission"; + +const Editor = lazy(() => import("../components/Editor")); +const ProblemInfoMenu = lazy(() => import("../components/ProblemInfoMenu")); + +export default function SubmitPage() { + const { id } = useParams(); + const toast = useToast(); + const navigate = useNavigate(); + const { data: details } = useDetailQuery({ pid: Number(id) || 0 }); + const [submit, result] = useSubmitMutation(); + + const [lang, setLang] = useState("c"); + const [code, setCode] = useState(""); + + const submitCode = () => { + void submit({ pid: Number(id) || 0, language: lang, code: code }); + }; + + useEffect(() => { + if (result.isSuccess) { + navigate(`/problem/${id}/status`); + } else if (result.isError) { + toast({ + status: "error", + title: "Oops...", + description: "Submit Failed", + isClosable: true, + }); + } + }, [id, navigate, result, toast]); + + const actionBtn = ( + + ); + + return ( + <> + + + + + + + + + + ); +} diff --git a/src/routes.tsx b/src/routes.tsx index d8ed73a..93bc2d3 100644 --- a/src/routes.tsx +++ b/src/routes.tsx @@ -3,13 +3,14 @@ import type { RouteObject } from "react-router-dom"; import { Root } from "./pages/Root"; import { ErrorPage } from "./pages/ErrorPage"; -// import { RequireAuth } from "./components/RequireAuth"; +import { RequireAuth } from "./components/RequireAuth"; const HomePage = lazy(() => import("./pages/HomePage")); const LoginPage = lazy(() => import("./pages/LoginPage")); const LogoutPage = lazy(() => import("./pages/LogoutPage")); const ProblemListPage = lazy(() => import("./pages/ProblemListPage")); const ProblemDetailPage = lazy(() => import("./pages/ProblemDetailPage")); +const SubmitPage = lazy(() => import("./pages/SubmitPage")); export const router: RouteObject[] = [ { @@ -41,6 +42,14 @@ export const router: RouteObject[] = [ path: "problem/:id", element: , }, + { + path: "problem/:id/submit", + element: ( + + + + ), + }, ], }, ];