Commit 65353848 authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

질문 삭제, 수정

parent 74ee10b0
import axios from "axios";
import { BasicQuestionType } from "../types";
import baseUrl from "./baseUrl";
export const createQuestion = async () => {
......@@ -7,8 +8,17 @@ export const createQuestion = async () => {
title: "Question Title",
isRequired: false,
comment: "질문에 대한 설명을 입력해주세요",
content: null,
content: { choices: [] },
});
return data;
};
};
export const updateQuestion = async (question: BasicQuestionType) => {
const { data } = await axios.post(`${baseUrl}/questions/update`, question);
return data;
};
export const deleteQuestion = async (id: string) => {
const { data } = await axios.post(`${baseUrl}/questions/delete`, { id: id });
return data;
};
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;
};
export const QCheckbox = ({ element }: Props) => {
const { questionListChange } = useQuestion();
export const CheckboxForm = ({ element, handleQuestion }: 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);
}
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 id="content" className="flex mt-4">
{choices.map((choice: any, index: number) => (
<div>
<input type="checkbox" checked={false}></input>
<input type="checkbox" disabled></input>
<input
id={`${index}`}
type="text"
className="mx-2 border-b-2"
placeholder={e.text}
placeholder={choice.text}
onChange={handleContent}
></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>
</div>
);
};
import { useQuestion } from "./question.context";
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;
};
export const QDropdown = ({ element }: Props) => {
const { questionListChange } = useQuestion();
export const DropdownForm = ({ element, handleQuestion }: 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);
}
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 mt-4">
<select className="mr-3">
{choices.map((choice: any, index: number) => (
<option>{choice.text}</option>
))}
</select>
{choices.map((choice: any, index: number) => (
<input
id={`${index}`}
type="text"
className="mx-2 border-b-2"
placeholder={e.text}
placeholder={choice.text}
onChange={handleContent}
></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>
</div>
);
};
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;
};
export const EssayForm = ({ element }: Props) => {
// const { questionListChange } = useQuestion();
return (
<div id="commentarea" className="flex mt-4 w-full justify-center">
<input className="border w-11/12 h-16" disabled></input>
......
import React, { useState } from "react";
import { FileType } from "../types";
import { useQuestion } from "./question.context";
import { TypeChange } from "./typeDD";
type Props = {
element: FileType;
};
export const QFile = ({ element }: Props) => {
const { questionListChange } = useQuestion();
export const FileForm = ({ element }: 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">
<div id="content" 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>
);
};
import { useQuestion } from "./question.context";
// import { useQuestion } from "./question.context";
import React, { useState } 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;
};
export const Question = ({ element }: Props) => {
const handleClick = () => {};
const typeDD = new Map([
const typeDropDown = new Map([
["essay", "주관식"],
["radio", "객관식"],
["dropdown", "드롭다운(객관식)"],
["dropdown", "드롭다운"],
["checkbox", "체크박스"],
["file", "파일"],
["rating", "선형"],
["grid", "그리드"],
["date", "날짜"],
]);
]);
export const Question = ({
element,
handleQuestion,
deleteQuestion,
}: Props) => {
const handleEdit = () => {
//setCurrentId해주고 currentId===element._id가 같은 input들만 disabled=false
};
async function handleComplete() {
//db에서 element._id인 애를 findOneAndUpdate() 해준다.
try {
const newQuestion: BasicQuestionType = await questionApi.updateQuestion(
element
);
console.log(newQuestion);
// setSuccess(true);
// setError("");
} catch (error) {
console.log("에러발생");
// catchErrors(error, setError)
} finally {
// setLoading(false);
}
}
function changeDD(e: React.ChangeEvent<HTMLSelectElement>) {
const tt = e.target.value;
// questionTypeChange(e);
console.log(tt);
//if문으로 type별로 content 바뀌게 해보기
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: "선택지1", value: "1" },
{ text: "선택지2", value: "2" },
{ text: "선택지3", value: "3" },
],
};
} else if (selectedType === "essay") {
element.content = { choices: [] };
} else if (selectedType === "rating") {
element.content = {
minRateDescription: "가장 낮음",
maxRateDescription: "가장 높음",
choices: [
{ text: "1", value: "1" },
{ text: "2", value: "2" },
{ text: "3", value: "3" },
],
};
}
element.type = selectedType;
handleQuestion(element._id);
}
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) {
......@@ -32,15 +97,19 @@ export const Question = ({ element }: Props) => {
case "essay":
return <EssayForm element={element} />;
case "radio":
// return <RadioForm element={element} />;
return <RadioForm handleQuestion={handleQuestion} element={element} />;
case "checkbox":
// return <CheckboxForm element={element} />;
return (
<CheckboxForm handleQuestion={handleQuestion} element={element} />
);
case "dropdown":
// return <DropdownForm element={element} />;
return (
<DropdownForm handleQuestion={handleQuestion} element={element} />
);
case "file":
// return <FileForm element={element} />;
return <FileForm element={element} />;
case "rating":
// return <RatingForm element={element} />;
return <RatingForm handleQuestion={handleQuestion} element={element} />;
default:
return <></>;
}
......@@ -54,18 +123,24 @@ 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}
></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 +151,28 @@ export const Question = ({ element }: Props) => {
id={element._id}
className="border w-11/12"
placeholder="질문에 대한 설명을 입력해주세요"
// onChange={questionListChange}
value={element.comment}
onChange={handleQuestionInfo}
></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>
<button type="button" className="px-1" onClick={handleEdit}>
수정
</button>
<button type="button" className="px-1" onClick={handleComplete}>
완료
</button>
</div>
</div>
);
......
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;
};
export const QRadio = ({ element }: Props) => {
const { questionListChange } = useQuestion();
export const RadioForm = ({ element, handleQuestion }: 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);
}
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 id="content" className="flex mt-4">
{choices.map((choice: any, index: number) => (
<div>
<input type="radio" disabled></input>
<input
type="radio"
id={element._id}
name="choice"
value={e.text}
disabled
/>
<input
id={`${index}`}
type="text"
name={"choice"}
// key={`${index}`}
className="mx-2 border-b-2"
placeholder={e.text}
onChange={questionListChange}
placeholder={choice.text}
onChange={handleContent}
></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>
</div>
);
};
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;
};
export const QRating = ({ element }: Props) => {
const { questionListChange } = useQuestion();
export const RatingForm = ({ element, handleQuestion }: 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: 0 });
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}
onChange={handleContent}
></input>
{element.content.choices.map((e) => (
{choices.map((e: 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}
onChange={handleContent}
></input>
))}
<input
name="maxRateDescription"
id={element._id}
className="border-b-2 text-center"
size={10}
placeholder={element.content.maxRateDescription}
onChange={handleContent}
></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}
>
삭제
</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}
>
추가
</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>
</>
);
};
......@@ -10,7 +10,15 @@ export const CreateSurvey = () => {
questions: [],
});
const handleChange = () => {};
const handleQuestion = (id: string) => {
const newList: BasicQuestionType[] = [...survey.questions];
setSurvey({ ...survey, questions: newList });
};
const handleSurvey = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = event.currentTarget;
setSurvey({ ...survey, [name]: value });
};
async function handleSubmit(event: FormEvent) {
event.preventDefault();
......@@ -31,7 +39,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,8 +49,25 @@ 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 (
<>
<form onSubmit={handleSubmit}>
......@@ -54,7 +78,7 @@ export const CreateSurvey = () => {
name="title"
className="font-bold text-4xl text-center m-2 border-b-2"
placeholder="설문지 제목"
onChange={handleChange}
onChange={handleSurvey}
></input>
<input
type="text"
......@@ -62,11 +86,15 @@ export const CreateSurvey = () => {
className="font-bold text-1xl text-center m-2 resize-none"
placeholder="설문조사에 대한 설명을 입력해주세요"
size={50}
onChange={handleChange}
onChange={handleSurvey}
></input>
</div>
{questions.map((question) => (
<Question element={question} />
<Question
element={question}
handleQuestion={handleQuestion}
deleteQuestion={deleteQuestion}
/>
))}
<div className="flex w-4/5 content-center justify-center border-2 border-black h-8 mt-3">
<button type="button" onClick={addQuestion}>
......
......@@ -7,3 +7,17 @@ export const createQuestion = asyncWrap(async (req, res) => {
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.updateQuestion(question);
return res.json(newQuestion);
});
export const deleteQuestion = asyncWrap(async (req, res) => {
const { id } = req.body;
console.log("Id: ", id);
const newQuestion = await questionDb.deleteQuestion(id);
return res.json(newQuestion);
});
......@@ -4,3 +4,14 @@ 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 deleteQuestion = async (id: string) => {
const newQuestion = await Question.findByIdAndDelete(id);
return newQuestion;
};
import { model, Schema, Types } from "mongoose";
import { model, ObjectId, Schema, Types } from "mongoose";
export interface IQuestion {
_id?: Types.ObjectId;
type: string;
// id: string;
title?: string;
isRequired: boolean;
comment?: string;
content?: any;
}
const schema = new Schema<IQuestion>({
type:{type:String},
title: {type:String},
isRequired: {type:Boolean},
comment:{type: String},
content:{type: Object},
}, {toJSON: {
versionKey: false
}});
}
export default model<IQuestion>("Question", schema);
const schema = new Schema<IQuestion>(
{
type: { type: String },
title: { type: String },
isRequired: { type: Boolean },
comment: { type: String },
content: { type: Object },
},
{
toJSON: {
versionKey: false,
},
}
);
export default model<IQuestion>("Question", schema);
import { model, Schema, Types } from "mongoose";
export interface ISurvey {
title: string;
comment: string;
questions: Types.ObjectId[]
}
title?: string;
comment?: string;
// userId: Types.ObjectId;
questions: Types.ObjectId[];
}
const schema = new Schema<ISurvey>({
title: {type:String},
comment: {type:String},
questions: [{ type: Schema.Types.ObjectId, ref: 'Question' }],
});
export default model<ISurvey>("Survey", schema);
const schema = new Schema<ISurvey>({
title: { type: String },
comment: { type: String },
// userId: { type: Schema.Types.ObjectId, ref: "User" },
questions: [{ type: Schema.Types.ObjectId, ref: "Question" }],
});
export default model<ISurvey>("Survey", schema);
......@@ -3,8 +3,8 @@ import { questionCtrl } from "../controllers";
const router = express.Router();
router
.route("/create")
.post(questionCtrl.createQuestion);
router.route("/create").post(questionCtrl.createQuestion);
router.route("/update").post(questionCtrl.updateQuestion);
router.route("/delete").post(questionCtrl.deleteQuestion);
export default router;
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