Commit 02b43c26 authored by Yoon, Daeki's avatar Yoon, Daeki 😅
Browse files

Merge branch 'develop' into main-dev

parents 52a72c18 d9047c9a
...@@ -42,6 +42,8 @@ export default function Profile() { ...@@ -42,6 +42,8 @@ export default function Profile() {
console.log("profile in submit", profile); console.log("profile in submit", profile);
const formdata = new FormData(); const formdata = new FormData();
profile.avatar && formdata.append("avatar", profile.avatar); profile.avatar && formdata.append("avatar", profile.avatar);
console.log(profile.avatar);
formdata.append("name", profile.name); formdata.append("name", profile.name);
console.log("form data", formdata.get("avatar")); console.log("form data", formdata.get("avatar"));
profileApi.profileUpload(formdata); profileApi.profileUpload(formdata);
......
...@@ -20,7 +20,7 @@ export default function BoardPage() { ...@@ -20,7 +20,7 @@ export default function BoardPage() {
const navigate = useNavigate(); const navigate = useNavigate();
const { user } = useAuth(); const { user } = useAuth();
console.log("get newPost Info", newPost); // console.log("get newPost Info", newPost);
const setNewPosts = (newpost: PostType) => { const setNewPosts = (newpost: PostType) => {
const postArr = posts?.splice(-1, 0, newPost); const postArr = posts?.splice(-1, 0, newPost);
......
...@@ -12,67 +12,75 @@ export default function Header() { ...@@ -12,67 +12,75 @@ export default function Header() {
const newvalue = e.target.value; const newvalue = e.target.value;
setSearch(newvalue); setSearch(newvalue);
}; };
// bg-gradient-to-t from-sky-200
return ( return (
<div className="flex flex-col md:px-56 "> <div className="flex flex-col ">
<div className="flex flex-col-reverse pt-3 pb-12 border-b-2 border-sky-200 bg-gradient-to-t from-sky-200"> <div className="flex flex-col md:px-56 z-10 ">
<div className="flex mt-5 justify-between pr-3"> <div className="flex flex-col-reverse pt-3 pb-12 ">
<button className="ml-3 shrink-0 md:text-2xl"> <div className="flex mt-5 justify-between pr-3">
<Link to="/" className="hover:text-sky-300 active:text-purple-500"> <button className="ml-3 shrink-0 md:text-2xl">
Travel Report <Link
</Link> to="/"
</button> className="hover:text-sky-300 active:text-purple-500 text-white"
<div className="flex h-12">
<input
className="ml-10 focus:outline-none focus:border-y-4 focus:border-l-4 focus:border-sky-500 w-3/5 md:w-4/5 border-y-4 border-l-4 border-sky-300 pl-9 rounded-l-full focus:border-0"
onChange={handleChange}
/>
<button className="whitespace-nowrap bg-white border-y-4 border-r-4 border-sky-500 rounded-r-full pr-4">
검색
</button>
</div>
</div>
<div className="flex justify-end ">
{user.isLoggedIn ? (
<div className="flex text-xs">
<Link to="/profile" className="mr-2 ">
프로필
</Link>
<div className="border-0 border-r-2 border-black "></div>
{user.role === "admin" ? <Link to={"/admin"}>어드민</Link> : null}
<button
className="ml-2 text-xs"
onClick={() => {
logout();
}}
> >
로그아웃 Travel Report
</Link>
</button>
<div className="flex h-12">
<input
className="ml-10 focus:outline-none focus:border-y-4 focus:border-l-4 focus:border-sky-500 w-3/5 md:w-4/5 border-y-4 border-l-4 border-sky-300 pl-9 rounded-l-full focus:border-0"
onChange={handleChange}
/>
<button className="whitespace-nowrap bg-white border-y-4 border-r-4 border-sky-500 rounded-r-full pr-4">
검색
</button> </button>
</div> </div>
) : ( </div>
<button className="shrink-0 "> <div className="flex justify-end ">
{user.isLoggedIn ? (
<div className="flex text-xs">
<Link to="/profile" className="mr-2 ">
프로필
</Link>
<div className="border-0 border-r-2 border-black "></div>
{user.role === "admin" ? (
<Link to={"/admin"}>어드민</Link>
) : null}
<button
className="ml-2 text-xs"
onClick={() => {
logout();
}}
>
로그아웃
</button>
</div>
) : (
<button className="shrink-0 ">
<Link
className="hover:text-sky-300 focus:text-purple-500 text-xs grid items-center"
to="/login"
>
로그인
</Link>
</button>
)}
<div className="ml-2 border-0 border-r-2 border-black "></div>
<div></div>
<button className="shrink-0 mr-3 text-xs ">
<Link <Link
className="hover:text-sky-300 focus:text-purple-500 text-xs grid items-center" to="/board"
to="/login" className="hover:text-sky-300 focus:text-purple-500 mx-2 grid items-center"
> >
로그인 게시판
</Link> </Link>
</button> </button>
)} </div>
<div className="ml-2 border-0 border-r-2 border-black "></div>
<div></div>
<button className="shrink-0 mr-3 text-xs ">
<Link
to="/board"
className="hover:text-sky-300 focus:text-purple-500 mx-2 grid items-center"
>
게시판
</Link>
</button>
</div> </div>
</div>
<Outlet /> <Outlet />
</div>
<div className="bg-center z-0 absolute w-full h-44 overflow-hidden object-cover object-center bg-[url('https://blog.kakaocdn.net/dn/b5qUMZ/btqN9NEYqcW/ZuZmPcI4u7bdK89shT3RL1/img.jpg')]"></div>
</div> </div>
); );
} }
...@@ -15,7 +15,7 @@ export default function Theme({ handleClick }: ThemeProps) { ...@@ -15,7 +15,7 @@ export default function Theme({ handleClick }: ThemeProps) {
}; };
return ( return (
<div className="overflow-x-auto flex rounded py-2 md:p-2 border-b-2 divide-x-2"> <div className="overflow-x-auto flex rounded py-2 md:p-4 shadow-lg divide-x-2 bg-white">
<div onClick={() => clickActive(1)}> <div onClick={() => clickActive(1)}>
<button <button
id={"surfing"} id={"surfing"}
......
...@@ -7,15 +7,16 @@ type CityProps = { ...@@ -7,15 +7,16 @@ type CityProps = {
export default function Citylist({ handleClick }: CityProps) { export default function Citylist({ handleClick }: CityProps) {
const [active, setActive] = useState(0); const [active, setActive] = useState(0);
const onactive = "text-start px-5 py-2 underline whitespace-nowrap"; const onactive =
const offactive = "text-start px-5 py-2 whitespace-nowrap"; "text-start px-5 py-2 whitespace-nowrap w-full border-b-4 md:border-b-0 md:border-r-4 border-sky-500";
const offactive = "text-start px-5 py-2 whitespace-nowrap w-full ";
const clickActive = (a: number) => { const clickActive = (a: number) => {
setActive(a); setActive(a);
}; };
return ( return (
<div className="overflow-auto w-full flex flex-row md:flex-col md:mr-24 bg-sky-100"> <div className="overflow-auto w-full flex flex-row md:flex-col md:mr-24 bg-red-100 shadow-lg">
<div className="text-start px-5 py-2 bg-white whitespace-nowrap"> <div className="text-start px-5 py-2 bg-white whitespace-nowrap">
도시 도시
</div> </div>
......
...@@ -39,7 +39,7 @@ export function EditPost() { ...@@ -39,7 +39,7 @@ export function EditPost() {
const imgArr = new Array(); const imgArr = new Array();
// console.log("post.file", post.file); console.log("post.file", post.file);
const updateImg2Db = async (filelist: FileList | undefined) => { const updateImg2Db = async (filelist: FileList | undefined) => {
const formdata = new FormData(); const formdata = new FormData();
...@@ -49,11 +49,15 @@ export function EditPost() { ...@@ -49,11 +49,15 @@ export function EditPost() {
formdata.append("city", user.city); formdata.append("city", user.city);
if (filelist === undefined) { if (filelist === undefined) {
const res = await postApi.updateImgAndPost(user._id, formdata); const res = await postApi.updateImgAndPost(user._id, formdata);
return res;
} else { } else {
for (var i = 0; i < filelist.length; i++) { for (var i = 0; i < filelist.length; i++) {
formdata.append("picture", filelist?.[i]); formdata.append("picture", filelist?.[i]);
} }
console.log("one file update before");
const res = await postApi.updateImgAndPost(user._id, formdata); const res = await postApi.updateImgAndPost(user._id, formdata);
console.log("one file update", res);
return res;
} }
}; };
...@@ -66,7 +70,11 @@ export function EditPost() { ...@@ -66,7 +70,11 @@ export function EditPost() {
setLoading(true); setLoading(true);
const updateRes = await updateImg2Db(file); const updateRes = await updateImg2Db(file);
navigate("/board", { replace: true, state: updateRes }); // console.log("find newfilename", updateRes);
navigate(
{ pathname: `/post/${post._id}` },
{ replace: true, state: updateRes }
);
setSuccess(true); setSuccess(true);
setError(""); setError("");
......
...@@ -9,23 +9,28 @@ export interface PostState { ...@@ -9,23 +9,28 @@ export interface PostState {
} }
export function IntoPost() { export function IntoPost() {
const [posts, setPosts] = useState<PostType>();
const location = useLocation() as PostState; const location = useLocation() as PostState;
const post = location.state; const post = location.state;
const navigate = useNavigate(); const navigate = useNavigate();
console.log("user info", post.user);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [error, setError] = useState(""); const [error, setError] = useState("");
const [addSuccess, setAddSuccess] = useState(false); const [addSuccess, setAddSuccess] = useState(false);
const [delSuccess, setDelSuccess] = useState(false); const [delSuccess, setDelSuccess] = useState(false);
// console.log("post.file", post.file);
useEffect(() => {
setPosts(post);
}, []);
const handleDeleteClick = async (event: MouseEvent<HTMLButtonElement>) => { const handleDeleteClick = async (event: MouseEvent<HTMLButtonElement>) => {
try { try {
if (confirm("삭제하시겠습니까?") == true) { if (confirm("삭제하시겠습니까?") == true) {
const postId = event.currentTarget.id; const postId = event.currentTarget.id;
const res = await postApi.deletePost(postId); const res = await postApi.deletePost(postId);
navigate("/board", { replace: true }); navigate("/board");
console.log("delete post", res); console.log("delete post", res);
} else { } else {
return false; return false;
...@@ -40,41 +45,41 @@ export function IntoPost() { ...@@ -40,41 +45,41 @@ export function IntoPost() {
<div className="flex flex-col"> <div className="flex flex-col">
<div className="flex h-8 gap-x-1 place-content-end place-items-center"> <div className="flex h-8 gap-x-1 place-content-end place-items-center">
<button <button
id={post._id} id={posts?._id}
onClick={handleDeleteClick} onClick={handleDeleteClick}
className=" whitespace-nowrap flex border-2 border-sky-100 place-self-center h-6 w-8 text-xs text-center transition delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-red-300 duration-300" className=" whitespace-nowrap flex border-2 border-sky-100 place-self-center h-6 w-8 text-xs text-center transition delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-red-300 duration-300"
> >
삭제 삭제
</button> </button>
<Link to="/edit" state={post}> <Link to="/edit" state={posts}>
<button className="whitespace-nowrap flex border-2 border-sky-100 place-self-center h-6 w-8 text-xs transition delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-sky-300 duration-300"> <button className="whitespace-nowrap flex border-2 border-sky-100 place-self-center h-6 w-8 text-xs transition delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-sky-300 duration-300">
수정 수정
</button> </button>
</Link> </Link>
</div> </div>
<div className="flex h-10 border-t-2 border-sky-500 items-center font-semibold"> <div className="flex h-10 border-t-2 border-sky-500 items-center font-semibold">
{post.title} {posts?.title}
</div> </div>
<div className="flex h-10 items-center border-t-2 border-sky-200 md:flex-row justify-between bg-slate-50 text-sm"> <div className="flex h-10 items-center border-t-2 border-sky-200 md:flex-row justify-between bg-slate-50 text-sm">
<div className="flex whitespace-nowrap pr-5 "> <div className="flex whitespace-nowrap pr-5 ">
작성자: {post.user.name} 작성자: {posts?.user.name}
</div> </div>
<div className="flex divide-x divide-slate-300 "> <div className="flex divide-x divide-slate-300 ">
<div className="flex basis-1/2 whitespace-nowrap px-2"> <div className="flex basis-1/2 whitespace-nowrap px-2">
작성일 : {post.date.slice(0, 10)} 작성일 : {posts?.date.slice(0, 10)}
</div> </div>
<div className="flex whitespace-nowrap px-2"> {post.city}</div> <div className="flex whitespace-nowrap px-2"> {posts?.city}</div>
<div className="flex whitespace-nowrap px-2"> {post.theme}</div> <div className="flex whitespace-nowrap px-2"> {posts?.theme}</div>
<div className="flex whitespace-nowrap px-2"> <div className="flex whitespace-nowrap px-2">
조회수 : {post.counts} 조회수 : {posts?.counts}
</div> </div>
</div> </div>
</div> </div>
<div className="flex border-t-2 border-sky-200 h-44 p-2 overflow-auto mb-5 "> <div className="flex border-t-2 border-sky-200 h-44 p-2 overflow-auto mb-5 ">
{post.file?.map((file, i) => ( {posts?.file?.map((file, i) => (
<img <img
key={i} key={i}
src={"http://localhost:3000/images/" + file.newfilename} src={"http://localhost:3000/images/" + file.newfilename}
...@@ -83,7 +88,7 @@ export function IntoPost() { ...@@ -83,7 +88,7 @@ export function IntoPost() {
/> />
))} ))}
</div> </div>
<div className="border-b-2 border-sky-500 h-44 mb-10">{post.text}</div> <div className="border-b-2 border-sky-500 h-44 mb-10">{posts?.text}</div>
</div> </div>
); );
} }
...@@ -24,6 +24,7 @@ export default function Posting() { ...@@ -24,6 +24,7 @@ export default function Posting() {
user: { user: {
_id: "", _id: "",
name: "", name: "",
avatar: "",
}, },
counts: 0, counts: 0,
_id: "", _id: "",
......
...@@ -23,6 +23,7 @@ export interface PostType { ...@@ -23,6 +23,7 @@ export interface PostType {
user: { user: {
_id: string; _id: string;
name: string; name: string;
avatar: string;
}; };
file: [ file: [
{ {
......
...@@ -197,7 +197,7 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => { ...@@ -197,7 +197,7 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => {
console.log("check files", files); console.log("check files", files);
if (files.picture === undefined || files.picture === null) { if (files.picture === undefined || files.picture === null) {
const postRes2 = await postDb.updatePostRow( const postRes1 = await postDb.updatePostRow(
{ {
title, title,
text, text,
...@@ -207,7 +207,8 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => { ...@@ -207,7 +207,8 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => {
}, },
postId postId
); );
console.log("no files update", postRes2); console.log("no files update", postRes1);
return res.json(postRes1);
} else { } else {
if (Array.isArray(files.picture)) { if (Array.isArray(files.picture)) {
const oldFilesId = await postDb.getFilesByPostId(postId); const oldFilesId = await postDb.getFilesByPostId(postId);
...@@ -273,16 +274,29 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => { ...@@ -273,16 +274,29 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => {
} }
} }
} }
console.log("all fileId", fileIdArr);
//post정보 + file정보 update
const postRes2 = await postDb.updatePostRow(
{
title,
text,
theme,
city,
date: Date.now(),
file: fileIdArr,
},
postId
);
console.log("plural files update", postRes2);
return res.json(postRes2);
} else { } else {
const oldFilesId = await postDb.getFilesByPostId(postId); const oldFilesId = await postDb.getFilesByPostId(postId);
if (!(oldFilesId === undefined)) { if (!(oldFilesId === undefined)) {
for (var i = 0; i < oldFilesId?.length; i++) { const name = await postDb.getOriginalFileName(oldFilesId[0]);
const name = await postDb.getOriginalFileName( if (!(name === undefined)) {
oldFilesId[i] oldSet.add(name);
);
if (!(name === undefined)) {
oldSet.add(name);
}
} }
} }
console.log("OldSet", oldSet); console.log("OldSet", oldSet);
...@@ -296,6 +310,8 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => { ...@@ -296,6 +310,8 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => {
//유지, 삭제, 추가 구분하기 //유지, 삭제, 추가 구분하기
const trdPart = SubTract(oldSet, newSet); const trdPart = SubTract(oldSet, newSet);
console.log("add part", trdPart.add);
//삭제 //삭제
for (var i = 0; i < trdPart.drop.length; i++) { for (var i = 0; i < trdPart.drop.length; i++) {
const dropRes = await postDb.deleteFileByName( const dropRes = await postDb.deleteFileByName(
...@@ -308,34 +324,34 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => { ...@@ -308,34 +324,34 @@ export const updateOnePost = asyncWrap(async (reqExp, res) => {
const originalfilename = files.picture.originalFilename; const originalfilename = files.picture.originalFilename;
const newfilename = files.picture.newFilename; const newfilename = files.picture.newFilename;
const filepath = files.picture.filepath; const filepath = files.picture.filepath;
for (var j = 0; j < trdPart.add.length; j++) { if (originalfilename === trdPart.add[0]) {
const check = trdPart.add[j]; const addRes = await postDb.createFilesRow(
if (originalfilename === check) { originalfilename,
const addRes = await postDb.createFilesRow( newfilename,
originalfilename, filepath
newfilename, );
filepath
);
fileIdArr.push(addRes._id); fileIdArr.push(addRes._id);
}
} }
console.log("all fileId", fileIdArr);
//post정보 + file정보 update
const postRes3 = await postDb.updatePostRow(
{
title,
text,
theme,
city,
date: Date.now(),
file: fileIdArr,
},
postId
);
console.log("singular file update", postRes3);
return res.json(postRes3);
} }
} }
console.log("all fileId", fileIdArr);
//post정보 + file정보 update
const postRes1 = await postDb.updatePostRow(
{
title,
text,
theme,
city,
date: Date.now(),
file: fileIdArr,
},
postId
);
} }
} }
} }
......
...@@ -2,9 +2,9 @@ import { userDb } from "../db"; ...@@ -2,9 +2,9 @@ import { userDb } from "../db";
import { asyncWrap } from "../helpers/asyncWrap"; import { asyncWrap } from "../helpers/asyncWrap";
import { Request } from "express"; import { Request } from "express";
import formidable from "formidable"; import formidable from "formidable";
import { ObjectId } from "mongoose"; import fs from "fs/promises";
import fs from "fs";
import { TypedRequest } from "../types"; import { TypedRequest } from "../types";
import { FileInfo, IUser, User } from "../models";
export interface TypedRequestAuth<T> extends Request { export interface TypedRequestAuth<T> extends Request {
auth: T; auth: T;
...@@ -36,7 +36,27 @@ export const updateProfile = asyncWrap(async (reqExp, res) => { ...@@ -36,7 +36,27 @@ export const updateProfile = asyncWrap(async (reqExp, res) => {
const { name } = req.body; const { name } = req.body;
const { avatar }: { avatar: formidable.File } = req.files; const { avatar }: { avatar: formidable.File } = req.files;
const user = await userDb.updateProfile(userId, name, avatar); const duplicate = await FileInfo.findOne({
originalfilename: avatar.originalFilename,
}); // 같은 사진이 DB에 있는지 확인
console.log(duplicate);
if (!duplicate) {
//만약 같은 사진이 DB안에 존재하지 않을 경우
const user = await userDb.updateProfile(userId, name, avatar);
res.json(user);
} else {
// 같은 사진이 DB안에 존재할 경우
await fs.unlink(avatar.filepath);
// await FileInfo.deleteOne({ _id: user?.avatar }); // 덮기 전의 FileInfo 삭제
const user = await User.findById(userId);
if (user !== null) {
user.avatar = duplicate._id;
await user.save();
}
}
// if (!Array.isArray(file.avatar)) { // if (!Array.isArray(file.avatar)) {
// //파일 좁히기 중 // //파일 좁히기 중
...@@ -58,8 +78,6 @@ export const updateProfile = asyncWrap(async (reqExp, res) => { ...@@ -58,8 +78,6 @@ export const updateProfile = asyncWrap(async (reqExp, res) => {
// } // }
// } // }
// } // }
res.json(user);
}); });
export const deleteUser = asyncWrap(async (reqExp, res) => { export const deleteUser = asyncWrap(async (reqExp, res) => {
......
...@@ -38,7 +38,6 @@ export const getPosts = async () => { ...@@ -38,7 +38,6 @@ export const getPosts = async () => {
.populate("file") .populate("file")
.populate("user") .populate("user")
.sort({ date: -1 }); .sort({ date: -1 });
console.log("file nickname", posts);
return posts; return posts;
}; };
...@@ -64,7 +63,7 @@ export const updatePostRow = async (post: PostType, postId: string) => { ...@@ -64,7 +63,7 @@ export const updatePostRow = async (post: PostType, postId: string) => {
file: post.file, file: post.file,
}, },
{ new: true } { new: true }
); ).populate("file");
return newPost; return newPost;
}; };
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment