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
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