From 4ee1b9869979a87a49110e614a5a7d4583c0bc19 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Thu, 21 Dec 2023 15:09:37 +0800 Subject: [PATCH] chore: refactor problem page --- src/api/loader.ts | 9 ++++ src/components/problem-details.tsx | 71 +++++++++++++++++++++++++++ src/pages/error-page.tsx | 2 +- src/pages/pages.tsx | 2 +- src/pages/problem.tsx | 78 ++---------------------------- 5 files changed, 87 insertions(+), 75 deletions(-) create mode 100644 src/api/loader.ts create mode 100644 src/components/problem-details.tsx diff --git a/src/api/loader.ts b/src/api/loader.ts new file mode 100644 index 0000000..3eded16 --- /dev/null +++ b/src/api/loader.ts @@ -0,0 +1,9 @@ +import { ProblemApi } from "./problem.ts"; + +export async function ProblemLoader({ params }: { params: { id: string } }) { + const id = parseInt(params.id); + if (isNaN(id)) { + throw new Error("invalid problem id"); + } + return await ProblemApi.Details({ pid: id }); +} diff --git a/src/components/problem-details.tsx b/src/components/problem-details.tsx new file mode 100644 index 0000000..6d2a069 --- /dev/null +++ b/src/components/problem-details.tsx @@ -0,0 +1,71 @@ +import React from "react"; +import { Link, useLoaderData } from "react-router-dom"; +import { Collapse, CollapseProps, Descriptions, Space, Tag } from "antd"; + +import { DetailsResp } from "../api/problem.ts"; + +interface ProblemDetailsProps { + action: React.ReactNode; +} + +export default function ProblemDetails(props: ProblemDetailsProps) { + const details = useLoaderData() as DetailsResp; + + const problemInfo = ( + + + + {details.problem.provider.nick_name} + + + + + {details.context.Languages.map((l) => ( + {l.Lang} + ))} + + + + {details.context.Tasks.length} + + + ); + + const runtimeLimit = ( + + + {details.context.Runtime.TimeLimit} ms + + + {details.context.Runtime.MemoryLimit} MB + + + {details.context.Runtime.NProcLimit} + + + ); + + const miscItems: CollapseProps["items"] = [ + { + key: "1", + label: "Problem Info", + children: problemInfo, + }, + { + key: "2", + label: "Runtime Limit", + children: runtimeLimit, + }, + { + key: "3", + label: "Action", + children: props.action, + }, + ]; + + return ( + <> + + + ); +} diff --git a/src/pages/error-page.tsx b/src/pages/error-page.tsx index 0380c5e..0d86fa1 100644 --- a/src/pages/error-page.tsx +++ b/src/pages/error-page.tsx @@ -11,7 +11,7 @@ const ErrorPage = () => { const convertError = (error: unknown): string => { if (isRouteErrorResponse(error)) { - return error.error?.message || error.statusText; + return `${error.status} ${error.statusText}`; } else if (error instanceof Error) { return error.message; } else if (typeof error === "string") { diff --git a/src/pages/pages.tsx b/src/pages/pages.tsx index 587e2d0..6cd5b45 100644 --- a/src/pages/pages.tsx +++ b/src/pages/pages.tsx @@ -2,5 +2,5 @@ export { Root } from "./root"; export { ErrorPage } from "./error-page"; export { HomePage } from "./home"; -export { ProblemLoader, ProblemPage } from "./problem"; +export { ProblemPage } from "./problem"; export { SearchPage } from "./search"; diff --git a/src/pages/problem.tsx b/src/pages/problem.tsx index 15400fe..411f8dd 100644 --- a/src/pages/problem.tsx +++ b/src/pages/problem.tsx @@ -1,63 +1,15 @@ -import { - Row, - Col, - Collapse, - CollapseProps, - Descriptions, - Tag, - Space, - Button, -} from "antd"; +import { Row, Col, Space, Button } from "antd"; import { PlayCircleOutlined, SearchOutlined } from "@ant-design/icons"; -import { Link, useLoaderData, useNavigate } from "react-router-dom"; +import { useLoaderData, useNavigate } from "react-router-dom"; import Markdown from "../components/markdown.tsx"; -import { DetailsResp, ProblemApi } from "../api/problem.ts"; - -export async function ProblemLoader({ params }: { params: { id: string } }) { - const id = parseInt(params.id); - if (isNaN(id)) { - throw new Error("invalid problem id"); - } - return await ProblemApi.Details({ pid: id }); -} +import { DetailsResp } from "../api/problem.ts"; +import ProblemDetails from "../components/problem-details.tsx"; export function ProblemPage() { const details = useLoaderData() as DetailsResp; const navigate = useNavigate(); - const problemInfo = ( - - - - {details.problem.provider.nick_name} - - - - - {details.context.Languages.map((l) => ( - {l.Lang} - ))} - - - - {details.context.Tasks.length} - - - ); - const runtimeLimit = ( - - - {details.context.Runtime.TimeLimit} ms - - - {details.context.Runtime.MemoryLimit} MB - - - {details.context.Runtime.NProcLimit} - - - ); const actionBtn = (