Commit 578446f7 authored by Jiwon Yoon's avatar Jiwon Yoon
Browse files

result 불러오기 완성

parent 6262a322
......@@ -18,11 +18,11 @@ export const SurveyRouter = () => {
<Route index element={<Home />} />
<Route path="login" element={<Login />} />
<Route path="signup" element={<SignUp />} />
<Route path="surveys/edit/" element={<EditResultButton />}>
<Route path=":surveyId" element={<EditSurvey />} />
<Route path=":surveyId/result" element={<ResultSurvey />} />
<Route path="surveys/:surveyId/" element={<EditResultButton />}>
<Route path="edit" element={<EditSurvey />} />
<Route path="result" element={<ResultSurvey />} />
</Route>
<Route path="surveys/:surveyId" element={<AnswerSurveyForm />} />
<Route path="survey/:surveyId" element={<AnswerSurveyForm />} />
<Route
path="profile"
element={
......
......@@ -16,20 +16,14 @@ export const MySurveyCard = ({ data }: Props) => {
const [success, setSuccess] = useState(false);
const editSurvey = () => {
navigate(`/surveys/edit/${data._id}`, {
navigate(`/surveys/${data._id}/edit`, {
replace: true,
state: { save: true },
});
};
const goSurvey = () => {
navigate(`/surveys/${data._id}`, {
replace: true,
});
};
const copyLink = () => {
navigator.clipboard.writeText(`http://localhost:8080/surveys/${data._id}`);
navigator.clipboard.writeText(`http://localhost:8080/survey/${data._id}`);
alert("설문조사의 링크가 클립보드에 저장되었습니다.");
};
......
......@@ -21,7 +21,7 @@ export const Profile = () => {
async function createSurvey() {
const newSurvey: SurveyType = await surveyApi.createSurvey(survey);
navigate(`/surveys/edit/${newSurvey._id}`, {
navigate(`/surveys/${newSurvey._id}/edit`, {
replace: true,
});
}
......@@ -36,7 +36,6 @@ export const Profile = () => {
return (
<div className="flex flex-col items-center">
<div className="mt-10 text-xl font-bold">나의 설문조사</div>
<img src={`${baseImageUrl}/9e24ad36a2947b08c89913b01`} />
<div className="grid grid-cols-1 md:grid-cols-4 sm:grid-cols-2 gap-4 mt-6">
<button
onClick={createSurvey}
......
import React, { useState, useRef } from "react";
import React, { useState, useRef, useEffect } from "react";
import { baseImageUrl } from "../apis";
import { BasicQuestionType } from "../types";
type AccordionProps = {
question: any;
answers: any;
};
const Accordion = ({ question, answers }: AccordionProps) => {
const Accordion = ({ question }: AccordionProps) => {
const [isOpened, setOpened] = useState<boolean>(false);
const [height, setHeight] = useState<string>("0px");
const contentElement = useRef<HTMLDivElement>(null);
// useEffect(() => {
// if (question.type === "file") {
// getFiles();
// }
// }, []);
// async function getFiles() {
// try {
// } catch (error) {}
// }
const HandleOpening = () => {
setOpened(!isOpened);
setHeight(!isOpened ? `${contentElement.current?.scrollHeight}px` : "0px");
......@@ -26,9 +37,17 @@ const Accordion = ({ question, answers }: AccordionProps) => {
style={{ height: height }}
className="bg-gray-100 overflow-hidden transition-all duration-700"
>
{answers.map((answer: any) => (
<p className="p-4">{answer.answer}</p>
))}
{question.type === "file"
? question.answers.map((answer: any) => (
<img
key={answer.url}
alt="file"
src={`${baseImageUrl}/${answer.url}`}
/>
))
: question.answers.map((answer: any) => (
<p className="p-4">{answer}</p>
))}
</div>
</div>
</div>
......
......@@ -6,18 +6,11 @@ export const EditResultButton = () => {
let { surveyId } = useParams<{ surveyId: string }>();
const navigate = useNavigate();
/*function editButtonClick(e: React.MouseEvent<HTMLButtonElement>) {
navigate(`/surveys/${surveyId}/edit`);
}
function resultButtonClick(e: React.MouseEvent<HTMLButtonElement>) {
navigate(`/surveys/${surveyId}/result`);
}*/
return (
<div>
<div className="flex place-content-center mt-6">
<NavLink
to={`/surveys/edit/${surveyId}`}
to={`/surveys/${surveyId}/edit`}
style={({ isActive }) =>
isActive
? {
......@@ -33,7 +26,7 @@ export const EditResultButton = () => {
<div className="text-xl m-3 ">설문지 수정</div>
</NavLink>
<NavLink
to={`/surveys/edit/${surveyId}/result`}
to={`/surveys/${surveyId}/result`}
style={({ isActive }) =>
isActive
? {
......
import React, { useEffect, useState } from "react";
import { answerApi } from "../apis";
import { answerApi, surveyApi } from "../apis";
import { catchErrors } from "../helpers";
import Accordion from "./Accordion";
import { useParams } from "react-router-dom";
import { SurveyType } from "../types";
export const ResultSurvey = () => {
let { surveyId } = useParams<{ surveyId: string }>();
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 }>();
const [survey, setSurvey] = useState<SurveyType>({
_id: surveyId || "",
user: {},
title: "",
comment: "",
questions: [],
});
useEffect(() => {
getAnswers();
}, [surveyId]);
......@@ -19,9 +24,9 @@ export const ResultSurvey = () => {
async function getAnswers() {
try {
if (surveyId) {
const answers = await answerApi.getAnswers(surveyId);
console.log(answers);
setAnswers(answers);
const survey = await answerApi.getAnswers(surveyId);
console.log(survey);
setSurvey(survey);
} else {
setLoading(true);
}
......@@ -32,40 +37,20 @@ export const ResultSurvey = () => {
}
}
const data = [
{
title: "1번질문",
content:
"1번 답변들asdfadsgsjadhfasld;nvaldkfnbljgnahgvlajnbl janl;nvja; sabv;jnsvjl;asjvh asjfagkfnjf;nvasgn va;sdn va sglanksvl ds af adb adf afg dgafbg dfh jbvlkna lkslbk kjv nbkkdlfn akdl nvjbnkdjf nlkbakdn bkjnakjn n knk",
},
{
title: "2번질문",
content: "2번답변들",
},
{
title: "3번질문",
content: "3번답변들",
},
];
return (
<div className="flex flex-col place-items-center">
<div className="flex flex-col container place-items-center mt-4">
<div className="font-bold text-4xl text-center m-2 border-b-2">
설문지 제목
{survey.title}
</div>
<div className="font-bold text-1xl text-center m-2 resize-none">
설문조사 설명
{survey.comment}
</div>
</div>
<div className="container w-11/12 place-self-center">
{answers.map((item) => (
<Accordion
key={item._id}
question={item.question}
answers={item.answers}
/>
{survey.questions.map((question) => (
<Accordion key={question._id} question={question} />
))}
</div>
</div>
......
......@@ -27,6 +27,7 @@ export interface BasicQuestionType {
isRequired: boolean;
comment: string;
content: any;
answers?: any;
[key: string]: string | number | boolean | any;
}
......
......@@ -3,7 +3,7 @@ import { asyncWrap } from "../helpers";
import { TypedRequest } from "../types";
import formidable from "formidable";
import { FileInfo } from "../models";
import { fileDb, userDb, answerDb } from "../db";
import { fileDb, userDb, answerDb, surveyDb } from "../db";
import fs from "fs/promises";
export const createAnswers = asyncWrap(async (reqExp, res) => {
......@@ -11,14 +11,18 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
const answer = req.body;
const answers = JSON.parse(answer.answers);
answer.answers = answers;
const files = req.files.uploadFiles as formidable.File[];
let files: any[] = [];
if (Array.isArray(req.files.uploadFiles)) {
files = req.files.uploadFiles as formidable.File[];
} else {
files.push(req.files.uploadFiles);
}
let uploadFile;
try {
if (files) {
// 1) 파일을 DB에 저장 후 다시 retFile가져와서
// *근데 파일이 여러 개일 수 있기 때문에 순회해야 됨-map()을 쓰면 async function이 되어버려서 for문 이용함
for (let index = 0; index < files.length; index++) {
const file = files[index];
// *근데 파일이 여러 개일 수 있기 때문에 순회해야 됨
const f = files.map(async (file) => {
uploadFile = new FileInfo({
name: file.originalFilename,
url: file.newFilename,
......@@ -31,26 +35,24 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
);
// 3) answer에다가 retFile의 _id 넣어주기
targetObj.answer = retFile._id;
}
});
await Promise.all(f);
}
// 3) Answer DB 만들기
console.log("원래 answer", answer);
console.log("원래 answer", answer.answers.length);
// for (let index = 0; index < answer.answers.length; index++) {
// const element = answer.answers[index];
// const newAnswer = await answerDb.createAnswer({
// surveyId: answer.surveyId,
// guestId: answer.guestId,
// questionId: element.questionId,
// answer: element.answer,
// });
// // console.log("DB에 넣은 answer", newAnswer);
// }
const c = answer.answers.map(async (element: any) => {
const newAnswer = await answerDb.createAnswer({
surveyId: answer.surveyId,
guestId: answer.guestId,
questionId: element.questionId,
answer: element.answer,
});
});
await Promise.all(c);
return res.json();
} catch (error: any) {
console.log("error in create answer:", error);
// 오류 발생시 저장된 파일 제거
if (files) {
if (req.files) {
// uploadFiles && (await fileDb.deleteFileById(uploadFiles._id.toString()));
// await fs.unlink(files.filepath);
}
......@@ -61,11 +63,27 @@ export const createAnswers = asyncWrap(async (reqExp, res) => {
export const getAnswers = asyncWrap(async (reqExp, res) => {
const req = reqExp as TypedRequest;
const { surveyId } = req.params;
console.log(surveyId);
try {
const survey = await surveyDb.getSurveyById(surveyId);
const answers = await answerDb.getAnswers(surveyId);
console.log("Db에서 가져온 answers= ", answers);
return res.json(answers);
console.log(answers);
const jsonSurvey = survey?.toJSON();
if (jsonSurvey && answers) {
const a = answers.map(async (a) => {
const targetObj = jsonSurvey.questions.find(
(q: any) => String(q._id) === String(a._id)
) as any;
if (targetObj) {
if (a.file.length) {
targetObj.answers = a.file;
} else {
targetObj.answers = a.answers;
}
}
});
await Promise.all(a);
}
return res.json(jsonSurvey);
} catch (error: any) {
res.status(422).send(error.message || "설문조사 결과 불러오기 오류");
}
......
......@@ -10,19 +10,17 @@ 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",
$group: {
_id: "$questionId",
answers: { $push: "$answer" },
},
},
{ $unwind: "$question" },
{
$group: {
_id: "$questionId",
answers: { $push: { guestId: "$guestId", answer: "$answer" } },
question: { $mergeObjects: "$question" },
$lookup: {
from: "fileinfos",
localField: "answers",
foreignField: "_id",
as: "file",
},
},
]);
......
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