posting.tsx 8.95 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, Link } 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";
Kim, MinGyu's avatar
Kim, MinGyu committed
8

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

Lee Soobeom's avatar
Lee Soobeom committed
18
  const [user, setUser] = useState<PostType>({
19
20
    title: "",
    text: "",
Lee Soobeom's avatar
Lee Soobeom committed
21
22
    theme: "theme",
    city: "city",
Lee Soobeom's avatar
Lee Soobeom committed
23
    date: "",
Lee Soobeom's avatar
Lee Soobeom committed
24
25
26
    user: {
      _id: "",
      name: "",
Lee Soobeom's avatar
Lee Soobeom committed
27
      avatar: "",
Lee Soobeom's avatar
Lee Soobeom committed
28
    },
Lee Soobeom's avatar
Lee Soobeom committed
29
    counts: 0,
Lee Soobeom's avatar
Lee Soobeom committed
30
    _id: "",
Lee Soobeom's avatar
Lee Soobeom committed
31
32
    file: [
      {
Lee Soobeom's avatar
Lee Soobeom committed
33
        _id: "",
Lee Soobeom's avatar
Lee Soobeom committed
34
35
36
37
38
        originalfilename: "",
        newfilename: "",
        picturepath: "",
      },
    ],
39
  });
Kim, MinGyu's avatar
Kim, MinGyu committed
40

41
42
43
44
  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
45

Lee Soobeom's avatar
Lee Soobeom committed
46
47
  const imgArr = new Array();

Kim, MinGyu's avatar
test    
Kim, MinGyu committed
48
49
50
51
52
53
54
55
56
  // const sendImg2Db = async (filelist: FileList) => {
  //   const formdata = new FormData();
  //   formdata.append("title", user.title);
  //   formdata.append("text", user.text);
  //   formdata.append("theme", user.theme);
  //   formdata.append("city", user.city);
  //   if (!(filelist === undefined || filelist === null)) {
  //     if (filelist.length === 1) {
  //       formdata.append("picture", filelist?.[0]);
Lee Soobeom's avatar
Lee Soobeom committed
57

Kim, MinGyu's avatar
test    
Kim, MinGyu committed
58
  // const res = await postApi.createFileAndPost(formdata);
Lee Soobeom's avatar
Lee Soobeom committed
59

Kim, MinGyu's avatar
test    
Kim, MinGyu committed
60
61
62
63
64
65
  //       return res;
  //     } else {
  //       for (var i = 0; i < filelist.length; i++) {
  //         formdata.append("picture", filelist?.[i]);
  //       }
  //       const res = await postApi.createFileAndPost(formdata);
Lee Soobeom's avatar
Lee Soobeom committed
66

Kim, MinGyu's avatar
test    
Kim, MinGyu committed
67
68
69
70
  //       return res;
  //     }
  //   }
  // };
Lee Soobeom's avatar
Lee Soobeom committed
71

72
  async function handlePostSubmit(event: FormEvent) {
Lee Soobeom's avatar
Lee Soobeom committed
73
    event.preventDefault();
74
    try {
Lee Soobeom's avatar
Lee Soobeom committed
75
      if (confirm("게시물을 작성하시겠습니까?") == true) {
76
        setError("");
Lee Soobeom's avatar
Lee Soobeom committed
77
78
79
        if (postingFormMatch(user, file)) {
          setLoading(true);
          if (file) {
Kim, MinGyu's avatar
test    
Kim, MinGyu committed
80
81
82
83
84
85
86
            const formdata = new FormData();
            formdata.append("title", user.title);
            formdata.append("text", user.text);
            formdata.append("theme", user.theme);
            formdata.append("city", user.city);
            // const postRes = await createPost(file, formdata);
            navigate("/posts", { replace: true, state: formdata });
Lee Soobeom's avatar
Lee Soobeom committed
87
88
89
90
91
92
          }
          setSuccess(true);
          setError("");
        }
      } else {
        return false;
93
94
95
96
97
98
99
      }
    } catch (error) {
      console.log("에러발생");
      catchErrors(error, setError);
    } finally {
      setLoading(false);
    }
Kim, MinGyu's avatar
Kim, MinGyu committed
100
101
  }

