Question.tsx 6.95 KB
Newer Older
Yoon, Daeki's avatar
Yoon, Daeki committed
1
2
import React, { useState } from "react";
import { BasicQuestionType } from "../types";
Jiwon Yoon's avatar
Jiwon Yoon committed
3
import { questionApi } from "../apis";
4
import { EssayForm } from "./EssayForm";
Jiwon Yoon's avatar
Jiwon Yoon committed
5
6
7
8
9
import { CheckboxForm } from "./CheckboxForm";
import { RadioForm } from "./RadioForm";
import { DropdownForm } from "./DropdownForm";
import { FileForm } from "./FileForm";
import { RatingForm } from "./RatingForm";
Jiwon Yoon's avatar
Jiwon Yoon committed
10
import { DateForm } from "./DateForm";
Yoon, Daeki's avatar
Yoon, Daeki committed
11
import { QUESTION_TYPES } from "../commons";
12
13
14

type Props = {
  element: BasicQuestionType;
Yoon, Daeki's avatar
Yoon, Daeki committed
15
16
  isEditing: boolean;
  handleEditing: (qid: string, isEditing: boolean) => void;
Yoon, Daeki's avatar
Yoon, Daeki committed
17
  handleQuestion: (element: BasicQuestionType) => void;
Jiwon Yoon's avatar
Jiwon Yoon committed
18
  deleteQuestion: (id: string) => void;
19
20
};

