posting.tsx 7.55 KB
Newer Older
Lee Soobeom's avatar
Lee Soobeom committed
1
import React, { FormEvent, useEffect, useState } from "react";
Lee Soobeom's avatar
Lee Soobeom committed
2
import { useNavigate } from "react-router-dom";
3
4
5
import isLength from "validator/lib/isLength";
import equals from "validator/lib/equals";
import { catchErrors } from "../helpers";
Lee Soobeom's avatar
Lee Soobeom committed
6
import { PostType } from "../types";
7
import { postApi } from "../apis";
Lee Soobeom's avatar
Lee Soobeom committed
8
import { File } from "formidable";
Kim, MinGyu's avatar
Kim, MinGyu committed
9

10
export default function Posting() {
Lee Soobeom's avatar
Lee Soobeom committed
11
12
  const [city, setCity] = useState<string>("city");
  const [theme, setTheme] = useState<string>("theme");
13
14
  const [title, setTitle] = useState<string>("");
  const [text, setText] = useState<string>("");
Lee Soobeom's avatar
Lee Soobeom committed
15
  const [file, setFile] = useState<FileList>();
Lee Soobeom's avatar
Lee Soobeom committed
16
  const [imgSrc, setImgSrc] = useState<string[]>();
Lee Soobeom's avatar
Lee Soobeom committed
17
  const navigate = useNavigate();
Kim, MinGyu's avatar
Kim, MinGyu committed
18

Lee Soobeom's avatar
Lee Soobeom committed
19
  const [user, setUser] = useState<PostType>({
20
21
22
23
    title: "",
    text: "",
    theme: "",
    city: "",
Lee Soobeom's avatar
Lee Soobeom committed
24
25
    date: "",
    user: "",
Lee Soobeom's avatar
Lee Soobeom committed
26
    counts: 0,
Lee Soobeom's avatar
Lee Soobeom committed
27
    _id: "",
28
  });
Kim, MinGyu's avatar
Kim, MinGyu committed
29

30
31
32
33
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [disabled, setDisabled] = useState(false);
  const [success, setSuccess] = useState(false);
Kim, MinGyu's avatar
Kim, MinGyu committed
34

Lee Soobeom's avatar
Lee Soobeom committed
35
36
37
38
  const imgArr = new Array();

  const sendImg2Db = async (filelist: FileList) => {
    const formdata = new FormData();
Lee Soobeom's avatar
Lee Soobeom committed
39
40
41
42
    formdata.append("title", user.title);
    formdata.append("text", user.text);
    formdata.append("theme", user.theme);
    formdata.append("city", user.city);
Lee Soobeom's avatar
Lee Soobeom committed
43
44
    if (!(filelist === undefined || filelist === null)) {
      for (var i = 0; i < filelist.length; i++) {
Lee Soobeom's avatar
Lee Soobeom committed
45
        formdata.append("picture", filelist?.[i]);
Lee Soobeom's avatar
Lee Soobeom committed
46
      }
Lee Soobeom's avatar
Lee Soobeom committed
47
48
      // formdata: post, imgs
      const res = await postApi.createImgAndPost(formdata);
Lee Soobeom's avatar
Lee Soobeom committed
49
    }
Lee Soobeom's avatar
Lee Soobeom committed
50
51
52
    // else {
    //   const res = await postApi.createImgAndPostTable(formdata);
    // }
Lee Soobeom's avatar
Lee Soobeom committed
53
54
  };

55
  async function handlePostSubmit(event: FormEvent) {
Lee Soobeom's avatar
Lee Soobeom committed
56
    event.preventDefault();
57
58
59
    try {
      setError("");
      console.log("user data", user);
Lee Soobeom's avatar
Lee Soobeom committed
60
      if (postingFormMatch(user)) {
61
        setLoading(true);
Lee Soobeom's avatar
Lee Soobeom committed
62
63
64
65
66
67
        if (file) {
          sendImg2Db(file);
        }
        // const res = await postApi.posting(user);
        // console.log("서버연결됬나요", res);

Lee Soobeom's avatar
Lee Soobeom committed
68
        navigate("/board", { replace: true });
69
70
71
72
73
74
75
76
77
        setSuccess(true);
        setError("");
      }
    } catch (error) {
      console.log("에러발생");
      catchErrors(error, setError);
    } finally {
      setLoading(false);
    }
Kim, MinGyu's avatar
Kim, MinGyu committed
78
79
  }

Lee Soobeom's avatar
Lee Soobeom committed
80
  function postingFormMatch(user: PostType) {
81
82
83
84
85
86
    if (!isLength(user.title ?? "", { min: 1 })) {
      setError("제목을 입력해 주세요.");
      return false;
    } else if (!isLength(user.text ?? "", { min: 1 })) {
      setError("내용을 입력해 주세요.");
      return false;
Lee Soobeom's avatar
Lee Soobeom committed
87
    } else if (equals(city, "city")) {
88
89
      setError("도시를 선택해 주세요.");
      return false;
Lee Soobeom's avatar
Lee Soobeom committed
90
91
92
    } else if (equals(theme, "theme")) {
      setError("테마를 선택해 주세요.");
      return false;
93
94
95
    } else {
      return true;
    }
Kim, MinGyu's avatar
Kim, MinGyu committed
96
97
  }

98
99
100
101
102
103
104
  const titleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
    const title = event.currentTarget.value;
    const newUser = { ...user, title: title };
    console.log(event.currentTarget.value);
    setTitle(event.currentTarget.value);
    setUser(newUser);
  };
Kim, MinGyu's avatar
Kim, MinGyu committed
105

106
107
108
109
110
111
112
  const textChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
    const text = event.currentTarget.value;
    const newUser = { ...user, text: text };
    console.log(event.currentTarget.value);
    setText(event.currentTarget.value);
    setUser(newUser);
  };
