Skip to content
Snippets Groups Projects
Commit ec34e755 authored by Gwangbin's avatar Gwangbin
Browse files

Feat: Add My Page

parent 2efc2351
Branches
No related tags found
No related merge requests found
...@@ -20,8 +20,9 @@ ...@@ -20,8 +20,9 @@
|---|---|---|---| |---|---|---|---|
|POST|/article|{<br>"title": string,<br>"content": string,<br>"img": string[],<br>"keyword": string,<br>"latitiude":number,<br>"longitude": number<br>}|게시글 작성 요청| |POST|/article|{<br>"title": string,<br>"content": string,<br>"img": string[],<br>"keyword": string,<br>"latitiude":number,<br>"longitude": number<br>}|게시글 작성 요청|
|DELETE|/article/[id]||특정 게시글 삭제 요청| |DELETE|/article/[id]||특정 게시글 삭제 요청|
|GET|/article||전체 게시글 요청| |GET|/article?keyword=?criteria=||조건에 맞는 전체 게시글 요청|
|GET|/article/[id]||특정 게시글 요청| |GET|/article/[id]||특정 게시글 요청|
|GET|/article/user/[userId]||특정 사용자의 게시글 요청|
|GET|/article/search/[keyword]||키워드로 게시글 검색 요청| |GET|/article/search/[keyword]||키워드로 게시글 검색 요청|
|GET|/article/sort/[crit]||게시글 정렬 요청| |GET|/article/sort/[crit]||게시글 정렬 요청|
|POST|/article/[id]/comment|{<br>"content": string<br>}|댓글 작성 요청| |POST|/article/[id]/comment|{<br>"content": string<br>}|댓글 작성 요청|
......
...@@ -61,7 +61,8 @@ router.get("/", async (req, res) => { ...@@ -61,7 +61,8 @@ router.get("/", async (req, res) => {
if (!req.session.sessionid) { if (!req.session.sessionid) {
console.log("No session"); console.log("No session");
} }
const articles = await articleService.findAllArticle();
const articles = await articleService.findArticles(req.query.keyword ? req.query.keyword : null, req.query.criteria);
articles.forEach((article) => { articles.forEach((article) => {
article.imageUrls.forEach( article.imageUrls.forEach(
(urls) => { (urls) => {
...@@ -82,7 +83,9 @@ router.get("/:id", async (req, res) => { ...@@ -82,7 +83,9 @@ router.get("/:id", async (req, res) => {
} }
const articles = await articleService.findArticleById(req.params.id); const articles = await articleService.findArticleById(req.params.id);
res.send(JSON.stringify(articles)); res.send(JSON.stringify(articles));
}).delete("/:id", async (req, res) => { });
router.delete("/:id", async (req, res) => {
if (!req.session.sessionid) { if (!req.session.sessionid) {
console.log("No session - del"); console.log("No session - del");
} }
...@@ -90,6 +93,14 @@ router.get("/:id", async (req, res) => { ...@@ -90,6 +93,14 @@ router.get("/:id", async (req, res) => {
res.send(JSON.stringify(articles)); res.send(JSON.stringify(articles));
}); });
router.get("/user/:id", async (req, res) => {
if (!req.session.sessionid) {
console.log("No session");
}
const articles = await articleService.findArticlesByAuthor(req.params.id);
res.send(JSON.stringify(articles));
});
router.post("/:id/comment", async (req, res) => { router.post("/:id/comment", async (req, res) => {
if (!req.session.sessionid) { if (!req.session.sessionid) {
console.log("No session"); console.log("No session");
...@@ -120,28 +131,4 @@ router.put("/:id/like", async (req, res) => { ...@@ -120,28 +131,4 @@ router.put("/:id/like", async (req, res) => {
res.send(JSON.stringify(articles)); res.send(JSON.stringify(articles));
}); });
router.get("/search/:keyword", async (req, res) => {
if (req.session.sessionid) {
console.log("세션 O")
}
else {
console.log("세션 X")
}
console.log(req.params.keyword)
const articles = await articleService.findArticlesByKeyword(req.params.keyword);
res.send(JSON.stringify(articles));
});
router.get("/sort/:crit", async (req, res) => {
if (req.session.sessionid) {
console.log("세션 O")
}
else {
console.log("세션 X")
}
console.log(req.params.crit)
const articles = await articleService.findAllAndSortArticle(req.params.crit);
res.send(JSON.stringify(articles));
});
export default router; export default router;
...@@ -11,16 +11,68 @@ const articleService = { ...@@ -11,16 +11,68 @@ const articleService = {
} }
}, },
async findAllArticle() { async findArticles(keyword, criteria) {
if (criteria === "like") {
try {
const agg =
await Article.aggregate(
[
{
"$project":
{
"title": 1,
"content": 1,
"imageUrls": 1,
"author": 1,
"keyword": 1,
"latitude": 1,
"longitude": 1,
"comments": 1,
"likes": 1,
"createdAt": 1,
"length": { "$size": "$likes" }
}
},
{ "$sort": { "length": -1 } },
]
)
let articles = null;
const result = await Article.populate(agg, { path: "author" }).then(
(res) => { return Article.populate(res, { path: "likes" }) }
).then(
(res) => { articles = res; }
);
return articles;
} catch (err) {
throw err;
}
}
else {
if (keyword === null) {
try { try {
const articles = await Article const articles = await Article
.find({}) .find({})
.populate('author') .populate('author')
.populate('likes'); .populate('likes')
.sort({ "createdAt": -1 });
return articles; return articles;
} catch (err) { } catch (err) {
throw err; throw err;
} }
}
else {
try {
const articles = await Article
.find({ keyword: keyword })
.populate('author')
.populate('likes')
.sort({ "createdAt": -1 });
return articles;
} catch (err) {
throw err;
}
}
}
}, },
async findAllAndSortArticle(criteria) { async findAllAndSortArticle(criteria) {
...@@ -99,7 +151,8 @@ const articleService = { ...@@ -99,7 +151,8 @@ const articleService = {
const articles = await Article const articles = await Article
.find({ author: authorId }) .find({ author: authorId })
.populate('author') .populate('author')
.populate('likes'); .populate('likes')
.sort({ "createdAt": -1 });
return articles; return articles;
} catch (err) { } catch (err) {
throw err; throw err;
...@@ -111,7 +164,8 @@ const articleService = { ...@@ -111,7 +164,8 @@ const articleService = {
const articles = await Article const articles = await Article
.find({ keyword: keyword }) .find({ keyword: keyword })
.populate('author') .populate('author')
.populate('likes'); .populate('likes')
.sort({ "createdAt": -1 });
return articles; return articles;
} catch (err) { } catch (err) {
throw err; throw err;
......
...@@ -15,23 +15,27 @@ router.post('/login', async (req, res) => { ...@@ -15,23 +15,27 @@ router.post('/login', async (req, res) => {
const expires = moment().add(sessionTime.toString(), 'm').toDate(); const expires = moment().add(sessionTime.toString(), 'm').toDate();
// 정보가 없다면 회원 가입 (강제?) // 정보가 없다면 회원 가입 (강제?)
const user = await userService.existsByEmail(req.body.email); const user = await userService.findUserByEmail(req.body.email);
let userId = null;
if (!user) { // 유저가 없다면 회원 가입 후 세션 생성 if (!user) { // 유저가 없다면 회원 가입 후 세션 생성
let userProfilePicture = req.body.picture || null; let userProfilePicture = req.body.picture || null;
await userService.createUser({ userId = await userService.createUser({
nickname: req.body.name, nickname: req.body.name,
email: req.body.email, email: req.body.email,
google: { google: {
id: req.body.sub, id: req.body.sub,
profileUrl: userProfilePicture, profileUrl: userProfilePicture,
}, },
}); }).then((user) => user._id);
console.log('new user saved!') console.log('new user saved!');
}
else {
userId = user._id;
} }
console.log('login done') console.log('login done');
req.session.sessionid = req.body; //프론트에서 건네받은 JWT로 세션 생성 req.session.sessionid = req.body; //프론트에서 건네받은 JWT로 세션 생성
res.cookie('name', JSON.stringify({ name: req.body.name, email: req.body.email, id: req.body.sub }), { expires }); //사용자 이름 쿠키 res.cookie('name', JSON.stringify({ name: req.body.name, email: req.body.email, id: userId }), { expires }); //사용자 이름 쿠키
res.send(req.body.name); // 이름 보내서 뭐하게? res.send(req.body.name); // 이름 보내서 뭐하게?
......
...@@ -14,6 +14,7 @@ import PostRead from "./pages/PostRead.js" ...@@ -14,6 +14,7 @@ import PostRead from "./pages/PostRead.js"
import Header from "./components/Header.js"; import Header from "./components/Header.js";
import axios from 'axios'; import axios from 'axios';
import MyPage from "./pages/MyPage.js";
axios.defaults.withCredentials = true; axios.defaults.withCredentials = true;
function App() { function App() {
...@@ -71,6 +72,7 @@ function App() { ...@@ -71,6 +72,7 @@ function App() {
<Route path="/search" element={<Search />}></Route> <Route path="/search" element={<Search />}></Route>
<Route path="/postwrite" element={<PostWrite />}></Route> <Route path="/postwrite" element={<PostWrite />}></Route>
<Route path="/post/:id" element={<PostRead />}></Route> <Route path="/post/:id" element={<PostRead />}></Route>
<Route path="/mypage" element={<MyPage />}></Route>
</Routes> </Routes>
</UserContext.Provider> </UserContext.Provider>
{/* <Footer/> */} {/* <Footer/> */}
......
...@@ -47,7 +47,7 @@ function Header({ cookie }) { ...@@ -47,7 +47,7 @@ function Header({ cookie }) {
<img className="logo_image" alt="logo" src={logo} /> <img className="logo_image" alt="logo" src={logo} />
</ButtonLink> </ButtonLink>
<ul> <ul>
<p>{cookie ? `${cookie.name}님, 환영합니다` : '로그인하세요.'}</p> <p>{cookie ? (<Link to="/mypage" style={{ textDecoration: "none", color: "black" }}>{cookie.name}, 환영합니다</Link>) : '로그인하세요.'}</p>
<ul className="menu_list"> <ul className="menu_list">
<li><ButtonLink link='/'>Home</ButtonLink></li> <li><ButtonLink link='/'>Home</ButtonLink></li>
<li><ButtonLink link='/search'>검색</ButtonLink></li> <li><ButtonLink link='/search'>검색</ButtonLink></li>
......
...@@ -58,7 +58,7 @@ function SearchMapByKeyword({ loc, setLoc }) { ...@@ -58,7 +58,7 @@ function SearchMapByKeyword({ loc, setLoc }) {
return ( return (
<div className="UserInput"> <div className="UserInput">
<input onChange={handleInput} /> <input onChange={handleInput} />
<button onClick={() => handleSearch()} style={{ width: '50px' }}>검색</button><br></br> <button onClick={() => handleSearch()} style={{ width: '50px', height: '30px' }}>검색</button><br></br>
<div style={{ display: 'flex' }}> <div style={{ display: 'flex' }}>
<Map // 지도를 표시할 Container <Map // 지도를 표시할 Container
center={info && info.position || defaultCenter} center={info && info.position || defaultCenter}
......
...@@ -34,7 +34,7 @@ function Main() { ...@@ -34,7 +34,7 @@ function Main() {
.then((response) => { .then((response) => {
console.log(response) console.log(response)
setArticleList(response.data) setArticleList(response.data)
}) });
}, []); }, []);
const handleSortChange = (event) => { const handleSortChange = (event) => {
...@@ -61,17 +61,9 @@ function Main() { ...@@ -61,17 +61,9 @@ function Main() {
</div>); </div>);
} }
async function requestLoadArticle() {
const response = await axios({
url: 'http://localhost:8080/article', // 통신할 웹문서
method: 'get', // 통신할 방식
});
return response;
}
async function requestSortArticle(crit) { async function requestSortArticle(crit) {
const response = await axios({ const response = await axios({
url: `http://localhost:8080/article/sort/${crit}`, // 통신할 웹문서 url: `http://localhost:8080/article/?criteria=${crit}`, // 통신할 웹문서
method: 'get', // 통신할 방식 method: 'get', // 통신할 방식
}); });
return response; return response;
......
import { useNavigate } from 'react-router-dom';
import { UserContext } from '../Context.js';
import Article from '../components/Article.js';
import cookie from 'react-cookies';
import React, { useEffect, useState, useContext } from 'react';
import axios from 'axios';
axios.defaults.withCredentials = true;
function MyPage() {
const userContext = useContext(UserContext);
const [articleList, setArticleList] = useState([]);
const userinfo = cookie.load('name');
let listItem = [];
listItem = articleList.map((article) => {
return (
<Article
key={article._id}
data={article}
></Article>
)
});
useEffect(() => {
requestArticles(userinfo.id)
.then((response) => {
setArticleList(response.data)
})
}, []);
return (
<div className="App">
<h1>{userinfo.name}님의 페이지</h1>
<div className="introduction">
{articleList.length}개의 게시글이 있습니다.
</div>
{listItem}
</div>);
}
async function requestArticles(id) {
const response = await axios({
url: `http://localhost:8080/article/user/${id}`, // 통신할 웹문서
method: 'get', // 통신할 방식
});
return response;
}
export default MyPage;
\ No newline at end of file
...@@ -113,7 +113,7 @@ function PostRead() { ...@@ -113,7 +113,7 @@ function PostRead() {
<Article data={article}></Article> <Article data={article}></Article>
<div style={{ display: 'flex' }}> <div style={{ display: 'flex' }}>
<button onClick={SetLike}>좋아요</button> <button onClick={SetLike}>좋아요</button>
<DelButton isThatYou={userinfo.id === article.author.google.id} target={article}></DelButton> <DelButton isThatYou={userinfo.id === article.author._id} target={article}></DelButton>
</div> </div>
<ArticleContext.Provider value={{ requestLoadArticleById, setArticle }}> <ArticleContext.Provider value={{ requestLoadArticleById, setArticle }}>
{ {
......
...@@ -28,13 +28,6 @@ function Search(props) { ...@@ -28,13 +28,6 @@ function Search(props) {
alert("로그인 바랍니다."); alert("로그인 바랍니다.");
MoveTo('/login'); MoveTo('/login');
} }
else {
// requestLoadArticle()
// .then((response) => {
// console.log(response)
// setArticleList(response.data)
// })
}
}) })
.catch((response) => { .catch((response) => {
console.log("error!:LogOut") console.log("error!:LogOut")
...@@ -88,22 +81,12 @@ function Search(props) { ...@@ -88,22 +81,12 @@ function Search(props) {
{listItem} {listItem}
</div> </div>
</div> </div>
); );
} }
async function requestLoadArticle() {
const response = await axios({
url: 'http://localhost:8080/article', // 통신할 웹문서
method: 'get', // 통신할 방식
});
return response;
}
async function requestLoadArticleByKeyword(keyword) { async function requestLoadArticleByKeyword(keyword) {
const response = await axios({ const response = await axios({
url: `http://localhost:8080/article/search/${keyword}`, // 통신할 웹문서 url: `http://localhost:8080/article/?keyword=${keyword}`, // 통신할 웹문서
method: 'get', // 통신할 방식 method: 'get', // 통신할 방식
}); });
return response; return response;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment