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
71310af1
Commit
71310af1
authored
Nov 06, 2020
by
baesangjune
Browse files
kkk
parent
92c68862
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/client/src/MainRouter.jsx
View file @
71310af1
...
@@ -33,9 +33,7 @@ function MainRouter() {
...
@@ -33,9 +33,7 @@ function MainRouter() {
<
Route
path
=
"/signup"
>
<
Route
path
=
"/signup"
>
<
Signup
/>
<
Signup
/>
</
Route
>
</
Route
>
<
Route
path
=
"/problems/:userId"
>
<
Problems
/>
</
Route
>
<
Route
path
=
"/quiz/new"
>
<
Route
path
=
"/quiz/new"
>
<
NewQuiz
/>
<
NewQuiz
/>
</
Route
>
</
Route
>
...
@@ -52,6 +50,9 @@ function MainRouter() {
...
@@ -52,6 +50,9 @@ function MainRouter() {
<
Route
path
=
"/quiz/:quizId"
>
<
Route
path
=
"/quiz/:quizId"
>
<
Quiz
/>
<
Quiz
/>
</
Route
>
</
Route
>
<
Route
path
=
"/problems/:quizId"
>
<
Problems
/>
</
Route
>
</
Switch
>
</
Switch
>
</
div
>
</
div
>
);
);
...
...
src/client/src/core/Warning.jsx
View file @
71310af1
...
@@ -6,13 +6,19 @@ import { read as readUser } from "../user/api-user";
...
@@ -6,13 +6,19 @@ import { read as readUser } from "../user/api-user";
import
{
list
,
read
as
readCourse
}
from
"
../course/api-course
"
;
import
{
list
,
read
as
readCourse
}
from
"
../course/api-course
"
;
import
{
useEffect
}
from
"
react
"
;
import
{
useEffect
}
from
"
react
"
;
import
Card
from
"
react-bootstrap/esm/Card
"
;
import
Card
from
"
react-bootstrap/esm/Card
"
;
import
{
Link
,
Redirect
}
from
"
react-router-dom
"
;
import
{
Link
,
Redirect
,
useParams
}
from
"
react-router-dom
"
;
import
authHelpers
from
"
../auth/auth-helpers
"
;
import
{
listByUserId
}
from
"
../quiz/api-quiz
"
;
function
Warning
()
{
function
Warning
()
{
const
[
data
,
setData
]
=
useState
({
name
:
""
});
const
[
data
,
setData
]
=
useState
({
name
:
""
});
const
[
courses
,
setCourses
]
=
useState
([
const
[
courses
,
setCourses
]
=
useState
([
{
name
:
""
,
description
:
""
,
code
:
""
},
{
name
:
""
,
description
:
""
,
code
:
""
},
]);
]);
const
[
quizzes
,
setQuizzes
]
=
useState
([{
id
:
""
,
course
:
""
}]);
const
{
userId
}
=
useParams
();
const
jwt
=
authHelpers
.
isAuthenticated
();
const
[
values
,
setValues
]
=
useState
({
const
[
values
,
setValues
]
=
useState
({
title
:
""
,
title
:
""
,
problems
:
[],
problems
:
[],
...
@@ -26,13 +32,26 @@ function Warning() {
...
@@ -26,13 +32,26 @@ function Warning() {
useEffect
(()
=>
{
useEffect
(()
=>
{
const
abortController
=
new
AbortController
();
const
abortController
=
new
AbortController
();
const
signal
=
abortController
.
signal
;
const
signal
=
abortController
.
signal
;
listByUserId
({
userId
:
authUser
.
user
.
_id
},
{
t
:
jwt
.
token
},
signal
).
then
((
data
)
=>
{
if
(
data
.
error
)
{
console
.
log
(
"
에러난다
"
,
data
.
error
);
}
else
{
console
.
log
(
"
quizzes=
"
,
data
);
setQuizzes
(
data
);
}
});
readUser
(
authUser
.
user
.
_id
,
{
t
:
authUser
.
token
}).
then
((
res
)
=>
{
readUser
(
authUser
.
user
.
_id
,
{
t
:
authUser
.
token
}).
then
((
res
)
=>
{
setData
(
res
);
setData
(
res
);
});
});
list
(
signal
).
then
((
res
)
=>
{
list
(
signal
).
then
((
res
)
=>
{
setCourses
(
res
);
setCourses
(
res
);
});
});
},
[]);
return
()
=>
{
abortController
.
abort
();
};
},
[
userId
]);
const
handleChange
=
(
event
)
=>
{
const
handleChange
=
(
event
)
=>
{
const
{
name
,
value
}
=
event
.
target
;
const
{
name
,
value
}
=
event
.
target
;
...
@@ -83,9 +102,20 @@ function Warning() {
...
@@ -83,9 +102,20 @@ function Warning() {
))
}
))
}
</
Form
.
Control
>
</
Form
.
Control
>
<
div
className
=
"text-right"
>
<
div
className
=
"text-right"
>
<
Link
to
=
{
`/problems/
${
authUser
.
user
.
_id
}
`
}
>
{
/* {console.log("11111 quizzes",quizzes)} */
}
<
a
className
=
"btn btn-danger"
>
Quiz Start
</
a
>
{
/* <Link to={`/problems/${quizzes[0]._id}`}> Start </Link> */
}
</
Link
>
{
quizzes
.
map
((
quiz
,
i
)
=>
{
// console.log("2222 i=",i)
return
(<>
<
Link
key
=
{
i
}
to
=
{
`/problems/
${
quiz
.
_id
}
`
}
>
<
button
className
=
"btn btn-danger"
>
{
quiz
.
course
}
</
button
>
{
/* {console.log("좀 돼라",i)} */
}
</
Link
>
{
/* <div> {console.log("3333quiz=",quiz)}</div> */
}
</>)
}
)
}
{
/* <a href="#" class="card-link">Another link</a> */
}
{
/* <a href="#" class="card-link">Another link</a> */
}
</
div
>
</
div
>
{
/* <p>시험문제 수 :</p>
{
/* <p>시험문제 수 :</p>
...
...
src/client/src/quiz/Problems.jsx
View file @
71310af1
import
React
,
{
useEffect
,
useState
}
from
"
react
"
;
import
React
,
{
useState
,
useEffect
}
from
"
react
"
;
import
{
Link
,
useParams
,
Redirect
}
from
'
react-router-dom
'
;
import
{
Link
,
useParams
}
from
"
react-router-dom
"
;
import
{
listByUserId
,
read
}
from
"
./api-quiz
"
;
import
{
read
,
removeProblem
,
updateProblem
}
from
"
./api-quiz
"
;
import
authHelpers
from
"
../auth/auth-helpers
"
;
import
auth
from
"
../auth/auth-helpers
"
;
import
Timer
from
'
react-compound-timer
'
;
import
Button
from
"
react-bootstrap/Button
"
;
import
EditableProblem
from
"
./EditableProblem
"
;
function
Problems
({
problem
,
number
,
onUpdate
,
onRemove
})
{
import
Container
from
"
react-bootstrap/Container
"
;
import
Row
from
"
react-bootstrap/Row
"
;
import
Col
from
"
react-bootstrap/Col
"
;
function
Problems
()
{
let
Time
=
1800100
let
Time
=
1800100
const
[
timeout
,
settimeout
]
=
useState
(
false
)
const
[
timeout
,
settimeout
]
=
useState
(
false
)
const
{
userId
}
=
useParams
();
const
[
problems
,
setProblems
]
=
useState
([])
const
[
quizzes
,
setQuizzes
]
=
useState
([{
title
:
""
,
author
:
""
,
course
:
""
,
problems
:
problems
,
}]);
const
jwt
=
authHelpers
.
isAuthenticated
();
const
{
quizId
}
=
useParams
();
const
{
quizId
}
=
useParams
();
const
[
quiz
,
setQuiz
]
=
useState
({
problems
:
""
,
author
:
""
,
title
:
""
,
course
:
""
});
const
jwt
=
auth
.
isAuthenticated
();
useEffect
(()
=>
{
useEffect
(()
=>
{
const
abortController
=
new
AbortController
();
const
abortController
=
new
AbortController
();
...
@@ -21,84 +25,91 @@ function Problems({ problem, number, onUpdate, onRemove }) {
...
@@ -21,84 +25,91 @@ function Problems({ problem, number, onUpdate, onRemove }) {
read
({
quizId
:
quizId
},
{
t
:
jwt
.
token
},
signal
).
then
((
data
)
=>
{
read
({
quizId
:
quizId
},
{
t
:
jwt
.
token
},
signal
).
then
((
data
)
=>
{
if
(
data
.
error
)
{
if
(
data
.
error
)
{
console
.
log
(
data
.
error
);
console
.
log
(
"
problem error
"
,
data
.
error
);
}
else
{
}
else
{
console
.
log
(
data
);
console
.
log
(
data
);
setQuiz
zes
(
data
);
setQuiz
(
data
);
}
}
});
});
return
()
=>
{
abortController
.
abort
();
listByUserId
({
userId
:
userId
},
{
t
:
jwt
.
token
},
signal
).
then
((
data
)
=>
{
};
},
[
quizId
]);
const
handleUpdate
=
(
index
,
problem
)
=>
{
console
.
log
(
`Quiz에서 handleUpdate
${
index
}
번 실행`
);
console
.
log
(
`Quiz에서 handleUpdate
${
JSON
.
stringify
(
quiz
.
problems
[
index
])}
`
);
console
.
log
(
`Quiz에서 handleUpdate updated problem
${
JSON
.
stringify
(
problem
)}
`
);
updateProblem
({
problemId
:
problem
.
_id
},
{
t
:
jwt
.
token
},
problem
).
then
(
(
data
)
=>
{
if
(
data
.
error
)
{
console
.
log
(
data
.
error
);
}
else
{
console
.
log
(
data
);
const
list
=
[...
quiz
.
problems
];
list
[
index
]
=
data
;
console
.
log
(
list
);
setQuiz
({
...
quiz
,
problems
:
list
});
}
}
);
};
const
handleRemove
=
(
index
)
=>
{
console
.
log
(
"
Quiz에서 handleRemove 실행
"
);
const
problem
=
quiz
.
problems
[
index
];
console
.
log
(
problem
);
removeProblem
({
problemId
:
problem
.
_id
},
{
t
:
jwt
.
token
}).
then
((
data
)
=>
{
if
(
data
.
error
)
{
if
(
data
.
error
)
{
console
.
log
(
data
.
error
);
console
.
log
(
data
.
error
);
}
else
{
}
else
{
console
.
log
(
data
);
console
.
log
(
"
deleted Problem:
"
,
data
);
setQuizzes
(
data
);
const
list
=
[...
quiz
.
problems
];
list
.
splice
(
index
,
1
);
setQuiz
({
...
quiz
,
problems
:
list
});
}
}
});
});
};
return
()
=>
{
abortController
.
abort
();
};
},
[
userId
]);
return
(
return
(
<>
<>
<
div
>
<
Container
>
{
console
.
log
(
"
quiz
zes=
"
,
quiz
zes
)
}
{
console
.
log
(
"
quiz
퀴즈
"
,
quiz
)
}
<
div
className
=
"container-fluid"
>
<
div
className
=
"container-fluid"
>
<
div
className
=
"text-center font-italic font-weight-bold py-2 text-muted"
>
{
quiz
zes
[
0
].
titl
e
}
</
div
>
<
div
className
=
"text-center font-italic font-weight-bold py-2 text-muted"
>
{
quiz
.
course
.
nam
e
}
</
div
>
<
div
className
=
"row justify-content-md-center"
>
<
div
className
=
"row justify-content-md-center"
>
<
div
className
=
"col-md-auto mt-4"
>
<
div
className
=
"col-md-auto mt-4"
>
<
div
className
=
"mb-4small"
>
문제 진척도
{
quizzes
[
0
].
_id
}
</
div
>
<
div
className
=
"mb-3"
>
응시자 :
{
quiz
.
author
.
name
}
<
span
className
=
"h5 text-left text-danger "
>
</
div
>
<
Timer
<
div
className
=
"mb-4small"
>
문제 진척도
</
div
>
initialTime
=
{
Time
}
direction
=
"backward"
{
/* <span className=" float-right ">
checkpoints
=
{
[
{i === quizzes.length}
{
?<Link to="/End">
time
:
1
,
<a className="btn btn-outline-danger">제출하기</a>
callback
:
()
=>
alert
(
'
시간이 초과되었습니다.
'
),
},
{
time
:
0
,
callback
:
()
=>
settimeout
(
true
),
}
]
}
>
{
()
=>
(
<>
<
Timer
.
Minutes
/>
:
<
Timer
.
Seconds
></
Timer
.
Seconds
>
/ 30 : 00
</>
)
}
</
Timer
>
{
/* npm i react-compound-timer */
}
</
span
>
<
span
className
=
" float-right "
>
<
Link
to
=
"/End"
>
<
a
className
=
"btn btn-danger"
>
제출하기
</
a
>
</Link>
</Link>
{
/* {(question.N - 1 === localQnA.length - 1)
:<button type="button" className="btn btn-outline-dark">다음</button>
? <Link to="/end">
온클릭으로 리랜더링 할 수 있게 해야함.
<button className="btn btn-outline-success" >제출</button>
</span> */
}
</Link>
: <button type="button" className="btn btn-outline-dark" onClick={handleQuestion}>다음</button>} */
}
</
span
>
<
div
className
=
"h2 mt-5"
>
<
div
className
=
"h2 mt-5"
>
<
span
className
=
'mr-4 font-weight-bold text-danger'
>
Quiz
<
span
className
=
'mr-4 font-weight-bold text-danger'
>
Quiz
<
div
></
div
>
<
div
>
{
quizzes
[
0
].
problems
}
</
div
>
</
span
>
</
span
>
</
div
>
</
div
>
<
div
className
=
"mt-2"
>
<
div
className
=
"mt-2"
>
<
form
>
<
form
>
보기자리
보기자리
{
quizze
s
.
map
((
quiz
,
i
)
=>
{
{
/* {quiz.problem
s.map((quiz,
i)
=>
{
return
<
div
>
{
quiz
.
problems
}
</
div
>
return <div>{quiz}</div>
})
}
})} */
}
{
/* {question.Choose.map((a, index) =>
{
/* {question.Choose.map((a, index) =>
<div>
<div>
<input type="radio" name='answer' id={index} value={a} onChange={handleChange} checked={selected === String(a)} />
<input type="radio" name='answer' id={index} value={a} onChange={handleChange} checked={selected === String(a)} />
<label className="font-weight-bold" htmlFor={a}>{a}</label>
<label className="font-weight-bold" htmlFor={a}>{a}</label>
...
@@ -112,50 +123,11 @@ function Problems({ problem, number, onUpdate, onRemove }) {
...
@@ -112,50 +123,11 @@ function Problems({ problem, number, onUpdate, onRemove }) {
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
{
timeout
?
<
Redirect
to
=
'/End'
/>
:
''
}
</
div
>
</
Container
>
</>
</>
// <div>
)
// {quizzes.map((quiz, i) => {
// return (
// <Link key={i} to={`/quiz/${quiz._id}`}>
// // <Card>
// <Card.Body>
// <Card.Title>
// {i + 1}번. {quiz}
// </Card.Title>
// Answers
// {problem.answers.map((answer, index) => {
// return <Card.Text key={index}>{answer}</Card.Text>;
// })}
// <Link to={`/quiz/problem/edit/${problem._id}`}>
// <Button onClick={(event) => onUpdate(number)}>수정</Button>
// </Link>
// <Button onClick={() => onRemove(number)}>삭제</Button>
// </Card.Body>
// </Card>
// </Link>
// );
// })}
// </div>
// <Card>
// <Card.Body>
// <Card.Title>
// {number + 1}번. {problem.question}
// </Card.Title>
// Answers
// {problem.answers.map((answer, index) => {
// return <Card.Text key={index}>{answer}</Card.Text>;
// })}
// <Link to={`/quiz/problem/edit/${problem._id}`}>
// <Button onClick={(event) => onUpdate(number)}>수정</Button>
// </Link>
// <Button onClick={() => onRemove(number)}>삭제</Button>
// </Card.Body>
// </Card>
);
}
}
export
default
Problems
;
export
default
Problems
;
\ No newline at end of file
src/client/src/quiz/SpreadProblem.jsx
0 → 100644
View file @
71310af1
import
React
,
{
useState
}
from
"
react
"
;
function
SpreadProblem
({
problem
,
number
}){
return
(
<
div
>
</
div
>
)
}
export
default
SpreadProblem
();
\ No newline at end of file
src/client/src/quiz/test.jsx
0 → 100644
View file @
71310af1
import
React
,
{
useEffect
,
useState
}
from
"
react
"
;
import
{
Link
,
useParams
,
Redirect
}
from
'
react-router-dom
'
;
import
{
listByUserId
,
read
as
readQuiz
}
from
"
./api-quiz
"
;
import
{
list
,
read
as
readCourse
}
from
"
../course/api-course
"
;
import
{
read
as
readUser
}
from
"
../user/api-user
"
;
import
authHelpers
from
"
../auth/auth-helpers
"
;
import
Timer
from
'
react-compound-timer
'
;
import
{
useAuth
}
from
"
../auth/auth-context
"
;
import
Card
from
"
react-bootstrap/Card
"
;
function
Problems
({
problem
,
number
,
onUpdate
,
onRemove
})
{
let
Time
=
1800100
const
[
timeout
,
settimeout
]
=
useState
(
false
)
// const { quizId } = useParams();
const
{
userId
}
=
useParams
();
// const [problems, setProblems] = useState([])
const
[
quizzes
,
setQuizzes
]
=
useState
([{
title
:
""
,
author
:
""
,
course
:
""
}]);
const
jwt
=
authHelpers
.
isAuthenticated
();
const
[
quiz
,
setQuiz
]
=
useState
({});
const
[
data
,
setData
]
=
useState
({
name
:
""
});
const
[
courses
,
setCourses
]
=
useState
([
{
name
:
""
,
description
:
""
,
code
:
""
},
]);
const
{
authUser
}
=
useAuth
();
useEffect
(()
=>
{
const
abortController
=
new
AbortController
();
const
signal
=
abortController
.
signal
;
// readQuiz({ quizId: quizId }, { t: jwt.token }, signal).then((data) => {
// if (data.error) {
// console.log(data.error);
// } else {
// console.log("readQuiz=",data);
// setQuiz(data);
// }
// });
readUser
(
authUser
.
user
.
_id
,
{
t
:
authUser
.
token
}).
then
((
res
)
=>
{
setData
(
res
);
});
list
(
signal
).
then
((
res
)
=>
{
setCourses
(
res
);
});
listByUserId
({
userId
:
userId
},
{
t
:
jwt
.
token
},
signal
).
then
((
data
)
=>
{
if
(
data
.
error
)
{
console
.
log
(
data
.
error
);
}
else
{
console
.
log
(
"
data=
"
,
data
);
setQuizzes
(
data
);
}
});
return
()
=>
{
abortController
.
abort
();
};
},
[
userId
]);
return
(
<>
<
div
>
{
quizzes
.
map
((
quiz
,
i
)
=>
{
return
(
<>
{
/* <Link key={i} to={`/quiz/${quiz._id}`}>
<Card>
<Card.Body>
<Card.Title>제목: {quiz.title}</Card.Title>
<Card.Text>만든날: {quiz.created}</Card.Text>
</Card.Body>
</Card>
</Link> */
}
{
/* {console.log("quizzes=", quizzes)} */
}
<
div
className
=
"container-fluid"
>
<
div
className
=
"text-center font-italic font-weight-bold py-2 text-muted"
>
{
courses
[
0
].
name
}
</
div
>
<
div
className
=
"row justify-content-md-center"
>
<
div
className
=
"col-md-auto mt-4"
>
<
div
className
=
"mb-3"
>
응시자 :
{
data
.
name
}
</
div
>
<
div
className
=
"mb-4small"
>
문제 진척도
{
quiz
.
problems
}
</
div
>
<
span
className
=
" float-right "
>
{
i
===
quizzes
.
length
}
?
<
Link
to
=
"/End"
>
<
a
className
=
"btn btn-outline-danger"
>
제출하기
</
a
>
</
Link
>
:
<
button
type
=
"button"
className
=
"btn btn-outline-dark"
>
다음
</
button
>
{
/* 온클릭으로 리랜더링 할 수 있게 해야함. */
}
</
span
>
<
div
className
=
"h2 mt-5"
>
<
span
className
=
'mr-4 font-weight-bold text-danger'
>
Quiz
<
div
>
{
quizzes
[
0
].
problems
}
</
div
>
</
span
>
</
div
>
<
div
className
=
"mt-2"
>
<
form
>
보기자리
{
/* {quiz.problems.map((quiz, i) => {
return <div>{quiz}</div>
})} */
}
{
/* {question.Choose.map((a, index) =>
<div>
<input type="radio" name='answer' id={index} value={a} onChange={handleChange} checked={selected === String(a)} />
<label className="font-weight-bold" htmlFor={a}>{a}</label>
</div>
)} */
}
</
form
>
<
span
className
=
"h5 font-weight-bold"
>
Your Answer :
</
span
>
<
span
className
=
"h2 font-weight-bold text-danger"
>
selected
</
span
>
</
div
>
</
div
>
<
div
className
=
"col"
>
</
div
>
</
div
>
</
div
>
</>
)
})
}
<
span
className
=
"h5 text-left text-danger "
>
<
Timer
initialTime
=
{
Time
}
direction
=
"backward"
checkpoints
=
{
[
{
time
:
1
,
callback
:
()
=>
alert
(
'
시간이 초과되어 결과페이지로 이동합니다.
'
),
},
{
time
:
0
,
callback
:
()
=>
settimeout
(
true
),
}
]
}
>
{
()
=>
(
<>
<
Timer
.
Minutes
/>
:
<
Timer
.
Seconds
></
Timer
.
Seconds
>
/ 30 : 00
</>
)
}
</
Timer
>
{
/* npm i react-compound-timer */
}
</
span
>
{
timeout
?
<
Redirect
to
=
'/End'
/>
:
''
}
</
div
>
</>
// <div>
// {quizzes.map((quiz, i) => {
// return (
// <Link key={i} to={`/quiz/${quiz._id}`}>
// // <Card>
// <Card.Body>
// <Card.Title>
// {i + 1}번. {quiz}
// </Card.Title>
// Answers
// {problem.answers.map((answer, index) => {
// return <Card.Text key={index}>{answer}</Card.Text>;
// })}
// <Link to={`/quiz/problem/edit/${problem._id}`}>
// <Button onClick={(event) => onUpdate(number)}>수정</Button>
// </Link>
// <Button onClick={() => onRemove(number)}>삭제</Button>
// </Card.Body>
// </Card>
// </Link>
// );
// })}
// </div>
// <Card>
// <Card.Body>
// <Card.Title>
// {number + 1}번. {problem.question}
// </Card.Title>
// Answers
// {problem.answers.map((answer, index) => {
// return <Card.Text key={index}>{answer}</Card.Text>;
// })}
// <Link to={`/quiz/problem/edit/${problem._id}`}>
// <Button onClick={(event) => onUpdate(number)}>수정</Button>
// </Link>
// <Button onClick={() => onRemove(number)}>삭제</Button>
// </Card.Body>
// </Card>
);
}
export
default
Problems
;
src/server/quiz/quiz.controller.js
View file @
71310af1
...
@@ -82,8 +82,7 @@ const isProblemAuthor = (req, res, next) => {
...
@@ -82,8 +82,7 @@ const isProblemAuthor = (req, res, next) => {
}
}
const
read
=
async
(
req
,
res
)
=>
{
const
read
=
async
(
req
,
res
)
=>
{
let
quiz
=
req
.
body
.
quiz
let
quiz
=
req
.
quiz
console
.
log
(
"
섭에어버
"
,
quiz
)
res
.
json
(
quiz
)
res
.
json
(
quiz
)
}
}
...
...
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