Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
students
quiz-competition
Commits
1c18d0e1
Commit
1c18d0e1
authored
Oct 05, 2020
by
Yoon, Daeki
😅
Browse files
정답 추가
parent
9d96ee41
Changes
9
Hide whitespace changes
Inline
Side-by-side
README.md
0 → 100644
View file @
1c18d0e1
# 퀴즈 출제 페이지
## 실행 방법
1.
두 개의 터미널을 엽니다.
1.
한쪽 터미널(서버)에서는, 프로젝트 디렉토리에서
`yarn install`
을 실행합니다.(이것은 패키지가 변경될 때마다 실행합니다.)
1.
다른쪽 터미널(클라이언트)에서는,
`cd src\client`
해서
`yarn install`
을 실행합니다.(이것은 패키지가 변경될 때마다 실행합니다.)
1.
서버 터미널에서
`yarn dev`
를 실행합니다.
1.
클라이언트 터미널에서
`yarn start`
를 실행합니다.
1.
코드를 수정합니다.
src/client/src/quiz/EditableProblem.jsx
View file @
1c18d0e1
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
}
...
...
src/client/src/quiz/NewProblem.jsx
View file @
1c18d0e1
...
...
@@ -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
>
...
...
src/client/src/quiz/NewQuiz.jsx
View file @
1c18d0e1
...
...
@@ -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);
//
set
S
how
(
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
);
set
Values
({
...
values
,
s
how
:
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> */
}
</>
);
}
src/client/src/quiz/Quiz.jsx
View file @
1c18d0e1
...
...
@@ -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
(
...
...
src/server/course/course.controller.js
View file @
1c18d0e1
...
...
@@ -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
src/server/course/course.routes.js
View file @
1c18d0e1
...
...
@@ -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
src/server/quiz/problem.model.js
View file @
1c18d0e1
...
...
@@ -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
src/server/quiz/quiz.controller.js
View file @
1c18d0e1
...
...
@@ -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
{
cons
t
problem
=
req
.
problem
le
t
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
({
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment