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
4949c01d
Commit
4949c01d
authored
Jul 14, 2022
by
Yoon, Daeki
😅
Browse files
Merge branch 'main' into file-upload
parents
6a24c10c
80a2b663
Changes
45
Hide whitespace changes
Inline
Side-by-side
frontend/src/commons/AEssayForm.tsx
0 → 100644
View file @
4949c01d
import
React
from
"
react
"
;
export
const
AEssayForm
=
()
=>
{
return
(
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-3"
>
<
div
className
=
"flex flexgi-row h-16 w-full place-content-between items-center"
>
<
form
className
=
"text-xl font-bold ml-6 w-1/2"
>
input
</
form
>
</
div
>
<
form
className
=
"border w-11/12 my-3"
>
설문조사 설명
</
form
>
<
input
className
=
"border w-11/12 h-36 my-3"
type
=
"text"
></
input
>
</
div
>
);
};
frontend/src/commons/ARadioForm.tsx
0 → 100644
View file @
4949c01d
import
React
from
"
react
"
;
import
{
RadioType
}
from
"
../types
"
;
// type Props = {
// element: RadioType;
// };
export
const
ARadioForm
=
()
=>
{
return
(
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-3"
>
<
div
className
=
"flex flexgi-row h-16 w-full place-content-between items-center"
>
<
form
className
=
"text-xl font-bold ml-6 w-1/2"
>
radio
</
form
>
</
div
>
<
form
className
=
"border w-11/12 my-4"
>
설문조사 설명
</
form
>
<
div
className
=
"flex flex-row items-center m-3"
>
<
div
className
=
"flex items-center mb-4 mx-4"
>
<
input
id
=
"default-radio-1"
type
=
"radio"
value
=
""
name
=
"default-radio"
className
=
"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg"
>
First radio
</
label
>
</
div
>
<
div
className
=
"flex items-center mb-4 mx-4"
>
<
input
id
=
"default-radio-1"
type
=
"radio"
value
=
""
name
=
"default-radio"
className
=
"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg"
>
Second radio
</
label
>
</
div
>
<
div
className
=
"flex items-center mb-4 mx-4"
>
<
input
checked
id
=
"default-radio-2"
type
=
"radio"
value
=
""
name
=
"default-radio"
className
=
"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg"
>
Checked state
</
label
>
</
div
>
</
div
>
</
div
>
);
};
frontend/src/commons/SurveyForm.tsx
View file @
4949c01d
import
React
,
{
InputHTMLAttributes
}
from
"
react
"
;
import
{
ACheckboxForm
}
from
"
./ACheckbox
"
;
import
{
ADropdownForm
}
from
"
./ADropdown
"
;
import
{
AEssayForm
}
from
"
./AEssayForm
"
;
import
{
ARadioForm
}
from
"
./ARadioForm
"
;
export
const
SurveyForm
=
()
=>
{
return
(
...
...
@@ -11,113 +15,15 @@ export const SurveyForm = () => {
rows
=
{
2
}
cols
=
{
60
}
></
textarea
>
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-3"
>
<
div
className
=
"flex flexgi-row h-16 w-full place-content-between items-center"
>
<
form
className
=
"text-xl font-bold ml-6 w-1/2"
>
Q1. 첫번째 질문
</
form
>
</
div
>
<
form
className
=
"border w-11/12 my-3"
>
설문조사 설명
</
form
>
<
input
className
=
"border w-11/12 h-36 my-3"
type
=
"text"
placeholder
=
"설문조사 답변"
></
input
>
{
/* <ACheckboxForm></ACheckboxForm> */
}
<
ADropdownForm
></
ADropdownForm
>
<
AEssayForm
></
AEssayForm
>
<
ARadioForm
></
ARadioForm
>
<
div
>
<
button
className
=
"rounded bg-themeColor my-5 py-2 px-5 font-bold text-white"
>
제출하기
</
button
>
</
div
>
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-3"
>
<
div
className
=
"flex flexgi-row h-16 w-full place-content-between items-center"
>
<
form
className
=
"text-xl font-bold ml-6 w-1/2"
>
Q2. 두번째 질문
</
form
>
</
div
>
<
form
className
=
"border w-11/12 my-4"
>
설문조사 설명
</
form
>
<
div
className
=
"flex flex-row items-center m-3"
>
<
div
className
=
"mb-4 mx-3"
>
<
input
id
=
"default-checkbox"
type
=
"checkbox"
className
=
"w-5 h-5 mt-3 text-blue-600 bg-gray-100 rounded border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg font-medium"
>
First checkbox
</
label
>
</
div
>
<
div
className
=
"mb-4 mx-3"
>
<
input
id
=
"default-checkbox"
type
=
"checkbox"
className
=
"w-5 h-5 mt-3 text-blue-600 bg-gray-100 rounded border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg font-medium"
>
Second checkbox
</
label
>
</
div
>
<
div
className
=
"mb-4 mx-3"
>
<
input
id
=
"default-checkbox"
type
=
"checkbox"
value
=
""
className
=
"w-5 h-5 mt-3 text-blue-600 bg-gray-100 rounded border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg font-medium"
>
Third checkbox
</
label
>
</
div
>
<
div
className
=
"mb-4 mx-4"
>
<
input
id
=
"default-checkbox"
type
=
"checkbox"
value
=
""
className
=
"w-5 h-5 mt-3 text-blue-600 bg-gray-100 rounded border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg font-medium"
>
Fourth checkbox
</
label
>
</
div
>
</
div
>
</
div
>
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-3"
>
<
div
className
=
"flex flexgi-row h-16 w-full place-content-between items-center"
>
<
form
className
=
"text-xl font-bold ml-6 w-1/2"
>
Q3. 세번째 질문
</
form
>
</
div
>
<
form
className
=
"border w-11/12 my-4"
>
설문조사 설명
</
form
>
<
div
className
=
"flex flex-row items-center m-3"
>
<
div
className
=
"flex items-center mb-4 mx-4"
>
<
input
id
=
"default-radio-1"
type
=
"radio"
value
=
""
name
=
"default-radio"
className
=
"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg"
>
First radio
</
label
>
</
div
>
<
div
className
=
"flex items-center mb-4 mx-4"
>
<
input
id
=
"default-radio-1"
type
=
"radio"
value
=
""
name
=
"default-radio"
className
=
"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg"
>
Second radio
</
label
>
</
div
>
<
div
className
=
"flex items-center mb-4 mx-4"
>
<
input
checked
id
=
"default-radio-2"
type
=
"radio"
value
=
""
name
=
"default-radio"
className
=
"w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
/>
<
label
className
=
"ml-2 text-lg"
>
Checked state
</
label
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
>
<
button
className
=
"rounded bg-themeColor my-5 py-2 px-5 font-bold text-white"
>
제출하기
</
button
>
</
div
>
</
div
>
);
...
...
frontend/src/home/Home.tsx
View file @
4949c01d
import
React
from
"
react
"
;
import
{
Link
}
from
"
react-router-dom
"
;
import
React
,
{
FormEvent
}
from
"
react
"
;
import
{
useAuth
}
from
"
../auth/auth.context
"
;
export
const
Home
=
()
=>
(
<
div
className
=
"flex flex-col place-items-center"
>
<
div
className
=
"justify-end text-center text-3xl text-black h-16 mt-12"
>
가장 쉽게 설문지를 만드세요!
</
div
>
<
div
className
=
"flex flex-col place-items-center container"
>
<
div
>
<
Link
to
=
"/create"
className
=
"flex h-14 w-28 items-center border-2 border-themeColor font-bold text-black bg-gray-200 hover:bg-themeColor rounded-lg "
>
<
div
className
=
"text-center w-28 font-bold text-black place-items-center"
>
export
const
Home
=
()
=>
{
const
{
user
}
=
useAuth
();
function
clickHome
(
e
:
React
.
MouseEvent
<
HTMLButtonElement
>
)
{
e
.
preventDefault
();
if
(
!
user
.
isLoggedIn
)
{
console
.
log
(
"
버튼
"
);
location
.
href
=
"
/login
"
;
}
else
{
location
.
href
=
"
/profile
"
;
}
}
return
(
<
div
className
=
"flex flex-col place-items-center"
>
<
div
className
=
"justify-end text-center text-3xl text-black h-16 mt-12"
>
가장 쉽게 설문지를 만드세요!
</
div
>
<
div
className
=
"flex flex-col place-items-center container"
>
<
div
className
=
"flex h-14 w-28 items-center border-2 border-themeColor font-bold text-black bg-gray-200 hover:bg-themeColor rounded-lg "
>
<
button
type
=
"button"
className
=
"text-center h-full w-28 font-bold text-black place-items-center"
onClick
=
{
clickHome
}
>
+
</
div
>
</
Link
>
</
button
>
</
div
>
<
p
className
=
"text-center text-xl text-black mt-3"
>
Create now!
</
p
>
</
div
>
<
div
className
=
"flex justify-center"
>
<
img
src
=
"https://3hbgf23vu0wr11wkpae5igwe-wpengine.netdna-ssl.com/wp-content/uploads/2021/04/SurveyExample_v3.jpg"
className
=
"object-scale-down justify-center"
/>
</
div
>
<
p
className
=
"text-center text-xl text-black"
>
Create now!
</
p
>
</
div
>
<
div
className
=
"flex justify-center"
>
<
img
src
=
"https://3hbgf23vu0wr11wkpae5igwe-wpengine.netdna-ssl.com/wp-content/uploads/2021/04/SurveyExample_v3.jpg"
className
=
"object-scale-down justify-center"
/>
</
div
>
</
div
>
)
;
);
}
;
frontend/src/profile/Profile.tsx
View file @
4949c01d
import
React
from
"
react
"
;
import
React
,
{
useState
}
from
"
react
"
;
import
{
useNavigate
}
from
"
react-router-dom
"
;
import
{
surveyApi
}
from
"
../apis
"
;
import
{
SurveyType
}
from
"
../types
"
;
export
const
Profile
=
()
=>
{
const
navigate
=
useNavigate
();
const
createSurvey
=
()
=>
{
// 먼저 서버에 survey 테이블에 새로운 survey 항목 추가 로직 필요
navigate
(
"
/surveys/create
"
,
{
replace
:
true
});
};
const
[
survey
,
setSurvey
]
=
useState
<
SurveyType
>
({
user
:
{},
title
:
""
,
comment
:
""
,
questions
:
[],
});
async
function
createSurvey
()
{
const
newSurvey
:
SurveyType
=
await
surveyApi
.
createSurvey
(
survey
);
navigate
(
`/surveys/edit/
${
newSurvey
.
_id
}
`
,
{
replace
:
true
,
});
}
return
(
<
div
className
=
"flex flex-col items-center"
>
<
div
className
=
"m-5"
>
나의 설문조사
</
div
>
<
div
className
=
"flex
flex-row
space-x-4 mt-5"
>
<
div
className
=
"flex space-x-4 mt-5"
>
<
button
onClick
=
{
createSurvey
}
className
=
"flex h-60 w-48 items-center border-2 border-themeColor font-bold bg-gray-200 hover:bg-themeColor rounded-lg "
...
...
@@ -31,7 +40,7 @@ export const Profile = () => {
<
div
className
=
"px-2 py-2"
>
<
label
>
설문조사 이름
</
label
>
</
div
>
<
div
className
=
"flex justify-end
dropdown-toggle
"
>
<
div
className
=
"flex justify-end"
>
<
select
className
=
"py-2 w-14 bg-themeColor rounded text-white"
>
<
option
selected
>
옵션
</
option
>
<
option
>
삭제
</
option
>
...
...
@@ -50,7 +59,7 @@ export const Profile = () => {
<
div
className
=
"px-2 py-2"
>
<
label
>
설문조사이름
</
label
>
</
div
>
<
div
className
=
"flex justify-end
dropdown-toggle
"
>
<
div
className
=
"flex justify-end"
>
<
select
className
=
"py-2 w-14 bg-themeColor rounded text-white"
>
<
option
selected
>
옵션
</
option
>
<
option
>
삭제
</
option
>
...
...
@@ -69,7 +78,7 @@ export const Profile = () => {
<
div
className
=
"px-2 py-2"
>
<
label
>
설문조사 이름
</
label
>
</
div
>
<
div
className
=
"flex justify-end
dropdown-toggle
"
>
<
div
className
=
"flex justify-end"
>
<
select
className
=
"py-2 w-14 bg-themeColor rounded text-white"
>
<
option
selected
>
옵션
</
option
>
<
option
>
삭제
</
option
>
...
...
@@ -88,7 +97,7 @@ export const Profile = () => {
<
div
className
=
"px-2 py-2"
>
<
label
>
설문조사 이름
</
label
>
</
div
>
<
div
className
=
"flex justify-end
dropdown-toggle
"
>
<
div
className
=
"flex justify-end"
>
<
select
className
=
"py-2 w-14 bg-themeColor rounded text-white"
>
<
option
selected
>
옵션
</
option
>
<
option
>
삭제
</
option
>
...
...
frontend/src/questions/CheckboxForm.tsx
View file @
4949c01d
import
React
from
"
react
"
;
import
React
,
{
useState
}
from
"
react
"
;
import
{
CheckboxType
}
from
"
../types
"
;
import
{
useQuestion
}
from
"
./question.context
"
;
import
{
Edit
}
from
"
./Edit
"
;
import
{
TypeChange
}
from
"
./typeDD
"
;
type
Props
=
{
element
:
CheckboxType
;
handleQuestion
:
(
id
:
string
)
=>
void
;
currentId
:
string
;
};
export
const
Q
Checkbox
=
({
element
}:
Props
)
=>
{
const
{
questionListChange
}
=
useQuestion
(
);
export
const
Checkbox
Form
=
({
element
,
handleQuestion
,
currentId
}:
Props
)
=>
{
const
[
choices
,
setChoices
]
=
useState
([...
element
.
content
.
choices
]
);
function
handleContent
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
{
id
,
value
}
=
event
.
target
;
choices
[
+
id
].
text
=
value
;
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
console
.
log
(
choices
);
}
function
deleteValue
()
{
//제일 마지막 index 제거
choices
.
splice
(
-
1
,
1
);
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
}
function
addValue
()
{
choices
.
push
({
text
:
""
,
value
:
choices
.
length
});
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
}
return
(
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-2"
>
<
div
className
=
"flex flexgi-row h-16 w-full place-content-between items-center"
>
<
input
type
=
"text"
name
=
"title"
id
=
{
element
.
_id
}
className
=
"text-xl font-bold ml-6 border-b-2 w-1/2"
placeholder
=
{
element
.
title
}
onChange
=
{
questionListChange
}
></
input
>
<
TypeChange
tt
=
"checkbox"
/>
</
div
>
<
div
className
=
"flex w-full justify-center"
>
<
input
type
=
"text"
name
=
"comment"
id
=
{
element
.
_id
}
className
=
"border w-11/12"
placeholder
=
"질문에 대한 설명을 입력해주세요"
onChange
=
{
questionListChange
}
></
input
>
</
div
>
<
div
id
=
"commentarea"
className
=
"flex mt-4"
>
{
element
.
content
.
choices
.
map
((
e
:
any
)
=>
(
<
div
>
<
input
type
=
"checkbox"
checked
=
{
false
}
></
input
>
<>
<
div
id
=
"content"
className
=
"mt-4 p-5"
>
{
choices
.
map
((
choice
:
any
,
index
:
number
)
=>
(
<
div
className
=
"m-5"
>
<
input
type
=
"checkbox"
disabled
></
input
>
<
input
id
=
{
`
${
index
}
`
}
type
=
"text"
className
=
"mx-2 border-b-2"
placeholder
=
{
e
.
text
}
placeholder
=
"선택지"
value
=
{
choice
.
text
}
onChange
=
{
handleContent
}
disabled
=
{
currentId
!==
element
.
_id
}
></
input
>
</
div
>
))
}
</
div
>
<
div
className
=
"flex w-full flex-row justify-end py-2"
>
<
button
className
=
"w-1/12"
>
필수
</
button
>
<
button
className
=
"w-1/12"
>
옵션
</
button
>
<
button
className
=
"w-1/12"
>
삭제
</
button
>
<
Edit
id
=
{
element
.
_id
}
/>
<
div
>
<
button
type
=
"button"
name
=
"rateValues"
className
=
"border border-red-500 rounded mx-2 px-2"
onClick
=
{
deleteValue
}
disabled
=
{
currentId
!==
element
.
_id
}
>
삭제
</
button
>
<
button
type
=
"button"
name
=
"rateValues"
className
=
"border border-blue-500 rounded mx-2 px-2"
onClick
=
{
addValue
}
disabled
=
{
currentId
!==
element
.
_id
}
>
추가
</
button
>
</
div
>
</
div
>
</>
);
};
frontend/src/questions/DateForm.tsx
View file @
4949c01d
import
{
useQuestion
}
from
"
./question.context
"
;
frontend/src/questions/DropdownForm.tsx
View file @
4949c01d
import
React
from
"
react
"
;
import
React
,
{
useState
}
from
"
react
"
;
import
{
DropdownType
}
from
"
../types
"
;
import
{
useQuestion
}
from
"
./question.context
"
;
import
{
TypeChange
}
from
"
./typeDD
"
;
type
Props
=
{
element
:
DropdownType
;
handleQuestion
:
(
id
:
string
)
=>
void
;
currentId
:
string
;
};
export
const
QDropdown
=
({
element
}:
Props
)
=>
{
const
{
questionListChange
}
=
useQuestion
();
export
const
DropdownForm
=
({
element
,
handleQuestion
,
currentId
}:
Props
)
=>
{
const
[
choices
,
setChoices
]
=
useState
([...
element
.
content
.
choices
]);
function
handleContent
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
{
id
,
value
}
=
event
.
target
;
choices
[
+
id
].
text
=
value
;
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
console
.
log
(
choices
);
}
function
deleteValue
()
{
//제일 마지막 index 제거
choices
.
splice
(
-
1
,
1
);
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
}
function
addValue
()
{
choices
.
push
({
text
:
""
,
value
:
choices
.
length
});
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
}
return
(
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-2"
>
<
div
className
=
"flex flexgi-row h-16 w-full place-content-between items-center"
>
<
input
type
=
"text"
name
=
"title"
id
=
{
element
.
_id
}
className
=
"text-xl font-bold ml-6 border-b-2 w-1/2"
placeholder
=
{
element
.
title
}
onChange
=
{
questionListChange
}
></
input
>
<
TypeChange
tt
=
"dropdown"
/>
</
div
>
<
div
className
=
"flex w-full justify-center"
>
<
input
type
=
"text"
name
=
"comment"
id
=
{
element
.
_id
}
className
=
"border w-11/12"
placeholder
=
"질문에 대한 설명을 입력해주세요"
onChange
=
{
questionListChange
}
></
input
>
</
div
>
<
div
id
=
"commentarea"
className
=
"flex mt-4"
>
{
element
.
content
.
choices
.
map
((
e
:
any
)
=>
(
<
div
>
<
input
type
=
"checkbox"
checked
=
{
false
}
></
input
>
<>
<
div
id
=
"content"
className
=
"flex-row mt-4 p-5"
>
<
select
className
=
"mr-3"
>
{
choices
.
map
((
choice
:
any
,
index
:
number
)
=>
(
<
option
>
{
choice
.
text
}
</
option
>
))
}
</
select
>
{
choices
.
map
((
choice
:
any
,
index
:
number
)
=>
(
<
div
className
=
"my-5"
>
<
input
id
=
{
`
${
index
}
`
}
type
=
"text"
className
=
"mx-2 border-b-2"
placeholder
=
{
e
.
text
}
placeholder
=
"선택지"
value
=
{
choice
.
text
}
onChange
=
{
handleContent
}
disabled
=
{
currentId
!==
element
.
_id
}
></
input
>
</
div
>
))
}
</
div
>
<
div
className
=
"flex w-full flex-row justify-end py-2"
>
<
button
className
=
"w-1/12"
>
필수
</
button
>
<
button
className
=
"w-1/12"
>
옵션
</
button
>
<
button
className
=
"w-1/12"
>
삭제
</
button
>
<
div
>
<
button
type
=
"button"
name
=
"rateValues"
className
=
"border border-red-500 rounded mx-2 px-2"
onClick
=
{
deleteValue
}
disabled
=
{
currentId
!==
element
.
_id
}
>
삭제
</
button
>
<
button
type
=
"button"
name
=
"rateValues"
className
=
"border border-blue-500 rounded mx-2 px-2"
onClick
=
{
addValue
}
disabled
=
{
currentId
!==
element
.
_id
}
>
추가
</
button
>
</
div
>
</
div
>
</>
);
};
frontend/src/questions/EssayForm.tsx
View file @
4949c01d
import
React
,
{
useState
}
from
"
react
"
;
import
React
from
"
react
"
;
import
{
EssayType
}
from
"
../types
"
;
// import { useQuestion } from "./question.context";
// import { Edit } from "./Edit";
// import { TypeChange } from "./typeDD";
type
Props
=
{
element
:
EssayType
;
currentId
:
string
;
};
export
const
EssayForm
=
({
element
}:
Props
)
=>
{
// const { questionListChange } = useQuestion();
export
const
EssayForm
=
({
element
,
currentId
}:
Props
)
=>
{
return
(
<
div
id
=
"commentarea"
className
=
"flex mt-4 w-full justify-center"
>
<
input
className
=
"border w-11/12 h-16"
disabled
></
input
>
...
...
frontend/src/questions/FileForm.tsx
View file @
4949c01d
import
React
,
{
useState
}
from
"
react
"
;
import
{
FileType
}
from
"
../types
"
;
import
{
useQuestion
}
from
"
./question.context
"
;
import
{
TypeChange
}
from
"
./typeDD
"
;
type
Props
=
{
element
:
FileType
;
currentId
:
string
;
};
export
const
QFile
=
({
element
}:
Props
)
=>
{
const
{
questionListChange
}
=
useQuestion
();
export
const
FileForm
=
({
element
,
currentId
}:
Props
)
=>
{
return
(
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-2"
>
<
div
className
=
"flex h-16 w-full place-content-between items-center"
>
<
input
type
=
"text"
name
=
"title"
id
=
{
element
.
_id
}
className
=
"text-xl font-bold ml-6 border-b-2 w-1/2"
placeholder
=
{
element
.
title
}
onChange
=
{
questionListChange
}
></
input
>
<
TypeChange
tt
=
"file"
/>
</
div
>
<
div
className
=
"flex w-full justify-center"
>
<
input
type
=
"text"
name
=
"comment"
id
=
{
element
.
_id
}
className
=
"border w-11/12"
placeholder
=
"질문에 대한 설명을 입력해주세요"
onChange
=
{
questionListChange
}
></
input
>
</
div
>
<
div
id
=
"commentarea"
className
=
"flex mt-4 w-full justify-center"
>
<
input
type
=
"file"
className
=
" w-11/12 h-16"
disabled
></
input
>
</
div
>
<
div
className
=
"flex w-full justify-end py-2"
>
<
button
className
=
"w-1/12"
>
필수
</
button
>
<
button
className
=
"w-1/12"
>
옵션
</
button
>
<
button
className
=
"w-1/12"
>
삭제
</
button
>
</
div
>
<
div
id
=
"content"
className
=
"flex mt-4 w-full justify-center"
>
<
input
type
=
"file"
className
=
" w-11/12 h-16"
disabled
></
input
>
</
div
>
);
};
frontend/src/questions/MatrixForm.tsx
View file @
4949c01d
import
{
useQuestion
}
from
"
./question.context
"
;
//
import { useQuestion } from "./question.context";
frontend/src/questions/Question.tsx
View file @
4949c01d
import
React
,
{
useState
}
from
"
react
"
;
import
React
,
{
useState
,
Dispatch
,
SetStateAction
}
from
"
react
"
;
import
{
BasicQuestionType
,
EssayType
}
from
"
../types
"
;
import
{
questionApi
}
from
"
../apis
"
;
import
{
EssayForm
}
from
"
./EssayForm
"
;
import
{
CheckboxForm
}
from
"
./CheckboxForm
"
;
import
{
RadioForm
}
from
"
./RadioForm
"
;
import
{
DropdownForm
}
from
"
./DropdownForm
"
;
import
{
FileForm
}
from
"
./FileForm
"
;
import
{
RatingForm
}
from
"
./RatingForm
"
;
type
Props
=
{
element
:
BasicQuestionType
;
handleQuestion
:
(
id
:
string
)
=>
void
;
deleteQuestion
:
(
id
:
string
)
=>
void
;
changeCurrentId
:
(
id
:
string
)
=>
void
;
currentId
:
string
;
};
export
const
Question
=
({
element
}:
Props
)
=>
{
const
handleClick
=
()
=>
{};
const
typeDropDown
=
new
Map
([
[
"
essay
"
,
"
주관식
"
],
[
"
radio
"
,
"
객관식
"
],
[
"
dropdown
"
,
"
드롭다운
"
],
[
"
checkbox
"
,
"
체크박스
"
],
[
"
file
"
,
"
파일
"
],
[
"
rating
"
,
"
선형
"
],
[
"
grid
"
,
"
그리드
"
],
[
"
date
"
,
"
날짜
"
],
]);
const
typeDD
=
new
Map
([
[
"
essay
"
,
"
주관식
"
],
[
"
radio
"
,
"
객관식
"
],
[
"
dropdown
"
,
"
드롭다운(객관식)
"
],
[
"
checkbox
"
,
"
체크박스
"
],
[
"
file
"
,
"
파일
"
],
[
"
rating
"
,
"
선형
"
],
[
"
grid
"
,
"
그리드
"
],
[
"
date
"
,
"
날짜
"
],
]);
export
const
Question
=
({
element
,
handleQuestion
,
deleteQuestion
,
changeCurrentId
,
currentId
,
}:
Props
)
=>
{
const
handleEditClick
=
()
=>
{
changeCurrentId
(
element
.
_id
);
};
async
function
handleEditComplete
()
{
try
{
const
newQuestion
:
BasicQuestionType
=
await
questionApi
.
updateQuestion
(
element
);
console
.
log
(
newQuestion
);
changeCurrentId
(
""
);
// setSuccess(true);
// setError("");
}
catch
(
error
)
{
console
.
log
(
"
에러발생
"
);
// catchErrors(error, setError)
}
finally
{
// setLoading(false);
}
}
function
handleSelect
(
event
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
{
const
selectedType
=
event
.
currentTarget
.
value
;
console
.
log
(
selectedType
);
if
(
selectedType
===
"
radio
"
||
selectedType
===
"
dropdown
"
||
selectedType
===
"
checkbox
"
)
{
element
.
content
=
{
choices
:
[
{
text
:
""
,
value
:
0
},
{
text
:
""
,
value
:
1
},
{
text
:
""
,
value
:
2
},
],
};
}
else
if
(
selectedType
===
"
essay
"
)
{
element
.
content
=
{
choices
:
[]
};
}
else
if
(
selectedType
===
"
rating
"
)
{
element
.
content
=
{
minRateDescription
:
""
,
maxRateDescription
:
""
,
choices
:
[
{
text
:
""
,
value
:
0
},
{
text
:
""
,
value
:
1
},
{
text
:
""
,
value
:
2
},
],
};
}
element
.
type
=
selectedType
;
handleQuestion
(
element
.
_id
);
}
function
changeDD
(
e
:
React
.
ChangeEvent
<
HTMLSelectElement
>
)
{
const
tt
=
e
.
target
.
value
;
// questionTypeChange(e);
console
.
log
(
tt
);
//if문으로 type별로 content 바뀌게 해보기
function
handleQuestionInfo
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
{
name
,
value
}
=
event
.
currentTarget
;
element
[
name
]
=
value
;
handleQuestion
(
element
.
_id
);
}
function
handleDelete
()
{
deleteQuestion
(
element
.
_id
);
}
function
getContent
(
element
:
BasicQuestionType
)
{
switch
(
element
.
type
)
{
case
"
essay
"
:
return
<
EssayForm
element
=
{
element
}
/>;
return
<
EssayForm
element
=
{
element
}
currentId
=
{
currentId
}
/>;
case
"
radio
"
:
// return <RadioForm element={element} />;
return
(
<
RadioForm
handleQuestion
=
{
handleQuestion
}
element
=
{
element
}
currentId
=
{
currentId
}
/>
);
case
"
checkbox
"
:
// return <CheckboxForm element={element} />;
return
(
<
CheckboxForm
handleQuestion
=
{
handleQuestion
}
element
=
{
element
}
currentId
=
{
currentId
}
/>
);
case
"
dropdown
"
:
// return <DropdownForm element={element} />;
return
(
<
DropdownForm
handleQuestion
=
{
handleQuestion
}
element
=
{
element
}
currentId
=
{
currentId
}
/>
);
case
"
file
"
:
//
return <FileForm element={element} />;
return
<
FileForm
element
=
{
element
}
currentId
=
{
currentId
}
/>;
case
"
rating
"
:
// return <RatingForm element={element} />;
return
(
<
RatingForm
handleQuestion
=
{
handleQuestion
}
element
=
{
element
}
currentId
=
{
currentId
}
/>
);
default
:
return
<></>;
}
...
...
@@ -54,18 +147,25 @@ export const Question = ({ element }: Props) => {
name
=
"title"
id
=
{
element
.
_id
}
className
=
"text-xl font-bold ml-6 border-b-2 w-1/2"
placeholder
=
{
element
.
title
}
// onChange={questionListChange}
placeholder
=
{
"
Question Title
"
}
value
=
{
element
.
title
}
onChange
=
{
handleQuestionInfo
}
disabled
=
{
currentId
!==
element
.
_id
}
></
input
>
<
select
id
=
"Questions"
id
=
{
element
.
_id
}
name
=
"type"
onChange
=
{
handleSelect
}
className
=
"w-36 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-themeColor w-full mr-3 p-2.5"
defaultValue
=
{
element
.
type
}
onChange
=
{
changeDD
}
>
{
Array
.
from
(
typeDD
.
entries
()).
map
(([
k
,
v
])
=>
(
<
option
value
=
{
k
}
>
{
v
}
</
option
>
{
Array
.
from
(
typeDropDown
.
entries
()).
map
(([
key
,
value
])
=>
(
<
option
id
=
{
element
.
_id
}
value
=
{
key
}
selected
=
{
key
===
element
.
type
}
>
{
value
}
</
option
>
))
}
</
select
>
</
div
>
...
...
@@ -76,18 +176,32 @@ export const Question = ({ element }: Props) => {
id
=
{
element
.
_id
}
className
=
"border w-11/12"
placeholder
=
"질문에 대한 설명을 입력해주세요"
// onChange={questionListChange}
value
=
{
element
.
comment
}
onChange
=
{
handleQuestionInfo
}
disabled
=
{
currentId
!==
element
.
_id
}
></
input
>
</
div
>
{
getContent
(
element
)
}
<
div
className
=
"flex w-full justify-end py-2"
>
<
button
className
=
"w-1/12"
>
필수
</
button
>
<
button
className
=
"w-1/12"
>
옵션
</
button
>
<
button
className
=
"w-1/12"
>
삭제
</
button
>
<
button
id
=
{
element
.
id
}
className
=
"w-1/12"
onClick
=
{
handleClick
}
>
수정
<
div
className
=
"place-self-end py-2"
>
<
button
type
=
"button"
className
=
"px-1"
>
필수
</
button
>
<
button
type
=
"button"
className
=
"px-1"
>
옵션
</
button
>
<
button
type
=
"button"
className
=
"px-1"
onClick
=
{
handleDelete
}
>
삭제
</
button
>
{
currentId
===
element
.
_id
?
(
<
button
type
=
"button"
className
=
"px-1"
onClick
=
{
handleEditComplete
}
>
수정완료
</
button
>
)
:
(
<
button
type
=
"button"
className
=
"px-1"
onClick
=
{
handleEditClick
}
>
수정하기
</
button
>
)
}
</
div
>
</
div
>
);
...
...
frontend/src/questions/RadioForm.tsx
View file @
4949c01d
import
React
from
"
react
"
;
import
React
,
{
useState
}
from
"
react
"
;
import
{
RadioType
}
from
"
../types
"
;
import
{
useQuestion
}
from
"
./question.context
"
;
import
{
TypeChange
}
from
"
./typeDD
"
;
type
Props
=
{
element
:
RadioType
;
handleQuestion
:
(
id
:
string
)
=>
void
;
currentId
:
string
;
};
export
const
QRadio
=
({
element
}:
Props
)
=>
{
const
{
questionListChange
}
=
useQuestion
();
export
const
RadioForm
=
({
element
,
handleQuestion
,
currentId
}:
Props
)
=>
{
const
[
choices
,
setChoices
]
=
useState
([...
element
.
content
.
choices
]);
function
handleContent
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
{
id
,
value
}
=
event
.
target
;
choices
[
+
id
].
text
=
value
;
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
console
.
log
(
choices
);
}
function
deleteValue
()
{
//제일 마지막 index 제거
choices
.
splice
(
-
1
,
1
);
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
}
function
addValue
()
{
choices
.
push
({
text
:
""
,
value
:
choices
.
length
});
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
}
return
(
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-2"
>
<
div
className
=
"flex h-16 w-full place-content-between items-center"
>
<
input
type
=
"text"
name
=
"title"
id
=
{
element
.
_id
}
className
=
"text-xl font-bold ml-6 border-b-2 w-1/2"
placeholder
=
{
element
.
title
}
onChange
=
{
questionListChange
}
></
input
>
<
TypeChange
tt
=
"radio"
/>
</
div
>
<
div
className
=
"flex w-full justify-center"
>
<
input
type
=
"text"
name
=
"comment"
id
=
{
element
.
_id
}
className
=
"border w-11/12"
placeholder
=
"질문에 대한 설명을 입력해주세요"
onChange
=
{
questionListChange
}
></
input
>
</
div
>
<
div
className
=
"flex mt-4"
>
{
element
.
content
.
choices
.
map
((
e
:
any
,
index
:
number
)
=>
(
<
div
>
<
input
type
=
"radio"
id
=
{
element
.
_id
}
name
=
"choice"
value
=
{
e
.
text
}
disabled
/>
<>
<
div
id
=
"content"
className
=
"mt-4 p-5"
>
{
choices
.
map
((
choice
:
any
,
index
:
number
)
=>
(
<
div
className
=
"m-5"
>
<
input
type
=
"radio"
disabled
></
input
>
<
input
id
=
{
`
${
index
}
`
}
type
=
"text"
name
=
{
"
choice
"
}
// key={`${index}`}
className
=
"mx-2 border-b-2"
placeholder
=
{
e
.
text
}
onChange
=
{
questionListChange
}
placeholder
=
"선택지"
value
=
{
choice
.
text
}
onChange
=
{
handleContent
}
disabled
=
{
currentId
!==
element
.
_id
}
></
input
>
<
button
></
button
>
</
div
>
))
}
{
/* <button className="border rounded-full border-green-500 border-4 text-green-500 font-bold px-2">
+
</button> */
}
</
div
>
<
div
className
=
"flex w-full flex-row justify-end py-2"
>
<
button
className
=
"w-1/12"
>
필수
</
button
>
<
button
className
=
"w-1/12"
>
옵션
</
button
>
<
button
className
=
"w-1/12"
>
삭제
</
button
>
<
div
>
<
button
type
=
"button"
name
=
"rateValues"
className
=
"border border-red-500 rounded mx-2 px-2"
onClick
=
{
deleteValue
}
disabled
=
{
currentId
!==
element
.
_id
}
>
삭제
</
button
>
<
button
type
=
"button"
name
=
"rateValues"
className
=
"border border-blue-500 rounded mx-2 px-2"
onClick
=
{
addValue
}
disabled
=
{
currentId
!==
element
.
_id
}
>
추가
</
button
>
</
div
>
</
div
>
</>
);
};
frontend/src/questions/RatingForm.tsx
View file @
4949c01d
import
React
from
"
react
"
;
import
React
,
{
useState
}
from
"
react
"
;
import
{
RatingType
}
from
"
../types
"
;
import
{
useQuestion
}
from
"
./question.context
"
;
import
{
TypeChange
}
from
"
./typeDD
"
;
type
Props
=
{
element
:
RatingType
;
// deleteValue: (e: React.MouseEvent<HTMLButtonElement>) => void;
handleQuestion
:
(
id
:
string
)
=>
void
;
currentId
:
string
;
};
export
const
QRating
=
({
element
}:
Props
)
=>
{
const
{
questionListChange
}
=
useQuestion
();
export
const
RatingForm
=
({
element
,
handleQuestion
,
currentId
}:
Props
)
=>
{
const
[
choices
,
setChoices
]
=
useState
([...
element
.
content
.
choices
]);
function
handleContent
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
{
const
{
id
,
value
,
name
}
=
event
.
target
;
if
(
name
===
"
text
"
)
{
choices
[
+
id
].
text
=
value
;
element
.
content
.
choices
=
choices
;
}
else
if
(
name
===
"
minRateDescription
"
)
{
element
.
content
=
{
...
element
.
content
,
minRateDescription
:
value
};
}
else
if
(
name
===
"
maxRateDescription
"
)
{
element
.
content
=
{
...
element
.
content
,
maxRateDescription
:
value
};
}
handleQuestion
(
element
.
_id
);
console
.
log
(
choices
);
}
function
deleteValue
()
{
//제일 마지막 index 제거
choices
.
splice
(
-
1
,
1
);
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
}
function
addValue
()
{
choices
.
push
({
text
:
"
0
"
,
value
:
choices
.
length
});
element
.
content
.
choices
=
choices
;
handleQuestion
(
element
.
_id
);
}
return
(
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 border-themeColor items-center m-3 py-2"
>
<
div
className
=
"flex h-16 w-full place-content-between items-center"
>
<
input
type
=
"text"
name
=
"title"
id
=
{
element
.
_id
}
className
=
"text-xl font-bold ml-6 border-b-2 w-1/2"
placeholder
=
{
element
.
title
}
onChange
=
{
questionListChange
}
></
input
>
<
TypeChange
tt
=
"rating"
/>
</
div
>
<
div
className
=
"flex w-full justify-center"
>
<
input
type
=
"text"
name
=
"comment"
id
=
{
element
.
_id
}
className
=
"border w-11/12"
placeholder
=
"질문에 대한 설명을 입력해주세요"
onChange
=
{
questionListChange
}
></
input
>
</
div
>
<>
<
div
className
=
"flex place-content-between items-center p-5"
>
<
input
name
=
"minRateDescription"
id
=
{
element
.
_id
}
className
=
"border-b-2 text-center"
size
=
{
10
}
placeholder
=
{
element
.
content
.
minRateDescription
}
placeholder
=
"비동의"
value
=
{
element
.
content
.
minRateDescription
}
onChange
=
{
handleContent
}
disabled
=
{
currentId
!==
element
.
_id
}
></
input
>
{
element
.
content
.
choices
.
map
((
e
)
=>
(
{
choices
.
map
((
choice
:
any
,
index
:
number
)
=>
(
<
input
name
=
"text"
id
=
{
element
.
_id
}
id
=
{
`
${
index
}
`
}
type
=
"text"
className
=
"border border-black rounded-full py-1 m-2 text-center"
size
=
{
1
}
placeholder
=
{
e
.
text
}
placeholder
=
"0"
value
=
{
choice
.
text
}
onChange
=
{
handleContent
}
disabled
=
{
currentId
!==
element
.
_id
}
></
input
>
))
}
<
input
name
=
"maxRateDescription"
id
=
{
element
.
_id
}
className
=
"border-b-2 text-center"
size
=
{
10
}
placeholder
=
{
element
.
content
.
maxRateDescription
}
placeholder
=
"동의"
value
=
{
element
.
content
.
maxRateDescription
}
onChange
=
{
handleContent
}
disabled
=
{
currentId
!==
element
.
_id
}
></
input
>
</
div
>
<
div
>
<
button
//
type="button"
type
=
"button"
name
=
"rateValues"
id
=
{
element
.
_id
}
className
=
"border border-red-500 rounded mx-2 px-2"
// onClick={deleteValue}
onClick
=
{
deleteValue
}
disabled
=
{
currentId
!==
element
.
_id
}
>
삭제
</
button
>
<
button
className
=
"border border-blue-500 rounded mx-2 px-2"
>
<
button
type
=
"button"
name
=
"rateValues"
className
=
"border border-blue-500 rounded mx-2 px-2"
onClick
=
{
addValue
}
disabled
=
{
currentId
!==
element
.
_id
}
>
추가
</
button
>
</
div
>
<
div
className
=
"flex w-full justify-end py-2"
>
<
button
className
=
"w-1/12"
>
필수
</
button
>
<
button
className
=
"w-1/12"
>
옵션
</
button
>
<
button
className
=
"w-1/12"
>
삭제
</
button
>
</
div
>
</
div
>
</>
);
};
frontend/src/survey/
Create
Survey.tsx
→
frontend/src/survey/
Edit
Survey.tsx
View file @
4949c01d
import
React
,
{
FormEvent
,
useState
}
from
"
react
"
;
import
React
,
{
FormEvent
,
useEffect
,
useState
}
from
"
react
"
;
import
{
useParams
}
from
"
react-router-dom
"
;
import
{
questionApi
,
surveyApi
}
from
"
../apis
"
;
import
{
SpinnerIcon
}
from
"
../icons
"
;
import
{
Question
}
from
"
../questions
"
;
import
{
BasicQuestionType
,
SurveyType
}
from
"
../types
"
;
export
const
CreateSurvey
=
()
=>
{
export
const
EditSurvey
=
()
=>
{
let
{
surveyId
}
=
useParams
<
{
surveyId
:
string
}
>
();
useEffect
(()
=>
{
getSurvey
();
},
[
surveyId
]);
const
[
error
,
setError
]
=
useState
(
""
);
const
[
loading
,
setLoading
]
=
useState
(
false
);
const
[
success
,
setSuccess
]
=
useState
(
false
);
const
[
survey
,
setSurvey
]
=
useState
<
SurveyType
>
({
_id
:
surveyId
,
user
:
{},
title
:
""
,
comment
:
""
,
questions
:
[],
});
const
[
currentId
,
setCurrentId
]
=
useState
(
""
);
const
changeCurrentId
=
(
id
:
string
)
=>
{
setCurrentId
(
id
);
};
async
function
getSurvey
()
{
try
{
if
(
surveyId
)
{
const
thisSurvey
:
SurveyType
=
await
surveyApi
.
getSurvey
(
surveyId
);
setSurvey
(
thisSurvey
);
setSuccess
(
true
);
setError
(
""
);
}
else
{
setLoading
(
true
);
}
}
catch
(
error
)
{
console
.
log
(
"
에러발생
"
);
// catchErrors(error, setError)
}
finally
{
setLoading
(
false
);
}
}
const
handleQuestion
=
(
id
:
string
)
=>
{
const
newList
:
BasicQuestionType
[]
=
[...
survey
.
questions
];
setSurvey
({
...
survey
,
questions
:
newList
});
};
const
handleChange
=
()
=>
{};
const
handleSurvey
=
(
event
:
React
.
ChangeEvent
<
HTMLInputElement
>
)
=>
{
const
{
name
,
value
}
=
event
.
currentTarget
;
setSurvey
({
...
survey
,
[
name
]:
value
});
};
async
function
handleSubmit
(
event
:
FormEvent
)
{
event
.
preventDefault
();
try
{
const
newSurvey
:
SurveyType
=
await
surveyApi
.
create
Survey
(
survey
);
const
newSurvey
:
SurveyType
=
await
surveyApi
.
edit
Survey
(
survey
);
console
.
log
(
newSurvey
);
// setSuccess(true);
// setError("");
...
...
@@ -31,7 +71,6 @@ export const CreateSurvey = () => {
try
{
const
newQuestion
:
BasicQuestionType
=
await
questionApi
.
createQuestion
();
setSurvey
({
...
survey
,
questions
:
[...
survey
.
questions
,
newQuestion
]
});
// setQuestions([...questions, newQuestion]);
// setSuccess(true);
// setError("");
}
catch
(
error
)
{
...
...
@@ -42,10 +81,30 @@ export const CreateSurvey = () => {
}
}
const
questions
=
survey
.
questions
;
async
function
deleteQuestion
(
id
:
string
)
{
const
newList
:
BasicQuestionType
[]
=
[...
survey
.
questions
];
try
{
const
newQuestion
:
BasicQuestionType
=
await
questionApi
.
deleteQuestion
(
id
);
setSurvey
({
...
survey
,
questions
:
newList
.
filter
((
a
)
=>
a
.
_id
!==
id
)
});
// setSuccess(true);
// setError("");
}
catch
(
error
)
{
console
.
log
(
"
에러발생
"
);
// catchErrors(error, setError)
}
finally
{
// setLoading(false);
}
}
const
questions
=
survey
.
questions
;
console
.
log
(
questions
);
return
(
<>
{
loading
&&
(
<
SpinnerIcon
className
=
"animate-spin h-5 w-5 mr-1 text-slate"
/>
)
}
<
form
onSubmit
=
{
handleSubmit
}
>
<
div
className
=
"flex flex-col place-items-center"
>
<
div
className
=
"flex flex-col container place-items-center mt-4"
>
...
...
@@ -54,7 +113,7 @@ export const CreateSurvey = () => {
name
=
"title"
className
=
"font-bold text-4xl text-center m-2 border-b-2"
placeholder
=
"설문지 제목"
onChange
=
{
handle
Change
}
onChange
=
{
handle
Survey
}
></
input
>
<
input
type
=
"text"
...
...
@@ -62,11 +121,17 @@ export const CreateSurvey = () => {
className
=
"font-bold text-1xl text-center m-2 resize-none"
placeholder
=
"설문조사에 대한 설명을 입력해주세요"
size
=
{
50
}
onChange
=
{
handle
Change
}
onChange
=
{
handle
Survey
}
></
input
>
</
div
>
{
questions
.
map
((
question
)
=>
(
<
Question
element
=
{
question
}
/>
<
Question
element
=
{
question
}
handleQuestion
=
{
handleQuestion
}
deleteQuestion
=
{
deleteQuestion
}
changeCurrentId
=
{
changeCurrentId
}
currentId
=
{
currentId
}
/>
))
}
<
div
className
=
"flex w-4/5 content-center justify-center border-2 border-black h-8 mt-3"
>
<
button
type
=
"button"
onClick
=
{
addQuestion
}
>
...
...
frontend/src/survey/index.tsx
View file @
4949c01d
export
{
Create
Survey
}
from
"
./
Create
Survey
"
;
export
{
Edit
Survey
}
from
"
./
Edit
Survey
"
;
frontend/src/types/index.ts
View file @
4949c01d
...
...
@@ -11,6 +11,8 @@ export interface SignupUser {
}
export
interface
SurveyType
{
_id
?:
string
;
user
:
any
;
title
:
string
;
comment
:
string
;
questions
:
BasicQuestionType
[];
...
...
src/controllers/question.controller.ts
View file @
4949c01d
import
{
NextFunction
,
Request
,
Response
}
from
"
express
"
;
import
{
questionDb
}
from
"
../db
"
;
import
{
asyncWrap
}
from
"
../helpers/asyncWrap
"
;
export
const
createQuestion
=
asyncWrap
(
async
(
req
,
res
)
=>
{
export
interface
TypedRequestAuth
<
T
>
extends
Request
{
auth
:
T
;
user
:
any
;
}
export
const
createQuestion
=
asyncWrap
(
async
(
reqExp
:
Request
,
res
:
Response
,
next
:
NextFunction
)
=>
{
const
req
=
reqExp
as
TypedRequestAuth
<
{
userId
:
string
}
>
;
const
{
userId
}
=
req
.
auth
;
let
question
=
req
.
body
;
question
.
user
=
userId
;
console
.
log
(
"
question body
"
,
question
);
const
newQuestion
=
await
questionDb
.
createQuestion
(
question
);
return
res
.
json
(
newQuestion
);
}
);
export
const
updateQuestion
=
asyncWrap
(
async
(
req
,
res
)
=>
{
const
question
=
req
.
body
;
console
.
log
(
"
question body
"
,
question
);
const
newQuestion
=
await
questionDb
.
createQuestion
(
question
);
const
newQuestion
=
await
questionDb
.
updateQuestion
(
question
);
return
res
.
json
(
newQuestion
);
});
export
const
deleteQuestionById
=
asyncWrap
(
async
(
req
,
res
)
=>
{
const
{
questionId
}
=
req
.
params
;
const
newQuestion
=
await
questionDb
.
deleteQuestionById
(
questionId
);
return
res
.
json
(
newQuestion
);
});
export
const
userByQuestionId
=
async
(
reqExp
:
Request
,
res
:
Response
,
next
:
NextFunction
,
questionId
:
string
)
=>
{
try
{
const
req
=
reqExp
as
TypedRequestAuth
<
{
userId
:
string
}
>
;
let
user
=
await
questionDb
.
findUserByQuestionId
(
questionId
);
if
(
!
user
)
{
return
res
.
status
(
404
).
send
(
"
사용자를 찾을 수 없습니다
"
);
}
req
.
user
=
user
;
next
();
}
catch
(
error
:
any
)
{
return
res
.
status
(
500
)
.
send
(
error
.
message
||
"
질문을 작성한 사용자를 찾아내는 중 오류 발생
"
);
}
};
src/controllers/survey.controller.ts
View file @
4949c01d
import
{
NextFunction
,
Request
,
Response
}
from
"
express
"
;
import
{
surveyDb
}
from
"
../db
"
;
import
{
asyncWrap
}
from
"
../helpers/asyncWrap
"
;
export
const
createSurvey
=
asyncWrap
(
async
(
req
,
res
)
=>
{
export
interface
TypedRequestAuth
<
T
>
extends
Request
{
auth
:
T
;
user
:
any
;
}
export
const
createSurvey
=
asyncWrap
(
async
(
reqExp
:
Request
,
res
:
Response
,
next
:
NextFunction
)
=>
{
const
req
=
reqExp
as
TypedRequestAuth
<
{
userId
:
string
}
>
;
const
{
userId
}
=
req
.
auth
;
let
survey
=
req
.
body
;
survey
.
user
=
userId
;
console
.
log
(
"
survey body
"
,
survey
);
const
newSurvey
=
await
surveyDb
.
createSurvey
(
survey
);
return
res
.
json
(
newSurvey
);
}
);
export
const
getSurveyById
=
asyncWrap
(
async
(
req
,
res
)
=>
{
const
{
surveyId
}
=
req
.
params
;
const
survey
=
await
surveyDb
.
getSurveyById
(
surveyId
);
console
.
log
(
"
Get완료
"
,
survey
);
return
res
.
json
(
survey
);
});
export
const
updateSurvey
=
asyncWrap
(
async
(
req
,
res
)
=>
{
const
survey
=
req
.
body
;
console
.
log
(
"
Survey body
"
,
survey
);
const
newSurvey
=
await
surveyDb
.
createSurvey
(
survey
);
const
newSurvey
=
await
surveyDb
.
updateSurvey
(
survey
);
return
res
.
json
(
newSurvey
);
});
export
const
userBySurveyId
=
async
(
reqExp
:
Request
,
res
:
Response
,
next
:
NextFunction
,
surveyId
:
string
)
=>
{
try
{
const
req
=
reqExp
as
TypedRequestAuth
<
{
userId
:
string
}
>
;
let
user
=
await
surveyDb
.
findUserBySurveyId
(
surveyId
);
if
(
!
user
)
{
return
res
.
status
(
404
).
send
(
"
사용자를 찾을 수 없습니다
"
);
}
req
.
user
=
user
;
next
();
}
catch
(
error
:
any
)
{
return
res
.
status
(
500
)
.
send
(
error
.
message
||
"
설문조사를 작성한 사용자를 찾아내는 중 오류 발생
"
);
}
};
src/db/question.db.ts
View file @
4949c01d
import
{
Question
,
IQuestion
}
from
"
../models
"
;
export
const
findUserByQuestionId
=
async
(
questionId
:
string
)
=>
{
const
question
=
await
Question
.
findById
(
questionId
).
populate
(
"
user
"
);
console
.
log
(
question
);
if
(
question
!==
null
)
{
console
.
log
(
question
.
user
);
return
question
.
user
;
}
return
null
;
};
export
const
createQuestion
=
async
(
question
:
IQuestion
)
=>
{
const
newQuestion
=
await
Question
.
create
(
question
);
return
newQuestion
;
};
export
const
updateQuestion
=
async
(
question
:
IQuestion
)
=>
{
const
id
=
question
.
_id
;
const
newQuestion
=
await
Question
.
findOneAndUpdate
({
_id
:
id
},
question
);
return
newQuestion
;
};
export
const
deleteQuestionById
=
async
(
id
:
string
)
=>
{
const
newQuestion
=
await
Question
.
findByIdAndDelete
(
id
);
return
newQuestion
;
};
Prev
1
2
3
Next
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