Compare commits

...

2 Commits

Author SHA1 Message Date
6aad88920d feat: add Empty info on details page 2023-12-31 16:41:59 +08:00
68ea8f439d feat: configurable page title 2023-12-31 16:36:21 +08:00
3 changed files with 48 additions and 19 deletions

View File

@ -1,6 +1,6 @@
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { Card, Col, Row, Tabs, TabsProps, Tooltip } from "antd";
import { Card, Col, Empty, Row, Tabs, TabsProps, Tooltip, Typography } from "antd";
import { PrismAsync } from "react-syntax-highlighter";
import { oneLight } from "react-syntax-highlighter/dist/cjs/styles/prism";
@ -11,6 +11,8 @@ import { DetailsResp } from "../api/problem.ts";
import { ProblemLoader } from "../api/loader.ts";
import { StatusApi, StatusInfo, Verdict } from "../api/status.ts";
const { Title, Paragraph } = Typography;
const VerdictMap: {
[key in Verdict]: { color: string; label: string; name: string };
} = {
@ -70,21 +72,31 @@ export default function DetailsPage() {
}).then(setDetails);
}, [status]);
const taskInfo = (
<Card style={{ padding: "1em" }}>
{status?.context?.tasks?.map((task) => (
<Card.Grid key={task.id} style={{ ...gridStyle, background: VerdictMap[task.verdict].color }}>
<Tooltip title={task.message} color="#2E3D89">
<div style={topLeftStyle}>{`#${task.id}`}</div>
<div>
<div style={labelStyle}>{VerdictMap[task.verdict].label}</div>
<div style={statusStyle}>{`${task.real_time}ms/${task.memory}KB`}</div>
</div>
</Tooltip>
</Card.Grid>
))}
</Card>
);
const taskInfo =
status?.context === undefined ? (
<Empty
description={
<Typography>
<Title level={4}>Waiting for Judge...</Title>
<Paragraph>Please refresh the page after a few seconds.</Paragraph>
</Typography>
}
/>
) : (
<Card style={{ padding: "1em" }}>
{status?.context?.tasks?.map((task) => (
<Card.Grid key={task.id} style={{ ...gridStyle, background: VerdictMap[task.verdict].color }}>
<Tooltip title={task.message} color="#2E3D89">
<div style={topLeftStyle}>{`#${task.id}`}</div>
<div>
<div style={labelStyle}>{VerdictMap[task.verdict].label}</div>
<div style={statusStyle}>{`${task.real_time}ms/${task.memory}KB`}</div>
</div>
</Tooltip>
</Card.Grid>
))}
</Card>
);
const sourceCode = (
<PrismAsync
@ -133,7 +145,12 @@ export default function DetailsPage() {
<>
<Row justify="center" align="top" gutter={[16, 16]}>
<Col flex={6}>{body}</Col>
<Col flex={1}>{details && <ProblemDetails details={details} />}</Col>
{details && (
<Col flex={1}>
{" "}
<ProblemDetails details={details} />
</Col>
)}
</Row>
</>
);

View File

@ -16,7 +16,7 @@ const LayoutProps: ProLayoutProps = {
layout: "top",
route: {
path: "/",
routes: NavConfigs.map((c) => {
routes: NavConfigs.filter((c) => c.show).map((c) => {
return {
path: c.to,
name: c.label,
@ -64,6 +64,9 @@ export default function Root() {
const curTab = NavConfigs.filter((c) => c.regex.test(location.pathname))
.map((c) => c.to)
.concat("/home")[0];
const title = NavConfigs.filter((c) => c.regex.test(location.pathname))
.map((c) => c.label)
.concat("Home")[0];
useEffect(
() => {
@ -115,7 +118,7 @@ export default function Root() {
return (
<ProLayout {...LayoutProps} location={{ pathname: curTab }} avatarProps={avatarProps}>
{msgContextHolder}
<PageContainer>
<PageContainer title={title}>
<React.Suspense fallback={<Skeleton />}>
<Outlet />
</React.Suspense>

View File

@ -96,6 +96,7 @@ const NavConfigs = [
label: "Home",
icon: <HomeOutlined />,
regex: /^\/$|^\/home$/i,
show: true,
},
{
key: "problem",
@ -103,6 +104,7 @@ const NavConfigs = [
label: "Problem",
icon: <QuestionCircleOutlined />,
regex: /^\/+(problem|search)($|\/.*)/i,
show: true,
},
{
key: "profile",
@ -110,6 +112,13 @@ const NavConfigs = [
label: "Profile",
icon: <ProfileOutlined />,
regex: /^\/profile($|\/.*)/i,
show: true,
},
{
key: "details",
label: "Details",
regex: /^\/details\/\d+$/i,
show: false,
},
];