diff --git a/backend/src/article/articleService.js b/backend/src/article/articleService.js index ff1cd667691b26dd4d574a854541bb9df5a10e2b..61e550286035c425928b778448f233fba4c5a585 100644 --- a/backend/src/article/articleService.js +++ b/backend/src/article/articleService.js @@ -62,7 +62,7 @@ const articleService = { const article = await Article.findById(articleId); article.comments.push(commentData); await article.save(); - return article; + return article.populate('author'); } catch (err) { throw err; } @@ -73,7 +73,7 @@ const articleService = { const article = await Article.findById(articleId); article.comments.pull({ _id: commentId }); await article.save(); - return article; + return article.populate('author'); } catch (err) { throw err; } diff --git a/backend/src/auth/authController.js b/backend/src/auth/authController.js index 4c63e5f4cb1e9ed6026f001c2f57a67077d991db..fe6133b6d6d9a8a0d3308a62ebd3674cb6e6e823 100644 --- a/backend/src/auth/authController.js +++ b/backend/src/auth/authController.js @@ -31,7 +31,7 @@ router.post('/login', async (req, res) => { console.log('login done') req.session.sessionid = req.body; //�꾨줎�몄뿉�� 嫄대꽕諛쏆� JWT濡� �몄뀡 �앹꽦 - res.cookie('name', req.body.name, {expires}); //�ъ슜�� �대쫫 荑좏궎 + res.cookie('name', JSON.stringify({name:req.body.name, id:req.body.email}), {expires}); //�ъ슜�� �대쫫 荑좏궎 res.send(req.body.name); // �대쫫 蹂대궡�� 萸먰븯寃�? diff --git a/frontend/src/App.js b/frontend/src/App.js index 3b4d66c4418c73e24b71c8a7843f030b3efa0225..feb13bad280e6d322cbb5f51db7c5b1d0e018508 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,6 +1,8 @@ import "./css/App.css"; import {Routes, Route, Link, useNavigate, Navigate } from 'react-router-dom'; import React, { useEffect, useState, useContext} from 'react'; +import cookie from 'react-cookies'; + import { UserContext } from './Context.js'; import Main from "./pages/Main.js"; @@ -22,6 +24,8 @@ function App() { function MoveTo(link){ navigate(link) } + + const userinfo = cookie.load('name') // �ㅻ뜑 �낅뜲�댄듃 const LogIn = (name)=>{ // API 濡쒓렇�꾩썐 �붿껌 @@ -60,7 +64,7 @@ function App() { return( <div className="App"> <UserContext.Provider value={{isloggedIn, userName, LogIn, LogOut, CheckSession}}> - <Header islogged={isloggedIn} username={userName}></Header> + <Header cookie={userinfo} username={userName}></Header> <Routes> <Route path="/" element={<Main/>}></Route> <Route path="/login" element={<Login/>}></Route> diff --git a/frontend/src/Context.js b/frontend/src/Context.js index effc8f2097cc4e9314180c352db2e812d02d390c..056890b00117d649850914cbe0daf1ab8b1070fa 100644 --- a/frontend/src/Context.js +++ b/frontend/src/Context.js @@ -8,8 +8,8 @@ const UserContext = createContext({ CheckSession : ()=>{} }); -const LocationContext = createContext({ - +const ArticleContext = createContext({ + Aritcle: {} }); -export {UserContext, LocationContext} \ No newline at end of file +export {UserContext, ArticleContext} \ No newline at end of file diff --git a/frontend/src/components/Article.js b/frontend/src/components/Article.js index 1c778fd22bc888b6443e9c3ccf5f283e6d11dbc7..bdefbd816a702012514ae0fbec5edaf6feab2ff6 100644 --- a/frontend/src/components/Article.js +++ b/frontend/src/components/Article.js @@ -20,8 +20,8 @@ function Article({ data }) { // http://localhost:8080/uploads/21701487062905.png return ( <img - src={`http://localhost:8080/${el.replaceAll("\\", "/").substring(7)}`} - alt={`http://localhost:8080/${el.replaceAll("\\", "/").substring(7)}`} + src={`http://localhost:8080/${el.replaceAll("\\", "/").substring(5)}`} + alt={`http://localhost:8080/${el.replaceAll("\\", "/").substring(5)}`} style={{ width: "100px", height: "100px" }} /> ) }); diff --git a/frontend/src/components/Comment.js b/frontend/src/components/Comment.js index 7e06f4e0992f450cb8012e7043bc749ceca0ed38..872328bc0d738c059ffb74271181e11d71d8f05b 100644 --- a/frontend/src/components/Comment.js +++ b/frontend/src/components/Comment.js @@ -1,28 +1,65 @@ -import React, {useEffect, useState} from "react"; import "../css/Article.css" -import {Routes, Route, Link, useNavigate, Navigate } from 'react-router-dom'; -import { useParams } from 'react-router-dom'; +import React, { useEffect, useState, useContext} from 'react'; +import cookie from 'react-cookies'; +import {Routes, Route, Link, useNavigate, Navigate, useParams } from 'react-router-dom'; + +import { UserContext, ArticleContext } from '../Context.js'; + import { DateTime } from 'luxon'; +import axios from 'axios'; +axios.defaults.withCredentials = true; function Comments({data}) { const { _id, content, author, createdAt} = data; - + let params = useParams(); const navigate = useNavigate(); function MoveTo(link){ navigate(link) } - + const articleContext = useContext(ArticleContext); + const userinfo = cookie.load('name') const date = DateTime.fromISO(createdAt).toFormat('yyyy�� MM�� dd�� HH:mm'); - - return ( - <div class="comment"> - <p>{author.nickname}</p> - <p>{content}</p> - <p>{date}</p> - </div> - ); + function DeleteComment(e) { + const data = {id: _id} + axios + .delete(`http://localhost:8080/post/comment/${params.id}/${_id}`, data, + { + headers: {"Content-Type": 'application/json'} + }) + .then(res => { + alert("The comment is successfully deleted"); + return articleContext.requestLoadArticleById(params.id) + }) + .then(res => { + articleContext.setArticle(res.data) + }) + .catch(err => { + console.error(err); + }); + }; + + if (userinfo.id===author.email) { + return ( + <div class="comment" style={{display: 'flex'}}> + <p>{author.nickname}</p> + <p>{content}</p> + <p>{date}</p> + <button style={{height: '30px'}} onClick={DeleteComment} type="submit">吏��곌린</button> + </div> + ); + } + else { + return ( + <div class="comment" style={{display: 'flex'}}> + <p>{author.nickname}</p> + <p>{content}</p> + <p>{date}</p> + </div> + ); + } + } export default Comments; diff --git a/frontend/src/components/Header.js b/frontend/src/components/Header.js index 05b61784ef93c4fd7efc492d7d20ee28857b1434..72a20ef588e94d6d1ce5cd10e7163c377bbac6a4 100644 --- a/frontend/src/components/Header.js +++ b/frontend/src/components/Header.js @@ -5,20 +5,8 @@ import { UserContext } from '../Context.js'; import React, { useEffect, useState, useContext} from 'react'; import { Link, useNavigate, Navigate } from "react-router-dom"; -import cookie from 'react-cookies'; -import {useCookies} from 'react-cookie' - - -function Welcome(props){ - return ( - <p> - {props.name?`${props.name}��, �섏쁺�⑸땲��`:'濡쒓렇�명븯�몄슂.'}<br/> - </p> - ) -} - function ButtonLink({link, status, children}){ const userContext = useContext(UserContext); @@ -29,35 +17,42 @@ function ButtonLink({link, status, children}){ if (status) { return ( - <botton onClick = {()=>{userContext.LogOut()}}> - {children} - </botton> + <div> + <label className='Labelheader' htmlFor={children}>{children}</label> + <button id={children} onClick = {()=>{userContext.LogOut()}} style={{ display: "none"}}> + {children} + </button> + </div> + ) } else { return ( - <botton onClick = {()=>{MoveTo(link)}}> - {children} - </botton> + <div> + <label className='Labelheader' htmlFor={children}>{children}</label> + <button id={children} onClick = {()=>{MoveTo(link)}} style={{ display: "none"}}> + {children} + </button> + </div> ) } } -function Header({islogged, username}){ - const name = cookie.load('name') +function Header({cookie}){ + return( <div className="header"> <ButtonLink link='/'> <img className="logo_image" alt="logo" src={logo}/> </ButtonLink> <ul> - <p>{name?`${name}��, �섏쁺�⑸땲��`:'濡쒓렇�명븯�몄슂.'}</p> + <p>{cookie?`${cookie.name}��, �섏쁺�⑸땲��`:'濡쒓렇�명븯�몄슂.'}</p> <ul className="menu_list"> <li><ButtonLink link='/'>Home</ButtonLink></li> <li><ButtonLink link='/search'>寃���</ButtonLink></li> <li><ButtonLink link='/postwrite'>�ъ뒪�� �묒꽦</ButtonLink></li> - <li><ButtonLink link={islogged?'/':'/login'} status={islogged}>{islogged?'濡쒓렇�꾩썐':'濡쒓렇��'}</ButtonLink></li> {/*濡쒓렇�� �щ� 濡쒖쭅 援ы쁽 �꾩슂*/} + <li><ButtonLink link={cookie?'/':'/login'} status={cookie?true:false}>{cookie?'濡쒓렇�꾩썐':'濡쒓렇��'}</ButtonLink></li> {/*濡쒓렇�� �щ� 濡쒖쭅 援ы쁽 �꾩슂*/} {/* { Object.keys(user).length != 0 ? <li><Link to={`/profile/${getUserId()}`}>profile</Link>/<span onClick={logout}>logout</span></li> : <li><Link to="/login">login</Link></li> diff --git a/frontend/src/css/Header.css b/frontend/src/css/Header.css index 14b0bf3a6ac90cd026a52340c503787fd825a681..701c6bcf85d4899aba2487738286c7da5725e35d 100644 --- a/frontend/src/css/Header.css +++ b/frontend/src/css/Header.css @@ -32,4 +32,14 @@ li{ margin-right: 3rem; font-size: 1.2rem; font-weight: 100; +} + +.Labelheader{ + font-size: xx-large; + color: #FF7002; + font-weight: bold; +} +.Labelheader:hover{ + color: #a5500f; + } \ No newline at end of file diff --git a/frontend/src/pages/Main.js b/frontend/src/pages/Main.js index e1dc2fbb0ee07a707c865078b798dc2ea3757cd2..559790b64738c46f25ae91951d9df8b05f1a1224 100644 --- a/frontend/src/pages/Main.js +++ b/frontend/src/pages/Main.js @@ -1,5 +1,5 @@ import { useNavigate } from 'react-router-dom'; -import cookie from 'react-cookies'; + import { UserContext } from '../Context.js'; import Article from '../components/Article.js'; import React, { useEffect, useState, useContext} from 'react'; @@ -52,7 +52,11 @@ function Main() { async function requestLoadArticle() { const response = await axios({ +<<<<<<< HEAD url: 'http://localhost:8080/article', // �듭떊�� �밸Ц�� +======= + url: 'http://localhost:8080/post/article', // �듭떊�� �밸Ц�� +>>>>>>> 2892e0e9c9dd1752080a370ba274deeca6254246 method: 'get', // �듭떊�� 諛⑹떇 }); return response; diff --git a/frontend/src/pages/PostRead.js b/frontend/src/pages/PostRead.js index 188acb07695deb3ea94e99d429dc4f383b3cd474..1aae62a8f492b180a2937fcb6731609dde9e5cc0 100644 --- a/frontend/src/pages/PostRead.js +++ b/frontend/src/pages/PostRead.js @@ -1,8 +1,7 @@ -import { useNavigate } from 'react-router-dom'; -import { useParams } from 'react-router-dom'; +import { useNavigate, useParams } from 'react-router-dom'; import React, { useEffect, useState, useContext} from 'react'; import Article from '../components/Article.js'; -import { UserContext } from '../Context.js'; +import { UserContext, ArticleContext } from '../Context.js'; import MapLocator from '../components/MapForLoaction.js'; import Comment from '../components/Comment.js'; @@ -10,75 +9,55 @@ import axios from 'axios'; axios.defaults.withCredentials = true; function PostRead() { - let params = useParams(); - const userContext = useContext(UserContext); - const [article, setArticle] = useState(null) - const navigate = useNavigate(); - function MoveTo(link){ - navigate(link) - } - useEffect(() => { - userContext.CheckSession() - .then((response) => { - if (!response.data) { - alert("�몄뀡�� 留뚮즺�섏뿀�듬땲��. �ㅼ떆 濡쒓렇�� 諛붾엻�덈떎.") - MoveTo('/login') - } - else{ - return requestLoadArticleById(params.id) - } - }) - .then((response) => { - console.log(response) - setArticle(response.data) - }) - .catch((response)=>{ - console.log("error!:LogOut") - console.log(response) - }) + let params = useParams(); + const userContext = useContext(UserContext); + const articleContext = useContext(ArticleContext); - }, []); - - console.log(article); - console.log(article?Object.values(article):"no"); - - if (article) { - return( - <> - <div className="introduction" style={{display: 'flex'}}> - <MapLocator loc={{lat: article.latitude, lng: article.longitude}} keyword={article.keyword}></MapLocator> - <div> - <Article data={article}></Article> - <button>議곗���</button> - </div> - </div> - <form> - <div style={{display: 'flex'}}> - <button>�볤� �묒꽦</button> - <input type="text"></input> - </div> - </form> - { - article.comments.map((el)=>{ - return( - <Comment key={el._id} data={el}></Comment> - ) - }) - } - </> - - ) - } - else { - return( - <div className="introduction" style={{display: 'flex'}}> - <p>濡쒕뵫以�</p> - </div> - ) + const [article, setArticle] = useState(null) + const [inputComment, setInputComment] = useState("") + const [commentList, setCommentList] = useState("") + const navigate = useNavigate(); + function MoveTo(link){ + navigate(link) + } + useEffect(() => { + userContext.CheckSession() + .then((response) => { + if (!response.data) { + alert("�몄뀡�� 留뚮즺�섏뿀�듬땲��. �ㅼ떆 濡쒓렇�� 諛붾엻�덈떎.") + MoveTo('/login') + } + else{ + return requestLoadArticleById(params.id) } + }) + .then((response) => { + console.log(response) + setArticle(response.data) + + }) + .catch((response)=>{ + console.log("error!:LogOut") + console.log(response) + }) + + }, []); + function SetLike(){ + axios.put(`http://localhost:8080/post/comment/like/${params.id}`) + .then(res => { + alert("The comment is successfully uploaded"); + return requestLoadArticleById(params.id) + }) + .then(res => { + setArticle(res.data) + }) + .catch(err => { + console.error(err); + }); } +<<<<<<< HEAD async function requestLoadArticleById(id) { const response = await axios({ url: `http://localhost:8080/article/${id}`, // �듭떊�� �밸Ц�� @@ -86,5 +65,79 @@ function PostRead() { }); return response; } +======= + const onTextChange = (e) => { + const {value} = e.target; + setInputComment(value); + } +>>>>>>> 2892e0e9c9dd1752080a370ba274deeca6254246 + + const onSubmit = e => { + e.preventDefault(); + if (!inputComment) { + alert("�볤��� �묒꽦�댁<�몄슂."); + return + } + const data = {content: inputComment} + axios.post(`http://localhost:8080/post/comment/${params.id}`, data, + { + headers: {"Content-Type": 'application/json'} + }) + .then(res => { + alert("The comment is successfully uploaded"); + return requestLoadArticleById(params.id) + }) + .then(res => { + setArticle(res.data) + }) + .catch(err => { + console.error(err); + }); + }; + + if (article) { + return( + <> + <div className="introduction" style={{display: 'flex'}}> + <MapLocator loc={{lat: article.latitude, lng: article.longitude}} keyword={article.keyword}></MapLocator> + <div> + <Article data={article}></Article> + <button onClick={SetLike}>議곗���</button> + </div> + </div> + <form onSubmit={onSubmit}> + <div style={{display: 'flex'}}> + <button>�볤� �묒꽦</button> + <input type="text" onChange={onTextChange}></input> + </div> + </form> + <ArticleContext.Provider value={{requestLoadArticleById, setArticle}}> + { + article.comments.map((el)=>{ + return( + <Comment key={el._id} data={el}></Comment> + ) + }) + } + </ArticleContext.Provider> + </> + ) + } + else { + return( + <div className="introduction" style={{display: 'flex'}}> + <p>濡쒕뵫以�</p> + </div> + ) + } +} + +async function requestLoadArticleById(id) { + const response = await axios({ + url: `http://localhost:8080/post/article/${id}`, // �듭떊�� �밸Ц�� + method: 'get', // �듭떊�� 諛⑹떇 + }); + return response; +} - export default PostRead; \ No newline at end of file +export default PostRead; \ No newline at end of file diff --git a/frontend/src/pages/PostWrite.js b/frontend/src/pages/PostWrite.js index b13e4f37cb9d7c4d8f2a8de498bdac5698f4b337..3016ca9dc6ea6dc7b867fa5c71490d2aa08d9ee1 100644 --- a/frontend/src/pages/PostWrite.js +++ b/frontend/src/pages/PostWrite.js @@ -1,6 +1,5 @@ import React, { useRef, useState, useEffect, useContext } from 'react'; import { useNavigate } from 'react-router-dom'; - import { UserContext } from '../Context.js'; import SearchMap from '../components/SearchMapByKeyword.js' diff --git a/frontend/src/pages/Search.js b/frontend/src/pages/Search.js index 43eb6a88e80d4c10f21173861d58e845a9a4f4c8..c380e2dbce3f47c05dfab81662276cd101025f0d 100644 --- a/frontend/src/pages/Search.js +++ b/frontend/src/pages/Search.js @@ -5,40 +5,6 @@ import SearchMap from '../components/SearchMapByKeyword.js' import { UserContext } from '../Context.js'; const {kakao} = window; -//移댁뭅�� 吏��� API瑜� �댁슜�� 寃���(�덉젙) -/* -function SearchMap(props){ - // �꾩<���숆탳瑜� 湲곕낯 �꾩튂濡� �ㅼ젙 - const [state, setState] = useState({ - center: { lat: 37.28238488648025, lng: 127.04350967609274 }, - isPanto: true, - }); - const [searchAddress, SetSearchAddress] = useState(); //二쇱냼 �낅젰 - - const handleInput = (e) => { - SetSearchAddress(e.target.value); - } - - const SearchStart = () => { - console.log('Start Search!');// action test - // 二쇱냼瑜� 湲곕컲�쇰줈 �� 寃��� 援ы쁽(�쒖<�밸퀎�먯튂�� �쒖<�� 泥⑤떒濡� 242 瑜� �낅젰�섎㈃ kakao媛� �섏삩��) - const geocoder = new kakao.maps.services.Geocoder(); - let callback = function(result, status) { - if (status === kakao.maps.services.Status.OK) { - const newSearch = result[0] - setState({ - center: { lat: newSearch.y, lng: newSearch.x } - }) - } - }; - geocoder.addressSearch(`${searchAddress}`, callback); - } - - -} -*/ - - function Search(props) { const userContext = useContext(UserContext);