Commit 1c18d0e1 authored by Yoon, Daeki's avatar Yoon, Daeki 😅
Browse files

정답 추가

parent 9d96ee41
# 퀴즈 출제 페이지
## 실행 방법
1. 두 개의 터미널을 엽니다.
1. 한쪽 터미널(서버)에서는, 프로젝트 디렉토리에서 `yarn install`을 실행합니다.(이것은 패키지가 변경될 때마다 실행합니다.)
1. 다른쪽 터미널(클라이언트)에서는, `cd src\client` 해서 `yarn install` 을 실행합니다.(이것은 패키지가 변경될 때마다 실행합니다.)
1. 서버 터미널에서 `yarn dev`를 실행합니다.
1. 클라이언트 터미널에서 `yarn start` 를 실행합니다.
1. 코드를 수정합니다.
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) => {
/>
</Form.Group>
<Form.Label>Answers</Form.Label>
{/* <ToggleButtonGroup type="radio" name="radio" > */}
{problem.answers.map((answer, index) => {
return (
<Form.Row key={index}>
<Col>
<Form.Check
type="radio"
value={index}
name="correct"
onChange={handleCorrect}
/>
</Col>
<Col>
<Form.Control
value={answer}
......@@ -49,6 +60,7 @@ const EditableForm = (props) => {
</Form.Row>
);
})}
{/* </ToggleButtonGroup> */}
<Button onClick={(event) => handleSave(event, number)}>저장</Button>
<Button onClick={handleCancel}>취소</Button>
</Form>
......@@ -65,6 +77,7 @@ const CardForm = (props) => {
{problem.answers.map((answer, index) => {
return <Card.Text key={index}>{answer}</Card.Text>;
})}
<Card.Text>정답: {+problem.correct + 1}</Card.Text>
<Button onClick={handleEditable}>수정</Button>
<Button onClick={() => onRemove(number)}>삭제</Button>
</Card.Body>
......@@ -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 }) {
<EditableForm
number={number}
problem={problemEdit}
handleCorrect={handleCorrect}
handleSave={handleSave}
handleCancel={handleCancel}
removeAnswer={removeAnswer}
......
......@@ -11,7 +11,8 @@ function NewProblem({ addProblem }) {
const { quizId } = useParams();
const [answers, setAnswers] = useState([""]);
const [question, setQuestion] = useState("");
const [show, setShow] = useState(false)
const [correct, setCorrect] = useState()
const [show, setShow] = useState(false);
const jwt = authHelpers.isAuthenticated();
......@@ -32,6 +33,12 @@ function NewProblem({ 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);
};
......@@ -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 (
<Form.Row key={index}>
<Col>
<Form.Check
type="radio"
value={index}
name="correct"
onChange={handleCorrect}
/>
</Col>
<Col>
<Form.Control
type="text"
......@@ -95,9 +111,7 @@ function NewProblem({ addProblem }) {
</Form>
<Modal show={show}>
<Modal.Header>New Problem</Modal.Header>
<Modal.Body>
Problem successfully created.
</Modal.Body>
<Modal.Body>Problem successfully created.</Modal.Body>
<Modal.Footer>
<Link to={`/quiz/${quizId}`}>
<Button>Go to quiz</Button>
......
......@@ -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,20 +28,20 @@ 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;
......@@ -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) => (
<option key={i} value={i}>{course.name}</option>
<option key={i} value={i}>
{course.name}
</option>
))}
</Form.Control>
</Form.Group>
......@@ -149,7 +151,15 @@ function NewQuiz() {
</Form.Row>
{problems.map((problem, index) => {
return <Problem key={index} problem={problem} number={index} onUpdate={handleUpdate} onRemove={handleRemove}/>;
return (
<Problem
key={index}
problem={problem}
number={index}
onUpdate={handleUpdate}
onRemove={handleRemove}
/>
);
})}
<NewQuizProblem addProblem={addProblem} />
<Button onClick={clickSubmit}>퀴즈 저장</Button>
......@@ -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 (
<>
{/* <Form> */}
<Form.Group controlId="question">
<Form.Label>Question</Form.Label>
<Form.Control
......@@ -219,6 +234,14 @@ function NewQuizProblem({ addProblem }) {
{answers.map((answer, index) => {
return (
<Form.Row key={index}>
<Col>
<Form.Check
type="radio"
value={index}
name="correct"
onChange={handleCorrect}
/>
</Col>
<Col>
<Form.Control
type="text"
......@@ -238,7 +261,6 @@ function NewQuizProblem({ addProblem }) {
);
})}
<Button onClick={clickAdd}>문제 추가</Button>
{/* </Form> */}
</>
);
}
......@@ -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 (
<Container>
<h2 className="text-center">제목: {quiz.title}</h2>
<Row>
<Col md={4}>과목: {quiz?.course?.name}</Col>
<Col md={4}>시작: {quiz?.startAt}</Col>
<Col md={4}>끝: {quiz?.endAt}</Col>
</Row>
{quiz.problems?.map((problem, i) => {
// return <Problem key={i} problem={problem} number={i} onUpdate={handleUpdate} onRemove={handleRemove} />;
return (
......
......@@ -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
......@@ -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
......@@ -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
......@@ -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({
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment