Commit 4e580901 authored by jang dong hyeok's avatar jang dong hyeok
Browse files

dnd 시도

parent 0150d3d8
......@@ -37,6 +37,8 @@
"d3-scale": "^4.0.2",
"d3-shape": "^3.2.0",
"react": "^18.2.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "^18.2.0",
"react-router-dom": "^6.3.0"
}
......
......@@ -2,12 +2,16 @@ import React from "react";
import { Outlet } from "react-router-dom";
import { AuthProvider } from "./auth/auth.context";
import { Footer, Header } from "./commons";
import { DndProvider } from "react-dnd/dist/core";
import { HTML5Backend } from "react-dnd-html5-backend";
const App = () => (
<AuthProvider>
<Header />
<div style={{ minHeight: "80vh" }}>
<Outlet />
<DndProvider backend={HTML5Backend}>
<Outlet />
</DndProvider>
</div>
<Footer />
</AuthProvider>
......
......@@ -10,6 +10,8 @@ import type {
} from "../types";
import { SpinnerIcon } from "../icons";
import { surveyApi } from "../apis";
import { DndProvider } from "react-dnd";
import { HTML5Backend } from "react-dnd-html5-backend";
type SurveyContextType = {
survey: ICreateSurvey;
......@@ -122,15 +124,17 @@ export const SurveyLayout = () => {
응답결과
</NavLink>
</div>
<Outlet
context={{
survey,
createQuestion,
removeQuestion,
updateQuestion,
updateTitleComment,
}}
/>
<DndProvider backend={HTML5Backend}>
<Outlet
context={{
survey,
createQuestion,
removeQuestion,
updateQuestion,
updateTitleComment,
}}
/>
</DndProvider>
</div>
);
};
......
......@@ -2,6 +2,9 @@ import React, { useState } from "react";
import { getEnumKeyByEnumValue, QUESTION_TYPES } from "../commons";
import { getElementByQuestionType } from "../helpers";
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]) => (
<option key={type} value={value}>
......@@ -9,6 +12,9 @@ const options = Object.entries(QUESTION_TYPES).map(([type, value]) => (
</option>
));
export interface DropResult {
name: string;
}
export const Question = ({
element,
handleQuestion,
......@@ -16,7 +22,39 @@ export const Question = ({
}: IQuestionProps) => {
const [question, setQuestion] = useState(element);
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() {
question.content.choices.map((choice) => {
if (choice.text.trim() === "") {
......@@ -71,82 +109,87 @@ export const Question = ({
};
return (
<div
style={{ borderColor: isEditing ? "red" : "#0A8A8A" }}
className="flex flex-col container w-4/5 h-auto border-2 items-center m-3 py-2 rounded-lg"
>
<div className="flex h-16 w-full place-content-center items-center">
<input
type="text"
name="title"
id={question._id}
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">
<div ref={drop} className="flex w-3/5 h-full justify-center">
<div
ref={drag}
style={{ borderColor: isEditing ? "red" : "#0A8A8A" }}
className={
"flex flex-col container w-full h-auto border-2 items-center m-3 py-2 rounded-lg cursor-move "
}
>
<div className="flex h-16 w-full place-content-center items-center">
<input
type="checkbox"
id="isRequired"
name="isRequired"
type="text"
name="title"
id={question._id}
className="text-xl font-bold border-b-2 w-11/12"
placeholder={"Question Title"}
value={question.title}
onChange={handleChange}
disabled={!isEditing}
checked={question.isRequired}
/>
<label htmlFor="isRequired" className="px-1">
필수
</label>
{isEditing ? (
<>
<button type="button" className="px-1" onClick={onCancel}>
취소
</button>
></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
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
type="button"
className="px-1"
onClick={handleEditComplete}
>
확인
</button>
</>
) : (
<>
<button type="button" className="px-1" onClick={onDelete}>
삭제
</button>
<button type="button" className="px-1" onClick={onEdit}>
수정
</button>
</>
)}
<button
type="button"
className="px-1"
onClick={handleEditComplete}
>
확인
</button>
</>
) : (
<>
<button type="button" className="px-1" onClick={onDelete}>
삭제
</button>
<button type="button" className="px-1" onClick={onEdit}>
수정
</button>
</>
)}
</div>
</div>
</div>
</div>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment