Commit 83daf4b0 authored by Lee Soobeom's avatar Lee Soobeom
Browse files

Merge branch 'sb10' into develop

parents 09cfa64e 2a68db77
import React from "react"; import React from "react";
import { BrowserRouter, Route, Routes, Link, Outlet } from "react-router-dom"; import { BrowserRouter, Route, Routes, Link, Outlet } from "react-router-dom";
import "tailwindcss/tailwind.css"; import "tailwindcss/tailwind.css";
import { Login, Signup, Profile } from "./auth"; import { IntoPost } from "./post/intopost";
import { Board } from "./board"; import { Login, Signup } from "./auth";
import { Header, Body } from "./home"; import { Header, Body } from "./home";
import { Board } from "./board";
import Posting from "./post/posting"; import Posting from "./post/posting";
import Layout from "./commons/layout";
export const App = () => { export const App = () => {
return ( return (
<BrowserRouter> <BrowserRouter>
<Routes> <Routes>
<Route element={<Layout />}>
<Route path="login" element={<Login />} /> <Route path="login" element={<Login />} />
<Route path="signup" element={<Signup />} /> <Route path="signup" element={<Signup />} />
<Route path="/" element={<Header />}> <Route path="/" element={<Header />}>
<Route index element={<Body />} /> <Route index element={<Body />} />
<Route path="board" element={<Board />} />
<Route path="posting" element={<Posting />} /> <Route path="posting" element={<Posting />} />
<Route path="profile" element={<Profile />} /> <Route path="board" element={<Board />} />
</Route> <Route path="post/:postId" element={<IntoPost />} />
</Route> </Route>
</Routes> </Routes>
</BrowserRouter> </BrowserRouter>
......
...@@ -7,3 +7,20 @@ export const posting = async (post: PostType) => { ...@@ -7,3 +7,20 @@ export const posting = async (post: PostType) => {
return data; return data;
}; };
export const getData = async () => {
const { data } = await axios.get(`${baseUrl}/posts/`);
return data;
};
export const addCounts = async (_id: string, counts: number) => {
const { data } = await axios.post(`${baseUrl}/posts/${_id}`, {
counts: counts + 1,
});
return data;
};
export const getPostByPostId = async (_id: string) => {
const { data } = await axios.get(`${baseUrl}/posts/${_id}`);
return data;
};
import React, { useState, MouseEvent } from "react"; import React, { useState, MouseEvent, useEffect } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { PostType } from "../types"; import { PostType } from "../types";
import Post from "../post/post"; import Post from "../post/post";
import { postApi } from "../apis";
interface Posts { interface Posts {
posts: PostType[]; posts: PostType[];
} }
export const fakes = [
{
userId: "lsb",
title: "여행가고싶다...",
date: "2022-06-30",
counts: 0,
theme: "surfing",
city: "seoul",
},
{
userId: "lsb",
title: "바다!바다!바다!",
date: "2022-08-01",
counts: 0,
theme: "surfing",
city: "seoul",
},
{
userId: "lsb",
title: "Jeju-island",
date: "2022-9-10",
counts: 0,
theme: "surfing",
city: "seoul",
},
{
userId: "lsb",
title: "마! 부싼 가봤나!",
date: "2022-9-22",
counts: 0,
theme: "surfing",
city: "seoul",
},
{
userId: "lsb",
title: "Daegu",
date: "2022-10-1",
counts: 0,
theme: "ski",
city: "Daegu",
},
{
userId: "lsb",
title: "강원도 감자는 맛있다.",
date: "2022-12-12",
counts: 0,
theme: "camping",
city: "강원도",
},
{
userId: "lsb",
title: "부산남자의 서울여행",
date: "2022-12-25",
counts: 0,
theme: "activity",
city: "seoul",
},
];
export default function BoardPage() { export default function BoardPage() {
const [posts, setPosts] = useState<PostType[]>(fakes); const [posts, setPosts] = useState<PostType[]>();
useEffect(() => {
getDataList();
}, [posts]);
const titleHandleClick = (event: MouseEvent<HTMLButtonElement>) => { const getDataList = async () => {
const res = await postApi.getData();
setPosts(res);
};
const titleHandleClick = async (event: MouseEvent<HTMLButtonElement>) => {
const postId = event.currentTarget.id; const postId = event.currentTarget.id;
const newposts = [...posts]; const newpost = posts?.find((element) => {
newposts.forEach((post) => { if (element._id === postId) {
if (post.userId === postId) { return element;
post.counts = post.counts + 1;
return;
} }
}); });
setPosts(newposts); if (!(newpost?._id === undefined)) {
const post = newpost;
const res = await postApi.addCounts(post._id, post.counts);
// console.log(res);
setPosts(res);
}
}; };
return ( return (
...@@ -104,12 +58,8 @@ export default function BoardPage() { ...@@ -104,12 +58,8 @@ export default function BoardPage() {
<div className="basis-2/12">Clicks</div> <div className="basis-2/12">Clicks</div>
</div> </div>
<div> <div>
{posts.map((post) => ( {posts?.map((post, i) => (
<Post <Post key={i} post={post} handleClick={titleHandleClick} />
key={post.userId}
post={post}
handleClick={titleHandleClick}
/>
))} ))}
</div> </div>
</div> </div>
......
import React, { useState } from "react";
import { useLocation, useParams } from "react-router-dom";
interface PostState {
state: {
title: string;
text: string;
theme: string;
city: string;
date: string;
counts: number;
_id: string;
user: string;
};
}
export function IntoPost() {
const location = useLocation() as PostState;
const post = location.state;
// console.log(post);
return (
<div>
<div>
<div className="flex flex-row">
<div className="flex basis-3/4">제목: {post.title}</div>
<div className="flex basis-1/4">작성자: nickname</div>
</div>
<div className="flex flex-row">
<div className="flex basis-1/4">도시: {post.city}</div>
<div className="flex basis-1/4">테마: {post.theme}</div>
<div className="flex basis-1/4">작성일: {post.date}</div>
<div className="flex basis-1/4">조회수: {post.counts}</div>
</div>
</div>
<div>{post.text}</div>
</div>
);
}
import React, { MouseEventHandler } from "react"; import React, { MouseEventHandler } from "react";
import { Link } from "react-router-dom";
import { PostType } from "../types"; import { PostType } from "../types";
import { IntoPost } from "./intopost";
type Props = { export type Props = {
post: PostType; post: PostType;
handleClick: MouseEventHandler; handleClick: MouseEventHandler;
}; };
// Link opts = state : send obj , useLocation location.state
export default function Post({ handleClick, post }: Props) { export default function Post({ handleClick, post }: Props) {
return ( return (
<div className="flex flex-row h-16 divide-x-2 border-2 border-solid"> <div className="flex flex-row h-16 divide-x-2 border-2 border-solid">
<div className="basis-full"> <div className="basis-full">
<button id={post.userId} onClick={handleClick}> <Link to={`/post/${post._id}`} state={post}>
<button id={post._id} onClick={handleClick}>
{post.title} {post.title}
</button> </button>
</Link>
</div> </div>
<div className="basis-3/12">{post.date}</div> <div className="basis-3/12">{post.date}</div>
<div className="basis-2/12">{post.counts}</div> <div className="basis-2/12">{post.counts}</div>
......
...@@ -2,7 +2,6 @@ import React, { FormEvent, useState } from "react"; ...@@ -2,7 +2,6 @@ import React, { FormEvent, useState } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import isLength from "validator/lib/isLength"; import isLength from "validator/lib/isLength";
import equals from "validator/lib/equals"; import equals from "validator/lib/equals";
// import { addDataList } from "../board/board";
import { catchErrors } from "../helpers"; import { catchErrors } from "../helpers";
import { PostType } from "../types"; import { PostType } from "../types";
import { postApi } from "../apis"; import { postApi } from "../apis";
...@@ -19,8 +18,10 @@ export default function Posting() { ...@@ -19,8 +18,10 @@ export default function Posting() {
text: "", text: "",
theme: "", theme: "",
city: "", city: "",
userId: "", date: "",
user: "",
counts: 0, counts: 0,
_id: "",
}); });
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
...@@ -36,7 +37,6 @@ export default function Posting() { ...@@ -36,7 +37,6 @@ export default function Posting() {
if (postingFormMatch()) { if (postingFormMatch()) {
setLoading(true); setLoading(true);
const res = await postApi.posting(user); const res = await postApi.posting(user);
// addDataList(res);
// console.log("서버연결됬나요", res); // console.log("서버연결됬나요", res);
// console.log("user save"); // console.log("user save");
navigate("/board", { replace: true }); navigate("/board", { replace: true });
......
...@@ -13,12 +13,13 @@ export interface LoginUser { ...@@ -13,12 +13,13 @@ export interface LoginUser {
export interface PostType { export interface PostType {
title: string; title: string;
text?: string; text: string;
theme: string; theme: string;
city: string; city: string;
date?: string; date: string;
counts: number; counts: number;
userId: string; _id: string;
user: string;
} }
export interface SignupUser { export interface SignupUser {
......
...@@ -3,7 +3,8 @@ import isLength from "validator/lib/isLength"; ...@@ -3,7 +3,8 @@ import isLength from "validator/lib/isLength";
import equals from "validator/lib/equals"; import equals from "validator/lib/equals";
import { TypedRequestAuth } from "./auth.controller"; import { TypedRequestAuth } from "./auth.controller";
import { asyncWrap } from "../helpers"; import { asyncWrap } from "../helpers";
import { postDb } from "../db"; import { postDb, userDb } from "../db";
import { TypedRequest } from "../types";
export const postCreate = asyncWrap(async (reqExp, res, next) => { export const postCreate = asyncWrap(async (reqExp, res, next) => {
const req = reqExp as TypedRequestAuth<{ userId: string }>; const req = reqExp as TypedRequestAuth<{ userId: string }>;
...@@ -51,3 +52,41 @@ export const postCreate = asyncWrap(async (reqExp, res, next) => { ...@@ -51,3 +52,41 @@ export const postCreate = asyncWrap(async (reqExp, res, next) => {
return res.json(newPost); return res.json(newPost);
}); });
export const getAllPost = asyncWrap(async (req, res) => {
const posts = await postDb.getPosts();
// console.log(posts);
return res.json(posts);
});
export const addCounts = asyncWrap(async (req, res) => {
// console.log(req.body);
const { postId } = req.params;
const { counts } = req.body as {
counts: number;
};
console.log(postId, counts);
const updateCounts = await postDb.addOneCount(postId, counts);
return res.json(updateCounts);
});
export const userByPostId = (
reqExp: Request,
res: Response,
next: NextFunction,
postId: string
) => {
const req = reqExp as TypedRequest;
req.user = userDb.findUserByPostId(postId);
next();
};
export const getOnePost = asyncWrap(async (req, res) => {
const { postId } = req.params;
const post = await postDb.getPost(postId);
return res.json(post);
});
...@@ -12,3 +12,25 @@ export const createPost = async (post: PostType) => { ...@@ -12,3 +12,25 @@ export const createPost = async (post: PostType) => {
}); });
return newPosting; return newPosting;
}; };
export const getPosts = async () => {
const posts = await Post.find({});
return posts;
};
export const addOneCount = async (_id: string, counts: number) => {
const newCounts = await Post.findOneAndUpdate(
{ _id: _id },
{ counts: counts },
{ new: true }
);
// console.log(newCounts);
return newCounts;
};
export const getPost = async (_id: string) => {
const post = await Post.findOne({ _id: _id });
return post;
};
import bcrypt from "bcryptjs"; import bcrypt from "bcryptjs";
import { Files } from "formidable"; import { Files } from "formidable";
import { ObjectId } from "mongoose"; import { ObjectId } from "mongoose";
import { IUser, User } from "../models"; import { IUser, Post, User } from "../models";
export const createUser = async (user: IUser) => { export const createUser = async (user: IUser) => {
// 비밀번호 암호화 // 비밀번호 암호화
...@@ -27,6 +27,11 @@ export const findUserByEmail = async ( ...@@ -27,6 +27,11 @@ export const findUserByEmail = async (
return user; return user;
}; };
export const findUserByPostId = async (postId: string) => {
const post = await Post.findOne({ _id: postId }).populate("user");
return post?.user;
};
export const getUsers = async () => { export const getUsers = async () => {
const users = await User.find({}); const users = await User.find({});
return users; return users;
......
import { Document, model, Schema, Types } from "mongoose"; import { Document, model, Schema, Types } from "mongoose";
// import { Posting } from ".";
export interface PostType { export interface PostType {
title: string; title: string;
......
import { Request } from "express";
export interface TypedRequest extends Request {
auth: any;
user: any;
files: any;
}
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