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

0713deleteQ in db

parents 005a4d71 65353848
import axios from "axios"; import axios from "axios";
import { BasicQuestionType } from "../types";
import baseUrl from "./baseUrl"; import baseUrl from "./baseUrl";
export const createQuestion = async () => { export const createQuestion = async () => {
const { data } = await axios.post(`${baseUrl}/questions/create`, { const { data } = await axios.post(`${baseUrl}/questions/create`, {
type: "essay", type: "essay",
title: "Question Title", title: "Question Title",
isRequired: false, isRequired: false,
comment: "질문에 대한 설명을 입력해주세요", comment: "질문에 대한 설명을 입력해주세요",
content: null, content: { choices: [] },
}); });
return data; return data;
}; };
\ No newline at end of file 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 { CheckboxType } from "../types";
type Props = { type Props = {
element: CheckboxType; element: CheckboxType;
handleQuestion: (id: string) => void;
}; };
export const QCheckbox = ({ element }: Props) => { 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 ( return (
<div id="commentarea" className="flex mt-4"> <div id="content" className="flex mt-4">
{element.content.choices.map((e: any) => ( {choices.map((choice: any, index: number) => (
<div> <div>
<input type="checkbox" checked={false}></input> <input type="checkbox" disabled></input>
<input <input
id={`${index}`}
type="text" type="text"
className="mx-2 border-b-2" className="mx-2 border-b-2"
placeholder={e.text} placeholder={choice.text}
onChange={handleContent}
></input> ></input>
</div> </div>
))} ))}
......
import React from "react"; import React, { useState } from "react";
import { DropdownType } from "../types"; import { DropdownType } from "../types";
type Props = { type Props = {
element: DropdownType; element: DropdownType;
handleQuestion: (id: string) => void;
}; };
export const QDropdown = ({ element }: Props) => { 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 ( return (
<div id="commentarea" className="flex mt-4"> <div id="content" className="flex mt-4">
{element.content.choices.map((e: any) => ( <select className="mr-3">
<div> {choices.map((choice: any, index: number) => (
<input type="checkbox" checked={false}></input> <option>{choice.text}</option>
<input ))}
type="text" </select>
className="mx-2 border-b-2" {choices.map((choice: any, index: number) => (
placeholder={e.text} <input
></input> id={`${index}`}
</div> type="text"
className="mx-2 border-b-2"
placeholder={choice.text}
onChange={handleContent}
></input>
))} ))}
</div> </div>
); );
......
import React, { useState } from "react"; import React from "react";
import { EssayType } from "../types"; import { EssayType } from "../types";
type Props = { type Props = {
......
...@@ -5,9 +5,9 @@ type Props = { ...@@ -5,9 +5,9 @@ type Props = {
element: FileType; element: FileType;
}; };
export const QFile = ({ element }: Props) => { export const FileForm = ({ element }: Props) => {
return ( return (
<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> <input type="file" className=" w-11/12 h-16" disabled></input>
</div> </div>
); );
......
// import { useQuestion } from "./question.context";
import React, { useState } from "react"; import React, { useState } from "react";
import { BasicQuestionType, EssayType } from "../types"; import { BasicQuestionType, EssayType } from "../types";
import { questionApi } from "../apis";
import { EssayForm } from "./EssayForm"; import { EssayForm } from "./EssayForm";
import { CheckboxForm } from "./CheckboxForm";
import { RadioForm } from "./RadioForm"; import { RadioForm } from "./RadioForm";
import { DropdownForm } from "./DropdownForm";
import { FileForm } from "./FileForm";
import { RatingForm } from "./RatingForm";
type Props = { type Props = {
element: BasicQuestionType; element: BasicQuestionType;
handleQuestion: (id: string) => void;
deleteQuestion: (id: string) => void;
}; };
export const Question = ({ element }: Props) => { const typeDropDown = new Map([
const handleClick = () => {}; ["essay", "주관식"],
["radio", "객관식"],
["dropdown", "드롭다운"],
["checkbox", "체크박스"],
["file", "파일"],
["rating", "선형"],
["grid", "그리드"],
["date", "날짜"],
]);
const typeDD = new Map([ export const Question = ({
["essay", "주관식"], element,
["radio", "객관식"], handleQuestion,
["dropdown", "드롭다운(객관식)"], deleteQuestion,
["checkbox", "체크박스"], }: Props) => {
["file", "파일"], const handleEdit = () => {
["rating", "선형"], //setCurrentId해주고 currentId===element._id가 같은 input들만 disabled=false
["grid", "그리드"], };
["date", "날짜"], 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 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 changeDD(e: React.ChangeEvent<HTMLSelectElement>) { function handleDelete() {
const tt = e.target.value; deleteQuestion(element._id);
// questionTypeChange(e);
console.log(tt);
//if문으로 type별로 content 바뀌게 해보기
} }
function getContent(element: BasicQuestionType) { function getContent(element: BasicQuestionType) {
...@@ -33,15 +97,19 @@ export const Question = ({ element }: Props) => { ...@@ -33,15 +97,19 @@ export const Question = ({ element }: Props) => {
case "essay": case "essay":
return <EssayForm element={element} />; return <EssayForm element={element} />;
case "radio": case "radio":
return <RadioForm element={element} />; return <RadioForm handleQuestion={handleQuestion} element={element} />;
case "checkbox": case "checkbox":
// return <CheckboxForm element={element} />; return (
<CheckboxForm handleQuestion={handleQuestion} element={element} />
);
case "dropdown": case "dropdown":
// return <DropdownForm element={element} />; return (
<DropdownForm handleQuestion={handleQuestion} element={element} />
);
case "file": case "file":
// return <FileForm element={element} />; return <FileForm element={element} />;
case "rating": case "rating":
// return <RatingForm element={element} />; return <RatingForm handleQuestion={handleQuestion} element={element} />;
default: default:
return <></>; return <></>;
} }
...@@ -55,18 +123,24 @@ export const Question = ({ element }: Props) => { ...@@ -55,18 +123,24 @@ export const Question = ({ element }: Props) => {
name="title" name="title"
id={element._id} id={element._id}
className="text-xl font-bold ml-6 border-b-2 w-1/2" className="text-xl font-bold ml-6 border-b-2 w-1/2"
placeholder={element.title} placeholder={"Question Title"}
// onChange={questionListChange} value={element.title}
onChange={handleQuestionInfo}
></input> ></input>
<select <select
id="Questions" id={element._id}
name="type" name="type"
className="w-36 bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg w-full mr-3 p-2.5" onChange={handleSelect}
defaultValue={element.type} 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"
onChange={changeDD}
> >
{Array.from(typeDD.entries()).map(([key, value]) => ( {Array.from(typeDropDown.entries()).map(([key, value]) => (
<option value={key}>{value}</option> <option
id={element._id}
value={key}
selected={key === element.type}
>
{value}
</option>
))} ))}
</select> </select>
</div> </div>
...@@ -77,18 +151,28 @@ export const Question = ({ element }: Props) => { ...@@ -77,18 +151,28 @@ export const Question = ({ element }: Props) => {
id={element._id} id={element._id}
className="border w-11/12" className="border w-11/12"
placeholder="질문에 대한 설명을 입력해주세요" placeholder="질문에 대한 설명을 입력해주세요"
// onChange={questionListChange} value={element.comment}
onChange={handleQuestionInfo}
></input> ></input>
</div> </div>
{getContent(element)} {getContent(element)}
<div className="place-self-end py-2"> <div className="place-self-end py-2">
<button className="px-0.5">필수</button> <button type="button" className="px-1">
<button className="px-0.5">옵션</button> 필수
<button className="px-0.5">삭제</button> </button>
<button id={element.id} className="px-0.5" onClick={handleClick}> <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>
<button type="button" className="px-1" onClick={handleComplete}>
완료
</button>
</div> </div>
</div> </div>
); );
......
import React from "react"; import React, { useState } from "react";
import { RadioType } from "../types"; import { RadioType } from "../types";
type Props = { type Props = {
element: RadioType; element: RadioType;
handleQuestion: (id: string) => void;
}; };
export const RadioForm = ({ element }: Props) => { 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 ( return (
<div className="flex mt-4"> <div id="content" className="flex mt-4">
{element.content.choices.map((e: any, index: number) => ( {choices.map((choice: any, index: number) => (
<div> <div>
<input type="radio" disabled></input>
<input <input
type="radio" id={`${index}`}
id={element._id} type="text"
name="choice" className="mx-2 border-b-2"
value={e.text} placeholder={choice.text}
disabled onChange={handleContent}
/> ></input>
</div> </div>
))} ))}
</div> </div>
......
import React from "react"; import React, { useState } from "react";
import { RatingType } from "../types"; import { RatingType } from "../types";
type Props = { type Props = {
element: RatingType; element: RatingType;
// deleteValue: (e: React.MouseEvent<HTMLButtonElement>) => void; handleQuestion: (id: string) => void;
}; };
export const QRating = ({ element }: Props) => { 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 ( return (
<div className="flex place-content-between items-center p-5"> <>
<input <div className="flex place-content-between items-center p-5">
name="minRateDescription" <input
id={element._id} name="minRateDescription"
className="border-b-2 text-center" className="border-b-2 text-center"
size={10} size={10}
placeholder={element.content.minRateDescription} placeholder={element.content.minRateDescription}
></input> onChange={handleContent}
{element.content.choices.map((e) => ( ></input>
{choices.map((e: any, index: number) => (
<input
name="text"
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 <input
name="text" name="maxRateDescription"
id={element._id} className="border-b-2 text-center"
type="text" size={10}
className="border border-black rounded-full py-1 m-2 text-center" placeholder={element.content.maxRateDescription}
size={1} onChange={handleContent}
placeholder={e.text}
></input> ></input>
))} </div>
<input <div>
name="maxRateDescription" <button
id={element._id} type="button"
className="border-b-2 text-center" name="rateValues"
size={10} className="border border-red-500 rounded mx-2 px-2"
placeholder={element.content.maxRateDescription} onClick={deleteValue}
></input> >
</div> 삭제
</button>
<button
type="button"
name="rateValues"
className="border border-blue-500 rounded mx-2 px-2"
onClick={addValue}
>
추가
</button>
</div>
</>
); );
}; };
...@@ -10,7 +10,15 @@ export const CreateSurvey = () => { ...@@ -10,7 +10,15 @@ export const CreateSurvey = () => {
questions: [], 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) { async function handleSubmit(event: FormEvent) {
event.preventDefault(); event.preventDefault();
...@@ -31,7 +39,6 @@ export const CreateSurvey = () => { ...@@ -31,7 +39,6 @@ export const CreateSurvey = () => {
try { try {
const newQuestion: BasicQuestionType = await questionApi.createQuestion(); const newQuestion: BasicQuestionType = await questionApi.createQuestion();
setSurvey({ ...survey, questions: [...survey.questions, newQuestion] }); setSurvey({ ...survey, questions: [...survey.questions, newQuestion] });
// setQuestions([...questions, newQuestion]);
// setSuccess(true); // setSuccess(true);
// setError(""); // setError("");
} catch (error) { } catch (error) {
...@@ -42,8 +49,25 @@ export const CreateSurvey = () => { ...@@ -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 ( return (
<> <>
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
...@@ -54,7 +78,7 @@ export const CreateSurvey = () => { ...@@ -54,7 +78,7 @@ export const CreateSurvey = () => {
name="title" name="title"
className="font-bold text-4xl text-center m-2 border-b-2" className="font-bold text-4xl text-center m-2 border-b-2"
placeholder="설문지 제목" placeholder="설문지 제목"
onChange={handleChange} onChange={handleSurvey}
></input> ></input>
<input <input
type="text" type="text"
...@@ -62,11 +86,15 @@ export const CreateSurvey = () => { ...@@ -62,11 +86,15 @@ export const CreateSurvey = () => {
className="font-bold text-1xl text-center m-2 resize-none" className="font-bold text-1xl text-center m-2 resize-none"
placeholder="설문조사에 대한 설명을 입력해주세요" placeholder="설문조사에 대한 설명을 입력해주세요"
size={50} size={50}
onChange={handleChange} onChange={handleSurvey}
></input> ></input>
</div> </div>
{questions.map((question) => ( {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"> <div className="flex w-4/5 content-center justify-center border-2 border-black h-8 mt-3">
<button type="button" onClick={addQuestion}> <button type="button" onClick={addQuestion}>
......
...@@ -7,3 +7,17 @@ export const createQuestion = asyncWrap(async (req, res) => { ...@@ -7,3 +7,17 @@ export const createQuestion = asyncWrap(async (req, res) => {
const newQuestion = await questionDb.createQuestion(question); const newQuestion = await questionDb.createQuestion(question);
return res.json(newQuestion); 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) => { ...@@ -4,3 +4,14 @@ export const createQuestion = async (question: IQuestion) => {
const newQuestion = await Question.create(question); const newQuestion = await Question.create(question);
return newQuestion; 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 { export interface IQuestion {
type: string; _id?: Types.ObjectId;
// id: string; type: string;
title?: string; title?: string;
isRequired: boolean; isRequired: boolean;
comment?: string; comment?: string;
content?: any; 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,
},
} }
);
const schema = new Schema<IQuestion>({
type:{type:String}, export default model<IQuestion>("Question", schema);
title: {type:String},
isRequired: {type:Boolean},
comment:{type: String},
content:{type: Object},
}, {toJSON: {
versionKey: false
}});
export default model<IQuestion>("Question", schema);
\ No newline at end of file
import { model, Schema, Types } from "mongoose"; import { model, Schema, Types } from "mongoose";
export interface ISurvey { export interface ISurvey {
title: string; title?: string;
comment: string; comment?: string;
questions: Types.ObjectId[] // userId: Types.ObjectId;
} questions: Types.ObjectId[];
}
const schema = new Schema<ISurvey>({
title: {type:String}, const schema = new Schema<ISurvey>({
comment: {type:String}, title: { type: String },
questions: [{ type: Schema.Types.ObjectId, ref: 'Question' }], comment: { type: String },
}); // userId: { type: Schema.Types.ObjectId, ref: "User" },
questions: [{ type: Schema.Types.ObjectId, ref: "Question" }],
export default model<ISurvey>("Survey", schema); });
\ No newline at end of file export default model<ISurvey>("Survey", schema);
...@@ -3,8 +3,8 @@ import { questionCtrl } from "../controllers"; ...@@ -3,8 +3,8 @@ import { questionCtrl } from "../controllers";
const router = express.Router(); const router = express.Router();
router router.route("/create").post(questionCtrl.createQuestion);
.route("/create") router.route("/update").post(questionCtrl.updateQuestion);
.post(questionCtrl.createQuestion); router.route("/delete").post(questionCtrl.deleteQuestion);
export default router; 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