Skip to content

Commit

Permalink
Merge pull request #15 from CTF-Compfest-15/improve-contest-info
Browse files Browse the repository at this point in the history
Improve contest info
  • Loading branch information
rorre authored Oct 7, 2023
2 parents 33aa827 + 9883be1 commit 48485a8
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 16 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
"dependencies": {
"@hookform/error-message": "^2.0.1",
"@phosphor-icons/react": "^2.0.10",
"@tailwindcss/typography": "^0.5.10",
"@tanstack/react-query": "^4.33.0",
"@types/katex": "^0.16.3",
"@types/node": "20.5.3",
"@types/react": "18.2.21",
"@types/react-dom": "18.2.7",
Expand All @@ -21,6 +23,7 @@
"eslint-config-next": "13.4.19",
"framer-motion": "^10.16.4",
"jotai": "^2.4.0",
"katex": "^0.16.9",
"ky": "^0.33.3",
"ky-universal": "^0.12.0",
"next": "13.4.19",
Expand Down
7 changes: 4 additions & 3 deletions src/components/module/attackmap/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export function getCoordinates(pointId: number, teamLen: number) {
const sizeY = 650 / numY;

const rowNum = Math.floor(pointId / numX);
const posY = 150 + rowNum * sizeY;
const posY = 100 + rowNum * sizeY;
var posX = 100 + (pointId % numX) * sizeX;
if (rowNum % 2 == 1) {
posX += sizeX / 2;
Expand Down Expand Up @@ -37,20 +37,21 @@ export function generateControlPoints(P0: Point, P3: Point) {
// Define factors for controlling the shape of the curve
var factor1 = 0.3; // Adjust this factor for different curves
var factor2 = 0.7; // Adjust this factor for different curves
var factorX = 0;

if (deltaY == 0) {
deltaY = deltaX * 0.5;
factor2 = factor1;
}

if (deltaX == 0) factorX = 30;
// Calculate control points based on the factors
const P1: Point = {
x: P0.x,
y: P0.y - factor1 * deltaY,
};

const P2: Point = {
x: P3.x,
x: P3.x - factorX,
y: P3.y - factor2 * deltaY,
};

Expand Down
31 changes: 23 additions & 8 deletions src/components/module/dashboard/DashboardLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Crown, Flag, MapTrifold, SignOut } from "@phosphor-icons/react";
import { Crown, Flag, MapTrifold, Question, SignOut } from "@phosphor-icons/react";
import React, { ReactElement, useEffect, useMemo } from "react";
import type { Icon } from "@phosphor-icons/react";
import { ComponentWithChildren } from "@/types/common";
Expand Down Expand Up @@ -51,13 +51,23 @@ export default function DashboardLayout({
<div className="p-4 flex flex-row justify-between">
<h1 className="text-2xl font-bold">{contest.event_name}</h1>
<strong className="font-bold text-2xl">
{contest.event_status.state === "finished"
? "Event Finished!"
: contest.event_status.state === "not started"
? "Not Started"
: contest.event_status.state === "running"
? `Round: ${contest.event_status.current_round} / Tick: ${contest.event_status.current_tick}`
: "Unknown event state"}
{contest.event_status.state === "finished" ? (
"Event Finished!"
) : contest.event_status.state === "not started" ? (
"Not Started"
) : contest.event_status.state === "running" ? (
<>
{contest.number_round > 1
? `Round: ${contest.event_status.current_round}`
: ""}
{contest.number_round > 1 && contest.number_tick > 1 && " / "}
{contest.number_tick > 1
? `Tick: ${contest.event_status.current_tick}`
: ""}
</>
) : (
"Unknown event state"
)}
</strong>
</div>
<div className="flex flex-row gap-8">
Expand All @@ -67,6 +77,11 @@ export default function DashboardLayout({
title="Challenges"
href="/dashboard"
/>
<ConfigMenu
icon={<Question size={24} />}
title="Documentation"
href="/dashboard/docs"
/>
<ConfigMenu
icon={<Crown size={24} />}
title="Leaderboard"
Expand Down
89 changes: 89 additions & 0 deletions src/components/module/dashboard/docs/DocsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { getUser } from "@/components/fetcher/user";
import { useQuery } from "@tanstack/react-query";
import React, { useEffect, useMemo, useState } from "react";
import katex from "katex";
import "katex/dist/katex.min.css";

interface DocsInterface {
label: string;
content: string;
}

function useDocs() {
const { data: apiDoc } = useQuery({
queryKey: ["apiDoc"],
queryFn: () => getUser<string>("docs/api"),
});
const { data: patchDoc } = useQuery({
queryKey: ["patchDoc"],
queryFn: () => getUser<string>("docs/patching"),
});
const { data: scoreDoc } = useQuery({
queryKey: ["scoreDoc"],
queryFn: () => getUser<string>("docs/scoring"),
});
return { apiDoc, patchDoc, scoreDoc };
}

export default function DocsPage() {
const { apiDoc, patchDoc, scoreDoc } = useDocs();

const docsMenu: { [index: string]: DocsInterface } = useMemo(
() => ({
api: { label: "API", content: apiDoc?.data ?? "" },
patching: { label: "Patching", content: patchDoc?.data ?? "" },
scoring: { label: "Scoring", content: scoreDoc?.data ?? "" },
}),
[apiDoc, patchDoc, scoreDoc]
);

const [menuActive, setMenuActive] = useState("api");
const [docsContent, setDocsContent] = useState(docsMenu["api"].content);

useEffect(() => {
// Replace $$ expressions with KaTeX rendering
const htmlWithMath = docsMenu[menuActive].content;
const renderedHtml = htmlWithMath.replace(
/\$\$(.*?)\$\$/g,
(_, mathExpression) => {
return katex.renderToString(mathExpression);
}
);

// Replace $ expressions with KaTeX rendering
const finalRenderedHtml = renderedHtml.replace(
/\$(.*?)\$/g,
(_, mathExpression) => {
return katex.renderToString(mathExpression, { displayMode: false });
}
);

setDocsContent(finalRenderedHtml);
}, [menuActive, docsMenu]);

return (
<div className="gap-4 px-4">
<div className="tabs w-full justify-center">
{Object.keys(docsMenu).map((key) => (
<a
key={`tab-docs-${key}`}
onClick={() => setMenuActive(key)}
className={
"tab tab-lg tab-bordered" +
(menuActive == key ? " tab-active" : "")
}
>
{docsMenu[key].label}
</a>
))}
</div>
<div className="p-4 rounded-md m-4">
<article
className="prose dark:prose-invert max-w-none"
style={{ color: "white" }}
dangerouslySetInnerHTML={{ __html: docsContent ?? "" }}
></article>
</div>
</div>
);
}
27 changes: 25 additions & 2 deletions src/pages/attackmap.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,32 @@
import { useContestContext } from "@/components/module/ContestContext";
import AttackMapPage from "@/components/module/attackmap/AttackMapPage";

export default function attackmap() {
export default function AttackMap() {
const { contest } = useContestContext();
return (
<div className="flex flex-col min-h-screen p-4 container mx-auto gap-4">
<h1 className="text-3xl font-bold">Attack Map</h1>
<div className="justify-between flex">
<h1 className="text-3xl font-bold">Attack Map</h1>
<strong className="font-bold text-2xl">
{contest.event_status.state === "finished" ? (
"Event Finished!"
) : contest.event_status.state === "not started" ? (
"Not Started"
) : contest.event_status.state === "running" ? (
<>
{contest.number_round > 1
? `Round: ${contest.event_status.current_round}`
: ""}
{contest.number_round > 1 && contest.number_tick > 1 && " / "}
{contest.number_tick > 1
? `Tick: ${contest.event_status.current_tick}`
: ""}
</>
) : (
"Unknown event state"
)}
</strong>
</div>
<AttackMapPage />
</div>
);
Expand Down
11 changes: 11 additions & 0 deletions src/pages/dashboard/docs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import DashboardLayout from "@/components/module/dashboard/DashboardLayout";
import DocsPage from "@/components/module/dashboard/docs/DocsPage";
import React, { ReactElement } from "react";

export default function docsPage() {
return <DocsPage />;
}

docsPage.getLayout = function getLayout(page: ReactElement) {
return <DashboardLayout>{page}</DashboardLayout>;
};
28 changes: 26 additions & 2 deletions src/pages/leaderboard.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
import { useContestContext } from "@/components/module/ContestContext";
import Leaderboard from "@/components/module/leaderboard/Leaderboard";
import React from "react";

export default function leaderboard() {
export default function LeaderboardPage() {
const { contest } = useContestContext();

return (
<div className="flex flex-col min-h-screen p-4 container mx-auto gap-4">
<h1 className="text-3xl font-bold">Leaderboard</h1>
<div className="justify-between flex">
<h1 className="text-3xl font-bold">Leaderboard</h1>
<strong className="font-bold text-2xl">
{contest.event_status.state === "finished" ? (
"Event Finished!"
) : contest.event_status.state === "not started" ? (
"Not Started"
) : contest.event_status.state === "running" ? (
<>
{contest.number_round > 1
? `Round: ${contest.event_status.current_round}`
: ""}
{contest.number_round > 1 && contest.number_tick > 1 && " / "}
{contest.number_tick > 1
? `Tick: ${contest.event_status.current_tick}`
: ""}
</>
) : (
"Unknown event state"
)}
</strong>
</div>
<Leaderboard className="w-full" />
</div>
);
Expand Down
1 change: 1 addition & 0 deletions src/styles/globals.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@tailwind typography;
@tailwind layout;

.map-entity {
Expand Down
5 changes: 4 additions & 1 deletion tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ const config: Config = {
},
},
},
plugins: [require("daisyui")],
plugins: [
require("daisyui"),
require('@tailwindcss/typography'),
],
daisyui: {
themes: ["dark"],
},
Expand Down
45 changes: 45 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,16 @@
dependencies:
tslib "^2.4.0"

"@tailwindcss/typography@^0.5.10":
version "0.5.10"
resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.10.tgz#2abde4c6d5c797ab49cf47610830a301de4c1e0a"
integrity sha512-Pe8BuPJQJd3FfRnm6H0ulKIGoMEQS+Vq01R6M5aCrFB/ccR/shT+0kXLjouGC1gFLm9hopTFN+DMP0pfwRWzPw==
dependencies:
lodash.castarray "^4.4.0"
lodash.isplainobject "^4.0.6"
lodash.merge "^4.6.2"
postcss-selector-parser "6.0.10"

"@tanstack/[email protected]":
version "4.33.0"
resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.33.0.tgz#7756da9a75a424e521622b1d84eb55b7a2b33715"
Expand All @@ -242,6 +252,11 @@
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==

"@types/katex@^0.16.3":
version "0.16.3"
resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.16.3.tgz#a341c89705145b7dd8e2a133b282a133eabe6076"
integrity sha512-CeVMX9EhVUW8MWnei05eIRks4D5Wscw/W9Byz1s3PA+yJvcdvq9SaDjiUKvRvEgjpdTyJMjQA43ae4KTwsvOPg==

"@types/[email protected]":
version "20.5.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.3.tgz#fa52c147f405d56b2f1dd8780d840aa87ddff629"
Expand Down Expand Up @@ -619,6 +634,11 @@ commander@^4.0.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==

commander@^8.3.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==

[email protected]:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
Expand Down Expand Up @@ -1663,6 +1683,13 @@ json5@^1.0.2:
object.assign "^4.1.4"
object.values "^1.1.6"

katex@^0.16.9:
version "0.16.9"
resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.9.tgz#bc62d8f7abfea6e181250f85a56e4ef292dcb1fa"
integrity sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==
dependencies:
commander "^8.3.0"

ky-universal@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.12.0.tgz#e01f5255628d2742a4535ccd1a85ee196af6b70c"
Expand Down Expand Up @@ -1712,6 +1739,16 @@ locate-path@^6.0.0:
dependencies:
p-locate "^5.0.0"

lodash.castarray@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.castarray/-/lodash.castarray-4.4.0.tgz#c02513515e309daddd4c24c60cfddcf5976d9115"
integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==

lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==

lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
Expand Down Expand Up @@ -2029,6 +2066,14 @@ postcss-nested@^6.0.1:
dependencies:
postcss-selector-parser "^6.0.11"

[email protected]:
version "6.0.10"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"

postcss-selector-parser@^6.0.11:
version "6.0.13"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b"
Expand Down

0 comments on commit 48485a8

Please sign in to comment.