Jiwon Yoon's avatar
Jiwon Yoon committed
21
22
export const Question = ({
  element,
Yoon, Daeki's avatar
Yoon, Daeki committed
23
24
  isEditing,
  handleEditing,
Jiwon Yoon's avatar
Jiwon Yoon committed
25
26
  handleQuestion,
  deleteQuestion,
Yoon, Daeki's avatar
Yoon, Daeki committed
27
}: Props) => {
Yoon, Daeki's avatar
Yoon, Daeki committed
28
  const [question, setQuestion] = useState({ ...element });
Yoon, Daeki's avatar
Yoon, Daeki committed
29
30
  // const [isEditing, setIsEditing] = useState(false);

Yoon, Daeki's avatar
Yoon, Daeki committed
31
  // console.log("is editing in question:", isEditing);
Yoon, Daeki's avatar
Yoon, Daeki committed
32

Jiwon Yoon's avatar
Jiwon Yoon committed
33
  async function handleEditComplete() {
Jiwon Yoon's avatar
Jiwon Yoon committed
34
    try {
Yoon, Daeki's avatar
Yoon, Daeki committed
35
      console.log(question);
Jiwon Yoon's avatar
Jiwon Yoon committed
36
      const newQuestion: BasicQuestionType = await questionApi.updateQuestion(
37
        question
Jiwon Yoon's avatar
Jiwon Yoon committed
38
      );
Yoon, Daeki's avatar
Yoon, Daeki committed
39
40
      // console.log(newQuestion);
      handleQuestion(question);
Yoon, Daeki's avatar
Yoon, Daeki committed
41
42
      // setIsEditing(true);
      handleEditing(question._id, false);
Jiwon Yoon's avatar
Jiwon Yoon committed
43
44
45
46
47
48
49
50
51
52
53
54
55
      // 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);
Yoon, Daeki's avatar
Yoon, Daeki committed
56
    let content;
Jiwon Yoon's avatar
Jiwon Yoon committed
57
58
59
60
61
    if (
      selectedType === "radio" ||
      selectedType === "dropdown" ||
      selectedType === "checkbox"
    ) {
Yoon, Daeki's avatar
Yoon, Daeki committed
62
      content = {
Jiwon Yoon's avatar
Jiwon Yoon committed
63
        choices: [{ text: "", value: 0 }],
Jiwon Yoon's avatar
Jiwon Yoon committed
64
65
      };
    } else if (selectedType === "essay") {
Yoon, Daeki's avatar
Yoon, Daeki committed
66
      content = { choices: [] };
Jiwon Yoon's avatar
Jiwon Yoon committed
67
    } else if (selectedType === "rating") {
Yoon, Daeki's avatar
Yoon, Daeki committed
68
      content = {
Jiwon Yoon's avatar
Jiwon Yoon committed
69
70
        minRateDescription: "",
        maxRateDescription: "",
Jiwon Yoon's avatar
Jiwon Yoon committed
71
        choices: [{ text: "", value: 0 }],
Jiwon Yoon's avatar
Jiwon Yoon committed
72
73
      };
    }
Yoon, Daeki's avatar
Yoon, Daeki committed
74
    setQuestion({ ...question, type: selectedType, content: content });
Jiwon Yoon's avatar
Jiwon Yoon committed
75
76
  }

Yoon, Daeki's avatar
Yoon, Daeki committed
77
78
79
80
81
  const handleElement = () => {
    console.log("handle element");
    setQuestion({ ...question });
  };

Jiwon Yoon's avatar
Jiwon Yoon committed
82
83
  function handleQuestionInfo(event: React.ChangeEvent<HTMLInputElement>) {
    const { name, value } = event.currentTarget;
Yoon, Daeki's avatar
Yoon, Daeki committed
84
    setQuestion({ ...question, [name]: value });
Jiwon Yoon's avatar
Jiwon Yoon committed
85
  }
86
87
88
89

  function getContent(element: BasicQuestionType) {
    switch (element.type) {
      case "essay":
Yoon, Daeki's avatar
Yoon, Daeki committed
90
        return <EssayForm element={element} isEditing={isEditing} />;
91
      case "radio":
Jiwon Yoon's avatar
Jiwon Yoon committed
92
93
        return (
          <RadioForm
Yoon, Daeki's avatar
Yoon, Daeki committed
94
            handleQuestion={handleElement}
Jiwon Yoon's avatar
Jiwon Yoon committed
95
            element={element}
Yoon, Daeki's avatar
Yoon, Daeki committed
96
            isEditing={isEditing}
Jiwon Yoon's avatar
Jiwon Yoon committed
97
98
          />
        );
99
      case "checkbox":
Jiwon Yoon's avatar
Jiwon Yoon committed
100
        return (
Jiwon Yoon's avatar
Jiwon Yoon committed
101
          <CheckboxForm
Yoon, Daeki's avatar
Yoon, Daeki committed
102
            handleQuestion={handleElement}
Jiwon Yoon's avatar
Jiwon Yoon committed
103
            element={element}
Yoon, Daeki's avatar
Yoon, Daeki committed
104
            isEditing={isEditing}
Jiwon Yoon's avatar
Jiwon Yoon committed
105
          />
Jiwon Yoon's avatar
Jiwon Yoon committed
106
        );
107
      case "dropdown":
Jiwon Yoon's avatar
Jiwon Yoon committed
108
        return (
Jiwon Yoon's avatar
Jiwon Yoon committed
109
          <DropdownForm
Yoon, Daeki's avatar
Yoon, Daeki committed
110
            handleQuestion={handleElement}
Jiwon Yoon's avatar
Jiwon Yoon committed
111
            element={element}
Yoon, Daeki's avatar
Yoon, Daeki committed
112
            isEditing={isEditing}
Jiwon Yoon's avatar
Jiwon Yoon committed
113
          />
Jiwon Yoon's avatar
Jiwon Yoon committed
114
        );
115
      case "file":
Yoon, Daeki's avatar
Yoon, Daeki committed
116
        return <FileForm element={element} isEditing={isEditing} />;
117
      case "rating":
Jiwon Yoon's avatar
Jiwon Yoon committed
118
119
        return (
          <RatingForm
Yoon, Daeki's avatar
Yoon, Daeki committed
120
            handleQuestion={handleElement}
Jiwon Yoon's avatar
Jiwon Yoon committed
121
            element={element}
Yoon, Daeki's avatar
Yoon, Daeki committed
122
            isEditing={isEditing}
Jiwon Yoon's avatar
Jiwon Yoon committed
123
124
          />
        );
Jiwon Yoon's avatar
Jiwon Yoon committed
125
126
      case "date":
        return <DateForm />;
127
128
129
130
      default:
        return <></>;
    }
  }
Yoon, Daeki's avatar
Yoon, Daeki committed
131

132
133
  const handleRequired = (event: React.ChangeEvent<HTMLInputElement>) => {
    const { checked, value } = event.currentTarget;
Yoon, Daeki's avatar
Yoon, Daeki committed
134
135
136
137
138
139
140
141
    question[value] = checked;
    setQuestion({ ...question, [value]: checked });
  };

  const onCancel = () => {
    console.log("element canceled button clicked", element);
    console.log("question canceled button clicked", question);
    setQuestion(element);
Yoon, Daeki's avatar
Yoon, Daeki committed
142
143
    // setIsEditing(true);
    handleEditing(question._id, false);
144
  };
Yoon, Daeki's avatar
Yoon, Daeki committed
145

146
  const handleDelete = () => {
Jiwon Yoon's avatar
Jiwon Yoon committed
147
148
149
150
151
152
    if (window.confirm("질문을 삭제하시겠습니까?")) {
      deleteQuestion(element._id);
      alert("삭제되었습니다.");
    } else {
      alert("질문 삭제를 취소합니다.");
    }
153
  };
Yoon, Daeki's avatar
Yoon, Daeki committed
154

155
  const handleEditClick = () => {
Yoon, Daeki's avatar
Yoon, Daeki committed
156
157
    // setIsEditing(false);
    handleEditing(question._id, true);
158
  };
Yoon, Daeki's avatar
Yoon, Daeki committed
159

160
  return (
Jiwon Yoon's avatar
Jiwon Yoon committed
161
    <div
Yoon, Daeki's avatar
Yoon, Daeki committed
162
      style={{ borderColor: isEditing ? "red" : "#0A8A8A" }}
163
      className="flex flex-col container w-4/5 h-auto border-2 items-center m-3 py-2 rounded-lg"
Jiwon Yoon's avatar
Jiwon Yoon committed
164
    >
Jiwon Yoon's avatar
Jiwon Yoon committed
165
      <div className="flex h-16 w-full place-content-center items-center">
166
167
168
        <input
          type="text"
          name="title"
Yoon, Daeki's avatar
Yoon, Daeki committed
169
          id={question._id}
Jiwon Yoon's avatar
Jiwon Yoon committed
170
          className="text-xl font-bold border-b-2 w-11/12"
Jiwon Yoon's avatar
Jiwon Yoon committed
171
          placeholder={"Question Title"}
Yoon, Daeki's avatar
Yoon, Daeki committed
172
          value={question.title}
Jiwon Yoon's avatar
Jiwon Yoon committed
173
          onChange={handleQuestionInfo}
Yoon, Daeki's avatar
Yoon, Daeki committed
174
          disabled={!isEditing}
175
176
177
178
179
180
        ></input>
      </div>
      <div className="flex w-full justify-center">
        <input
          type="text"
          name="comment"
Yoon, Daeki's avatar
Yoon, Daeki committed
181
          id={question._id}
182
183
          className="border w-11/12"
          placeholder="질문에 대한 설명을 입력해주세요"
Yoon, Daeki's avatar
Yoon, Daeki committed
184
          value={question.comment}
Jiwon Yoon's avatar
Jiwon Yoon committed
185
          onChange={handleQuestionInfo}
Yoon, Daeki's avatar
Yoon, Daeki committed
186
          disabled={!isEditing}
187
188
        ></input>
      </div>
Yoon, Daeki's avatar
Yoon, Daeki committed
189
      {getContent(question)}
Jiwon Yoon's avatar
Jiwon Yoon committed
190
191
192
193
194
      <div className="flex flex-row place-content-between w-11/12 py-2">
        <select
          id={question._id}
          name="type"
          onChange={handleSelect}
Yoon, Daeki's avatar
Yoon, Daeki committed
195
          disabled={!isEditing}
Jiwon Yoon's avatar
Jiwon Yoon committed
196
197
198
199
200
201
202
203
204
          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"
        >
          {Array.from(QUESTION_TYPES.entries()).map(([key, value]) => (
            <option key={key} id={question._id} value={key}>
              {value}
            </option>
          ))}
        </select>
Jiwon Yoon's avatar
Jiwon Yoon committed
205
        <div className="place-self-end py-2">
Jiwon Yoon's avatar
Jiwon Yoon committed
206
207
208
209
210
          <input
            type="checkbox"
            id="isRequired"
            value="isRequired"
            onChange={handleRequired}
Jiwon Yoon's avatar
Jiwon Yoon committed
211
            disabled={!isEditing}
Jiwon Yoon's avatar
Jiwon Yoon committed
212
213
214
215
216
            checked={question.isRequired}
          />
          <label htmlFor="isRequired" className="px-1">
            필수
          </label>
Jiwon Yoon's avatar
Jiwon Yoon committed
217
          {isEditing ? (
Jiwon Yoon's avatar
Jiwon Yoon committed
218
219
220
221
            <>
              <button type="button" className="px-1" onClick={onCancel}>
                취소
              </button>
Yoon, Daeki's avatar
Yoon, Daeki committed
222

Jiwon Yoon's avatar
Jiwon Yoon committed
223
224
225
226
227
228
229
230
              <button
                type="button"
                className="px-1"
                onClick={handleEditComplete}
              >
                확인
              </button>
            </>
Jiwon Yoon's avatar
Jiwon Yoon committed
231
232
233
234
235
236
237
238
239
          ) : (
            <>
              <button type="button" className="px-1" onClick={handleDelete}>
                삭제
              </button>
              <button type="button" className="px-1" onClick={handleEditClick}>
                수정
              </button>
            </>
Jiwon Yoon's avatar
Jiwon Yoon committed
240
241
          )}
        </div>
242
243
244
245
      </div>
    </div>
  );
};