Lee Soobeom's avatar
Lee Soobeom committed
102
  function postingFormMatch(user: PostType, file: FileList | undefined) {
103
    if (!isLength(user.title ?? "", { min: 1 })) {
Lee Soobeom's avatar
Lee Soobeom committed
104
      alert("제목을 입력해 주세요.");
105
106
107
      setError("제목을 입력해 주세요.");
      return false;
    } else if (!isLength(user.text ?? "", { min: 1 })) {
Lee Soobeom's avatar
Lee Soobeom committed
108
      alert("내용을 입력해 주세요.");
109
110
      setError("내용을 입력해 주세요.");
      return false;
Lee Soobeom's avatar
Lee Soobeom committed
111
112
113
114
    } else if (file === undefined) {
      alert("사진을 첨부해 주세요.");
      setError("사진을 첨부해 주세요.");
      return false;
Lee Soobeom's avatar
Lee Soobeom committed
115
    } else if (equals(user.city, "city")) {
Lee Soobeom's avatar
Lee Soobeom committed
116
      alert("도시를 선택해 주세요.");
117
118
      setError("도시를 선택해 주세요.");
      return false;
Lee Soobeom's avatar
Lee Soobeom committed
119
    } else if (equals(user.theme, "theme")) {
Lee Soobeom's avatar
Lee Soobeom committed
120
      alert("테마를 선택해 주세요.");
Lee Soobeom's avatar
Lee Soobeom committed
121
122
      setError("테마를 선택해 주세요.");
      return false;
123
124
125
    } else {
      return true;
    }
Kim, MinGyu's avatar
Kim, MinGyu committed
126
127
  }

Kim, MinGyu's avatar
test    
Kim, MinGyu committed
128
129
130
  const stringChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
    const { name, value } = event.currentTarget;
    const newUser = { ...user, [name]: value };
131
132
133
134
    console.log(event.currentTarget.value);
    setTitle(event.currentTarget.value);
    setUser(newUser);
  };
Kim, MinGyu's avatar
Kim, MinGyu committed
135

Kim, MinGyu's avatar
test    
Kim, MinGyu committed
136
137
138
  const selectChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    const { name, value } = event.currentTarget;
    const newUser = { ...user, [name]: value };
139
140
141
142
    console.log(event.currentTarget.value);
    setText(event.currentTarget.value);
    setUser(newUser);
  };
Kim, MinGyu's avatar
Kim, MinGyu committed
143

Lee Soobeom's avatar
Lee Soobeom committed
144
145
146
  const handleInputPic = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const maxImg = 10;
    const { files } = event.target;
Lee Soobeom's avatar
Lee Soobeom committed
147
148
149
150
151

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

Lee Soobeom's avatar
Lee Soobeom committed
152
153
154
155
156
157
158
159
160
161
    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
162
163
        }
      } else {
Lee Soobeom's avatar
Lee Soobeom committed
164
        alert(`사진은 최대 ${maxImg}장까지 업로드 가능합니다!`);
Lee Soobeom's avatar
Lee Soobeom committed
165
166
167
168
      }
    }
  };

Lee Soobeom's avatar
Lee Soobeom committed
169
170
171
172
173
174
  const GoBack = () => {
    if (confirm("취소하시겠습니까?") == true) {
      navigate(-1);
    }
  };

