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
survey
Commits
0f920a13
Commit
0f920a13
authored
Jul 22, 2022
by
Jiwon Yoon
Browse files
isRequired check
parent
6fb8d9e5
Changes
12
Hide whitespace changes
Inline
Side-by-side
frontend/src/commons/ACheckboxForm.tsx
View file @
0f920a13
...
@@ -3,23 +3,35 @@ import { CheckboxType, AnswersType } from "../types";
...
@@ -3,23 +3,35 @@ import { CheckboxType, AnswersType } from "../types";
type
Props
=
{
type
Props
=
{
element
:
CheckboxType
;
element
:
CheckboxType
;
answers
:
AnswersType
|
undefined
;
answerQuestion
:
any
|
undefined
;
handleAnswer
:
()
=>
void
;
};
};
export
const
ACheckboxForm
=
({
element
,
answer
s
,
handleAnswer
}:
Props
)
=>
{
export
const
ACheckboxForm
=
({
element
,
answer
Question
}:
Props
)
=>
{
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
{
value
}
=
event
.
currentTarget
;
const
{
value
}
=
event
.
currentTarget
;
// response.answers.map((a) => {
if
(
answerQuestion
.
answer
)
{
// if (a.questionId === element._id) {
if
(
answerQuestion
.
answer
.
find
((
a
:
any
)
=>
a
===
value
))
{
// a.answer = value;
const
newList
=
answerQuestion
.
answer
.
filter
((
a
:
any
)
=>
a
!==
value
);
// }
answerQuestion
.
answer
=
newList
;
// });
if
(
answerQuestion
.
answer
.
length
)
{
answers
&&
(
answers
.
answer
=
value
);
answerQuestion
.
requiredCheck
=
true
;
}
else
{
answerQuestion
.
requiredCheck
=
false
;
}
}
else
{
answerQuestion
.
answer
.
push
(
value
);
answerQuestion
.
requiredCheck
=
true
;
}
}
else
{
answerQuestion
.
answer
=
[];
answerQuestion
.
answer
.
push
(
value
);
answerQuestion
.
requiredCheck
=
true
;
}
setAnswer
(
value
);
setAnswer
(
value
);
handleAnswer
();
console
.
log
(
answerQuestion
);
};
};
return
(
return
(
<
div
className
=
"flex w-full gap-2 justify-around my-3"
>
<
div
className
=
"flex w-full gap-2 justify-around my-3"
>
...
@@ -30,7 +42,6 @@ export const ACheckboxForm = ({ element, answers, handleAnswer }: Props) => {
...
@@ -30,7 +42,6 @@ export const ACheckboxForm = ({ element, answers, handleAnswer }: Props) => {
type
=
"checkbox"
type
=
"checkbox"
value
=
{
choice
.
text
}
value
=
{
choice
.
text
}
onChange
=
{
handleChange
}
onChange
=
{
handleChange
}
required
=
{
element
.
isRequired
}
/>
/>
<
label
className
=
"text-lg"
>
{
choice
.
text
}
</
label
>
<
label
className
=
"text-lg"
>
{
choice
.
text
}
</
label
>
</
div
>
</
div
>
...
...
frontend/src/commons/ADateForm.tsx
View file @
0f920a13
...
@@ -2,29 +2,24 @@ import React, { useState } from "react";
...
@@ -2,29 +2,24 @@ import React, { useState } from "react";
import
{
DateType
,
AnswersType
}
from
"
../types
"
;
import
{
DateType
,
AnswersType
}
from
"
../types
"
;
type
Props
=
{
type
Props
=
{
element
:
DateType
;
element
:
DateType
;
answers
:
AnswersType
|
undefined
;
answerQuestion
:
any
|
undefined
;
handleAnswer
:
()
=>
void
;
};
};
export
const
ADateForm
=
({
element
,
answer
s
,
handleAnswer
}:
Props
)
=>
{
export
const
ADateForm
=
({
element
,
answer
Question
}:
Props
)
=>
{
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
{
value
}
=
event
.
currentTarget
;
const
{
value
}
=
event
.
currentTarget
;
// response.answers.map((a) => {
answerQuestion
.
answer
=
value
;
// if (a.questionId === element._id) {
// a.answer = value;
// }
// });
answers
&&
(
answers
.
answer
=
value
);
setAnswer
(
value
);
setAnswer
(
value
);
handleAnswer
();
if
(
answerQuestion
.
answer
)
{
answerQuestion
.
requiredCheck
=
true
;
}
else
{
answerQuestion
.
requiredCheck
=
false
;
}
console
.
log
(
answerQuestion
);
};
};
return
(
return
(
<
div
className
=
"justify-start w-11/12 m-3 py-4"
>
<
div
className
=
"justify-start w-11/12 m-3 py-4"
>
<
input
<
input
type
=
"date"
onChange
=
{
handleChange
}
></
input
>
type
=
"date"
onChange
=
{
handleChange
}
required
=
{
element
.
isRequired
}
></
input
>
</
div
>
</
div
>
);
);
};
};
frontend/src/commons/ADropdownForm.tsx
View file @
0f920a13
...
@@ -3,30 +3,28 @@ import { DropdownType, AnswersType } from "../types";
...
@@ -3,30 +3,28 @@ import { DropdownType, AnswersType } from "../types";
type
Props
=
{
type
Props
=
{
element
:
DropdownType
;
element
:
DropdownType
;
answers
:
AnswersType
|
undefined
;
answerQuestion
:
any
|
undefined
;
handleAnswer
:
()
=>
void
;
};
};
export
const
ADropdownForm
=
({
element
,
h
an
dleAnswer
,
answers
}:
Props
)
=>
{
export
const
ADropdownForm
=
({
element
,
an
swerQuestion
}:
Props
)
=>
{
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
=>
{
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
=>
{
const
{
value
}
=
event
.
currentTarget
;
const
{
value
}
=
event
.
currentTarget
;
// response.answers.map((a) => {
answerQuestion
.
answer
=
value
;
// if (a.questionId === element._id) {
// a.answer = value;
// }
// });
answers
&&
(
answers
.
answer
=
value
);
setAnswer
(
value
);
setAnswer
(
value
);
handleAnswer
();
if
(
answerQuestion
.
answer
)
{
answerQuestion
.
requiredCheck
=
true
;
}
else
{
answerQuestion
.
requiredCheck
=
false
;
}
console
.
log
(
answerQuestion
);
};
};
return
(
return
(
<
div
className
=
"flex flex-col container w-4/5 h-auto items-center m-3 py-3"
>
<
div
className
=
"flex flex-col container w-4/5 h-auto items-center m-3 py-3"
>
<
select
<
select
className
=
"py-2 hover:bg-themeColor bg-gray-200 rounded"
className
=
"py-2 hover:bg-themeColor bg-gray-200 rounded"
onChange
=
{
handleChange
}
onChange
=
{
handleChange
}
required
=
{
element
.
isRequired
}
>
>
{
element
.
content
.
choices
.
map
((
choice
)
=>
(
{
element
.
content
.
choices
.
map
((
choice
)
=>
(
<
option
value
=
{
choice
.
text
}
>
{
choice
.
text
}
</
option
>
<
option
value
=
{
choice
.
text
}
>
{
choice
.
text
}
</
option
>
...
...
frontend/src/commons/AEssayForm.tsx
View file @
0f920a13
...
@@ -3,23 +3,22 @@ import { EssayType, AnswersType } from "../types";
...
@@ -3,23 +3,22 @@ import { EssayType, AnswersType } from "../types";
type
Props
=
{
type
Props
=
{
element
:
EssayType
;
element
:
EssayType
;
answers
:
AnswersType
|
undefined
;
answerQuestion
:
any
|
undefined
;
handleAnswer
:
()
=>
void
;
};
};
export
const
AEssayForm
=
({
element
,
h
an
dleAnswer
,
answers
}:
Props
)
=>
{
export
const
AEssayForm
=
({
element
,
an
swerQuestion
}:
Props
)
=>
{
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
{
value
}
=
event
.
currentTarget
;
const
{
value
}
=
event
.
currentTarget
;
// response.answers.map((a) => {
answerQuestion
.
answer
=
value
;
// if (a.questionId === element._id) {
// a.answer = value;
// }
// });
answers
&&
(
answers
.
answer
=
value
);
setAnswer
(
value
);
setAnswer
(
value
);
handleAnswer
();
if
(
answerQuestion
.
answer
)
{
answerQuestion
.
requiredCheck
=
true
;
}
else
{
answerQuestion
.
requiredCheck
=
false
;
}
console
.
log
(
answerQuestion
);
};
};
return
(
return
(
<
div
className
=
"flex mt-3 w-full justify-center"
>
<
div
className
=
"flex mt-3 w-full justify-center"
>
...
@@ -29,7 +28,6 @@ export const AEssayForm = ({ element, handleAnswer, answers }: Props) => {
...
@@ -29,7 +28,6 @@ export const AEssayForm = ({ element, handleAnswer, answers }: Props) => {
id
=
{
element
.
_id
}
id
=
{
element
.
_id
}
onChange
=
{
handleChange
}
onChange
=
{
handleChange
}
value
=
{
answer
}
value
=
{
answer
}
required
=
{
element
.
isRequired
}
></
input
>
></
input
>
</
div
>
</
div
>
);
);
...
...
frontend/src/commons/AFileForm.tsx
View file @
0f920a13
...
@@ -3,28 +3,24 @@ import { FileType, AnswersType } from "../types";
...
@@ -3,28 +3,24 @@ import { FileType, AnswersType } from "../types";
type
Props
=
{
type
Props
=
{
element
:
FileType
;
element
:
FileType
;
answers
:
AnswersType
|
undefined
;
answerQuestion
:
any
|
undefined
;
handleAnswer
:
()
=>
void
;
addFiles
:
(
oneFile
:
{
questionId
:
string
;
file
:
File
})
=>
void
;
addFiles
:
(
oneFile
:
{
questionId
:
string
;
file
:
File
})
=>
void
;
};
};
export
const
AFileForm
=
({
export
const
AFileForm
=
({
element
,
answerQuestion
,
addFiles
}:
Props
)
=>
{
element
,
const
[
answer
,
setAnswer
]
=
useState
(
""
);
answers
,
handleAnswer
,
addFiles
,
}:
Props
)
=>
{
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
if
(
event
.
currentTarget
.
files
)
{
if
(
event
.
currentTarget
.
files
)
{
const
uploadFile
=
event
.
currentTarget
.
files
[
0
];
const
uploadFile
=
event
.
currentTarget
.
files
[
0
];
addFiles
({
questionId
:
element
.
_id
,
file
:
uploadFile
});
addFiles
({
questionId
:
element
.
_id
,
file
:
uploadFile
});
// response.answers.map((a) => {
answerQuestion
.
answer
=
uploadFile
.
name
;
// if (a.questionId === element._id) {
if
(
answerQuestion
.
answer
)
{
// a.answer = uploadFile.name;
answerQuestion
.
requiredCheck
=
true
;
// }
}
else
{
// });
answerQuestion
.
requiredCheck
=
false
;
answers
&&
(
answers
.
answer
=
uploadFile
.
name
);
}
handleAnswer
();
setAnswer
(
uploadFile
.
name
);
console
.
log
(
answerQuestion
);
}
}
};
};
return
(
return
(
...
@@ -34,7 +30,6 @@ export const AFileForm = ({
...
@@ -34,7 +30,6 @@ export const AFileForm = ({
name
=
"file"
name
=
"file"
className
=
" w-11/12 h-16"
className
=
" w-11/12 h-16"
onChange
=
{
handleChange
}
onChange
=
{
handleChange
}
required
=
{
element
.
isRequired
}
></
input
>
></
input
>
</
div
>
</
div
>
);
);
...
...
frontend/src/commons/AQuestion.tsx
View file @
0f920a13
import
React
from
"
react
"
;
import
React
from
"
react
"
;
import
{
BasicQuestionType
,
AnswersType
}
from
"
../types
"
;
import
{
BasicQuestionType
,
AnswersType
,
SurveyType
}
from
"
../types
"
;
import
{
ACheckboxForm
}
from
"
./ACheckboxForm
"
;
import
{
ACheckboxForm
}
from
"
./ACheckboxForm
"
;
import
{
ADateForm
}
from
"
./ADateForm
"
;
import
{
ADateForm
}
from
"
./ADateForm
"
;
import
{
ADropdownForm
}
from
"
./ADropdownForm
"
;
import
{
ADropdownForm
}
from
"
./ADropdownForm
"
;
...
@@ -10,75 +10,42 @@ import { ARatingForm } from "./ARatingForm";
...
@@ -10,75 +10,42 @@ import { ARatingForm } from "./ARatingForm";
type
Props
=
{
type
Props
=
{
question
:
BasicQuestionType
;
question
:
BasicQuestionType
;
answer
:
AnswersType
|
undefined
;
answerQuestion
:
any
|
undefined
;
handleAnswer
:
()
=>
void
;
addFiles
:
(
oneFile
:
{
questionId
:
string
;
file
:
File
})
=>
void
;
addFiles
:
(
oneFile
:
{
questionId
:
string
;
file
:
File
})
=>
void
;
};
};
export
const
AQuestion
=
({
export
const
AQuestion
=
({
question
,
answerQuestion
,
addFiles
}:
Props
)
=>
{
question
,
handleAnswer
,
answer
,
addFiles
,
}:
Props
)
=>
{
function
getContent
(
question
:
BasicQuestionType
)
{
function
getContent
(
question
:
BasicQuestionType
)
{
switch
(
question
.
type
)
{
switch
(
question
.
type
)
{
case
"
essay
"
:
case
"
essay
"
:
return
(
return
(
<
AEssayForm
<
AEssayForm
element
=
{
question
}
answerQuestion
=
{
answerQuestion
}
/>
element
=
{
question
}
answers
=
{
answer
}
handleAnswer
=
{
handleAnswer
}
/>
);
);
case
"
radio
"
:
case
"
radio
"
:
return
(
return
(
<
ARadioForm
<
ARadioForm
element
=
{
question
}
answerQuestion
=
{
answerQuestion
}
/>
element
=
{
question
}
answers
=
{
answer
}
handleAnswer
=
{
handleAnswer
}
/>
);
);
case
"
checkbox
"
:
case
"
checkbox
"
:
return
(
return
(
<
ACheckboxForm
<
ACheckboxForm
element
=
{
question
}
answerQuestion
=
{
answerQuestion
}
/>
element
=
{
question
}
answers
=
{
answer
}
handleAnswer
=
{
handleAnswer
}
/>
);
);
case
"
dropdown
"
:
case
"
dropdown
"
:
return
(
return
(
<
ADropdownForm
<
ADropdownForm
element
=
{
question
}
answerQuestion
=
{
answerQuestion
}
/>
element
=
{
question
}
answers
=
{
answer
}
handleAnswer
=
{
handleAnswer
}
/>
);
);
case
"
file
"
:
case
"
file
"
:
return
(
return
(
<
AFileForm
<
AFileForm
element
=
{
question
}
element
=
{
question
}
answers
=
{
answer
}
answerQuestion
=
{
answerQuestion
}
handleAnswer
=
{
handleAnswer
}
addFiles
=
{
addFiles
}
addFiles
=
{
addFiles
}
/>
/>
);
);
case
"
rating
"
:
case
"
rating
"
:
return
(
return
(
<
ARatingForm
<
ARatingForm
element
=
{
question
}
answerQuestion
=
{
answerQuestion
}
/>
element
=
{
question
}
answers
=
{
answer
}
handleAnswer
=
{
handleAnswer
}
/>
);
);
case
"
date
"
:
case
"
date
"
:
return
(
return
<
ADateForm
element
=
{
question
}
answerQuestion
=
{
answerQuestion
}
/>;
<
ADateForm
element
=
{
question
}
answers
=
{
answer
}
handleAnswer
=
{
handleAnswer
}
/>
);
default
:
default
:
return
<></>;
return
<></>;
}
}
...
@@ -88,6 +55,11 @@ export const AQuestion = ({
...
@@ -88,6 +55,11 @@ export const AQuestion = ({
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-4"
>
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-4"
>
<
div
className
=
"flex flexgi-row my-1 w-11/12 place-content-between items-center"
>
<
div
className
=
"flex flexgi-row my-1 w-11/12 place-content-between items-center"
>
<
div
className
=
"text-xl font-bold"
>
{
question
.
title
}
</
div
>
<
div
className
=
"text-xl font-bold"
>
{
question
.
title
}
</
div
>
{
question
.
isRequired
?
(
<
div
className
=
"text-xs text-red-600"
>
* 필수질문
</
div
>
)
:
(
<></>
)
}
</
div
>
</
div
>
<
div
className
=
"w-11/12 text-slate-500"
>
{
question
.
comment
}
</
div
>
<
div
className
=
"w-11/12 text-slate-500"
>
{
question
.
comment
}
</
div
>
{
getContent
(
question
)
}
{
getContent
(
question
)
}
...
...
frontend/src/commons/ARadioForm.tsx
View file @
0f920a13
...
@@ -3,23 +3,22 @@ import { RadioType, AnswersType } from "../types";
...
@@ -3,23 +3,22 @@ import { RadioType, AnswersType } from "../types";
type
Props
=
{
type
Props
=
{
element
:
RadioType
;
element
:
RadioType
;
answers
:
AnswersType
|
undefined
;
answerQuestion
:
any
|
undefined
;
handleAnswer
:
()
=>
void
;
};
};
export
const
ARadioForm
=
({
element
,
answer
s
,
handleAnswer
}:
Props
)
=>
{
export
const
ARadioForm
=
({
element
,
answer
Question
}:
Props
)
=>
{
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
handleChange
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
{
value
}
=
event
.
currentTarget
;
const
{
value
}
=
event
.
currentTarget
;
// response.answers.map((a) => {
answerQuestion
.
answer
=
value
;
// if (a.questionId === element._id) {
// a.answer = value;
// }
// });
answers
&&
(
answers
.
answer
=
value
);
setAnswer
(
value
);
setAnswer
(
value
);
handleAnswer
();
if
(
answerQuestion
.
answer
)
{
answerQuestion
.
requiredCheck
=
true
;
}
else
{
answerQuestion
.
requiredCheck
=
false
;
}
console
.
log
(
answerQuestion
);
};
};
return
(
return
(
<
div
className
=
"flex w-full gap-2 justify-around my-3"
>
<
div
className
=
"flex w-full gap-2 justify-around my-3"
>
...
@@ -32,7 +31,6 @@ export const ARadioForm = ({ element, answers, handleAnswer }: Props) => {
...
@@ -32,7 +31,6 @@ export const ARadioForm = ({ element, answers, handleAnswer }: Props) => {
name
=
{
element
.
_id
}
name
=
{
element
.
_id
}
onChange
=
{
handleChange
}
onChange
=
{
handleChange
}
value
=
{
choice
.
text
}
value
=
{
choice
.
text
}
required
=
{
element
.
isRequired
}
></
input
>
></
input
>
<
label
className
=
"text-lg"
id
=
{
choice
.
text
}
>
<
label
className
=
"text-lg"
id
=
{
choice
.
text
}
>
{
choice
.
text
}
{
choice
.
text
}
...
...
frontend/src/commons/ARatingForm.tsx
View file @
0f920a13
...
@@ -3,32 +3,31 @@ import { RatingType, AnswersType } from "../types";
...
@@ -3,32 +3,31 @@ import { RatingType, AnswersType } from "../types";
type
Props
=
{
type
Props
=
{
element
:
RatingType
;
element
:
RatingType
;
answers
:
AnswersType
|
undefined
;
answerQuestion
:
any
|
undefined
;
handleAnswer
:
()
=>
void
;
};
};
export
const
ARatingForm
=
({
element
,
answer
s
,
handleAnswer
}:
Props
)
=>
{
export
const
ARatingForm
=
({
element
,
answer
Question
}:
Props
)
=>
{
const
[
selectedchoice
,
setSelectedchoice
]
=
useState
(
""
);
const
[
selectedchoice
,
setSelectedchoice
]
=
useState
(
""
);
const
[
answer
,
setAnswer
]
=
useState
(
""
);
const
[
answer
,
setAnswer
]
=
useState
(
""
);
function
buttonClick
(
event
:
React
.
MouseEvent
<
HTMLButtonElement
>
)
{
function
buttonClick
(
event
:
React
.
MouseEvent
<
HTMLButtonElement
>
)
{
event
.
preventDefault
();
event
.
preventDefault
();
const
{
name
}
=
event
.
currentTarget
;
const
{
name
}
=
event
.
currentTarget
;
// response.answers.map((a) => {
answerQuestion
.
answer
=
name
;
// if (a.questionId === element._id) {
// a.answer = name;
// }
// });
answers
&&
(
answers
.
answer
=
name
);
setAnswer
(
name
);
setAnswer
(
name
);
setSelectedchoice
(
event
.
currentTarget
.
name
);
setSelectedchoice
(
event
.
currentTarget
.
name
);
handleAnswer
();
if
(
answerQuestion
.
answer
)
{
answerQuestion
.
requiredCheck
=
true
;
}
else
{
answerQuestion
.
requiredCheck
=
false
;
}
console
.
log
(
answerQuestion
);
}
}
return
(
return
(
<
div
className
=
"flex w-full justify-center
space-x-12
my-3"
>
<
div
className
=
"flex w-full justify-center my-3"
>
<
label
className
=
"mt-3"
>
{
element
.
content
.
minRateDescription
}
</
label
>
<
label
className
=
"mt-3"
>
{
element
.
content
.
minRateDescription
}
</
label
>
{
element
.
content
.
choices
.
map
((
choice
)
=>
(
{
element
.
content
.
choices
.
map
((
choice
)
=>
(
<
div
className
=
"flex gap-4"
>
<
div
className
=
"flex gap-4
mx-1
"
>
<
button
<
button
type
=
"button"
type
=
"button"
className
=
"border border-themeColor rounded-full w-12 h-12 text-center hover:bg-slate-300"
className
=
"border border-themeColor rounded-full w-12 h-12 text-center hover:bg-slate-300"
...
...
frontend/src/commons/SurveyForm.tsx
View file @
0f920a13
...
@@ -2,12 +2,14 @@ import React, { FormEvent, useEffect, useRef, useState } from "react";
...
@@ -2,12 +2,14 @@ import React, { FormEvent, useEffect, useRef, useState } from "react";
import
{
useParams
}
from
"
react-router-dom
"
;
import
{
useParams
}
from
"
react-router-dom
"
;
import
{
surveyApi
,
answerApi
}
from
"
../apis
"
;
import
{
surveyApi
,
answerApi
}
from
"
../apis
"
;
import
{
catchErrors
}
from
"
../helpers
"
;
import
{
catchErrors
}
from
"
../helpers
"
;
import
{
Question
}
from
"
../questions
"
;
import
{
AnswerType
,
SurveyType
}
from
"
../types
"
;
import
{
AnswerType
,
SurveyType
}
from
"
../types
"
;
import
{
AQuestion
}
from
"
./AQuestion
"
;
import
{
AQuestion
}
from
"
./AQuestion
"
;
export
const
SurveyForm
=
()
=>
{
export
const
SurveyForm
=
()
=>
{
let
{
surveyId
}
=
useParams
<
{
surveyId
:
string
}
>
();
let
{
surveyId
}
=
useParams
<
{
surveyId
:
string
}
>
();
const
[
files
,
setFiles
]
=
useState
<
{
questionId
:
string
;
file
:
File
}[]
>
([]);
const
[
files
,
setFiles
]
=
useState
<
{
questionId
:
string
;
file
:
File
}[]
>
([]);
const
[
requiredErrorMessage
,
setRequiredErrorMessage
]
=
useState
(
""
);
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
);
...
@@ -19,12 +21,18 @@ export const SurveyForm = () => {
...
@@ -19,12 +21,18 @@ export const SurveyForm = () => {
questions
:
[],
questions
:
[],
});
});
const
answer
=
useRef
<
AnswerType
>
({
const
answerSurvey
=
useRef
<
any
>
({
surveyId
:
"
surveyId
"
,
_id
:
"
surveyId
"
,
guestId
:
""
,
user
:
{},
answers
:
[],
title
:
""
,
comment
:
""
,
questions
:
[],
});
});
useEffect
(()
=>
{
ansSurvey
();
},
[
surveyId
]);
const
addFiles
=
(
oneFile
:
{
questionId
:
string
;
file
:
File
})
=>
{
const
addFiles
=
(
oneFile
:
{
questionId
:
string
;
file
:
File
})
=>
{
if
(
!
files
.
find
((
a
)
=>
a
.
questionId
===
oneFile
.
questionId
))
{
if
(
!
files
.
find
((
a
)
=>
a
.
questionId
===
oneFile
.
questionId
))
{
setFiles
([...
files
,
oneFile
]);
setFiles
([...
files
,
oneFile
]);
...
@@ -34,23 +42,12 @@ export const SurveyForm = () => {
...
@@ -34,23 +42,12 @@ export const SurveyForm = () => {
async
function
ansSurvey
()
{
async
function
ansSurvey
()
{
try
{
try
{
if
(
surveyId
)
{
if
(
surveyId
)
{
const
answersurvey
:
any
=
await
surveyApi
.
ansSurvey
(
surveyId
);
const
getSurvey
:
any
=
await
surveyApi
.
ansSurvey
(
surveyId
);
console
.
log
(
answersurvey
);
console
.
log
(
"
survey가져옴ㅎㅎ
"
,
getSurvey
);
const
questionIds
=
answersurvey
.
questions
.
map
((
el
:
any
)
=>
{
if
(
getSurvey
)
{
return
{
questionId
:
el
.
_id
,
type
:
el
.
type
,
answer
:
""
};
answerSurvey
.
current
.
_id
=
getSurvey
.
_id
;
});
answerSurvey
.
current
.
questions
=
getSurvey
.
questions
;
console
.
log
(
questionIds
);
setSurvey
(
getSurvey
);
if
(
answersurvey
)
{
// setResponse({
// ...answer,
// surveyId: answersurvey._id,
// answers: questionIds,
// });
answer
.
current
.
surveyId
=
answersurvey
.
_id
;
answer
.
current
.
guestId
=
answersurvey
.
guestId
;
answer
.
current
.
answers
=
questionIds
;
setSurvey
(
answersurvey
);
setSuccess
(
true
);
setSuccess
(
true
);
setError
(
""
);
setError
(
""
);
}
}
...
@@ -64,40 +61,40 @@ export const SurveyForm = () => {
...
@@ -64,40 +61,40 @@ export const SurveyForm = () => {
}
}
}
}
useEffect
(()
=>
{
ansSurvey
();
},
[
surveyId
]);
async
function
handleSubmit
(
event
:
FormEvent
)
{
async
function
handleSubmit
(
event
:
FormEvent
)
{
event
.
preventDefault
();
event
.
preventDefault
();
try
{
const
answers
=
answerSurvey
.
current
.
questions
.
map
((
q
:
any
)
=>
{
const
formData
=
new
FormData
();
return
{
questionId
:
q
.
questionId
,
answer
:
q
.
answer
,
type
:
q
.
type
};
formData
.
append
(
"
surveyId
"
,
answer
.
current
.
surveyId
);
});
formData
.
append
(
"
guestId
"
,
""
);
const
requiredErrorQ
=
answerSurvey
.
current
.
questions
.
find
(
formData
.
append
(
"
answers
"
,
JSON
.
stringify
(
answer
.
current
.
answers
));
(
q
:
any
)
=>
q
.
isRequired
&&
q
.
isRequired
!==
q
.
requiredCheck
files
.
map
((
f
)
=>
{
);
formData
.
append
(
"
uploadFiles
"
,
f
.
file
);
if
(
requiredErrorQ
)
{
});
alert
(
"
필수질문에 응답하지 않으셨습니다.
"
);
const
newAnswer
:
AnswerType
=
await
answerApi
.
saveAnswers
(
formData
);
}
else
{
// console.log(newAnswer);
try
{
setSuccess
(
true
);
const
formData
=
new
FormData
();
setError
(
""
);
formData
.
append
(
"
surveyId
"
,
answerSurvey
.
current
.
_id
);
}
catch
(
error
)
{
formData
.
append
(
"
guestId
"
,
""
);
catchErrors
(
error
,
setError
);
formData
.
append
(
"
answers
"
,
JSON
.
stringify
(
answers
));
}
finally
{
files
.
map
((
f
)
=>
{
setLoading
(
false
);
formData
.
append
(
"
uploadFiles
"
,
f
.
file
);
});
const
newAnswer
:
AnswerType
=
await
answerApi
.
saveAnswers
(
formData
);
// console.log(newAnswer);
setSuccess
(
true
);
setError
(
""
);
}
catch
(
error
)
{
catchErrors
(
error
,
setError
);
}
finally
{
setLoading
(
false
);
}
}
}
}
}
const
handleAnswer
=
()
=>
{
console
.
log
(
"
handle answer:
"
,
answer
.
current
);
// const newList = [...answer.answers];
// setResponse({ ...answer, answers: newList });
};
return
(
return
(
<>
<>
{
console
.
log
(
"
rendering survey form
"
,
answer
.
current
)
}
{
console
.
log
(
"
rendering survey form
"
,
answer
Survey
.
current
)
}
<
form
onSubmit
=
{
handleSubmit
}
>
<
form
onSubmit
=
{
handleSubmit
}
>
<
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"
>
...
@@ -105,15 +102,12 @@ export const SurveyForm = () => {
...
@@ -105,15 +102,12 @@ export const SurveyForm = () => {
<
p
className
=
"font-bold text-1xl text-center m-2"
>
<
p
className
=
"font-bold text-1xl text-center m-2"
>
{
survey
.
comment
}
{
survey
.
comment
}
</
p
>
</
p
>
{
survey
.
questions
.
map
((
question
)
=>
{
{
survey
.
questions
.
map
((
question
,
index
)
=>
{
return
(
return
(
<
AQuestion
<
AQuestion
question
=
{
question
}
question
=
{
question
}
answer
=
{
answer
.
current
.
answers
.
find
(
answerQuestion
=
{
answerSurvey
.
current
.
questions
[
index
]
}
(
ans
)
=>
ans
.
questionId
===
question
.
_id
)
}
addFiles
=
{
addFiles
}
addFiles
=
{
addFiles
}
handleAnswer
=
{
handleAnswer
}
></
AQuestion
>
></
AQuestion
>
);
);
})
}
})
}
...
...
src/controllers/answer.controller.ts
View file @
0f920a13
...
@@ -2,7 +2,7 @@ import { asyncWrap } from "../helpers";
...
@@ -2,7 +2,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
}
from
"
../db
"
;
import
{
fileDb
,
userDb
,
answerDb
}
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,29 +11,39 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
...
@@ -11,29 +11,39 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
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
[];
const
files
=
req
.
files
.
uploadFiles
as
formidable
.
File
[];
console
.
log
(
"
controller의 files
"
,
files
);
//
console.log("controller의 files", files);
let
uploadFile
;
let
uploadFile
;
try
{
try
{
if
(
files
)
{
if
(
files
)
{
// 1) 파일을 DB에 저장 후 다시 retFile가져와서
// 1) 파일을 DB에 저장 후 다시 retFile가져와서
// *근데 파일이 여러 개일 수 있기 때문에 순회해야 됨
// *근데 파일이 여러 개일 수 있기 때문에 순회해야 됨-map()을 쓰면 async function이 되어버려서 for문 이용함
files
.
map
(
async
(
file
)
=>
{
for
(
let
index
=
0
;
index
<
files
.
length
;
index
++
)
{
const
file
=
files
[
index
];
uploadFile
=
new
FileInfo
({
uploadFile
=
new
FileInfo
({
name
:
file
.
originalFilename
,
name
:
file
.
originalFilename
,
url
:
file
.
newFilename
,
url
:
file
.
newFilename
,
isNew
:
true
,
isNew
:
true
,
});
});
const
retFile
=
await
fileDb
.
createFile
(
file
);
const
retFile
=
await
fileDb
.
createFile
(
file
);
console
.
log
(
retFile
);
// 2) answers의 type이 file인 친구들 찾아서 그 친구의 answer와 filename을 비교 후 같으면
// 2) answers의 type이 file인 친구들 찾아서 그 친구의 answer와 filename을 비교 후 같으면
const
targetObj
=
answer
.
find
((
ans
:
any
)
=>
ans
.
type
===
"
file
"
);
const
targetObj
=
answer
.
answers
.
find
(
(
ans
:
any
)
=>
ans
.
answer
===
file
.
originalFilename
);
// 3) answer에다가 retFile의 _id 넣어주기
// 3) answer에다가 retFile의 _id 넣어주기
targetObj
.
answer
=
retFile
.
_id
;
targetObj
.
answer
=
retFile
.
_id
;
}
);
}
}
}
// 3) Answer DB 만들기(map을 돌려서 하나씩 추가시켜야 함)
// 3) Answer DB 만들기(map을 돌려서 하나씩 추가시켜야 함)
// console.log(answer);
for
(
let
index
=
0
;
index
<
answer
.
answers
.
length
;
index
++
)
{
// const newAnswer = await answerDb.createAnswer(answer);
const
element
=
answer
.
answers
[
index
];
const
newAnswer
=
await
answerDb
.
createAnswer
({
surveyId
:
answer
.
surveyId
,
guestId
:
answer
.
guestId
,
questionId
:
element
.
questionId
,
answer
:
element
.
answer
,
});
console
.
log
(
"
DB에 넣은 answer
"
,
newAnswer
);
}
// 주의: ref는 반드시 save를 해야 디비에 생성이 됩니다.
// 주의: ref는 반드시 save를 해야 디비에 생성이 됩니다.
return
res
.
json
();
return
res
.
json
();
}
catch
(
error
:
any
)
{
}
catch
(
error
:
any
)
{
...
...
src/db/answer.db.ts
View file @
0f920a13
import
{
Answer
,
IAnswer
}
from
"
../models
"
;
export
const
createAnswer
=
async
(
answer
:
IAnswer
)
=>
{
const
newQuestion
=
await
Answer
.
create
(
answer
);
return
newQuestion
;
};
src/db/index.ts
View file @
0f920a13
...
@@ -3,3 +3,4 @@ export * as questionDb from "./question.db";
...
@@ -3,3 +3,4 @@ export * as questionDb from "./question.db";
export
*
as
roleDb
from
"
./role.db
"
;
export
*
as
roleDb
from
"
./role.db
"
;
export
*
as
surveyDb
from
"
./survey.db
"
;
export
*
as
surveyDb
from
"
./survey.db
"
;
export
*
as
userDb
from
"
./user.db
"
;
export
*
as
userDb
from
"
./user.db
"
;
export
*
as
answerDb
from
"
./answer.db
"
;
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