From 7285bfbd6128b693f62275bb8fc383b39af519fd Mon Sep 17 00:00:00 2001 From: Lee Soobeom Date: Mon, 25 Jul 2022 10:45:34 +0900 Subject: [PATCH] files muliple uploads --- frontend/src/App.tsx | 3 +- frontend/src/apis/post.api.ts | 26 +++--- frontend/src/board/board.tsx | 4 +- frontend/src/post/editpost.tsx | 122 ++++++++++++++++++++++------- frontend/src/post/intopost.tsx | 105 +++++++++++++++++++------ frontend/src/post/post.tsx | 2 +- frontend/src/post/posting.tsx | 62 +++++++++------ src/controllers/post.controller.ts | 66 +++++++++++----- src/db/post.db.ts | 23 +++--- src/models/fileinfo.model.ts | 2 +- src/models/post.model.ts | 12 +-- src/routes/post.route.ts | 7 +- 12 files changed, 295 insertions(+), 139 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index ced8e42..938be3a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -29,7 +29,6 @@ export const App = () => { } /> } /> } /> - {/* */} { } /> } /> - }/> + } /> diff --git a/frontend/src/apis/post.api.ts b/frontend/src/apis/post.api.ts index be313f7..d8e2a17 100644 --- a/frontend/src/apis/post.api.ts +++ b/frontend/src/apis/post.api.ts @@ -2,7 +2,7 @@ import axios from "axios"; import baseUrl from "./baseUrl"; import { PostType } from "../types"; -export const createImgAndPost = async (formdata: FormData) => { +export const createFileAndPost = async (formdata: FormData) => { const { data } = await axios.post(`${baseUrl}/posts/`, formdata); return data; }; @@ -10,31 +10,31 @@ export const createImgAndPost = async (formdata: FormData) => { export const getData = async () => { const { data } = await axios.get(`${baseUrl}/posts/`); return data; -}; +}; //board + +export const getFileByPostId = async (postId: string) => { + const { data } = await axios.get(`${baseUrl}/posts/files/${postId}`); + return data; +}; // export const getImgData = async (name: string) => { const { data } = await axios.get(`/images/${name}`); return data; }; -export const addCounts = async (_id: string, counts: number) => { - const { data } = await axios.post(`${baseUrl}/posts/${_id}`, { +export const addCounts = async (postId: string, counts: number) => { + const { data } = await axios.post(`${baseUrl}/posts/${postId}`, { counts: counts + 1, }); return data; }; -export const getPostByPostId = async (_id: string) => { - const { data } = await axios.get(`${baseUrl}/posts/${_id}`); - return data; -}; - -export const deletePost = async (_id: string) => { - const { data } = await axios.delete(`${baseUrl}/posts/${_id}`); +export const deletePost = async (postId: string) => { + const { data } = await axios.delete(`${baseUrl}/posts/${postId}`); return data; }; -export const updating = async (post: PostType) => { - const { data } = await axios.put(`${baseUrl}/posts/${post._id}`, post); +export const updateImgAndPost = async (postId: string, formdata: FormData) => { + const { data } = await axios.put(`${baseUrl}/posts/${postId}`, formdata); return data; }; diff --git a/frontend/src/board/board.tsx b/frontend/src/board/board.tsx index b864008..8c4f7a7 100644 --- a/frontend/src/board/board.tsx +++ b/frontend/src/board/board.tsx @@ -13,8 +13,8 @@ export default function BoardPage() { useEffect(() => { getDataList(); - }, [posts]); - + }, []); + // posts const getDataList = async () => { const res = await postApi.getData(); setPosts(res); diff --git a/frontend/src/post/editpost.tsx b/frontend/src/post/editpost.tsx index d99ad95..67a03b0 100644 --- a/frontend/src/post/editpost.tsx +++ b/frontend/src/post/editpost.tsx @@ -1,4 +1,4 @@ -import React, { FormEvent, useState } from "react"; +import React, { FormEvent, useState, useEffect } from "react"; import { useNavigate, useLocation } from "react-router-dom"; import isLength from "validator/lib/isLength"; import equals from "validator/lib/equals"; @@ -6,12 +6,16 @@ import { catchErrors } from "../helpers"; import { PostType } from "../types"; import { postApi } from "../apis"; import { PostState } from "./intopost"; +import { FileType } from "./intopost"; export function EditPost() { const [city, setCity] = useState("city"); const [theme, setTheme] = useState("theme"); const [title, setTitle] = useState(""); const [text, setText] = useState(""); + const [file, setFile] = useState(); + const [imgSrc, setImgSrc] = useState(); + const [filesList, setFilesList] = useState(); const navigate = useNavigate(); const location = useLocation() as PostState; @@ -24,7 +28,7 @@ export function EditPost() { city: post.city, date: post.date, user: post.user, - counts: 0, + counts: post.counts, _id: post._id, }); @@ -33,21 +37,51 @@ export function EditPost() { const [disabled, setDisabled] = useState(false); const [success, setSuccess] = useState(false); - async function reWriteSubmit(event: FormEvent) { - event.preventDefault(); - try { - setError(""); + useEffect(() => { + getFilesList(post._id); + }, []); - console.log("user data", user); + const imgArr = new Array(); + + const getFilesList = async (postId: string) => { + const res = await postApi.getFileByPostId(postId); //_id는 req.params에 항상 같이 보낸다 + setFilesList(res); + }; - if (postingFormMatch(user) === true) { - setLoading(true); - const res = await postApi.updating(user); + const updateImg2Db = 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) { + const res = await postApi.updateImgAndPost(user._id, formdata); + } else { + for (var i = 0; i < filelist.length; i++) { + formdata.append("picture", filelist?.[i]); + } + const res = await postApi.updateImgAndPost(user._id, formdata); + } + }; - console.log("clear", res); - navigate("/board", { replace: true }); - setSuccess(true); + async function reWriteSubmit(event: FormEvent) { + event.preventDefault(); + try { + if (confirm("게시물을 수정하시겠습니까?") == true) { setError(""); + // console.log("user data", user); + if (postingFormMatch(user) === true) { + setLoading(true); + if (file) { + const res = updateImg2Db(file); + // console.log(res); + } + navigate("/board", { replace: true }); + setSuccess(true); + setError(""); + } + } else { + return false; } } catch (error) { console.log("에러발생"); @@ -57,17 +91,46 @@ export function EditPost() { } } + const handleInputPic = async (event: React.ChangeEvent) => { + const maxImg = 10; + const { files } = event.target; + + if (!(files === null)) { + setFile(files); + } + + 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); + }; + } + } else { + alert(`사진은 최대 ${maxImg}장까지 업로드 가능합니다!`); + } + } + }; + function postingFormMatch(user: PostType) { if (!isLength(user.title ?? "", { min: 1 })) { setError("제목을 입력해 주세요."); + alert("제목을 입력해 주세요."); return false; } else if (!isLength(user.text ?? "", { min: 1 })) { + alert("내용을 입력해 주세요."); setError("내용을 입력해 주세요."); return false; - } else if (equals(city, "city")) { + } else if (equals(user.city, "city")) { + alert("도시를 선택해 주세요."); setError("도시를 선택해 주세요."); return false; - } else if (equals(theme, "theme")) { + } else if (equals(user.theme, "theme")) { + alert("테마를 선택해 주세요."); setError("테마를 선택해 주세요."); return false; } else { @@ -119,7 +182,7 @@ export function EditPost() { id="files" type="file" multiple - // onChange={handleInputPic} + onChange={handleInputPic} className="hidden" />