diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..f6cd364b3ca5bac9b7d973f60b596f5887130845
--- /dev/null
+++ b/README.md
@@ -0,0 +1,10 @@
+# 퀴즈 출제 페이지
+
+## 실행 방법
+
+1. 두 개의 터미널을 엽니다.
+1. 한쪽 터미널(서버)에서는, 프로젝트 디렉토리에서 `yarn install`을 실행합니다.(이것은 패키지가 변경될 때마다 실행합니다.)
+1. 다른쪽 터미널(클라이언트)에서는, `cd src\client` 해서 `yarn install` 을 실행합니다.(이것은 패키지가 변경될 때마다 실행합니다.)
+1. 서버 터미널에서 `yarn dev`를 실행합니다.
+1. 클라이언트 터미널에서 `yarn start` 를 실행합니다.
+1. 코드를 수정합니다.
diff --git a/src/client/src/quiz/EditableProblem.jsx b/src/client/src/quiz/EditableProblem.jsx
index 6b05102fdcbf458ee71502eb42b9d601d3399881..ccbe227cfde2224aec6c3a0522398dcd565ad198 100644
--- a/src/client/src/quiz/EditableProblem.jsx
+++ b/src/client/src/quiz/EditableProblem.jsx
@@ -1,15 +1,17 @@
import React, { useState } from "react";
-import { Link } from "react-router-dom";
import Card from "react-bootstrap/Card";
import Form from "react-bootstrap/Form";
import Col from "react-bootstrap/Col";
import Button from "react-bootstrap/Button";
-import { remove } from "lodash";
+import ButtonGroup from "react-bootstrap/ButtonGroup";
+import ToggleButton from "react-bootstrap/ToggleButton";
+import ToggleButtonGroup from "react-bootstrap/ToggleButtonGroup";
const EditableForm = (props) => {
const {
problem,
number,
+ handleCorrect,
removeAnswer,
addAnswer,
handleQuestion,
@@ -28,9 +30,18 @@ const EditableForm = (props) => {
/>
Answers
+ {/* */}
{problem.answers.map((answer, index) => {
return (
+
+
+
{
);
})}
+ {/* */}
@@ -65,6 +77,7 @@ const CardForm = (props) => {
{problem.answers.map((answer, index) => {
return {answer};
})}
+ 정답: {+problem.correct + 1}
@@ -80,6 +93,12 @@ function EditableProblem({ problem, number, onUpdate, onRemove }) {
setEditable(!editable);
};
+ const handleCorrect = (event) => {
+ const { name, value } = event.target;
+ console.log("name:", name, "value:", value);
+ setProblemEdit({...problemEdit, correct: value})
+ };
+
const handleCancel = (event) => {
// const { name, value } = event.target;
// console.log(name, value);
@@ -111,8 +130,8 @@ function EditableProblem({ problem, number, onUpdate, onRemove }) {
};
const handleSave = (event, index) => {
- onUpdate(index, problemEdit)
- setEditable(!editable)
+ onUpdate(index, problemEdit);
+ setEditable(!editable);
};
return (
@@ -121,6 +140,7 @@ function EditableProblem({ problem, number, onUpdate, onRemove }) {
{
+ const { name, value } = event.target;
+ console.log("name:", name, "value:", value);
+ setCorrect(value)
+ };
+
const handleQuestion = (event) => {
setQuestion(event.target.value);
};
@@ -42,6 +49,7 @@ function NewProblem({ addProblem }) {
question,
answers,
quiz: quizId,
+ correct: correct,
};
createProblem({ userId: jwt.user._id }, { t: jwt.token }, problem).then(
(data) => {
@@ -50,7 +58,7 @@ function NewProblem({ addProblem }) {
} else {
setQuestion(data.question);
setAnswers(data.answers);
- setShow(true)
+ setShow(true);
}
}
);
@@ -73,6 +81,14 @@ function NewProblem({ addProblem }) {
{answers.map((answer, index) => {
return (
+
+
+
New Problem
-
- Problem successfully created.
-
+ Problem successfully created.
diff --git a/src/client/src/quiz/NewQuiz.jsx b/src/client/src/quiz/NewQuiz.jsx
index 8131c28c0c7899a951f335804417c506f4106f8e..5df71f43a99d8c567dc89ef568407cbb999558ec 100644
--- a/src/client/src/quiz/NewQuiz.jsx
+++ b/src/client/src/quiz/NewQuiz.jsx
@@ -15,7 +15,7 @@ import { list } from "../course/api-course";
function NewQuiz() {
const [problems, setProblems] = useState([]);
const [quiz, setQuiz] = useState({});
- const [courses, setCourses] = useState([])
+ const [courses, setCourses] = useState([]);
const [values, setValues] = useState({
title: "",
problems: [],
@@ -28,26 +28,26 @@ function NewQuiz() {
const jwt = authHelpers.isAuthenticated();
useEffect(() => {
- const abortController = new AbortController()
- const signal = abortController.signal
- list(signal).then(data => {
+ const abortController = new AbortController();
+ const signal = abortController.signal;
+ list(signal).then((data) => {
if (data.error) {
console.log(data.error);
} else {
console.log(data);
- setCourses(data)
+ setCourses(data);
}
- })
+ });
return () => {
- abortController.abort()
- }
- }, [])
+ abortController.abort();
+ };
+ }, []);
const handleChange = (event) => {
const { name, value } = event.target;
console.log("name", name, "value", value);
console.log("values:", values);
-
+
if (name === "course") {
console.log(`${name}: ${courses[value]._id}`);
setValues({ ...values, [name]: courses[value]._id });
@@ -59,16 +59,16 @@ function NewQuiz() {
const handleUpdate = (index) => {
console.log(`Quiz에서 handleUpdate ${index}번 실행`);
// console.log(`Quiz에서 handleUpdate ${JSON.stringify(quiz.problems[index])}`);
- }
+ };
const handleRemove = (index) => {
- console.log('handleRemove 실행');
- const problem = problems[index]
+ console.log("handleRemove 실행");
+ const problem = problems[index];
console.log(problem);
- const list = [...problems]
- list.splice(index, 1)
- setProblems(list)
- }
+ const list = [...problems];
+ list.splice(index, 1);
+ setProblems(list);
+ };
const addProblem = (problem) => {
console.log(problem);
@@ -88,17 +88,17 @@ function NewQuiz() {
console.log(quizData);
- // create({ userId: jwt.user._id }, { t: jwt.token }, quizData).then(
- // (data) => {
- // if (data.error) {
- // console.log(data.error);
- // } else {
- // console.log(data);
- // setQuiz(data);
- // setShow(true);
- // }
- // }
- // );
+ create({ userId: jwt.user._id }, { t: jwt.token }, quizData).then(
+ (data) => {
+ if (data.error) {
+ console.log(data.error);
+ } else {
+ console.log(data);
+ setQuiz(data);
+ setValues({ ...values, show: true });
+ }
+ }
+ );
};
return (
@@ -124,7 +124,9 @@ function NewQuiz() {
onChange={handleChange}
>
{courses.map((course, i) => (
-
+
))}
@@ -149,7 +151,15 @@ function NewQuiz() {
{problems.map((problem, index) => {
- return ;
+ return (
+
+ );
})}
@@ -173,9 +183,9 @@ function NewQuiz() {
export default NewQuiz;
function NewQuizProblem({ addProblem }) {
- // const { quizId } = useParams();
const [answers, setAnswers] = useState([""]);
const [question, setQuestion] = useState("");
+ const [correct, setCorrect] = useState()
const addAnswer = () => {
setAnswers([...answers, ""]);
@@ -194,18 +204,23 @@ function NewQuizProblem({ addProblem }) {
setAnswers(list);
};
+ const handleCorrect = (event) => {
+ const { name, value } = event.target;
+ console.log("name:", name, "value:", value);
+ setCorrect(value)
+ };
+
const handleQuestion = (event) => {
setQuestion(event.target.value);
};
const clickAdd = (event) => {
event.preventDefault();
- addProblem({ question, answers });
+ addProblem({ question, answers, correct });
};
return (
<>
- {/*
Question
{
return (
+
+
+
문제 추가
- {/* */}
>
);
}
diff --git a/src/client/src/quiz/Quiz.jsx b/src/client/src/quiz/Quiz.jsx
index 2f01874051b900deab5be31c917c47c2ff2160dc..69d312f106d853972220f2f2cca43f4566cdc538 100644
--- a/src/client/src/quiz/Quiz.jsx
+++ b/src/client/src/quiz/Quiz.jsx
@@ -2,10 +2,11 @@ import React, { useState, useEffect } from "react";
import { Link, useParams } from "react-router-dom";
import { read, removeProblem, updateProblem } from "./api-quiz";
import auth from "../auth/auth-helpers";
-import Problem from "./Problem";
import Button from "react-bootstrap/Button";
import EditableProblem from "./EditableProblem";
import Container from "react-bootstrap/Container";
+import Row from "react-bootstrap/Row";
+import Col from "react-bootstrap/Col";
function Quiz() {
const { quizId } = useParams();
@@ -21,6 +22,7 @@ function Quiz() {
if (data.error) {
console.log(data.error);
} else {
+ console.log(data);
setQuiz(data);
}
});
@@ -43,10 +45,10 @@ function Quiz() {
console.log(data.error);
} else {
console.log(data);
- const list = [...quiz.problems]
- list[index] = data
+ const list = [...quiz.problems];
+ list[index] = data;
console.log(list);
- setQuiz({...quiz, problems: list})
+ setQuiz({ ...quiz, problems: list });
}
}
);
@@ -56,21 +58,26 @@ function Quiz() {
console.log("Quiz에서 handleRemove 실행");
const problem = quiz.problems[index];
console.log(problem);
- removeProblem({problemId: problem._id}, {t: jwt.token}).then(data => {
+ removeProblem({ problemId: problem._id }, { t: jwt.token }).then((data) => {
if (data.error) {
console.log(data.error);
} else {
- console.log('deleted Problem:', data);
- const list = [...quiz.problems]
- list.splice(index, 1)
- setQuiz({...quiz, problems: list})
+ console.log("deleted Problem:", data);
+ const list = [...quiz.problems];
+ list.splice(index, 1);
+ setQuiz({ ...quiz, problems: list });
}
- })
+ });
};
return (
제목: {quiz.title}
+
+ 과목: {quiz?.course?.name}
+ 시작: {quiz?.startAt}
+ 끝: {quiz?.endAt}
+
{quiz.problems?.map((problem, i) => {
// return ;
return (
diff --git a/src/server/course/course.controller.js b/src/server/course/course.controller.js
index 037d19a5299638aacd1b4c021b25919f87de3024..98dabc1029725a4e48911c1b71f7d153b509d4b1 100644
--- a/src/server/course/course.controller.js
+++ b/src/server/course/course.controller.js
@@ -22,10 +22,34 @@ const list = async (req, res) => {
error: dbErrorHandler.getErrorMessage(error)
})
}
+}
+
+const read = (req, res) => {
+ return res.json(req.course)
+}
+const courseById = async (req, res, next, id) => {
+ // console.log('req.body in userById', req.body);
+ try {
+ let course = await Course.findById(id)
+ .exec()
+ if (!course) {
+ return res.status(400).json({
+ error: 'Course not found'
+ })
+ }
+ req.course = course
+ next()
+ } catch (error) {
+ return res.status(400).json({
+ error: 'Could not retrieve course'
+ })
+ }
}
export default {
create,
list,
+ read,
+ courseById,
}
\ No newline at end of file
diff --git a/src/server/course/course.routes.js b/src/server/course/course.routes.js
index cb6f783dbd86902bdb443bcfadb911b5c16018a9..dc05eccbe77f55620de9586db79638c144f06081 100644
--- a/src/server/course/course.routes.js
+++ b/src/server/course/course.routes.js
@@ -8,9 +8,13 @@ const router = express.Router()
router.route('/api/courses')
.get(courseCtrl.list)
+router.route('/api/courses/:courseId')
+ .get(courseCtrl.read)
+
router.route('/api/courses/by/:userId')
.post(authCtrl.requireSignin, authCtrl.hasAuthorization, userCtrl.isAdmin, courseCtrl.create)
router.param('userId', userCtrl.userById)
+router.param('courseId', courseCtrl.courseById)
export default router
\ No newline at end of file
diff --git a/src/server/quiz/problem.model.js b/src/server/quiz/problem.model.js
index 7e0ece7ebdbfc1eec3c672dd9295c17b16230c63..75b923578d7f19ba23b5688b969bac7ff896f1f4 100644
--- a/src/server/quiz/problem.model.js
+++ b/src/server/quiz/problem.model.js
@@ -20,10 +20,11 @@ const ProblemSchema = new mongoose.Schema({
score: Number, //문제당 할당 점수
question: String, //질문
answers: [String], // 선택형 항목
- correct: {
- type: mongoose.Schema.Types.ObjectId,
- ref: 'Answer'
- }, // 정답; Answer Model 객체
+ correct: String, // 정답
+ // correct: {
+ // type: mongoose.Schema.Types.ObjectId,
+ // ref: 'Answer'
+ // }, // 정답; Answer Model 객체
})
export default mongoose.model('Problem', ProblemSchema)
\ No newline at end of file
diff --git a/src/server/quiz/quiz.controller.js b/src/server/quiz/quiz.controller.js
index 4b3a2dd4c7103f3d756b5ee080bb152dec9a3931..3d4f39bc384fc17f82c25c52c5ef1603f5efe872 100644
--- a/src/server/quiz/quiz.controller.js
+++ b/src/server/quiz/quiz.controller.js
@@ -3,10 +3,11 @@ import fs from 'fs'
import dbErrorHandler from '../helpers/dbErrorHandler.js'
import Problem from './problem.model.js'
import Quiz from './quiz.model.js'
+import extend from 'lodash/extend.js'
const create = async (req, res) => {
try {
- const { title, problems } = req.body
+ const { title, problems, startAt, endAt, course } = req.body
const quiz = new Quiz()
// console.log('quiz in quiz.controller:', quiz);
@@ -22,6 +23,9 @@ const create = async (req, res) => {
}
quiz.title = title
+ quiz.startAt = startAt
+ quiz.endAt = endAt
+ quiz.course = course
quiz.author = req.profile
// console.log('quiz in quiz.controller:', quiz);
@@ -89,10 +93,11 @@ const readProblem = async (req, res) => {
const updateProblem = async (req, res) => {
try {
- const problem = req.problem
+ let problem = req.problem
console.log('req.body in updateProblem in quiz.controller', req.body);
- problem.question = req.body.question
- problem.answers = req.body.answers
+ problem = extend(problem, req.body)
+ // problem.question = req.body.question
+ // problem.answers = req.body.answers
problem.updated = new Date()
console.log('updated problem in updateProblem in quiz.controller', problem);
await problem.save()
@@ -137,6 +142,7 @@ const quizById = async (req, res, next, id) => {
const quiz = await Quiz.findById(id)
.populate('author', '_id name')
.populate('problems')
+ .populate('course', '_id name')
.exec()
if (!quiz) {
return res.status(400).json({