Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

어드민 페이지 퍼블리싱 완성했습니다 #44

Merged
merged 2 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions src/admin/Admin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { AlignCenter, LayOut, StyleLink } from './style';
import Quiz from './types/Quiz';

export default function Admin() {
const quizzes: Quiz[] = [
//단답형
{
id: 1,
part: 'Easy',
sectionId: 1,
title: '실행결과를 쓰시오',
question: 'console.log(1 + 2)',
answer: ['3'],
category: 'ShortAnswer',
answerChoice: [''],
},
//객관식
{
id: 2,
part: 'Normal',
sectionId: 1,
title: '실행결과를 쓰시오',
question: 'console.log(1 + 2)',
answer: ['3'],
category: 'MultipleChoice',
answerChoice: ['1', '4', '3', '7'],
},
//ox유형
{
id: 3,
part: 'Hard',
sectionId: 1,
title: 'OX문제',
question: '1 은 number타입이다?',
answer: ['O'],
category: 'OXSelector',
answerChoice: [''],
},
//조합형
{
id: 4,
part: 'VeryHard',
sectionId: 1,
title: '빈칸을 채우시오',
question: '[ ].log([ ])',
answer: ['3'],
category: 'Combination',
answerChoice: ['console', '1+2', 'function', '어쩌구저쩌구', '두두두두'],
},
];
return (
<AlignCenter>
<LayOut>
<StyleLink to="/admin/create-quiz">문제 생성</StyleLink>
<ul>
{quizzes?.map(quiz => (
<li key={quiz.id}>
섹션: {quiz.sectionId}파트 : {quiz.part}타이틀: {quiz.title}{' '}
문제ㅇㅇ:
{quiz.question}
</li>
))}
</ul>
</LayOut>
</AlignCenter>
);
}
113 changes: 113 additions & 0 deletions src/admin/CreateQuiz.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { useState, useRef } from 'react';
import {
AlignCenter,
FlexDiv,
InputBox,
Label,
LayOut,
SelectBox,
} from './style';
import Quiz from './types/Quiz';

