Skip to content

Commit

Permalink
Merge pull request #235 from yosupo06/feature/hack
Browse files Browse the repository at this point in the history
enforce hack feature
  • Loading branch information
yosupo06 authored Aug 4, 2024
2 parents 265b7e9 + 0d58e90 commit 3251773
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 140 deletions.
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function App(): JSX.Element {
element={<StatementViewer />}
/>
<Route path="/hack" element={<Hack />} />
<Route path="/hack/:ID" element={<HackInfo />} />
<Route path="/hack/:id" element={<HackInfo />} />
<Route element={NotFound} />
</Routes>
</Box>
Expand Down
4 changes: 2 additions & 2 deletions src/components/NavBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ const NavBar: React.FC = () => {
return (
<>
<AppBar position="static">
<Toolbar sx={{ display: { xs: "none", md: "flex" } }}>
<Toolbar key="bar-md" sx={{ display: { xs: "none", md: "flex" } }}>
{title}
<NavBarElements />
</Toolbar>

<Toolbar sx={{ display: { xs: "flex", md: "none" } }}>
<Toolbar key="bar-xs" sx={{ display: { xs: "flex", md: "none" } }}>
{title}
<IconButton
onClick={toggleDrawerOpen}
Expand Down
7 changes: 7 additions & 0 deletions src/pages/Hack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useNavigate } from "react-router-dom";
import SourceEditor from "../components/SourceEditor";
import { useHackMutation } from "../api/client_wrapper";
import {
Alert,
Box,
Container,
FormControl,
Expand All @@ -13,6 +14,7 @@ import {
TextField,
} from "@mui/material";
import { refactorTestCase } from "../utils/hack";
import { RpcError } from "@protobuf-ts/runtime-rpc";

const Hack: React.FC = () => {
const navigate = useNavigate();
Expand Down Expand Up @@ -53,6 +55,11 @@ const Hack: React.FC = () => {
Hack (β)
</Typography>

{mutation.isSuccess && <Alert severity="success">Hack submitted</Alert>}
{mutation.isError && (
<Alert severity="error">{(mutation.error as RpcError).message}</Alert>
)}

<Box component="form" onSubmit={handleSubmit}>
<FormControl>
<TextField
Expand Down
123 changes: 85 additions & 38 deletions src/pages/HackInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,74 +5,121 @@ import { useParams } from "react-router-dom";
import { useHackInfo } from "../api/client_wrapper";
import CircularProgress from "@mui/material/CircularProgress";
import Link from "@mui/material/Link";
import { Alert, Container } from "@mui/material";
import { HackInfoResponse } from "../proto/library_checker";
import {
Alert,
Container,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
} from "@mui/material";
import { HackInfoResponse, HackOverview } from "../proto/library_checker";
import { RpcError } from "@protobuf-ts/runtime-rpc";

const HackInfo: React.FC = () => {
const { ID } = useParams<"ID">();
if (!ID) {
const { id } = useParams<"id">();
if (!id) {
throw new Error(`hack ID is not defined`);
}
const hackInfoQuery = useHackInfo(parseInt(ID), {
if (Number.isNaN(parseInt(id))) {
throw new Error(`hack ID is not int`);
}
return (
<Container>
<Typography variant="h2" paragraph={true}>
Hack #{id}
</Typography>
<HackInfoBody id={parseInt(id)} />
</Container>
);
};
export default HackInfo;

const HackInfoBody: React.FC<{
id: number;
}> = (props) => {
const { id } = props;
const hackInfoQuery = useHackInfo(id, {
refetchInterval: 1000,
});

if (hackInfoQuery.isLoading) {
return (
<Container>
<Typography variant="h2" paragraph={true}>
Hack #{ID}
</Typography>
<Box>
<CircularProgress />
</Container>
</Box>
);
}

if (hackInfoQuery.isError) {
return (
<Container>
<Typography variant="h2" paragraph={true}>
Hack #{ID}
</Typography>
<Box>
<Alert severity="error">
{(hackInfoQuery.error as RpcError).toString()}
</Alert>
</Container>
</Box>
);
}
return (
<Container>
<Typography variant="h2" paragraph={true}>
Hack #{ID}
</Typography>
<HackInfoBody info={hackInfoQuery.data} />
</Container>
);
};

export default HackInfo;
const info = hackInfoQuery.data;

const HackInfoBody: React.FC<{
info: HackInfoResponse;
}> = (props) => {
const { info } = props;
return (
<Box>
<Typography>
Submission:{" "}
<Link href={`/submission/${info.overview?.submissionId}`}>
#{info.overview?.submissionId}
</Link>
</Typography>
<Typography>Status: {info.overview?.status}</Typography>
{info.overview && <OverView overview={info.overview} />}
<TestCase info={info} />
<Typography>Checker output</Typography>
<pre>{new TextDecoder().decode(info.checkerOut)}</pre>
{info.stderr && (
<Box>
<Typography>Stderr</Typography>
<pre>{new TextDecoder().decode(info.stderr)}</pre>
</Box>
)}
{info.judgeOutput && (
<Box>
<Typography>Judge output</Typography>
<pre>{new TextDecoder().decode(info.judgeOutput)}</pre>
</Box>
)}
</Box>
);
};

const OverView: React.FC<{
overview: HackOverview;
}> = (props) => {
const { overview } = props;

return (
<TableContainer>
<Table>
<TableHead>
<TableRow>
<TableCell>Submission</TableCell>
<TableCell>Hacker</TableCell>
<TableCell>Status</TableCell>
<TableCell>Time</TableCell>
<TableCell>Memory</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow>
<TableCell>
<Link href={`/submission/${overview.submissionId}`}>
#{overview.submissionId}
</Link>
</TableCell>
<TableCell>{overview.userName ?? "(Anonymous)"}</TableCell>
<TableCell>{overview.status}</TableCell>
<TableCell>{overview.time?.toString()}</TableCell>
<TableCell>{overview.memory?.toString()}</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
);
};

const TestCase: React.FC<{
info: HackInfoResponse;
}> = (props) => {
Expand Down
99 changes: 0 additions & 99 deletions src/pages/HackList.tsx

This file was deleted.

0 comments on commit 3251773

Please sign in to comment.