SurveyLayout.tsx 4.18 KB
Newer Older
1
2
3
4
import React from "react";
import { NavLink, useOutletContext } from "react-router-dom";
import { Outlet, useNavigate, useParams } from "react-router-dom";
import { useSurveys } from "./SurveysLayout";
5
6
7
8
9
10
import type {
  CreateQuestionData,
  ICreateSurvey,
  IQuestionData,
  ISurvey,
} from "../types";
11
import { SpinnerIcon } from "../icons";
Yoon, Daeki's avatar
Yoon, Daeki committed
12
import { surveyApi } from "../apis";
13
14

type SurveyContextType = {
15
  survey: ICreateSurvey;
16
  createQuestion: (question: IQuestionData) => Promise<any>;
Yoon, Daeki's avatar
Yoon, Daeki committed
17
18
  removeQuestion: (questionId: string) => Promise<any>;
  updateQuestion: (question: CreateQuestionData) => Promise<any>;
19
  updateTitleComment: (state: { title: string; comment: string }) => void;
20
21
22
23
24
};

const activeStyle =
  "w-36 h-12 flex justify-center items-center bg-themeColor p-1 text-white text-center font-bold text-xl";
const inActiveStyle =
25
  "w-36 h-12 flex justify-center items-center bg-white border border-themeColor first:border-r-0 last:border-l-0 p-1 text-center font-bold text-xl";
26
27

export const SurveyLayout = () => {
Yoon, Daeki's avatar
Yoon, Daeki committed
28
  const { surveys, update, updateLocalSurveysList } = useSurveys();
29
30
31
  let { surveyId } = useParams<{ surveyId: string }>();
  const survey = surveys.find((survey) => survey._id === surveyId);

Yoon, Daeki's avatar
Yoon, Daeki committed
32
  // console.log("surveys in survey layout", surveys);
33
34
35
36
37
38
39
40
41

  if (!survey) {
    return (
      <div className="flex justify-center mt-5">
        <SpinnerIcon className="animate-spin h-10 w-10 mr-1 bg-white text-slate-500" />
      </div>
    );
  }

42
  const createQuestion = async (question: IQuestionData) => {
Yoon, Daeki's avatar
Yoon, Daeki committed
43
44
    const newQuestion = await surveyApi.addQuestion(survey._id!, question);
    console.log("new question:", newQuestion);
45
    newQuestion.isEditing = true;
Yoon, Daeki's avatar
Yoon, Daeki committed
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    survey.questions.push(newQuestion);
    updateLocalSurveysList(survey);
  };

  const removeQuestion = async (questionId: string) => {
    await surveyApi.deleteQuestion(survey._id!, questionId);

    const questions = survey.questions;
    const updatedQuestions = questions.filter((q) => q._id !== questionId);

    console.log("questions after deleted question:", updatedQuestions);
    survey.questions = updatedQuestions;
    updateLocalSurveysList(survey);
  };

61
62
63
64
65
  /**
   * 수정된 질문을 입력받아 기존 질문을 대체합니다.
   * @param question 수정할 질문
   * @returns 없음
   */
Yoon, Daeki's avatar
Yoon, Daeki committed
66
  const updateQuestion = async (question: CreateQuestionData) => {
Yoon, Daeki's avatar
Yoon, Daeki committed
67
68
69
70
    const updatedQuestion = await surveyApi.updateQuestion(
      survey._id!,
      question
    );
Yoon, Daeki's avatar
Yoon, Daeki committed
71
72
73
74
75
76
77
78
79
80
81
82

    const questions = survey.questions;
    const index = questions.findIndex((q) => q._id === question._id);
    if (index < 0) {
      return;
    }
    questions[index] = question;
    console.log("questions in update question:", questions);
    survey.questions = questions;
    updateLocalSurveysList(survey);
  };

83
84
85
86
87
88
89
90
91
92
93
  const updateTitleComment = async (state: {
    title: string;
    comment: string;
  }) => {
    survey.title = state.title;
    survey.comment = state.comment;
    console.log("title in handle title and comment:", state);
    const result = await surveyApi.updateSurvey(survey);
    updateLocalSurveysList(survey);
  };

94
95
96
97
  return (
    <div>
      <div className="flex justify-center items-center mt-6">
        <NavLink
98
          to={`/surveys/${surveyId}/edit`}
99
100
101
102
103
104
          className={({ isActive }) =>
            isActive
              ? activeStyle + " rounded-l-3xl"
              : inActiveStyle + " rounded-l-3xl"
          }
        >
105
          설문지 수정
106
107
        </NavLink>
        <NavLink
108
109
          to={`/surveys/${surveyId}`}
          end={true}
110
111
          className={({ isActive }) => (isActive ? activeStyle : inActiveStyle)}
        >
112
          설문 미리보기
113
114
115
116
117
118
119
120
121
122
123
124
        </NavLink>
        <NavLink
          to={`/surveys/${surveyId}/result`}
          className={({ isActive }) =>
            isActive
              ? activeStyle + " rounded-r-3xl"
              : inActiveStyle + " rounded-r-3xl"
          }
        >
          응답결과
        </NavLink>
      </div>
Yoon, Daeki's avatar
Yoon, Daeki committed
125
126
127
128
129
130
      <Outlet
        context={{
          survey,
          createQuestion,
          removeQuestion,
          updateQuestion,
131
          updateTitleComment,
Yoon, Daeki's avatar
Yoon, Daeki committed
132
133
        }}
      />
134
135
136
137
138
139
140
    </div>
  );
};

export const useSurvey = () => {
  return useOutletContext<SurveyContextType>();
};