Commit b9b919e7 authored by Yoon, Daeki's avatar Yoon, Daeki 😅
Browse files

Merge branch 'develop0727' into main-dev

parents 71ea74d6 287f9033
import React, { useState } from "react"; import React, { useState } from "react";
import { AnswerProps, AnswerQuestionType, EssayType } from "../types"; import { AnswerProps } from "../types";
export const AEssayForm = ({ element, answerQuestion }: AnswerProps) => { export const AEssayForm = ({ element, answerQuestion }: AnswerProps) => {
const [answer, setAnswer] = useState(""); const [answer, setAnswer] = useState("");
...@@ -19,7 +19,7 @@ export const AEssayForm = ({ element, answerQuestion }: AnswerProps) => { ...@@ -19,7 +19,7 @@ export const AEssayForm = ({ element, answerQuestion }: AnswerProps) => {
<div className="flex mt-3 w-full justify-center"> <div className="flex mt-3 w-full justify-center">
<input <input
type="text" type="text"
className="border w-11/12 h-36 my-3" className="border w-11/12 h-24 my-3"
id={element._id} id={element._id}
onChange={handleChange} onChange={handleChange}
value={answer} value={answer}
......
...@@ -42,7 +42,7 @@ export const Header = () => { ...@@ -42,7 +42,7 @@ export const Header = () => {
</button> </button>
</Link> </Link>
<Link to="/signup"> <Link to="/signup">
<button className="font-bold text-white hover:bg-blue-500 mx-1 py-2 px-3 bg-themeColor rounded-md "> <button className="font-bold text-white hover:bg-themeColor2 mx-1 py-2 px-3 bg-themeColor rounded-md ">
회원가입 회원가입
</button> </button>
</Link> </Link>
......
import React, { FormEvent } from "react"; import React, { FormEvent } from "react";
import { useAuth } from "../auth/auth.context"; import { useAuth } from "../auth/auth.context";
import SurveyImg from "../icons/surveyimg.png"; import homeImg from "../icons/homeImg.png";
export const Home = () => { export const Home = () => {
const { user } = useAuth(); const { user } = useAuth();
...@@ -30,10 +30,10 @@ export const Home = () => { ...@@ -30,10 +30,10 @@ export const Home = () => {
+ +
</button> </button>
</div> </div>
<p className="text-center text-xl text-black mt-3">Create now!</p> <p className="text-center text-xl text-black my-3">Create now!</p>
</div> </div>
<div className="flex justify-center mt-3"> <div className="flex mt-5 md:px-48 bg-themeColor">
<img src={SurveyImg} className="object-scale-down justify-center" /> <img src={homeImg} className="m-3" />
</div> </div>
</div> </div>
); );
......
...@@ -162,12 +162,12 @@ export const Question = ({ ...@@ -162,12 +162,12 @@ export const Question = ({
style={{ borderColor: isEditing ? "red" : "#0A8A8A" }} 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" 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-between items-center"> <div className="flex h-16 w-full place-content-center items-center">
<input <input
type="text" type="text"
name="title" name="title"
id={question._id} id={question._id}
className="text-xl font-bold ml-6 border-b-2 w-1/2" className="text-xl font-bold border-b-2 w-11/12"
placeholder={"Question Title"} placeholder={"Question Title"}
value={question.title} value={question.title}
onChange={handleQuestionInfo} onChange={handleQuestionInfo}
...@@ -206,39 +206,58 @@ export const Question = ({ ...@@ -206,39 +206,58 @@ export const Question = ({
></input> ></input>
</div> </div>
{getContent(question)} {getContent(question)}
<div className="flex flex-row place-content-between w-11/12 py-2">
<div className="place-self-end py-2"> <select
<input id={question._id}
type="checkbox" name="type"
id="isRequired" onChange={handleSelect}
value="isRequired"
onChange={handleRequired}
disabled={!isEditing} disabled={!isEditing}
checked={question.isRequired} value={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"
<label htmlFor="isRequired" className="px-1"> >
필수 {Array.from(QUESTION_TYPES.entries()).map(([key, value]) => (
</label> <option key={key} id={question._id} value={key}>
{isEditing ? ( {value}
<> </option>
<button type="button" className="px-1" onClick={onCancel}> ))}
취소 </select>
</button> <div className="place-self-end py-2">
<input
type="checkbox"
id="isRequired"
value="isRequired"
onChange={handleRequired}
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
확인 type="button"
</button> className="px-1"
</> onClick={handleEditComplete}
) : ( >
<> 확인
<button type="button" className="px-1" onClick={handleDelete}> </button>
삭제 </>
</button> ) : (
<button type="button" className="px-1" onClick={handleEditClick}> <>
수정 <button type="button" className="px-1" onClick={handleDelete}>
</button> 삭제
</> </button>
)} <button type="button" className="px-1" onClick={handleEditClick}>
수정
</button>
</>
)}
</div>
</div> </div>
</div> </div>
); );
......
import React, { useState, useRef, useEffect } from "react"; import React, { useState, useRef, useEffect } from "react";
import { baseImageUrl } from "../apis";
import { BasicQuestionType } from "../types"; import { BasicQuestionType } from "../types";
import { REssayForm } from "./REssayForm";
import { RCheckboxForm } from "./RCheckboxForm";
import { RRadioForm } from "./RRadioForm";
import { RDropdownForm } from "./RDropdownForm";
import { RFileForm } from "./RFileForm";
import { RRatingForm } from "./RRatingForm";
import { RDateForm } from "./RDateForm";
type AccordionProps = { type AccordionProps = {
question: BasicQuestionType; question: BasicQuestionType;
}; };
const Accordion = ({ question }: AccordionProps) => { export const Accordion = ({ question }: 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);
...@@ -14,7 +19,27 @@ const Accordion = ({ question }: AccordionProps) => { ...@@ -14,7 +19,27 @@ const Accordion = ({ question }: AccordionProps) => {
setOpened(!isOpened); setOpened(!isOpened);
setHeight(!isOpened ? `${contentElement.current?.scrollHeight}px` : "0px"); setHeight(!isOpened ? `${contentElement.current?.scrollHeight}px` : "0px");
}; };
function getContent(question: BasicQuestionType) {
switch (question.type) {
case "essay":
return <REssayForm question={question} />;
case "radio":
return <RRadioForm question={question} />;
case "checkbox":
return <RCheckboxForm question={question} />;
case "dropdown":
return <RDropdownForm question={question} />;
case "file":
return <RFileForm question={question} />;
case "rating":
return <RRatingForm question={question} />;
case "date":
return <RDateForm question={question} />;
default:
return <></>;
}
}
console.log(question);
return ( return (
<div className="p-1"> <div className="p-1">
<div onClick={HandleOpening}> <div onClick={HandleOpening}>
...@@ -31,20 +56,7 @@ const Accordion = ({ question }: AccordionProps) => { ...@@ -31,20 +56,7 @@ const Accordion = ({ question }: AccordionProps) => {
style={{ height: height }} style={{ height: height }}
className="bg-gray-100 overflow-hidden transition-all duration-300" className="bg-gray-100 overflow-hidden transition-all duration-300"
> >
{question.answers && {question.answers && getContent(question)}
(question.type === "file"
? question.answers.map((answer: any) => (
<img
key={answer.url}
alt="file"
src={`${baseImageUrl}/${answer.url}`}
/>
))
: question.answers.map((answer: any, index: number) => (
<p key={index} className="p-4">
{answer}
</p>
)))}
</div> </div>
</div> </div>
</div> </div>
......
import React from "react";
import { BasicQuestionType } from "../types";
type Props = {
question: BasicQuestionType;
};
export const RCheckboxForm = ({ question }: Props) => {
const result = question.answers.flat().reduce((acc: any, cur: any) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc;
}, {});
console.log(result);
return (
<div className="m-5">
{question.content.choices.map((choice: any) => (
<div className="">
<span className="font-bold">{choice.text}</span>
<span className="ml-3">
- {result[choice.text] ? result[choice.text] : 0}
</span>
</div>
))}
</div>
);
};
import React from "react";
import { BasicQuestionType } from "../types";
type Props = {
question: BasicQuestionType;
};
export const RDateForm = ({ question }: Props) => {
return (
<div className="m-5">
{question.answers.map((answer: any) => (
<div className="font-bold">{answer}</div>
))}
</div>
);
};
import React from "react";
import { BasicQuestionType } from "../types";
type Props = {
question: BasicQuestionType;
};
export const RDropdownForm = ({ question }: Props) => {
const result = question.answers.reduce((acc: any, cur: any) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc;
}, {});
console.log(result);
return (
<div className="m-5">
{question.content.choices.map((choice: any) => (
<div className="">
<span className="font-bold">{choice.text}</span>
<span className="ml-3">
- {result[choice.text] ? result[choice.text] : 0}
</span>
</div>
))}
</div>
);
};
import React from "react";
import { BasicQuestionType } from "../types";
type Props = {
question: BasicQuestionType;
};
export const REssayForm = ({ question }: Props) => {
return (
<div className="m-5">
{question.answers.map((answer: any) => (
<div className="font-bold">{answer}</div>
))}
</div>
);
};
import React from "react";
import { baseImageUrl } from "../apis";
type Props = {
question: any;
};
export const RFileForm = ({ question }: Props) => {
return (
<div className="m-5 flex justify-start items-center">
{question.answers.map((answer: any) => (
<>
<img
className="h-14"
key={answer.url}
alt="file"
src={`${baseImageUrl}/${answer.url}`}
/>
<div className="ml-3">{answer.name}</div>
</>
))}
</div>
);
};
import React from "react";
import { BasicQuestionType } from "../types";
type Props = {
question: BasicQuestionType;
};
export const RRadioForm = ({ question }: Props) => {
const result = question.answers.reduce((acc: any, cur: any) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc;
}, {});
console.log(result);
return (
<div className="m-5">
{question.content.choices.map((choice: any) => (
<div className="">
<span className="font-bold">{choice.text}</span>
<span className="ml-3">
- {result[choice.text] ? result[choice.text] : 0}
</span>
</div>
))}
</div>
);
};
import React from "react";
import { BasicQuestionType } from "../types";
type Props = {
question: BasicQuestionType;
};
export const RRatingForm = ({ question }: Props) => {
const result = question.answers.reduce((acc: any, cur: any) => {
acc[cur] = (acc[cur] || 0) + 1;
return acc;
}, {});
console.log(result);
return (
<div className="m-5">
<div>{question.content.minRateDescription}</div>
{question.content.choices.map((choice: any) => (
<div className="">
<span className="font-bold">{choice.text}</span>
<span className="ml-3">
- {result[choice.text] ? result[choice.text] : 0}
</span>
</div>
))}
<div>{question.content.maxRateDescription}</div>
</div>
);
};
export { Accordion } from "./Accordion";
...@@ -77,17 +77,22 @@ export const CreateSurvey = () => { ...@@ -77,17 +77,22 @@ export const CreateSurvey = () => {
async function handleSubmit(event: FormEvent) { async function handleSubmit(event: FormEvent) {
event.preventDefault(); event.preventDefault();
try { const notEditComplete = isEditing?.find((el) => el.isEditing);
const newSurvey: SurveyType = await surveyApi.editSurvey(survey); if (notEditComplete) {
console.log(newSurvey); alert("아직 수정이 완료되지 않은 질문이 존재합니다.");
setSuccess(true); } else {
alert("저장되었습니다"); try {
navigate("/profile"); const newSurvey: SurveyType = await surveyApi.editSurvey(survey);
setError(""); console.log(newSurvey);
} catch (error) { setSuccess(true);
catchErrors(error, setError); alert("저장되었습니다");
} finally { navigate("/profile");
setLoading(false); setError("");
} catch (error) {
catchErrors(error, setError);
} finally {
setLoading(false);
}
} }
} }
......
...@@ -79,17 +79,22 @@ export const EditSurvey = () => { ...@@ -79,17 +79,22 @@ export const EditSurvey = () => {
async function handleSubmit(event: FormEvent) { async function handleSubmit(event: FormEvent) {
event.preventDefault(); event.preventDefault();
try { const notEditComplete = isEditing?.find((el) => el.isEditing);
const newSurvey: SurveyType = await surveyApi.editSurvey(survey); if (notEditComplete) {
console.log(newSurvey); alert("아직 수정이 완료되지 않은 질문이 존재합니다.");
setSuccess(true); } else {
alert("저장되었습니다"); try {
navigate("/profile"); const newSurvey: SurveyType = await surveyApi.editSurvey(survey);
setError(""); console.log(newSurvey);
} catch (error) { setSuccess(true);
catchErrors(error, setError); alert("저장되었습니다");
} finally { navigate("/profile");
setLoading(false); setError("");
} catch (error) {
catchErrors(error, setError);
} finally {
setLoading(false);
}
} }
} }
......
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { answerApi, surveyApi } from "../apis"; import { answerApi, surveyApi } from "../apis";
import { catchErrors } from "../helpers"; import { catchErrors } from "../helpers";
import Accordion from "./Accordion"; import { Accordion } from "../results";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { SurveyType } from "../types"; import { SurveyType } from "../types";
......
...@@ -8,6 +8,7 @@ router.route("/").get(authCtrl.requireLogin, surveyCtrl.getSurveys); ...@@ -8,6 +8,7 @@ router.route("/").get(authCtrl.requireLogin, surveyCtrl.getSurveys);
router.route("/create").post(authCtrl.requireLogin, surveyCtrl.createSurvey); router.route("/create").post(authCtrl.requireLogin, surveyCtrl.createSurvey);
router.route("/:surveyId").get(surveyCtrl.getSurveyById); router.route("/:surveyId").get(surveyCtrl.getSurveyById);
router router
.route("/:surveyId/edit") .route("/:surveyId/edit")
.get(authCtrl.requireLogin, authCtrl.authenticate, surveyCtrl.getSurveyById) .get(authCtrl.requireLogin, authCtrl.authenticate, surveyCtrl.getSurveyById)
......
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