Commit 4a36252e authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

answers 결과 불러오기

parent 036ec8c6
...@@ -35,13 +35,13 @@ export const AnswerSurveyForm = () => { ...@@ -35,13 +35,13 @@ export const AnswerSurveyForm = () => {
ansSurvey(); ansSurvey();
}, [surveyId]); }, [surveyId]);
const isSurvey = localStorage.getItem(`survey_${surveyId}`); // const isSurvey = localStorage.getItem(`survey_${surveyId}`);
if (isSurvey) { // if (isSurvey) {
console.log("object", isSurvey); // console.log("object", isSurvey);
alert("제출한 설문조사입니다"); // alert("제출한 설문조사입니다");
navigate("/"); // navigate("/");
} // }
const addFiles = (oneFile: { questionId: string; file: File }) => { const addFiles = (oneFile: { questionId: string; file: File }) => {
if (!files.find((a) => a.questionId === oneFile.questionId)) { if (!files.find((a) => a.questionId === oneFile.questionId)) {
...@@ -74,7 +74,7 @@ export const AnswerSurveyForm = () => { ...@@ -74,7 +74,7 @@ export const AnswerSurveyForm = () => {
async function handleSubmit(event: FormEvent) { async function handleSubmit(event: FormEvent) {
event.preventDefault(); event.preventDefault();
const answers = answerSurvey.current.questions.map((q: any) => { const answers = answerSurvey.current.questions.map((q: any) => {
return { questionId: q.questionId, answer: q.answer, type: q.type }; return { questionId: q._id, answer: q.answer, type: q.type };
}); });
const requiredErrorQ = answerSurvey.current.questions.find( const requiredErrorQ = answerSurvey.current.questions.find(
(q: any) => q.isRequired && q.isRequired !== q.requiredCheck (q: any) => q.isRequired && q.isRequired !== q.requiredCheck
...@@ -85,7 +85,7 @@ export const AnswerSurveyForm = () => { ...@@ -85,7 +85,7 @@ export const AnswerSurveyForm = () => {
try { try {
const formData = new FormData(); const formData = new FormData();
formData.append("surveyId", answerSurvey.current._id); formData.append("surveyId", answerSurvey.current._id);
formData.append("guestId", "quest1"); formData.append("guestId", "guest1");
formData.append("answers", JSON.stringify(answers)); formData.append("answers", JSON.stringify(answers));
files.map((f) => { files.map((f) => {
formData.append("uploadFiles", f.file); formData.append("uploadFiles", f.file);
...@@ -93,7 +93,7 @@ export const AnswerSurveyForm = () => { ...@@ -93,7 +93,7 @@ export const AnswerSurveyForm = () => {
const newAnswer: AnswerType = await answerApi.saveAnswers(formData); const newAnswer: AnswerType = await answerApi.saveAnswers(formData);
console.log(newAnswer); console.log(newAnswer);
localStorage.setItem(`survey_${surveyId}`, surveyId ?? ""); localStorage.setItem(`survey_${surveyId}`, surveyId ?? "");
alert("제출되었습니다"); // alert("제출되었습니다");
setSuccess(true); setSuccess(true);
setError(""); setError("");
......
...@@ -6,3 +6,8 @@ export const saveAnswers = async (answer: FormData) => { ...@@ -6,3 +6,8 @@ export const saveAnswers = async (answer: FormData) => {
const { data } = await axios.post(`${baseUrl}/answers`, answer); const { data } = await axios.post(`${baseUrl}/answers`, answer);
return data; return data;
}; };
export const getAnswers = async (surveyId: string) => {
const { data } = await axios.get(`${baseUrl}/answers/${surveyId}`);
return data;
};
import React, { useState, useRef } from "react"; import React, { useState, useRef } from "react";
import { BasicQuestionType } from "../types";
type AccordionProps = { type AccordionProps = {
title: string; question: any;
content: string; answers: any;
}; };
const Accordion = ({ title, content }: AccordionProps) => { const Accordion = ({ question, answers }: AccordionProps) => {
const [isOpened, setOpened] = useState<boolean>(false); const [isOpened, setOpened] = useState<boolean>(false);
const [height, setHeight] = useState<string>("0px"); const [height, setHeight] = useState<string>("0px");
const contentElement = useRef<HTMLDivElement>(null); const contentElement = useRef<HTMLDivElement>(null);
...@@ -17,7 +18,7 @@ const Accordion = ({ title, content }: AccordionProps) => { ...@@ -17,7 +18,7 @@ const Accordion = ({ title, content }: AccordionProps) => {
<div className="p-1"> <div className="p-1">
<div onClick={HandleOpening}> <div onClick={HandleOpening}>
<div className={"bg-themeColor p-4 flex justify-between text-white"}> <div className={"bg-themeColor p-4 flex justify-between text-white"}>
<h4 className="font-semibold">{title}</h4> <h4 className="font-semibold">{question.title}</h4>
{isOpened ? "" : ""} {isOpened ? "" : ""}
</div> </div>
<div <div
...@@ -25,7 +26,9 @@ const Accordion = ({ title, content }: AccordionProps) => { ...@@ -25,7 +26,9 @@ const Accordion = ({ title, content }: AccordionProps) => {
style={{ height: height }} style={{ height: height }}
className="bg-gray-100 overflow-hidden transition-all duration-700" className="bg-gray-100 overflow-hidden transition-all duration-700"
> >
<p className="p-4">{content}</p> {answers.map((answer: any) => (
<p className="p-4">{answer.answer}</p>
))}
</div> </div>
</div> </div>
</div> </div>
......
// import React, { FormEvent, useEffect, useState } from "react";
// import { useParams, useNavigate } from "react-router-dom";
// import { questionApi, surveyApi } from "../apis";
// import { SpinnerIcon } from "../icons";
// import { Question } from "../questions";
// import { BasicQuestionType, SurveyType } from "../types";
// import { catchErrors } from "../helpers";
// export const EditSurvey = () => {
// let { surveyId } = useParams<{ surveyId: string }>();
// const navigate = useNavigate();
// useEffect(() => {
// getSurvey();
// }, [surveyId]);
// const [error, setError] = useState("");
// const [loading, setLoading] = useState(false);
// const [success, setSuccess] = useState(false);
// const [survey, setSurvey] = useState<SurveyType>({
// _id: surveyId,
// user: {},
// title: "",
// comment: "",
// questions: [],
// });
// const [currentId, setCurrentId] = useState("");
// const changeCurrentId = (id: string) => {
// setCurrentId(id);
// };
// async function getSurvey() {
// try {
// if (surveyId) {
// const thisSurvey: SurveyType = await surveyApi.getSurvey(surveyId);
// setSurvey(thisSurvey);
// setSuccess(true);
// setError("");
// } else {
// setLoading(true);
// }
// } catch (error) {
// catchErrors(error, setError);
// // navigate(`/`, {
// // replace: false,
// // });
// } finally {
// setLoading(false);
// }
// }
// 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();
// try {
// const newSurvey: SurveyType = await surveyApi.editSurvey(survey);
// console.log(newSurvey);
// setSuccess(true);
// setError("");
// } catch (error) {
// catchErrors(error, setError);
// } finally {
// setLoading(false);
// }
// }
// const questions = survey.questions;
// console.log(questions);
// return (
// <>
// {error ? alert(error) : <></>}
// {loading && (
// <SpinnerIcon className="animate-spin h-5 w-5 mr-1 text-slate" />
// )}
// <form onSubmit={handleSubmit}>
// <div className="flex flex-col place-items-center">
// <div className="flex flex-col container place-items-center mt-4">
// <input
// type="text"
// name="title"
// className="font-bold text-4xl text-center m-2 border-b-2"
// placeholder="설문지 제목"
// value={survey.title}
// onChange={handleSurvey}
// ></input>
// <input
// type="text"
// name="comment"
// className="font-bold text-1xl text-center m-2 resize-none"
// placeholder="설문조사에 대한 설명을 입력해주세요"
// size={50}
// value={survey.comment}
// onChange={handleSurvey}
// ></input>
// </div>
// {questions.map((question) => (
// <Question
// element={question}
// currentId={currentId}
// />
// ))}
// <div className="flex w-4/5 content-center justify-center border-2 border-black h-8 mt-3">
// 질문 추가
// </button>
// </div>
// <div>
// <button
// type="submit"
// className="border bg-themeColor my-5 py-2 px-3 font-bold text-white"
// >
// 저장하기
// </button>
// </div>
// </div>
// </form>
// </>
// );
// };
import React from "react"; import React, { useEffect, useState } from "react";
import { answerApi } from "../apis";
import { catchErrors } from "../helpers";
import Accordion from "./Accordion"; import Accordion from "./Accordion";
import { useParams } from "react-router-dom";
export const ResultSurvey = () => { export const ResultSurvey = () => {
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false);
const [answers, setAnswers] = useState([
{ _id: "", answers: [], question: {} },
]);
let { surveyId } = useParams<{ surveyId: string }>();
useEffect(() => {
getAnswers();
}, [surveyId]);
async function getAnswers() {
try {
if (surveyId) {
const answers = await answerApi.getAnswers(surveyId);
console.log(answers);
setAnswers(answers);
} else {
setLoading(true);
}
} catch (error) {
catchErrors(error, setError);
} finally {
setLoading(false);
}
}
const data = [ const data = [
{ {
title: "1번질문", title: "1번질문",
...@@ -17,6 +47,7 @@ export const ResultSurvey = () => { ...@@ -17,6 +47,7 @@ export const ResultSurvey = () => {
content: "3번답변들", content: "3번답변들",
}, },
]; ];
return ( return (
<div className="flex flex-col place-items-center"> <div className="flex flex-col place-items-center">
<div className="flex flex-col container place-items-center mt-4"> <div className="flex flex-col container place-items-center mt-4">
...@@ -29,11 +60,11 @@ export const ResultSurvey = () => { ...@@ -29,11 +60,11 @@ export const ResultSurvey = () => {
</div> </div>
<div className="container w-11/12 place-self-center"> <div className="container w-11/12 place-self-center">
{data.map((item) => ( {answers.map((item) => (
<Accordion <Accordion
key={item.title} key={item._id}
title={item.title} question={item.question}
content={item.content} answers={item.answers}
/> />
))} ))}
</div> </div>
......
import { NextFunction, Request, Response } from "express";
import { asyncWrap } from "../helpers"; import { asyncWrap } from "../helpers";
import { TypedRequest } from "../types"; import { TypedRequest } from "../types";
import formidable from "formidable"; import formidable from "formidable";
...@@ -11,7 +12,6 @@ export const createAnswers = asyncWrap(async (reqExp, res) => { ...@@ -11,7 +12,6 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
const answers = JSON.parse(answer.answers); const answers = JSON.parse(answer.answers);
answer.answers = answers; answer.answers = answers;
const files = req.files.uploadFiles as formidable.File[]; const files = req.files.uploadFiles as formidable.File[];
// console.log("controller의 files", files);
let uploadFile; let uploadFile;
try { try {
if (files) { if (files) {
...@@ -33,18 +33,19 @@ export const createAnswers = asyncWrap(async (reqExp, res) => { ...@@ -33,18 +33,19 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
targetObj.answer = retFile._id; targetObj.answer = retFile._id;
} }
} }
// 3) Answer DB 만들기(map을 돌려서 하나씩 추가시켜야 함) // 3) Answer DB 만들기
console.log("원래 answer", answer); console.log("원래 answer", answer);
for (let index = 0; index < answer.answers.length; index++) { console.log("원래 answer", answer.answers.length);
const element = answer.answers[index]; // for (let index = 0; index < answer.answers.length; index++) {
const newAnswer = await answerDb.createAnswer({ // const element = answer.answers[index];
surveyId: answer.surveyId, // const newAnswer = await answerDb.createAnswer({
guestId: answer.guestId, // surveyId: answer.surveyId,
questionId: element.questionId, // guestId: answer.guestId,
answer: element.answer, // questionId: element.questionId,
}); // answer: element.answer,
console.log("DB에 넣은 answer", newAnswer); // });
} // // console.log("DB에 넣은 answer", newAnswer);
// }
return res.json(); return res.json();
} catch (error: any) { } catch (error: any) {
console.log("error in create answer:", error); console.log("error in create answer:", error);
...@@ -56,3 +57,16 @@ export const createAnswers = asyncWrap(async (reqExp, res) => { ...@@ -56,3 +57,16 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
res.status(422).send(error.message || "설문조사 응답 생성 오류"); res.status(422).send(error.message || "설문조사 응답 생성 오류");
} }
}); });
export const getAnswers = asyncWrap(async (reqExp, res) => {
const req = reqExp as TypedRequest;
const { surveyId } = req.params;
console.log(surveyId);
try {
const answers = await answerDb.getAnswers(surveyId);
console.log("Db에서 가져온 answers= ", answers);
return res.json(answers);
} catch (error: any) {
res.status(422).send(error.message || "설문조사 결과 불러오기 오류");
}
});
import { Answer, IAnswer } from "../models"; import { Answer, IAnswer } from "../models";
import { model, Schema, Types } from "mongoose";
export const createAnswer = async (answer: IAnswer) => { export const createAnswer = async (answer: IAnswer) => {
const newQuestion = await Answer.create(answer); const newQuestion = await Answer.create(answer);
return newQuestion; return newQuestion;
}; };
export const getAnswers = async (surveyId: string) => {
const answers = await Answer.aggregate([
{ $match: { surveyId: new Types.ObjectId(surveyId) } },
{
$lookup: {
from: "questions",
localField: "questionId",
foreignField: "_id",
as: "question",
},
},
{ $unwind: "$question" },
{
$group: {
_id: "$questionId",
answers: { $push: { guestId: "$guestId", answer: "$answer" } },
question: { $mergeObjects: "$question" },
},
},
]);
return answers;
};
import express from "express"; import express from "express";
import { answerCtrl, fileCtrl } from "../controllers"; import { answerCtrl, authCtrl, fileCtrl, surveyCtrl } from "../controllers";
const router = express.Router(); const router = express.Router();
router.route("/").post(fileCtrl.uploadFile, answerCtrl.createAnswers); router.route("/").post(fileCtrl.uploadFile, answerCtrl.createAnswers);
router
.route("/:surveyId")
.get(authCtrl.requireLogin, authCtrl.authenticate, answerCtrl.getAnswers);
router.param("surveyId", surveyCtrl.userBySurveyId);
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