feat: problem detail page
This commit is contained in:
parent
5049330fde
commit
aedf2bbf17
@ -10,6 +10,7 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.1.4",
|
||||
"@sentry/react": "^7.58.1",
|
||||
"@sentry/vite-plugin": "^2.4.0",
|
||||
"antd": "^5.7.0",
|
||||
|
@ -5,6 +5,9 @@ settings:
|
||||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@ant-design/icons':
|
||||
specifier: ^5.1.4
|
||||
version: 5.1.4(react-dom@18.2.0)(react@18.2.0)
|
||||
'@sentry/react':
|
||||
specifier: ^7.58.1
|
||||
version: 7.58.1(react@18.2.0)
|
||||
|
@ -1,61 +1,115 @@
|
||||
import { Row, Col, Card, Button, Space } from "antd";
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Collapse,
|
||||
CollapseProps,
|
||||
Descriptions,
|
||||
Tag,
|
||||
Space,
|
||||
Typography,
|
||||
Button,
|
||||
} from "antd";
|
||||
import { PlayCircleOutlined, SearchOutlined } from "@ant-design/icons";
|
||||
import { Link, useLoaderData, useNavigate } from "react-router-dom";
|
||||
|
||||
import Markdown from "../components/markdown.tsx";
|
||||
import { useLoaderData } from "react-router-dom";
|
||||
import { DetailsResp, ProblemApi } from "../api/problem.ts";
|
||||
|
||||
interface LoaderProps {
|
||||
params: {
|
||||
id: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface ProblemProps {
|
||||
text: string;
|
||||
}
|
||||
|
||||
export async function ProblemLoader({ params }: LoaderProps) {
|
||||
console.log(params.id);
|
||||
const text = `
|
||||
# Problem 1
|
||||
|
||||
| Time Limit | Memory Limit |
|
||||
| ---------- | ------------ |
|
||||
| 1s | 256MB |
|
||||
|
||||
\`\`\`cpp
|
||||
#include<iostream>
|
||||
using namespace std;
|
||||
int main() {
|
||||
cout << "hello world" << endl;
|
||||
return 0;
|
||||
}
|
||||
\`\`\`
|
||||
|
||||
I'm a paragraph.
|
||||
|
||||
inline \`code\` test
|
||||
|
||||
`;
|
||||
|
||||
return { text: text };
|
||||
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 });
|
||||
}
|
||||
|
||||
function ProblemPage() {
|
||||
const { text } = useLoaderData() as ProblemProps;
|
||||
const details = useLoaderData() as DetailsResp;
|
||||
const navigate = useNavigate();
|
||||
|
||||
const problemInfo = (
|
||||
<Descriptions bordered column={1} size="small">
|
||||
<Descriptions.Item label="Provider">
|
||||
<Link to={`/user/${details.problem.provider.meta.ID}`}>
|
||||
<Typography.Link>
|
||||
{details.problem.provider.nick_name}
|
||||
</Typography.Link>
|
||||
</Link>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Supported Languages">
|
||||
<Space size={[0, 8]} wrap>
|
||||
{details.context.Languages.map((l) => (
|
||||
<Tag>{l.Lang}</Tag>
|
||||
))}
|
||||
</Space>
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Task Nums">
|
||||
{details.context.Tasks.length}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
);
|
||||
const runtimeLimit = (
|
||||
<Descriptions bordered column={1} size="small">
|
||||
<Descriptions.Item label="Time Limit">
|
||||
{details.context.Runtime.TimeLimit} ms
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Memory Limit">
|
||||
{details.context.Runtime.MemoryLimit} MB
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Process Limit">
|
||||
{details.context.Runtime.NProcLimit}
|
||||
</Descriptions.Item>
|
||||
</Descriptions>
|
||||
);
|
||||
const actionBtn = (
|
||||
<Space wrap>
|
||||
<Button
|
||||
icon={<PlayCircleOutlined />}
|
||||
onClick={() =>
|
||||
navigate(`/problem/${details.problem.meta.ID}/submit`)
|
||||
}
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
<Button
|
||||
icon={<SearchOutlined />}
|
||||
onClick={() =>
|
||||
navigate(`/problem/${details.problem.meta.ID}/status`)
|
||||
}
|
||||
>
|
||||
Status
|
||||
</Button>
|
||||
</Space>
|
||||
);
|
||||
|
||||
const miscItems: CollapseProps["items"] = [
|
||||
{
|
||||
key: "1",
|
||||
label: "Problem Info",
|
||||
children: problemInfo,
|
||||
},
|
||||
{
|
||||
key: "2",
|
||||
label: "Runtime Limit",
|
||||
children: runtimeLimit,
|
||||
},
|
||||
{
|
||||
key: "3",
|
||||
label: "Action",
|
||||
children: actionBtn,
|
||||
},
|
||||
];
|
||||
|
||||
const ProblemStatement = <Markdown markdown={details.problem.statement} />;
|
||||
const MiscPanel = (
|
||||
<Collapse items={miscItems} defaultActiveKey={["1", "2", "3"]} />
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Row justify="center" align="top" gutter={[16, 16]}>
|
||||
<Col span={18}>
|
||||
<Markdown markdown={text} />
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card title="卡片标题">
|
||||
<Space>
|
||||
<Button type="primary">Primary</Button>
|
||||
<Button type="primary">Primary</Button>
|
||||
</Space>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={18}>{ProblemStatement}</Col>
|
||||
<Col span={6}>{MiscPanel}</Col>
|
||||
</Row>
|
||||
</>
|
||||
);
|
||||
|
Reference in New Issue
Block a user