Showing
14 changed files
with
205 additions
and
24 deletions
.gitignore
100644 → 100755
File mode changed
... | @@ -14,6 +14,7 @@ | ... | @@ -14,6 +14,7 @@ |
14 | "next-remove-imports": "^1.0.6", | 14 | "next-remove-imports": "^1.0.6", |
15 | "react": "17.0.2", | 15 | "react": "17.0.2", |
16 | "react-dom": "17.0.2", | 16 | "react-dom": "17.0.2", |
17 | + "react-promise": "^3.0.2", | ||
17 | "semantic-ui-react": "^2.0.4", | 18 | "semantic-ui-react": "^2.0.4", |
18 | "swr": "^1.0.1" | 19 | "swr": "^1.0.1" |
19 | }, | 20 | }, |
... | @@ -6671,6 +6672,11 @@ | ... | @@ -6671,6 +6672,11 @@ |
6671 | "react": "^16.8.0 || ^17" | 6672 | "react": "^16.8.0 || ^17" |
6672 | } | 6673 | } |
6673 | }, | 6674 | }, |
6675 | + "node_modules/react-promise": { | ||
6676 | + "version": "3.0.2", | ||
6677 | + "resolved": "https://registry.npmjs.org/react-promise/-/react-promise-3.0.2.tgz", | ||
6678 | + "integrity": "sha512-Ez2aFel11b08H2HAWNnKf0GDV5ATGBmxK9UXHXxoKwCEoQey9manXDTwB2n3mhgOvMRzGH/YTHACdqQUjXf6Rw==" | ||
6679 | + }, | ||
6674 | "node_modules/react-refresh": { | 6680 | "node_modules/react-refresh": { |
6675 | "version": "0.8.3", | 6681 | "version": "0.8.3", |
6676 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", | 6682 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", |
... | @@ -13747,6 +13753,11 @@ | ... | @@ -13747,6 +13753,11 @@ |
13747 | "warning": "^4.0.2" | 13753 | "warning": "^4.0.2" |
13748 | } | 13754 | } |
13749 | }, | 13755 | }, |
13756 | + "react-promise": { | ||
13757 | + "version": "3.0.2", | ||
13758 | + "resolved": "https://registry.npmjs.org/react-promise/-/react-promise-3.0.2.tgz", | ||
13759 | + "integrity": "sha512-Ez2aFel11b08H2HAWNnKf0GDV5ATGBmxK9UXHXxoKwCEoQey9manXDTwB2n3mhgOvMRzGH/YTHACdqQUjXf6Rw==" | ||
13760 | + }, | ||
13750 | "react-refresh": { | 13761 | "react-refresh": { |
13751 | "version": "0.8.3", | 13762 | "version": "0.8.3", |
13752 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", | 13763 | "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", | ... | ... |
... | @@ -17,6 +17,7 @@ | ... | @@ -17,6 +17,7 @@ |
17 | "next-remove-imports": "^1.0.6", | 17 | "next-remove-imports": "^1.0.6", |
18 | "react": "17.0.2", | 18 | "react": "17.0.2", |
19 | "react-dom": "17.0.2", | 19 | "react-dom": "17.0.2", |
20 | + "react-promise": "^3.0.2", | ||
20 | "semantic-ui-react": "^2.0.4", | 21 | "semantic-ui-react": "^2.0.4", |
21 | "swr": "^1.0.1" | 22 | "swr": "^1.0.1" |
22 | }, | 23 | }, | ... | ... |
1 | -import auth from '../auth' | 1 | +import * as auth from '../auth' |
2 | import axios from 'axios'; | 2 | import axios from 'axios'; |
3 | import { SERVER_BASE_URL } from '..'; | 3 | import { SERVER_BASE_URL } from '..'; |
4 | 4 | ||
5 | -export const newPost = async (title, content, privat) => { | 5 | +export const newPost = async ( |
6 | + title, | ||
7 | + explain, | ||
8 | + example, | ||
9 | + testinput, | ||
10 | + testoutput, | ||
11 | +) => { | ||
6 | if (!auth.validateToken()) { | 12 | if (!auth.validateToken()) { |
7 | throw new Error("plz login"); | 13 | throw new Error("plz login"); |
8 | } | 14 | } |
9 | - const response = await axios.post(`${SERVER_BASE_URL}/post/new`, { | 15 | + const response = await axios.post(`${SERVER_BASE_URL}/post`, { |
10 | token: auth.getToken(), | 16 | token: auth.getToken(), |
11 | title, | 17 | title, |
12 | - content, | 18 | + explain, |
13 | - privat, | 19 | + example, |
20 | + testinput, | ||
21 | + testoutput, | ||
14 | }); | 22 | }); |
15 | - if (response.status !== 200) { | 23 | + if (response.status !== 200 && response.status !== 201) { |
16 | throw new Error('Failed to create new post!'); | 24 | throw new Error('Failed to create new post!'); |
17 | } | 25 | } |
18 | - return response.data; | 26 | + return response.data.id; |
19 | } | 27 | } |
20 | 28 | ||
21 | export const getPostbyId = async (id) => { | 29 | export const getPostbyId = async (id) => { |
22 | - const response = await axios.get(`${SERVER_BASE_URL}/post/${id}`); | 30 | + const response = await axios.get(`${SERVER_BASE_URL}/post/id/${id}`); |
23 | if (response.status !== 200) { | 31 | if (response.status !== 200) { |
24 | throw new Error('Failed to get post!'); | 32 | throw new Error('Failed to get post!'); |
25 | } | 33 | } |
26 | return response.data; | 34 | return response.data; |
27 | } | 35 | } |
36 | + | ||
37 | +export const getPosts = async (takes) => { | ||
38 | + const response = await axios.get(`${SERVER_BASE_URL}/post`, { | ||
39 | + params: { | ||
40 | + takes, | ||
41 | + }, | ||
42 | + }); | ||
43 | + if (response.status !== 200) { | ||
44 | + throw new Error('Failed to get posts!'); | ||
45 | + } | ||
46 | + return response.data; | ||
47 | +} | ||
48 | + | ||
49 | +export const getPostsByDifficulty = async (difficulty) => { | ||
50 | + const response = await axios.get(`${SERVER_BASE_URL}/post/difficulty/${difficulty}`); | ||
51 | + | ||
52 | + if (response.status !== 200) { | ||
53 | + throw new Error('Failed to get posts!'); | ||
54 | + } | ||
55 | + console.log(response.data); | ||
56 | + return response.data; | ||
57 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
src/api/runner/index.js
100644 → 100755
File mode changed
src/api/runner/runner.js
100644 → 100755
File mode changed
... | @@ -6,25 +6,39 @@ export default function Nav() { | ... | @@ -6,25 +6,39 @@ export default function Nav() { |
6 | const moverun = () => { | 6 | const moverun = () => { |
7 | router.push("/run") | 7 | router.push("/run") |
8 | } | 8 | } |
9 | + | ||
10 | + const movenew = () => { | ||
11 | + router.push("/new") | ||
12 | + } | ||
13 | + | ||
14 | + const movelow = () => { | ||
15 | + router.push("/difficulty/low") | ||
16 | + } | ||
17 | + const movemed = () => { | ||
18 | + router.push("/difficulty/medium") | ||
19 | + } | ||
20 | + const movehigh = () => { | ||
21 | + router.push("/difficulty/high") | ||
22 | + } | ||
9 | return ( | 23 | return ( |
10 | <nav className="navbar"> | 24 | <nav className="navbar"> |
11 | <div className="flex px-10 sm:px-20 text-2xl whitespace-nowrap | 25 | <div className="flex px-10 sm:px-20 text-2xl whitespace-nowrap |
12 | space-x-10 sm:space-x-20"> | 26 | space-x-10 sm:space-x-20"> |
13 | - <a herf="" className="last:pr-24 cursor-pointer transition | ||
14 | - duration-100 transform hover:scale-125 hover:text-white | ||
15 | - active:text-blue-500">난이도 하</a> | ||
16 | <Button onClick={moverun} className="cursor-pointer transition | 27 | <Button onClick={moverun} className="cursor-pointer transition |
17 | duration-100 transform hover:scale-125 hover:text-white | 28 | duration-100 transform hover:scale-125 hover:text-white |
18 | - active:text-blue-500">실행하기</Button> | 29 | + active:text-blue-500">테스트</Button> |
19 | - <a herf="" className="last:pr-24 cursor-pointer transition | 30 | + <Button onClick={movelow} className="cursor-pointer transition |
31 | + duration-100 transform hover:scale-125 hover:text-white | ||
32 | + active:text-blue-500">난이도 하</Button> | ||
33 | + <Button onClick={movemed} className="cursor-pointer transition | ||
20 | duration-100 transform hover:scale-125 hover:text-white | 34 | duration-100 transform hover:scale-125 hover:text-white |
21 | - active:text-blue-500">난이도 중</a> | 35 | + active:text-blue-500">난이도 중</Button> |
22 | - <a herf="" className="last:pr-24 cursor-pointer transition | 36 | + <Button onClick={movehigh} className="cursor-pointer transition |
23 | duration-100 transform hover:scale-125 hover:text-white | 37 | duration-100 transform hover:scale-125 hover:text-white |
24 | - active:text-blue-500">난이도 상</a> | 38 | + active:text-blue-500">난이도 상</Button> |
25 | - <a herf="" className="last:pr-24 cursor-pointer transition | 39 | + <Button onClick={movenew} className="cursor-pointer transition |
26 | duration-100 transform hover:scale-125 hover:text-white | 40 | duration-100 transform hover:scale-125 hover:text-white |
27 | - active:text-blue-500">북마크</a> | 41 | + active:text-blue-500">문제 만들기</Button> |
28 | </div> | 42 | </div> |
29 | </nav> | 43 | </nav> |
30 | ) | 44 | ) | ... | ... |
src/components/Popular.js
0 → 100644
1 | +import { Link } from "@nextui-org/react"; | ||
2 | +import { getPosts } from "../api/post"; | ||
3 | +import { useState } from "react"; | ||
4 | +import { useEffect } from "react"; | ||
5 | + | ||
6 | +export default function Popular() { | ||
7 | + const [posts, setPosts] = useState([]); | ||
8 | + useEffect(() => { | ||
9 | + getPosts(10).then(setPosts); | ||
10 | + }, []); | ||
11 | + return ( | ||
12 | + <div> | ||
13 | + <ul> | ||
14 | + {posts.map(post => ( | ||
15 | + <li key={post.id}> | ||
16 | + <Link href={`/post/${post.id}`}> | ||
17 | + <a>{post.title}</a> | ||
18 | + </Link> | ||
19 | + </li> | ||
20 | + ))} | ||
21 | + </ul> | ||
22 | + </div> | ||
23 | + ); | ||
24 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/pages/difficulty/low.js
0 → 100644
1 | +import { Link } from "@nextui-org/react"; | ||
2 | +import { getPostsByDifficulty } from "../../api/post"; | ||
3 | +import { useState } from "react"; | ||
4 | +import { useEffect } from "react"; | ||
5 | + | ||
6 | +export default function Popular() { | ||
7 | + const [posts, setPosts] = useState([]); | ||
8 | + useEffect(() => { | ||
9 | + getPostsByDifficulty(1).then(setPosts); | ||
10 | + }, []); | ||
11 | + return ( | ||
12 | + <div> | ||
13 | + <ul> | ||
14 | + {posts.map(post => ( | ||
15 | + <li key={post.id}> | ||
16 | + <Link href={`/post/${post.id}`}> | ||
17 | + <a>{post.title}</a> | ||
18 | + </Link> | ||
19 | + </li> | ||
20 | + ))} | ||
21 | + </ul> | ||
22 | + </div> | ||
23 | + ); | ||
24 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
src/pages/difficulty/medium.js
0 → 100644
1 | +import { Link } from "@nextui-org/react"; | ||
2 | +import { getPostsByDifficulty } from "../../api/post"; | ||
3 | +import { useState } from "react"; | ||
4 | +import { useEffect } from "react"; | ||
5 | + | ||
6 | +export default function Popular() { | ||
7 | + const [posts, setPosts] = useState([]); | ||
8 | + useEffect(() => { | ||
9 | + getPostsByDifficulty(2).then(setPosts); | ||
10 | + }, []); | ||
11 | + return ( | ||
12 | + <div> | ||
13 | + <ul> | ||
14 | + {posts.map(post => ( | ||
15 | + <li key={post.id}> | ||
16 | + <Link href={`/post/${post.id}`}> | ||
17 | + <a>{post.title}</a> | ||
18 | + </Link> | ||
19 | + </li> | ||
20 | + ))} | ||
21 | + </ul> | ||
22 | + </div> | ||
23 | + ); | ||
24 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | -import {Header} from 'semantic-ui-react' | 1 | +import { Header } from 'semantic-ui-react' |
2 | import Head from 'next/head' | 2 | import Head from 'next/head' |
3 | +import Popular from '../components/Popular' | ||
3 | 4 | ||
4 | export default function Home() { | 5 | export default function Home() { |
5 | return ( | 6 | return ( |
... | @@ -11,7 +12,7 @@ export default function Home() { | ... | @@ -11,7 +12,7 @@ export default function Home() { |
11 | </Head> | 12 | </Head> |
12 | {/* 기본 컨텐츠 */} | 13 | {/* 기본 컨텐츠 */} |
13 | <Header as='h3' textAlign='center'>인기 문제</Header> | 14 | <Header as='h3' textAlign='center'>인기 문제</Header> |
14 | - | 15 | + <Popular /> |
15 | </div> | 16 | </div> |
16 | ) | 17 | ) |
17 | } | 18 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
src/pages/new.js
0 → 100644
1 | +import { Button } from "semantic-ui-react"; | ||
2 | +import { newPost } from "../api/post"; | ||
3 | + | ||
4 | +export default function New() { | ||
5 | + async function makePost(event) { | ||
6 | + event.preventDefault(); | ||
7 | + const form = event.target; | ||
8 | + const title = form.title.value; | ||
9 | + const explain = form.explain.value; | ||
10 | + const example = form.example.value; | ||
11 | + const testinput = form.testinput.value.split("\n"); | ||
12 | + const testoutput = form.testoutput.value.split("\n"); | ||
13 | + const post = await newPost(title, explain, example, testinput, testoutput); | ||
14 | + console.log(post); | ||
15 | + }; | ||
16 | + return ( | ||
17 | + <div> | ||
18 | + <h1>New Post</h1> | ||
19 | + <form onSubmit={makePost}> | ||
20 | + <label>제목</label> | ||
21 | + <input type="text" id="title" /> | ||
22 | + <select id="level" defaultValue="1"> | ||
23 | + <option value="1">LOW</option> | ||
24 | + <option value="2">MEDIUM</option> | ||
25 | + <option value="3">HIGH</option> | ||
26 | + </select> | ||
27 | + <label>문제 설명</label> | ||
28 | + <textarea id="explain"></textarea><br /> | ||
29 | + <label>예시 코드</label> | ||
30 | + <textarea id="example"></textarea><br /> | ||
31 | + <label>예시 입력(Enter로 구분)</label> | ||
32 | + <textarea id="testinput"></textarea> | ||
33 | + <label>예시 출력(Enter로 구분)</label> | ||
34 | + <textarea id="testoutput"></textarea><br /> | ||
35 | + <button type="submit">제출</button> | ||
36 | + </form> | ||
37 | + </div> | ||
38 | + ); | ||
39 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -2,7 +2,7 @@ import { useRouter } from "next/dist/client/router" | ... | @@ -2,7 +2,7 @@ import { useRouter } from "next/dist/client/router" |
2 | import { getPostbyId } from "../../api/post" | 2 | import { getPostbyId } from "../../api/post" |
3 | import "@uiw/react-textarea-code-editor/dist.css"; | 3 | import "@uiw/react-textarea-code-editor/dist.css"; |
4 | import dynamic from "next/dynamic"; | 4 | import dynamic from "next/dynamic"; |
5 | -import { useState } from "react"; | 5 | +import { useEffect, useState } from "react"; |
6 | import { Button } from "semantic-ui-react"; | 6 | import { Button } from "semantic-ui-react"; |
7 | 7 | ||
8 | const CodeEditor = dynamic( | 8 | const CodeEditor = dynamic( |
... | @@ -12,8 +12,18 @@ const CodeEditor = dynamic( | ... | @@ -12,8 +12,18 @@ const CodeEditor = dynamic( |
12 | 12 | ||
13 | export default function Post() { | 13 | export default function Post() { |
14 | const router = useRouter() | 14 | const router = useRouter() |
15 | + | ||
16 | + const [post, setPost] = useState({}) | ||
17 | + | ||
18 | + useEffect(() => { | ||
19 | + if (!router.isReady) return; | ||
15 | const { id } = router.query | 20 | const { id } = router.query |
16 | - const post = getPostbyId(id) | 21 | + getPostbyId(id).then(res => { |
22 | + setPost(res) | ||
23 | + }) | ||
24 | + }, [router.isReady]); | ||
25 | + | ||
26 | + console.log(post); | ||
17 | 27 | ||
18 | const [value, setValue] = useState("c"); | 28 | const [value, setValue] = useState("c"); |
19 | 29 | ||
... | @@ -25,8 +35,10 @@ export default function Post() { | ... | @@ -25,8 +35,10 @@ export default function Post() { |
25 | 35 | ||
26 | return ( | 36 | return ( |
27 | <div> | 37 | <div> |
28 | - <p>{post.title}</p> | 38 | + <h1>{post.title}</h1> |
29 | - <p>{post.body}</p> | 39 | + <p>{post.explain}</p> |
40 | + <p>{post.testinput}</p> | ||
41 | + <p>{post.testoutput}</p> | ||
30 | <select value={value} onChange={(e) => setValue(e.target.value)}> | 42 | <select value={value} onChange={(e) => setValue(e.target.value)}> |
31 | <option value="c">c</option> | 43 | <option value="c">c</option> |
32 | <option value="cpp">cpp</option> | 44 | <option value="cpp">cpp</option> |
... | @@ -46,6 +58,7 @@ export default function Post() { | ... | @@ -46,6 +58,7 @@ export default function Post() { |
46 | }} | 58 | }} |
47 | /> | 59 | /> |
48 | <Button onClick={runCode}>Run</Button> | 60 | <Button onClick={runCode}>Run</Button> |
61 | + <p>{post.example}</p> | ||
49 | </div> | 62 | </div> |
50 | ) | 63 | ) |
51 | } | 64 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
src/pages/run.js
100644 → 100755
File mode changed
-
Please register or login to post a comment