From 1c18d0e111d1be433ce2c7b19b4e2d7e8c2d6ee8 Mon Sep 17 00:00:00 2001 From: "Yoon, Daeki" Date: Mon, 5 Oct 2020 14:11:46 +0900 Subject: [PATCH] =?UTF-8?q?=EC=A0=95=EB=8B=B5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +++ src/client/src/quiz/EditableProblem.jsx | 28 ++++++-- src/client/src/quiz/NewProblem.jsx | 24 +++++-- src/client/src/quiz/NewQuiz.jsx | 90 +++++++++++++++---------- src/client/src/quiz/Quiz.jsx | 27 +++++--- src/server/course/course.controller.js | 24 +++++++ src/server/course/course.routes.js | 4 ++ src/server/quiz/problem.model.js | 9 +-- src/server/quiz/quiz.controller.js | 14 ++-- 9 files changed, 169 insertions(+), 61 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f6cd364 --- /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 6b05102..ccbe227 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 8131c28..5df71f4 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 2f01874..69d312f 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 037d19a..98dabc1 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 cb6f783..dc05ecc 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 7e0ece7..75b9235 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 4b3a2dd..3d4f39b 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({ -- GitLab