Kim, MinGyu's avatar
Kim, MinGyu committed
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
  const cityChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    const city = event.currentTarget.value;
    const newUser = { ...user, city: city };
    console.log(event.currentTarget.value);
    setCity(event.currentTarget.value);
    setUser(newUser);
  };

  const themeChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    const theme = event.currentTarget.value;
    const newUser = { ...user, theme: theme };
    console.log(event.currentTarget.value);
    setTheme(event.currentTarget.value);
    setUser(newUser);
  };
Lee Soobeom's avatar
Lee Soobeom committed
129

Lee Soobeom's avatar
Lee Soobeom committed
130
131
132
  const handleInputPic = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const maxImg = 10;
    const { files } = event.target;
Lee Soobeom's avatar
Lee Soobeom committed
133
134
135
136
137

    if (!(files === null)) {
      setFile(files);
    }

Lee Soobeom's avatar
Lee Soobeom committed
138
139
140
141
142
143
144
145
146
147
    if (!(files?.length === undefined)) {
      if (files?.length <= maxImg) {
        for (var i = 0; i < files.length; i++) {
          const reader = new FileReader();
          reader.readAsDataURL(files?.[i]);

          reader.onload = (e) => {
            imgArr.push(e.target?.result);
            setImgSrc(imgArr);
          };
Lee Soobeom's avatar
Lee Soobeom committed
148
149
        }
      } else {
Lee Soobeom's avatar
Lee Soobeom committed
150
        alert(`사진은 최대 ${maxImg}장까지 업로드 가능합니다!`);
Lee Soobeom's avatar
Lee Soobeom committed
151
152
153
154
      }
    }
  };

Kim, MinGyu's avatar
Kim, MinGyu committed
155
  return (
Lee Soobeom's avatar
Lee Soobeom committed
156
    <div className="flex flex-col border-3 ">
157
      <form onSubmit={handlePostSubmit} className="w-full items-center">
Kim, MinGyu's avatar
Kim, MinGyu committed
158
159
        <div className="flex flex-row relative">
          <p className="basis-1/12 gap-x-8">Id</p>
Lee Soobeom's avatar
Lee Soobeom committed
160
161
          <p className="basis-6/12 invisible">empty</p>
          <div className="basis-2/12 border-2 border-sky-300">
Lee Soobeom's avatar
Lee Soobeom committed
162
            <input type="file" multiple onChange={handleInputPic} />
Lee Soobeom's avatar
Lee Soobeom committed
163
          </div>
164
165
166
          <select
            name="city"
            id="Questions"
Lee Soobeom's avatar
Lee Soobeom committed
167
            className="border-2 border-sky-300 w-1/12"
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
            onChange={cityChange}
            defaultValue="질문종류"
          >
            <option value="질문종류">도시</option>
            <option value="Seoul">서울</option>
            <option value="Busan">부산</option>
            <option value="Incheon">인천</option>
            <option value="Daegoo">대구</option>
            <option value="Kwangjoo">광주</option>
            <option value="Daejeon">대전</option>
            <option value="Woolsan">울산</option>
            <option value="Sejong">세종</option>
            <option value="Dokdo">독도</option>
            <option value="Jeju">제주</option>
          </select>
          <select
            name="theme"
            id="Questions"
Lee Soobeom's avatar
Lee Soobeom committed
186
            className="border-2 border-sky-300 w-1/12"
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
            onChange={themeChange}
            defaultValue="질문종류"
          >
            <option value="질문종류">테마</option>
            <option value="cycling">사이클링</option>
            <option value="surfing">서핑</option>
            <option value="activity">액티비티</option>
            <option value="camping">캠핑</option>
            <option value="sking">스키</option>
            <option value="boat">보트</option>
            <option value="desert">사막</option>
            <option value="golf">골프</option>
            <option value="cave">동굴</option>
            <option value="history">문화재</option>
            <option value="zoo">동물원</option>
            <option value="cycling">사이클링</option>
          </select>
Kim, MinGyu's avatar
Kim, MinGyu committed
204
205
206

          <button
            type="submit"
Lee Soobeom's avatar
Lee Soobeom committed
207
            className="border-2 border-sky-300 basis-1/12 gap-x-8"
Kim, MinGyu's avatar
Kim, MinGyu committed
208
209
210
211
212
          >
            글쓰기
          </button>
        </div>

Lee Soobeom's avatar
Lee Soobeom committed
213
        <div className="flex">
Kim, MinGyu's avatar
Kim, MinGyu committed
214
          <textarea
215
216
            name="title"
            onChange={titleChange}
Kim, MinGyu's avatar
Kim, MinGyu committed
217
            placeholder="title"
Lee Soobeom's avatar
Lee Soobeom committed
218
            className="w-full h-8 border-2 border-sky-300"
Kim, MinGyu's avatar
Kim, MinGyu committed
219
220
          ></textarea>
        </div>
Lee Soobeom's avatar
Lee Soobeom committed
221
222
223
224
225
        <div className="flex flex-col">
          <div className="flex h-48 overflow-x-scroll">
            {imgSrc?.map((img, i) => (
              <img key={i} src={img} width={200} height={200} />
            ))}
Lee Soobeom's avatar
Lee Soobeom committed
226
          </div>
227
228
229
230
          <textarea
            onChange={textChange}
            name="text"
            placeholder="text"
Lee Soobeom's avatar
Lee Soobeom committed
231
            className="w-full h-96 border-2 border-sky-300"
232
          ></textarea>
Lee Soobeom's avatar
Lee Soobeom committed
233
        </div>
Kim, MinGyu's avatar
Kim, MinGyu committed
234
235
236
237
      </form>
    </div>
  );
}