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
4e580901
Commit
4e580901
authored
Jan 09, 2023
by
jang dong hyeok
Browse files
dnd 시도
parent
0150d3d8
Changes
4
Hide whitespace changes
Inline
Side-by-side
frontend/package.json
View file @
4e580901
...
@@ -37,6 +37,8 @@
...
@@ -37,6 +37,8 @@
"d3-scale"
:
"^4.0.2"
,
"d3-scale"
:
"^4.0.2"
,
"d3-shape"
:
"^3.2.0"
,
"d3-shape"
:
"^3.2.0"
,
"react"
:
"^18.2.0"
,
"react"
:
"^18.2.0"
,
"react-dnd"
:
"^16.0.1"
,
"react-dnd-html5-backend"
:
"^16.0.1"
,
"react-dom"
:
"^18.2.0"
,
"react-dom"
:
"^18.2.0"
,
"react-router-dom"
:
"^6.3.0"
"react-router-dom"
:
"^6.3.0"
}
}
...
...
frontend/src/App.tsx
View file @
4e580901
...
@@ -2,12 +2,16 @@ import React from "react";
...
@@ -2,12 +2,16 @@ import React from "react";
import
{
Outlet
}
from
"
react-router-dom
"
;
import
{
Outlet
}
from
"
react-router-dom
"
;
import
{
AuthProvider
}
from
"
./auth/auth.context
"
;
import
{
AuthProvider
}
from
"
./auth/auth.context
"
;
import
{
Footer
,
Header
}
from
"
./commons
"
;
import
{
Footer
,
Header
}
from
"
./commons
"
;
import
{
DndProvider
}
from
"
react-dnd/dist/core
"
;
import
{
HTML5Backend
}
from
"
react-dnd-html5-backend
"
;
const
App
=
()
=>
(
const
App
=
()
=>
(
<
AuthProvider
>
<
AuthProvider
>
<
Header
/>
<
Header
/>
<
div
style
=
{
{
minHeight
:
"
80vh
"
}
}
>
<
div
style
=
{
{
minHeight
:
"
80vh
"
}
}
>
<
Outlet
/>
<
DndProvider
backend
=
{
HTML5Backend
}
>
<
Outlet
/>
</
DndProvider
>
</
div
>
</
div
>
<
Footer
/>
<
Footer
/>
</
AuthProvider
>
</
AuthProvider
>
...
...
frontend/src/layouts/SurveyLayout.tsx
View file @
4e580901
...
@@ -10,6 +10,8 @@ import type {
...
@@ -10,6 +10,8 @@ import type {
}
from
"
../types
"
;
}
from
"
../types
"
;
import
{
SpinnerIcon
}
from
"
../icons
"
;
import
{
SpinnerIcon
}
from
"
../icons
"
;
import
{
surveyApi
}
from
"
../apis
"
;
import
{
surveyApi
}
from
"
../apis
"
;
import
{
DndProvider
}
from
"
react-dnd
"
;
import
{
HTML5Backend
}
from
"
react-dnd-html5-backend
"
;
type
SurveyContextType
=
{
type
SurveyContextType
=
{
survey
:
ICreateSurvey
;
survey
:
ICreateSurvey
;
...
@@ -122,15 +124,17 @@ export const SurveyLayout = () => {
...
@@ -122,15 +124,17 @@ export const SurveyLayout = () => {
응답결과
응답결과
</
NavLink
>
</
NavLink
>
</
div
>
</
div
>
<
Outlet
<
DndProvider
backend
=
{
HTML5Backend
}
>
context
=
{
{
<
Outlet
survey
,
context
=
{
{
createQuestion
,
survey
,
removeQuestion
,
createQuestion
,
updateQuestion
,
removeQuestion
,
updateTitleComment
,
updateQuestion
,
}
}
updateTitleComment
,
/>
}
}
/>
</
DndProvider
>
</
div
>
</
div
>
);
);
};
};
...
...
frontend/src/surveys/Question.tsx
View file @
4e580901
...
@@ -2,6 +2,9 @@ import React, { useState } from "react";
...
@@ -2,6 +2,9 @@ import React, { useState } from "react";
import
{
getEnumKeyByEnumValue
,
QUESTION_TYPES
}
from
"
../commons
"
;
import
{
getEnumKeyByEnumValue
,
QUESTION_TYPES
}
from
"
../commons
"
;
import
{
getElementByQuestionType
}
from
"
../helpers
"
;
import
{
getElementByQuestionType
}
from
"
../helpers
"
;
import
{
IQuestionProps
}
from
"
../types
"
;
import
{
IQuestionProps
}
from
"
../types
"
;
import
{
useDrag
,
useDrop
}
from
"
react-dnd
"
;
import
{
SurveyLayout
}
from
"
../layouts
"
;
import
{
surveyApi
}
from
"
../apis
"
;
const
options
=
Object
.
entries
(
QUESTION_TYPES
).
map
(([
type
,
value
])
=>
(
const
options
=
Object
.
entries
(
QUESTION_TYPES
).
map
(([
type
,
value
])
=>
(
<
option
key
=
{
type
}
value
=
{
value
}
>
<
option
key
=
{
type
}
value
=
{
value
}
>
...
@@ -9,6 +12,9 @@ const options = Object.entries(QUESTION_TYPES).map(([type, value]) => (
...
@@ -9,6 +12,9 @@ const options = Object.entries(QUESTION_TYPES).map(([type, value]) => (
</
option
>
</
option
>
));
));
export
interface
DropResult
{
name
:
string
;
}
export
const
Question
=
({
export
const
Question
=
({
element
,
element
,
handleQuestion
,
handleQuestion
,
...
@@ -16,7 +22,39 @@ export const Question = ({
...
@@ -16,7 +22,39 @@ export const Question = ({
}:
IQuestionProps
)
=>
{
}:
IQuestionProps
)
=>
{
const
[
question
,
setQuestion
]
=
useState
(
element
);
const
[
question
,
setQuestion
]
=
useState
(
element
);
const
isEditing
=
question
.
isEditing
;
const
isEditing
=
question
.
isEditing
;
//
const
[{
isDragging
},
drag
]
=
useDrag
(()
=>
({
type
:
SurveyLayout
.
name
,
item
:
{
name
:
question
.
type
},
end
:
(
item
,
monitor
)
=>
{
const
dropResult
=
monitor
.
getDropResult
<
DropResult
>
();
if
(
item
&&
dropResult
)
{
alert
(
`You dropped
${
item
.
name
}
`
);
}
},
collect
:
(
monitor
)
=>
({
isDragging
:
monitor
.
isDragging
(),
handlerId
:
monitor
.
getHandlerId
(),
}),
}));
const
[{
canDrop
,
isOver
},
drop
]
=
useDrop
(()
=>
({
accept
:
SurveyLayout
.
name
,
collect
:
(
monitor
)
=>
({
isOver
:
monitor
.
isOver
(),
canDrop
:
monitor
.
canDrop
(),
}),
}));
const
isActive
=
canDrop
&&
isOver
;
let
backgroundColor
=
"
#222
"
;
if
(
isActive
)
{
backgroundColor
=
"
darkgreen
"
;
}
else
if
(
canDrop
)
{
backgroundColor
=
"
darkkhaki
"
;
}
//
async
function
handleEditComplete
()
{
async
function
handleEditComplete
()
{
question
.
content
.
choices
.
map
((
choice
)
=>
{
question
.
content
.
choices
.
map
((
choice
)
=>
{
if
(
choice
.
text
.
trim
()
===
""
)
{
if
(
choice
.
text
.
trim
()
===
""
)
{
...
@@ -71,82 +109,87 @@ export const Question = ({
...
@@ -71,82 +109,87 @@ export const Question = ({
};
};
return
(
return
(
<
div
<
div
ref
=
{
drop
}
className
=
"flex w-3/5 h-full justify-center"
>
style
=
{
{
borderColor
:
isEditing
?
"
red
"
:
"
#0A8A8A
"
}
}
<
div
className
=
"flex flex-col container w-4/5 h-auto border-2 items-center m-3 py-2 rounded-lg"
ref
=
{
drag
}
>
style
=
{
{
borderColor
:
isEditing
?
"
red
"
:
"
#0A8A8A
"
}
}
<
div
className
=
"flex h-16 w-full place-content-center items-center"
>
className
=
{
<
input
"
flex flex-col container w-full h-auto border-2 items-center m-3 py-2 rounded-lg cursor-move
"
type
=
"text"
}
name
=
"title"
>
id
=
{
question
.
_id
}
<
div
className
=
"flex h-16 w-full place-content-center items-center"
>
className
=
"text-xl font-bold border-b-2 w-11/12"
placeholder
=
{
"
Question Title
"
}
value
=
{
question
.
title
}
onChange
=
{
handleChange
}
disabled
=
{
!
isEditing
}
></
input
>
</
div
>
<
div
className
=
"flex w-full justify-center"
>
<
input
type
=
"text"
name
=
"comment"
id
=
{
question
.
_id
}
className
=
"border w-11/12"
placeholder
=
"질문에 대한 설명을 입력해주세요"
value
=
{
question
.
comment
}
onChange
=
{
handleChange
}
disabled
=
{
!
isEditing
}
></
input
>
</
div
>
{
getElementByQuestionType
(
question
,
handleElement
,
isEditing
)
}
<
div
className
=
"flex flex-row place-content-between w-11/12 py-2"
>
<
select
id
=
{
question
.
_id
}
name
=
"type"
onChange
=
{
handleSelect
}
disabled
=
{
!
isEditing
}
value
=
{
QUESTION_TYPES
[
question
.
type
]
}
className
=
"w-32 h-10 md:w-36 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-themeColor"
>
{
options
}
</
select
>
<
div
className
=
"place-self-end py-2"
>
<
input
<
input
type
=
"checkbox"
type
=
"text"
id
=
"isRequired"
name
=
"title"
name
=
"isRequired"
id
=
{
question
.
_id
}
className
=
"text-xl font-bold border-b-2 w-11/12"
placeholder
=
{
"
Question Title
"
}
value
=
{
question
.
title
}
onChange
=
{
handleChange
}
onChange
=
{
handleChange
}
disabled
=
{
!
isEditing
}
disabled
=
{
!
isEditing
}
checked
=
{
question
.
isRequired
}
></
input
>
/>
</
div
>
<
label
htmlFor
=
"isRequired"
className
=
"px-1"
>
<
div
className
=
"flex w-full justify-center"
>
필수
<
input
</
label
>
type
=
"text"
{
isEditing
?
(
name
=
"comment"
<>
id
=
{
question
.
_id
}
<
button
type
=
"button"
className
=
"px-1"
onClick
=
{
onCancel
}
>
className
=
"border w-11/12"
취소
placeholder
=
"질문에 대한 설명을 입력해주세요"
</
button
>
value
=
{
question
.
comment
}
onChange
=
{
handleChange
}
disabled
=
{
!
isEditing
}
></
input
>
</
div
>
{
getElementByQuestionType
(
question
,
handleElement
,
isEditing
)
}
<
div
className
=
"flex flex-row place-content-between w-11/12 py-2"
>
<
select
id
=
{
question
.
_id
}
name
=
"type"
onChange
=
{
handleSelect
}
disabled
=
{
!
isEditing
}
value
=
{
QUESTION_TYPES
[
question
.
type
]
}
className
=
"w-32 h-10 md:w-36 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-themeColor"
>
{
options
}
</
select
>
<
div
className
=
"place-self-end py-2"
>
<
input
type
=
"checkbox"
id
=
"isRequired"
name
=
"isRequired"
onChange
=
{
handleChange
}
disabled
=
{
!
isEditing
}
checked
=
{
question
.
isRequired
}
/>
<
label
htmlFor
=
"isRequired"
className
=
"px-1"
>
필수
</
label
>
{
isEditing
?
(
<>
<
button
type
=
"button"
className
=
"px-1"
onClick
=
{
onCancel
}
>
취소
</
button
>
<
button
<
button
type
=
"button"
type
=
"button"
className
=
"px-1"
className
=
"px-1"
onClick
=
{
handleEditComplete
}
onClick
=
{
handleEditComplete
}
>
>
확인
확인
</
button
>
</
button
>
</>
</>
)
:
(
)
:
(
<>
<>
<
button
type
=
"button"
className
=
"px-1"
onClick
=
{
onDelete
}
>
<
button
type
=
"button"
className
=
"px-1"
onClick
=
{
onDelete
}
>
삭제
삭제
</
button
>
</
button
>
<
button
type
=
"button"
className
=
"px-1"
onClick
=
{
onEdit
}
>
<
button
type
=
"button"
className
=
"px-1"
onClick
=
{
onEdit
}
>
수정
수정
</
button
>
</
button
>
</>
</>
)
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
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