diff --git a/packages/frontend/src/components/quiz/CommandAccordion/CommandAccordion.tsx b/packages/frontend/src/components/quiz/CommandAccordion/CommandAccordion.tsx
index 9945d65d..15cf9054 100644
--- a/packages/frontend/src/components/quiz/CommandAccordion/CommandAccordion.tsx
+++ b/packages/frontend/src/components/quiz/CommandAccordion/CommandAccordion.tsx
@@ -1,7 +1,11 @@
import Link from "next/link";
import { GIT_BOOK_URL } from "../../../constants/path";
-import { Accordion, Badge , badgeVariantList } from "../../../design-system/components/common";
+import {
+ Accordion,
+ Badge,
+ badgeVariantList,
+} from "../../../design-system/components/common";
import badgeGroupLayout from "./CommandAccordion.css";
diff --git a/packages/frontend/src/components/quiz/QuizContent/QuizContent.css.ts b/packages/frontend/src/components/quiz/QuizContent/QuizContent.css.ts
index a60aaa79..1d99ac89 100644
--- a/packages/frontend/src/components/quiz/QuizContent/QuizContent.css.ts
+++ b/packages/frontend/src/components/quiz/QuizContent/QuizContent.css.ts
@@ -12,16 +12,11 @@ export const description = style([
typography.$semantic.body2Regular,
{
marginTop: 10,
- height: 60,
+ maxHeight: 190,
padding: "0 8px 4px 0",
color: color.$scale.grey700,
overflowY: "auto",
whiteSpace: "break-spaces",
- "@media": {
- "(min-width: 1920px) and (max-width: 2559px)": {
- height: 250,
- },
- },
},
]);
diff --git a/packages/frontend/src/components/quiz/QuizContent/QuizContent.tsx b/packages/frontend/src/components/quiz/QuizContent/QuizContent.tsx
index 60d8d800..2f487a40 100644
--- a/packages/frontend/src/components/quiz/QuizContent/QuizContent.tsx
+++ b/packages/frontend/src/components/quiz/QuizContent/QuizContent.tsx
@@ -15,13 +15,13 @@ export default function QuizContent({
category,
}: QuizContentProps) {
return (
- <>
+
);
}
diff --git a/packages/frontend/src/components/quiz/QuizGuide/QuizGuide.css.ts b/packages/frontend/src/components/quiz/QuizGuide/QuizGuide.css.ts
new file mode 100644
index 00000000..5ae15661
--- /dev/null
+++ b/packages/frontend/src/components/quiz/QuizGuide/QuizGuide.css.ts
@@ -0,0 +1,24 @@
+import { style } from "@vanilla-extract/css";
+
+import color from "../../../design-system/tokens/color";
+import { flexColumn } from "../../../design-system/tokens/utils.css";
+
+const containerPadding = 23;
+
+export const quizContentContainer = style([
+ flexColumn,
+ {
+ position: "relative",
+ width: "50%",
+ height: "400px",
+ borderLeft: `1px solid ${color.$semantic.border}`,
+ padding: containerPadding,
+ gap: 12,
+ },
+]);
+
+export const checkAnswerButton = style({
+ position: "absolute",
+ right: containerPadding,
+ bottom: containerPadding,
+});
diff --git a/packages/frontend/src/components/quiz/QuizGuide/QuizGuide.tsx b/packages/frontend/src/components/quiz/QuizGuide/QuizGuide.tsx
new file mode 100644
index 00000000..92cf59d5
--- /dev/null
+++ b/packages/frontend/src/components/quiz/QuizGuide/QuizGuide.tsx
@@ -0,0 +1,22 @@
+import { Button } from "../../../design-system/components/common";
+import { Quiz } from "../../../types/quiz";
+import CommandAccordion from "../CommandAccordion";
+import QuizContent from "../QuizContent";
+
+import * as styles from "./QuizGuide.css";
+
+export function QuizGuide({ quiz }: { quiz: Quiz }) {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/packages/frontend/src/components/quiz/QuizGuide/index.ts b/packages/frontend/src/components/quiz/QuizGuide/index.ts
new file mode 100644
index 00000000..0842440c
--- /dev/null
+++ b/packages/frontend/src/components/quiz/QuizGuide/index.ts
@@ -0,0 +1 @@
+export { QuizGuide } from "./QuizGuide";
diff --git a/packages/frontend/src/components/terminal/Terminal.css.ts b/packages/frontend/src/components/terminal/Terminal.css.ts
index ec55850d..9e4af9c5 100644
--- a/packages/frontend/src/components/terminal/Terminal.css.ts
+++ b/packages/frontend/src/components/terminal/Terminal.css.ts
@@ -2,12 +2,13 @@ import { style } from "@vanilla-extract/css";
import color from "../../design-system/tokens/color";
import typography from "../../design-system/tokens/typography";
-import { flexAlignCenter } from "../../design-system/tokens/utils.css";
+import { border, flexAlignCenter } from "../../design-system/tokens/utils.css";
const hrHeight = "20px";
export const container = style([
typography.$semantic.code,
+ border.all,
{
height: 180,
width: "100%",
@@ -18,7 +19,6 @@ export const hr = style({
height: hrHeight,
margin: 0,
border: "none",
- borderTop: `1px solid ${color.$semantic.border}`,
borderBottom: `1px solid ${color.$semantic.border}`,
backgroundColor: color.$scale.grey100,
});
diff --git a/packages/frontend/src/pages/quizzes/[id].page.tsx b/packages/frontend/src/pages/quizzes/[id].page.tsx
new file mode 100644
index 00000000..b1578d08
--- /dev/null
+++ b/packages/frontend/src/pages/quizzes/[id].page.tsx
@@ -0,0 +1,79 @@
+import axios from "axios";
+import { GetStaticPaths, GetStaticProps, GetStaticPropsContext } from "next";
+import { useRouter } from "next/router";
+import { useEffect, useState } from "react";
+
+import { quizAPI } from "../../apis/quiz";
+import { QuizGuide } from "../../components/quiz/QuizGuide";
+import { Terminal } from "../../components/terminal";
+import { Button } from "../../design-system/components/common";
+import { Categories, Quiz } from "../../types/quiz";
+import { TerminalContentType } from "../../types/terminalType";
+import { isString } from "../../utils/typeGuard";
+
+import * as styles from "./quiz.css";
+
+export default function QuizPage({ quiz }: { quiz: Quiz }) {
+ const [contentArray, setContentArray] = useState([]);
+ const {
+ query: { id },
+ } = useRouter();
+
+ useEffect(() => {
+ setContentArray([]);
+ }, [id]);
+
+ const handleTerminal = async (input: string) => {
+ if (!isString(id)) {
+ return;
+ }
+
+ const data = await quizAPI.postCommand({
+ id: +id,
+ command: input,
+ });
+ setContentArray([
+ ...contentArray,
+ { type: "stdin", content: input },
+ { type: "stdout", content: data.message },
+ ]);
+ };
+
+ if (!quiz) return null;
+ return (
+
+
+
+
+
+ );
+}
+
+export const getStaticProps = (async ({ params }: GetStaticPropsContext) => {
+ const { data } = await axios.get(
+ `https://git-challenge.com/api/v1/quizzes/${params?.id}`,
+ );
+
+ return {
+ props: {
+ quiz: data,
+ },
+ };
+}) satisfies GetStaticProps<{
+ quiz: Quiz;
+}>;
+
+export const getStaticPaths = (async () => {
+ const {
+ data: { categories },
+ } = await axios.get("https://git-challenge.com/api/v1/quizzes");
+
+ const paths = categories.flatMap(({ quizzes }) =>
+ quizzes.map(({ id }) => ({ params: { id: String(id) } })),
+ );
+
+ return { paths, fallback: "blocking" };
+}) satisfies GetStaticPaths;
diff --git a/packages/frontend/src/pages/quizzes/quiz.css.ts b/packages/frontend/src/pages/quizzes/quiz.css.ts
new file mode 100644
index 00000000..07a43f92
--- /dev/null
+++ b/packages/frontend/src/pages/quizzes/quiz.css.ts
@@ -0,0 +1,7 @@
+import { style } from "@vanilla-extract/css";
+
+import { border, flex, widthFull } from "../../design-system/tokens/utils.css";
+
+export const mainContainer = style([widthFull]);
+
+export const topContainer = style([flex, border.verticalSide]);