export default function CreateQuiz() {
//퀴즈의 정보를 저장하는 상태
const [quiz, setQuiz] = useState<Quiz>({
sectionId: 0,
part: 'Easy',
title: '',
question: '',
answer: [],
category: 'MultipleChoice',
});
const sectionRef = useRef<HTMLInputElement>(null);
const handelQuizChange = (
e: React.ChangeEvent<HTMLTextAreaElement | HTMLSelectElement>
) => {
const { id, value } = e.target;

if (id === 'answerChoice' || id === 'answer') {
setQuiz({ ...quiz, [id]: value.split(',') });
} else {
setQuiz({ ...quiz, [id]: value });
}
};

return (
<AlignCenter>
<LayOut>
<div>
<Label>섹션 선택하기</Label>
<Label $marginLeft="420px">파트 선택하기</Label>
</div>
<div>
<SelectBox id="sectionId" onChange={handelQuizChange}>
<option value="0">변수</option>
<option value="1">자료형</option>
<option>등등..</option>
</SelectBox>
<input type="text" placeholder="섹션추가" ref={sectionRef}></input>
<button
onClick={() => {
console.log(sectionRef.current?.value);
}}
>
섹션추가
</button>
<SelectBox id="part" onChange={handelQuizChange}>
<option value="Easy">Easy</option>
<option value="Normal">Normal</option>
<option value="Hard">Hard</option>
<option value="Very Hard">Very Hard</option>
</SelectBox>
</div>
<Label>문제 지문 입력(title)</Label>
<InputBox id="title" onChange={handelQuizChange} />
<div>
<Label>문제(question)</Label>
<Label $marginLeft="420px">정답(answer)</Label>
</div>
<div>
<InputBox
id="question"
wrap="hard"
$height="200px"
onChange={handelQuizChange}
/>
<InputBox
id="answer"
wrap="hard"
$height="200px"
onChange={handelQuizChange}
placeholder="조합형의 경우 순서대로 ,로 구분해서 적어주시면 됩니다.ex) function, add, return"
/>
</div>
<div>
<Label>문제 유형 선택하기</Label>
<Label $marginLeft="380px">
객관식, 조합식의 경우만 보기를 작성해주시면 됩니다.
</Label>
</div>

<FlexDiv>
<SelectBox
id="category"
$marginRight="125px"
onChange={handelQuizChange}
>
<option value="MultipleChoice">객관식</option>
<option value="Combination">조합식</option>
<option value="OXSelector">O/X</option>
<option value="ShortAnswer">단답형</option>
</SelectBox>
<InputBox
id="answerChoice"
$height="200px"
onChange={handelQuizChange}
></InputBox>
</FlexDiv>

<button onClick={() => console.log(quiz)}>확인</button>
</LayOut>
</AlignCenter>
);
}
45 changes: 45 additions & 0 deletions src/admin/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { Link } from 'react-router-dom';
import styled from 'styled-components';
import type { InputBoxStyle, LabelStyle, SelectBoxStyle } from './types/style';
export const AlignCenter = styled.div`
display: flex;
justify-content: center;
`;
export const LayOut = styled.div`
width: 1280px;
display: flex;
flex-direction: column;
`;
export const StyleLink = styled(Link)`
color: #000000;
display: block;
text-decoration: none;
width: 300px;
height: 70px;
font-size: 24px;
text-align: center;
align-content: center;
background-color: lightgray;
border: 2px solid #000000;
`;
export const Label = styled.label<LabelStyle>`
margin-left: ${({ $marginLeft }) => $marginLeft || '30px'};
font-size: 18px;
`;
export const SelectBox = styled.select<SelectBoxStyle>`
margin: 20px;
font-size: 18px;
width: 400px;
height: 30px;
margin-right: ${({ $marginRight }) => $marginRight || '0px;'};
`;
export const InputBox = styled.textarea<InputBoxStyle>`
width: 500px;
margin: 20px;
height: ${({ $height }) => $height || '40px'};
resize: none;
`;
export const FlexDiv = styled.div`
display: flex;
align-items: center;
`;
10 changes: 10 additions & 0 deletions src/admin/types/Quiz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default interface Quiz {
id?: number;
part: string;
sectionId: number;
title: string;
question: string;
answer: string[];
category: 'Combination' | 'MultipleChoice' | 'OXSelector' | 'ShortAnswer';
answerChoice?: string[];
}
Comment on lines +1 to +10
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

카톡에서 했던 이야기 연장선인데, part와 category 를 db에서 enum으로 잡고 했어요. 요기에서는 string 카멜케이스로 req를 주는듯 한데 저는 대문자 스네이크케이스가 오는걸 전제로 작성했었습니다. 나중에 백이나 프론트에서 정한 형태로 맞춰야할듯 합니다

9 changes: 9 additions & 0 deletions src/admin/types/style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface InputBoxStyle {
$height?: string;
}
export interface LabelStyle {
$marginLeft?: string;
}
export interface SelectBoxStyle {
$marginRight?: string;
}
5 changes: 5 additions & 0 deletions src/route/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Main from '../pages/main/Main';
import Quest from '../pages/Quest/Quest';
import Ranking from '../pages/Ranking/Ranking';
import Admin from '../admin/Admin';
import CreateQuiz from '../admin/CreateQuiz';
export default function Router() {
return (
<>
Expand All @@ -10,6 +12,9 @@ export default function Router() {
<Route path="/" element={<Main />}></Route>
<Route path="/quest" element={<Quest />}></Route>
<Route path="/Ranking" element={<Ranking />}></Route>
{/*어드민 페이지 부분 문제조회/추가 이외에 규모 확장 시 레포 분리 */}
<Route path="/admin" element={<Admin />} />
<Route path="/admin/create-quiz" element={<CreateQuiz />}></Route>
</Routes>
</BrowserRouter>
</>
Expand Down