Kim, MinGyu's avatar
Kim, MinGyu committed
175
  return (
Lee Soobeom's avatar
Lee Soobeom committed
176
177
178
179
    <div className="shadow-lg bg-white rounded px-8 py-4">
      <div className="text-2xl font-semibold md:text-4xl">
        당신의 여행을 알려주세요!
      </div>
Lee Soobeom's avatar
Lee Soobeom committed
180
181
      <form onSubmit={handlePostSubmit} className="flex flex-col w-full">
        <div className="flex flex-row gap-x-1 justify-end h-10 ">
Lee Soobeom's avatar
Lee Soobeom committed
182
          <div className="place-self-center w-16 h-6 border-2 border-sky-400 transition delay-150 bg-white-400 hover:-translate-y-1 hover:bg-gray-300 duration-300">
Lee Soobeom's avatar
Lee Soobeom committed
183
184
185
186
187
188
189
190
191
192
193
            <input
              id="files"
              type="file"
              multiple
              onChange={handleInputPic}
              className="hidden"
            />
            <label htmlFor="files" className="text-xs grid place-items-center">
              파일 선택
            </label>
          </div>
Kim, MinGyu's avatar
Kim, MinGyu committed
194

Lee Soobeom's avatar
Lee Soobeom committed
195
196
          <select
            name="city"
Lee Soobeom's avatar
Lee Soobeom committed
197
            className="border-2 border-sky-400 text-xs h-6 place-self-center"
Kim, MinGyu's avatar
test    
Kim, MinGyu committed
198
            onChange={selectChange}
Lee Soobeom's avatar
Lee Soobeom committed
199
            defaultValue="city"
Lee Soobeom's avatar
Lee Soobeom committed
200
          >
Lee Soobeom's avatar
Lee Soobeom committed
201
            <option value="city">도시</option>
Lee Soobeom's avatar
Lee Soobeom committed
202
203
204
205
206
207
208
209
210
211
212
            <option value="Seoul">서울</option>
            <option value="Busan">부산</option>
            <option value="Incheon">인천</option>
            <option value="Daegu">대구</option>
            <option value="Gwangju">광주</option>
            <option value="Daejeon">대전</option>
            <option value="Woolsan">울산</option>
            <option value="Sejong">세종</option>
            <option value="Dokdo">독도</option>
            <option value="Jeju">제주</option>
          </select>
Kim, MinGyu's avatar
Kim, MinGyu committed
213

Lee Soobeom's avatar
Lee Soobeom committed
214
215
216
          <select
            name="theme"
            className="border-2 border-sky-400  text-xs h-6 place-self-center"
Kim, MinGyu's avatar
test    
Kim, MinGyu committed
217
            onChange={selectChange}
Lee Soobeom's avatar
Lee Soobeom committed
218
            defaultValue="theme"
Lee Soobeom's avatar
Lee Soobeom committed
219
          >
Lee Soobeom's avatar
Lee Soobeom committed
220
            <option value="theme">테마</option>
Lee Soobeom's avatar
Lee Soobeom committed
221
222
223
224
225
226
227
228
229
230
231
232
233
            <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
234

Lee Soobeom's avatar
Lee Soobeom committed
235
236
          <button
            type="submit"
Lee Soobeom's avatar
Lee Soobeom committed
237
            className="h-6 place-self-center place-self-center border-2 border-sky-400 text-xs text-center transition delay-150 bg-white-400 hover:-translate-y-1 hover:bg-sky-300 duration-300"
Lee Soobeom's avatar
Lee Soobeom committed
238
239
240
241
          >
            글쓰기
          </button>
        </div>
Kim, MinGyu's avatar
Kim, MinGyu committed
242

Lee Soobeom's avatar
Lee Soobeom committed
243
244
245
        <div className="flex flex-col w-full border-y-2 border-sky-500">
          <textarea
            name="title"
Kim, MinGyu's avatar
test    
Kim, MinGyu committed
246
            onChange={stringChange}
Lee Soobeom's avatar
Lee Soobeom committed
247
248
249
250
251
252
253
254
255
            placeholder="제목을 입력해 주세요!"
            className="flex focus:outline-none"
          />
          <div className="flex flex-col mt-1 mb-1 border-t-2 border-sky-200">
            <div className="flex gap-x-2 h-44 overflow-x-auto">
              {imgSrc?.map((img, i) => (
                <img key={i} src={img} width={200} height={200} />
              ))}
            </div>
Lee Soobeom's avatar
Lee Soobeom committed
256
          </div>
Lee Soobeom's avatar
Lee Soobeom committed
257
          <textarea
Kim, MinGyu's avatar
test    
Kim, MinGyu committed
258
            onChange={stringChange}
Lee Soobeom's avatar
Lee Soobeom committed
259
260
261
262
            name="text"
            placeholder="여행 후기를 알려주세요!"
            className="flex h-44 border-t-2 border-sky-200 focus:outline-none "
          />
Lee Soobeom's avatar
Lee Soobeom committed
263
        </div>
Lee Soobeom's avatar
Lee Soobeom committed
264
265
266
267
268
269
270
271
      </form>
      <div className="flex  md:mb-20 justify-center">
        <button
          onClick={GoBack}
          className=" mt-5 h-12 w-40  text-lg border-2 border-sky-500 place-self-center"
        >
          취소
        </button>
Kim, MinGyu's avatar
Kim, MinGyu committed
272
      </div>
Lee Soobeom's avatar
Lee Soobeom committed
273
    </div>
Kim, MinGyu's avatar
Kim, MinGyu committed
274
275
  );
}