Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
students
survey
Commits
578446f7
Commit
578446f7
authored
Jul 25, 2022
by
Jiwon Yoon
Browse files
result 불러오기 완성
parent
6262a322
Changes
9
Show whitespace changes
Inline
Side-by-side
frontend/src/SurveyRouter.tsx
View file @
578446f7
...
@@ -18,11 +18,11 @@ export const SurveyRouter = () => {
...
@@ -18,11 +18,11 @@ export const SurveyRouter = () => {
<
Route
index
element
=
{
<
Home
/>
}
/>
<
Route
index
element
=
{
<
Home
/>
}
/>
<
Route
path
=
"login"
element
=
{
<
Login
/>
}
/>
<
Route
path
=
"login"
element
=
{
<
Login
/>
}
/>
<
Route
path
=
"signup"
element
=
{
<
SignUp
/>
}
/>
<
Route
path
=
"signup"
element
=
{
<
SignUp
/>
}
/>
<
Route
path
=
"surveys/
edit
/"
element
=
{
<
EditResultButton
/>
}
>
<
Route
path
=
"surveys/
:surveyId
/"
element
=
{
<
EditResultButton
/>
}
>
<
Route
path
=
"
:surveyId
"
element
=
{
<
EditSurvey
/>
}
/>
<
Route
path
=
"
edit
"
element
=
{
<
EditSurvey
/>
}
/>
<
Route
path
=
"
:surveyId/
result"
element
=
{
<
ResultSurvey
/>
}
/>
<
Route
path
=
"result"
element
=
{
<
ResultSurvey
/>
}
/>
</
Route
>
</
Route
>
<
Route
path
=
"survey
s
/:surveyId"
element
=
{
<
AnswerSurveyForm
/>
}
/>
<
Route
path
=
"survey/:surveyId"
element
=
{
<
AnswerSurveyForm
/>
}
/>
<
Route
<
Route
path
=
"profile"
path
=
"profile"
element
=
{
element
=
{
...
...
frontend/src/profile/MySurveyCard.tsx
View file @
578446f7
...
@@ -16,20 +16,14 @@ export const MySurveyCard = ({ data }: Props) => {
...
@@ -16,20 +16,14 @@ export const MySurveyCard = ({ data }: Props) => {
const
[
success
,
setSuccess
]
=
useState
(
false
);
const
[
success
,
setSuccess
]
=
useState
(
false
);
const
editSurvey
=
()
=>
{
const
editSurvey
=
()
=>
{
navigate
(
`/surveys/
edit/
${
data
.
_id
}
`
,
{
navigate
(
`/surveys/
${
data
.
_id
}
/edit
`
,
{
replace
:
true
,
replace
:
true
,
state
:
{
save
:
true
},
state
:
{
save
:
true
},
});
});
};
};
const
goSurvey
=
()
=>
{
navigate
(
`/surveys/
${
data
.
_id
}
`
,
{
replace
:
true
,
});
};
const
copyLink
=
()
=>
{
const
copyLink
=
()
=>
{
navigator
.
clipboard
.
writeText
(
`http://localhost:8080/survey
s
/
${
data
.
_id
}
`
);
navigator
.
clipboard
.
writeText
(
`http://localhost:8080/survey/
${
data
.
_id
}
`
);
alert
(
"
설문조사의 링크가 클립보드에 저장되었습니다.
"
);
alert
(
"
설문조사의 링크가 클립보드에 저장되었습니다.
"
);
};
};
...
...
frontend/src/profile/Profile.tsx
View file @
578446f7
...
@@ -21,7 +21,7 @@ export const Profile = () => {
...
@@ -21,7 +21,7 @@ export const Profile = () => {
async
function
createSurvey
()
{
async
function
createSurvey
()
{
const
newSurvey
:
SurveyType
=
await
surveyApi
.
createSurvey
(
survey
);
const
newSurvey
:
SurveyType
=
await
surveyApi
.
createSurvey
(
survey
);
navigate
(
`/surveys/
edit/
${
newSurvey
.
_id
}
`
,
{
navigate
(
`/surveys/
${
newSurvey
.
_id
}
/edit
`
,
{
replace
:
true
,
replace
:
true
,
});
});
}
}
...
@@ -36,7 +36,6 @@ export const Profile = () => {
...
@@ -36,7 +36,6 @@ export const Profile = () => {
return
(
return
(
<
div
className
=
"flex flex-col items-center"
>
<
div
className
=
"flex flex-col items-center"
>
<
div
className
=
"mt-10 text-xl font-bold"
>
나의 설문조사
</
div
>
<
div
className
=
"mt-10 text-xl font-bold"
>
나의 설문조사
</
div
>
<
img
src
=
{
`
${
baseImageUrl
}
/9e24ad36a2947b08c89913b01`
}
/>
<
div
className
=
"grid grid-cols-1 md:grid-cols-4 sm:grid-cols-2 gap-4 mt-6"
>
<
div
className
=
"grid grid-cols-1 md:grid-cols-4 sm:grid-cols-2 gap-4 mt-6"
>
<
button
<
button
onClick
=
{
createSurvey
}
onClick
=
{
createSurvey
}
...
...
frontend/src/survey/Accordion.tsx
View file @
578446f7
import
React
,
{
useState
,
useRef
}
from
"
react
"
;
import
React
,
{
useState
,
useRef
,
useEffect
}
from
"
react
"
;
import
{
baseImageUrl
}
from
"
../apis
"
;
import
{
BasicQuestionType
}
from
"
../types
"
;
import
{
BasicQuestionType
}
from
"
../types
"
;
type
AccordionProps
=
{
type
AccordionProps
=
{
question
:
any
;
question
:
any
;
answers
:
any
;
};
};
const
Accordion
=
({
question
,
answers
}:
AccordionProps
)
=>
{
const
Accordion
=
({
question
}:
AccordionProps
)
=>
{
const
[
isOpened
,
setOpened
]
=
useState
<
boolean
>
(
false
);
const
[
isOpened
,
setOpened
]
=
useState
<
boolean
>
(
false
);
const
[
height
,
setHeight
]
=
useState
<
string
>
(
"
0px
"
);
const
[
height
,
setHeight
]
=
useState
<
string
>
(
"
0px
"
);
const
contentElement
=
useRef
<
HTMLDivElement
>
(
null
);
const
contentElement
=
useRef
<
HTMLDivElement
>
(
null
);
// useEffect(() => {
// if (question.type === "file") {
// getFiles();
// }
// }, []);
// async function getFiles() {
// try {
// } catch (error) {}
// }
const
HandleOpening
=
()
=>
{
const
HandleOpening
=
()
=>
{
setOpened
(
!
isOpened
);
setOpened
(
!
isOpened
);
setHeight
(
!
isOpened
?
`
${
contentElement
.
current
?.
scrollHeight
}
px`
:
"
0px
"
);
setHeight
(
!
isOpened
?
`
${
contentElement
.
current
?.
scrollHeight
}
px`
:
"
0px
"
);
...
@@ -26,8 +37,16 @@ const Accordion = ({ question, answers }: AccordionProps) => {
...
@@ -26,8 +37,16 @@ const Accordion = ({ question, answers }: AccordionProps) => {
style
=
{
{
height
:
height
}
}
style
=
{
{
height
:
height
}
}
className
=
"bg-gray-100 overflow-hidden transition-all duration-700"
className
=
"bg-gray-100 overflow-hidden transition-all duration-700"
>
>
{
answers
.
map
((
answer
:
any
)
=>
(
{
question
.
type
===
"
file
"
<
p
className
=
"p-4"
>
{
answer
.
answer
}
</
p
>
?
question
.
answers
.
map
((
answer
:
any
)
=>
(
<
img
key
=
{
answer
.
url
}
alt
=
"file"
src
=
{
`
${
baseImageUrl
}
/
${
answer
.
url
}
`
}
/>
))
:
question
.
answers
.
map
((
answer
:
any
)
=>
(
<
p
className
=
"p-4"
>
{
answer
}
</
p
>
))
}
))
}
</
div
>
</
div
>
</
div
>
</
div
>
...
...
frontend/src/survey/EditResultButton.tsx
View file @
578446f7
...
@@ -6,18 +6,11 @@ export const EditResultButton = () => {
...
@@ -6,18 +6,11 @@ export const EditResultButton = () => {
let
{
surveyId
}
=
useParams
<
{
surveyId
:
string
}
>
();
let
{
surveyId
}
=
useParams
<
{
surveyId
:
string
}
>
();
const
navigate
=
useNavigate
();
const
navigate
=
useNavigate
();
/*function editButtonClick(e: React.MouseEvent<HTMLButtonElement>) {
navigate(`/surveys/${surveyId}/edit`);
}
function resultButtonClick(e: React.MouseEvent<HTMLButtonElement>) {
navigate(`/surveys/${surveyId}/result`);
}*/
return
(
return
(
<
div
>
<
div
>
<
div
className
=
"flex place-content-center mt-6"
>
<
div
className
=
"flex place-content-center mt-6"
>
<
NavLink
<
NavLink
to
=
{
`/surveys/
edit/
${
surveyId
}
`
}
to
=
{
`/surveys/
${
surveyId
}
/edit
`
}
style
=
{
({
isActive
})
=>
style
=
{
({
isActive
})
=>
isActive
isActive
?
{
?
{
...
@@ -33,7 +26,7 @@ export const EditResultButton = () => {
...
@@ -33,7 +26,7 @@ export const EditResultButton = () => {
<
div
className
=
"text-xl m-3 "
>
설문지 수정
</
div
>
<
div
className
=
"text-xl m-3 "
>
설문지 수정
</
div
>
</
NavLink
>
</
NavLink
>
<
NavLink
<
NavLink
to
=
{
`/surveys/
edit/
${
surveyId
}
/result`
}
to
=
{
`/surveys/
${
surveyId
}
/result`
}
style
=
{
({
isActive
})
=>
style
=
{
({
isActive
})
=>
isActive
isActive
?
{
?
{
...
...
frontend/src/survey/ResultSurvey.tsx
View file @
578446f7
import
React
,
{
useEffect
,
useState
}
from
"
react
"
;
import
React
,
{
useEffect
,
useState
}
from
"
react
"
;
import
{
answerApi
}
from
"
../apis
"
;
import
{
answerApi
,
surveyApi
}
from
"
../apis
"
;
import
{
catchErrors
}
from
"
../helpers
"
;
import
{
catchErrors
}
from
"
../helpers
"
;
import
Accordion
from
"
./Accordion
"
;
import
Accordion
from
"
./Accordion
"
;
import
{
useParams
}
from
"
react-router-dom
"
;
import
{
useParams
}
from
"
react-router-dom
"
;
import
{
SurveyType
}
from
"
../types
"
;
export
const
ResultSurvey
=
()
=>
{
export
const
ResultSurvey
=
()
=>
{
let
{
surveyId
}
=
useParams
<
{
surveyId
:
string
}
>
();
const
[
error
,
setError
]
=
useState
(
""
);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
success
,
setSuccess
]
=
useState
(
false
);
const
[
success
,
setSuccess
]
=
useState
(
false
);
const
[
answers
,
setAnswers
]
=
useState
([
const
[
survey
,
setSurvey
]
=
useState
<
SurveyType
>
({
{
_id
:
""
,
answers
:
[],
question
:
{}
},
_id
:
surveyId
||
""
,
]);
user
:
{},
let
{
surveyId
}
=
useParams
<
{
surveyId
:
string
}
>
();
title
:
""
,
comment
:
""
,
questions
:
[],
});
useEffect
(()
=>
{
useEffect
(()
=>
{
getAnswers
();
getAnswers
();
},
[
surveyId
]);
},
[
surveyId
]);
...
@@ -19,9 +24,9 @@ export const ResultSurvey = () => {
...
@@ -19,9 +24,9 @@ export const ResultSurvey = () => {
async
function
getAnswers
()
{
async
function
getAnswers
()
{
try
{
try
{
if
(
surveyId
)
{
if
(
surveyId
)
{
const
answers
=
await
answerApi
.
getAnswers
(
surveyId
);
const
survey
=
await
answerApi
.
getAnswers
(
surveyId
);
console
.
log
(
answers
);
console
.
log
(
survey
);
set
Answers
(
answers
);
set
Survey
(
survey
);
}
else
{
}
else
{
setLoading
(
true
);
setLoading
(
true
);
}
}
...
@@ -32,40 +37,20 @@ export const ResultSurvey = () => {
...
@@ -32,40 +37,20 @@ export const ResultSurvey = () => {
}
}
}
}
const
data
=
[
{
title
:
"
1번질문
"
,
content
:
"
1번 답변들asdfadsgsjadhfasld;nvaldkfnbljgnahgvlajnbl janl;nvja; sabv;jnsvjl;asjvh asjfagkfnjf;nvasgn va;sdn va sglanksvl ds af adb adf afg dgafbg dfh jbvlkna lkslbk kjv nbkkdlfn akdl nvjbnkdjf nlkbakdn bkjnakjn n knk
"
,
},
{
title
:
"
2번질문
"
,
content
:
"
2번답변들
"
,
},
{
title
:
"
3번질문
"
,
content
:
"
3번답변들
"
,
},
];
return
(
return
(
<
div
className
=
"flex flex-col place-items-center"
>
<
div
className
=
"flex flex-col place-items-center"
>
<
div
className
=
"flex flex-col container place-items-center mt-4"
>
<
div
className
=
"flex flex-col container place-items-center mt-4"
>
<
div
className
=
"font-bold text-4xl text-center m-2 border-b-2"
>
<
div
className
=
"font-bold text-4xl text-center m-2 border-b-2"
>
설문지 제목
{
survey
.
title
}
</
div
>
</
div
>
<
div
className
=
"font-bold text-1xl text-center m-2 resize-none"
>
<
div
className
=
"font-bold text-1xl text-center m-2 resize-none"
>
설문조사 설명
{
survey
.
comment
}
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className
=
"container w-11/12 place-self-center"
>
<
div
className
=
"container w-11/12 place-self-center"
>
{
answers
.
map
((
item
)
=>
(
{
survey
.
questions
.
map
((
question
)
=>
(
<
Accordion
<
Accordion
key
=
{
question
.
_id
}
question
=
{
question
}
/>
key
=
{
item
.
_id
}
question
=
{
item
.
question
}
answers
=
{
item
.
answers
}
/>
))
}
))
}
</
div
>
</
div
>
</
div
>
</
div
>
...
...
frontend/src/types/index.ts
View file @
578446f7
...
@@ -27,6 +27,7 @@ export interface BasicQuestionType {
...
@@ -27,6 +27,7 @@ export interface BasicQuestionType {
isRequired
:
boolean
;
isRequired
:
boolean
;
comment
:
string
;
comment
:
string
;
content
:
any
;
content
:
any
;
answers
?:
any
;
[
key
:
string
]:
string
|
number
|
boolean
|
any
;
[
key
:
string
]:
string
|
number
|
boolean
|
any
;
}
}
...
...
src/controllers/answer.controller.ts
View file @
578446f7
...
@@ -3,7 +3,7 @@ import { asyncWrap } from "../helpers";
...
@@ -3,7 +3,7 @@ import { asyncWrap } from "../helpers";
import
{
TypedRequest
}
from
"
../types
"
;
import
{
TypedRequest
}
from
"
../types
"
;
import
formidable
from
"
formidable
"
;
import
formidable
from
"
formidable
"
;
import
{
FileInfo
}
from
"
../models
"
;
import
{
FileInfo
}
from
"
../models
"
;
import
{
fileDb
,
userDb
,
answerDb
}
from
"
../db
"
;
import
{
fileDb
,
userDb
,
answerDb
,
surveyDb
}
from
"
../db
"
;
import
fs
from
"
fs/promises
"
;
import
fs
from
"
fs/promises
"
;
export
const
createAnswers
=
asyncWrap
(
async
(
reqExp
,
res
)
=>
{
export
const
createAnswers
=
asyncWrap
(
async
(
reqExp
,
res
)
=>
{
...
@@ -11,14 +11,18 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
...
@@ -11,14 +11,18 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
const
answer
=
req
.
body
;
const
answer
=
req
.
body
;
const
answers
=
JSON
.
parse
(
answer
.
answers
);
const
answers
=
JSON
.
parse
(
answer
.
answers
);
answer
.
answers
=
answers
;
answer
.
answers
=
answers
;
const
files
=
req
.
files
.
uploadFiles
as
formidable
.
File
[];
let
files
:
any
[]
=
[];
if
(
Array
.
isArray
(
req
.
files
.
uploadFiles
))
{
files
=
req
.
files
.
uploadFiles
as
formidable
.
File
[];
}
else
{
files
.
push
(
req
.
files
.
uploadFiles
);
}
let
uploadFile
;
let
uploadFile
;
try
{
try
{
if
(
files
)
{
if
(
files
)
{
// 1) 파일을 DB에 저장 후 다시 retFile가져와서
// 1) 파일을 DB에 저장 후 다시 retFile가져와서
// *근데 파일이 여러 개일 수 있기 때문에 순회해야 됨-map()을 쓰면 async function이 되어버려서 for문 이용함
// *근데 파일이 여러 개일 수 있기 때문에 순회해야 됨
for
(
let
index
=
0
;
index
<
files
.
length
;
index
++
)
{
const
f
=
files
.
map
(
async
(
file
)
=>
{
const
file
=
files
[
index
];
uploadFile
=
new
FileInfo
({
uploadFile
=
new
FileInfo
({
name
:
file
.
originalFilename
,
name
:
file
.
originalFilename
,
url
:
file
.
newFilename
,
url
:
file
.
newFilename
,
...
@@ -31,26 +35,24 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
...
@@ -31,26 +35,24 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
);
);
// 3) answer에다가 retFile의 _id 넣어주기
// 3) answer에다가 retFile의 _id 넣어주기
targetObj
.
answer
=
retFile
.
_id
;
targetObj
.
answer
=
retFile
.
_id
;
}
});
await
Promise
.
all
(
f
);
}
}
// 3) Answer DB 만들기
// 3) Answer DB 만들기
console
.
log
(
"
원래 answer
"
,
answer
);
const
c
=
answer
.
answers
.
map
(
async
(
element
:
any
)
=>
{
console
.
log
(
"
원래 answer
"
,
answer
.
answers
.
length
);
const
newAnswer
=
await
answerDb
.
createAnswer
({
// for (let index = 0; index < answer.answers.length; index++) {
surveyId
:
answer
.
surveyId
,
// const element = answer.answers[index];
guestId
:
answer
.
guestId
,
// const newAnswer = await answerDb.createAnswer({
questionId
:
element
.
questionId
,
// surveyId: answer.surveyId,
answer
:
element
.
answer
,
// guestId: answer.guestId,
});
// questionId: element.questionId,
});
// answer: element.answer,
await
Promise
.
all
(
c
);
// });
// // console.log("DB에 넣은 answer", newAnswer);
// }
return
res
.
json
();
return
res
.
json
();
}
catch
(
error
:
any
)
{
}
catch
(
error
:
any
)
{
console
.
log
(
"
error in create answer:
"
,
error
);
console
.
log
(
"
error in create answer:
"
,
error
);
// 오류 발생시 저장된 파일 제거
// 오류 발생시 저장된 파일 제거
if
(
files
)
{
if
(
req
.
files
)
{
// uploadFiles && (await fileDb.deleteFileById(uploadFiles._id.toString()));
// uploadFiles && (await fileDb.deleteFileById(uploadFiles._id.toString()));
// await fs.unlink(files.filepath);
// await fs.unlink(files.filepath);
}
}
...
@@ -61,11 +63,27 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
...
@@ -61,11 +63,27 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
export
const
getAnswers
=
asyncWrap
(
async
(
reqExp
,
res
)
=>
{
export
const
getAnswers
=
asyncWrap
(
async
(
reqExp
,
res
)
=>
{
const
req
=
reqExp
as
TypedRequest
;
const
req
=
reqExp
as
TypedRequest
;
const
{
surveyId
}
=
req
.
params
;
const
{
surveyId
}
=
req
.
params
;
console
.
log
(
surveyId
);
try
{
try
{
const
survey
=
await
surveyDb
.
getSurveyById
(
surveyId
);
const
answers
=
await
answerDb
.
getAnswers
(
surveyId
);
const
answers
=
await
answerDb
.
getAnswers
(
surveyId
);
console
.
log
(
"
Db에서 가져온 answers=
"
,
answers
);
console
.
log
(
answers
);
return
res
.
json
(
answers
);
const
jsonSurvey
=
survey
?.
toJSON
();
if
(
jsonSurvey
&&
answers
)
{
const
a
=
answers
.
map
(
async
(
a
)
=>
{
const
targetObj
=
jsonSurvey
.
questions
.
find
(
(
q
:
any
)
=>
String
(
q
.
_id
)
===
String
(
a
.
_id
)
)
as
any
;
if
(
targetObj
)
{
if
(
a
.
file
.
length
)
{
targetObj
.
answers
=
a
.
file
;
}
else
{
targetObj
.
answers
=
a
.
answers
;
}
}
});
await
Promise
.
all
(
a
);
}
return
res
.
json
(
jsonSurvey
);
}
catch
(
error
:
any
)
{
}
catch
(
error
:
any
)
{
res
.
status
(
422
).
send
(
error
.
message
||
"
설문조사 결과 불러오기 오류
"
);
res
.
status
(
422
).
send
(
error
.
message
||
"
설문조사 결과 불러오기 오류
"
);
}
}
...
...
src/db/answer.db.ts
View file @
578446f7
...
@@ -10,19 +10,17 @@ export const getAnswers = async (surveyId: string) => {
...
@@ -10,19 +10,17 @@ export const getAnswers = async (surveyId: string) => {
const
answers
=
await
Answer
.
aggregate
([
const
answers
=
await
Answer
.
aggregate
([
{
$match
:
{
surveyId
:
new
Types
.
ObjectId
(
surveyId
)
}
},
{
$match
:
{
surveyId
:
new
Types
.
ObjectId
(
surveyId
)
}
},
{
{
$lookup
:
{
$group
:
{
from
:
"
questions
"
,
_id
:
"
$questionId
"
,
localField
:
"
questionId
"
,
answers
:
{
$push
:
"
$answer
"
},
foreignField
:
"
_id
"
,
as
:
"
question
"
,
},
},
},
},
{
$unwind
:
"
$question
"
},
{
{
$group
:
{
$lookup
:
{
_id
:
"
$questionId
"
,
from
:
"
fileinfos
"
,
answers
:
{
$push
:
{
guestId
:
"
$guestId
"
,
answer
:
"
$answer
"
}
},
localField
:
"
answers
"
,
question
:
{
$mergeObjects
:
"
$question
"
},
foreignField
:
"
_id
"
,
as
:
"
file
"
,
},
},
},
},
]);
]);
...
...
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