-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[48기 이인재] PostList 기능 구현 #3
base: main
Are you sure you want to change the base?
Changes from 15 commits
27f252f
19e0492
b544d92
4151d23
0654d26
f3c2d81
b967fc5
c1f80e3
4e95ad9
df2861a
b8f7a4b
1a0dd15
b927f52
20e1abe
d2197b9
9598a51
08d2429
36dd1a9
c726390
158a86a
7f79db3
9b1189d
223d6f2
da2c16d
f54f2a0
45b0a62
25bf773
e9f57bd
389d715
0ff885c
42f1cb6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
[ | ||
{ | ||
"id": 0, | ||
"userImage": "https://ca.slack-edge.com/TH0U6FBTN-U05CNSZS4ET-02b82fbf4c55-512", | ||
"nickname": "이인재", | ||
"content": "일라이자 효과는 인간의 사고 과정과 감정을 AI 시스템에 잘못 돌리는 사람들의 경향을 말하며, 따라서 시스템이 실제보다 더 지능적이라고 믿는다. 이 현상은 1966년 MIT 교수 조셉 웨이젠바움이 만든 챗봇인 ELIZA의 이름을 따서 명명되었다.", | ||
"createdAt": 1689087600000, | ||
"updatedAt": 11 | ||
}, | ||
{ | ||
"id": 1, | ||
"userImage": "https://images.unsplash.com/photo-1580489944761-15a19d654956?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MjF8fHBlcnNvbnxlbnwwfHwwfHx8MA%3D%3D&auto=format&fit=crop&w=500&q=60", | ||
"nickname": "John", | ||
"content": "일라이자 효과는 컴퓨터 과학에서, 무의식적으로 컴퓨터의 행위를 인간의 행위와 유사한 것으로 추정하고 의인화하는 경향이다.", | ||
"createdAt": 1686495600000, | ||
"updatedAt": 11 | ||
}, | ||
{ | ||
"id": 2, | ||
"userImage": "https://images.unsplash.com/photo-1552058544-f2b08422138a?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Nnx8cGVyc29ufGVufDB8fDB8fHww&auto=format&fit=crop&w=500&q=60", | ||
"nickname": "Julia", | ||
"content": "성별과 성격과 같은 인간의 특성을 AI 음성 비서에게 돌리기", | ||
"createdAt": 1691830007441, | ||
"updatedAt": 11 | ||
}, | ||
{ | ||
"id": 3, | ||
"userImage": "https://images.unsplash.com/photo-1500048993953-d23a436266cf?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MTV8fHBlcnNvbnxlbnwwfHwwfHx8MA%3D%3D&auto=format&fit=crop&w=500&q=60", | ||
"nickname": "pliossun", | ||
"content": "성별과 성격과 같은 인간의 특성을 AI 음성 비서에게 돌리기", | ||
"createdAt": 1676127600000, | ||
"updatedAt": 11 | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,54 @@ | ||
import React from 'react'; | ||
import React, { useEffect, useState } from 'react'; | ||
import './PostList.scss'; | ||
import Feed from './components/Feed'; | ||
llinjae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const PostList = () => { | ||
return <div>PostList</div>; | ||
const [feedsData, setFeedsData] = useState([]); | ||
|
||
useEffect(() => { | ||
fetch('/data/data.json', { | ||
method: 'GET', | ||
headers: { | ||
'Content-Type': 'application/json;charset=utf-8', | ||
}, | ||
}) | ||
.then(res => res.json()) | ||
.then(data => setFeedsData(data)); | ||
}, []); | ||
|
||
const noListMessage = '게시글이 없습니다.'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 컴포넌트가 렌더링 될 때마다 다시 그려질 필요가 없는 상수 데이터이기 때문에, 컴포넌트 외부에 작성해도 됩니다. 그리고 개인의 성향일 수 있지만, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그러면 게시글이 없는 것을 현재 상태에서 어떻게 보여주면 좋을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 말씀드린 제 기준에 따른다면, 따로 변수로 지정하지 않고 리터럴하게 직접 JSX Element 안에 작성할 것 같습니다. |
||
|
||
const handleRemove = targetId => { | ||
const newList = feedsData.filter(data => data.id !== targetId); | ||
setFeedsData(newList); | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 삭제 기능을 실제로 백엔드 서버와 붙이는 것까지 고려했다면, 이 부분은 프론트 단에서만 작동하는 코드이기 때문에 실제로 반영하려면 다른 방식이 필요할 수도 있습니다. |
||
|
||
return ( | ||
<div className="postListContainer"> | ||
<div className="postListContentContainer"> | ||
<div className="feedContainer"> | ||
<div className="feedContentContainer"> | ||
llinjae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{feedsData.length === 0 ? ( | ||
<p>{noListMessage}</p> | ||
) : ( | ||
<> | ||
{feedsData.map((feedData, index) => ( | ||
<Feed | ||
key={index} | ||
feedData={feedData} | ||
handleRemove={handleRemove} | ||
/> | ||
))} | ||
</> | ||
)} | ||
llinjae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</div> | ||
</div> | ||
<div className="btnBox"> | ||
<button className="btn">글 쓰기</button> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default PostList; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
@import '../../style/variables.scss'; | ||
|
||
.postListContainer { | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
width: 100%; | ||
height: 80vh; | ||
} | ||
|
||
.postListContentContainer { | ||
max-width: 100%; | ||
max-height: 100%; | ||
width: 100%; | ||
height: calc(100% - 80px); | ||
llinjae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: space-between; | ||
} | ||
|
||
.feedContainer { | ||
width: 90%; | ||
height: 85%; | ||
|
||
display: flex; | ||
flex-direction: column; | ||
|
||
.feedContentContainer { | ||
overflow-y: scroll; | ||
|
||
&::-webkit-scrollbar { | ||
display: none; | ||
} | ||
} | ||
} | ||
|
||
.btnBox { | ||
width: 90%; | ||
height: 56px; | ||
display: flex; | ||
justify-content: end; | ||
|
||
.btn { | ||
border: none; | ||
border-radius: 6px; | ||
background-color: $blue; | ||
color: white; | ||
font-weight: 800; | ||
font-size: 16px; | ||
width: 120px; | ||
llinjae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
padding: 0px 34px; | ||
justify-content: center; | ||
align-items: center; | ||
cursor: pointer; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import React from 'react'; | ||
import './CommentItem.scss'; | ||
|
||
const CommentItem = ({ feedData, feedDate }) => { | ||
return ( | ||
<> | ||
<form className="inputForm"> | ||
<input | ||
type="text" | ||
placeholder="댓글을 작성해주세요." | ||
className="feedInput" | ||
/> | ||
<button className="postBtn">댓글 게시</button> | ||
</form> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. inputForm, postBtn 등은 다른 컴포넌트에서도 쓰일 수 있는 className인 만큼, 최상단을 Fragment가 아닌 element로 작성하고 className을 부여해 nesting해주시는 게 안전하겠네요! |
||
|
||
<div className="commentContainer"> | ||
<div className="commentProfileBox"> | ||
<img | ||
className="commentProfileImg" | ||
src={feedData.userImage} | ||
alt="프로필 이미지" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alt 값에는 |
||
/> | ||
<div className="commentRightBox"> | ||
<div className="commentDetailUserInfo"> | ||
<p className="userName"> | ||
<b>{feedData.nickname}</b> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. feedData도 구조분해할당해서 사용하면 더 편리하겠네요! |
||
</p> | ||
<div className="commentProfileBoxRight"> | ||
<p className="date">{feedDate}</p> | ||
<button className="deleteBtn">삭제</button> | ||
<button className="editBtn">수정</button> | ||
</div> | ||
</div> | ||
<p className="userCommentBox"> | ||
sdafasddsafasdfasdfsafasfasdfjssdafasddsafasdfasdfsafasfasdfjssdafasddsafasdfasdfsafasfasdfjssdafasddsafasdfasdfsafasfasdfjssdafasddsafasdfasdfsafasfasdfjssdafasddsafasdfasdfsafasfasdfjs | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default CommentItem; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
@import '../../../style/variables.scss'; | ||
.inputForm { | ||
width: 100%; | ||
display: grid; | ||
grid-template-columns: 6fr 1fr; | ||
gap: 8px; | ||
height: 50px; | ||
margin: 24px 0; | ||
|
||
.feedInput { | ||
border: 1px solid #e6e6e6; | ||
border-radius: 4px; | ||
} | ||
|
||
.postBtn { | ||
border: 1px solid $grey60; | ||
background-color: #fff; | ||
border-radius: 4px; | ||
cursor: pointer; | ||
} | ||
} | ||
|
||
.commentContainer { | ||
max-width: 100%; | ||
width: 100%; | ||
height: auto; | ||
|
||
.commentProfileBox { | ||
display: flex; | ||
justify-content: space-between; | ||
gap: 24px; | ||
padding: 0 8px; | ||
margin-bottom: 24px; | ||
height: auto; | ||
|
||
.commentProfileImg { | ||
width: 32px; | ||
height: 32px; | ||
border-radius: 50%; | ||
} | ||
|
||
.commentRightBox { | ||
width: 100%; | ||
display: flex; | ||
flex-direction: column; | ||
|
||
.commentDetailUserInfo { | ||
display: flex; | ||
justify-content: space-between; | ||
|
||
.userName { | ||
font-size: 16px; | ||
} | ||
} | ||
|
||
.userCommentBox { | ||
width: 100%; | ||
word-break: break-all; | ||
} | ||
} | ||
|
||
.commentProfileBoxRight { | ||
display: flex; | ||
align-items: center; | ||
|
||
.date { | ||
color: $grey60; | ||
font-weight: 400; | ||
} | ||
|
||
.deleteBtn { | ||
outline: none; | ||
border: none; | ||
background-color: transparent; | ||
color: $red; | ||
font-size: 14px; | ||
cursor: pointer; | ||
} | ||
|
||
.editBtn { | ||
outline: none; | ||
border: none; | ||
background-color: transparent; | ||
font-size: 14px; | ||
cursor: pointer; | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import React, { useState } from 'react'; | ||
import './Feed.scss'; | ||
import CommentItem from './CommentItem'; | ||
|
||
const Feed = ({ feedData, handleRemove }) => { | ||
const [heartToggle, setHeartToggle] = useState(false); | ||
const [like, setLike] = useState(0); | ||
const [hideFeedContent, setHideFeedContent] = useState(true); | ||
llinjae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const feedDate = new Date(feedData.createdAt).toLocaleDateString(); | ||
|
||
const handleHeartToggle = () => { | ||
setHeartToggle(!heartToggle); | ||
setLike(heartToggle ? like - 1 : like + 1); | ||
}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분도, 위에 삭제 관련된 코멘트 참고해주세요! |
||
|
||
const handleHideFeedContent = () => { | ||
setHideFeedContent(!hideFeedContent); | ||
}; | ||
|
||
return ( | ||
<> | ||
<div className="feed" onClick={handleHideFeedContent}> | ||
<div className="feedProfileBox"> | ||
<div className="feedProfileBoxLeft"> | ||
<img | ||
className="profileImg" | ||
src={feedData.userImage} | ||
alt="프로필 이미지" | ||
/> | ||
<p className="userName"> | ||
<b>{feedData.nickname}</b> | ||
</p> | ||
</div> | ||
<div className="feedProfileBoxRight"> | ||
<p className="date">{feedDate}</p> | ||
<button | ||
className="deleteBtn" | ||
onClick={() => handleRemove(feedData.id)} | ||
> | ||
삭제 | ||
</button> | ||
</div> | ||
</div> | ||
<div className="feedContentBox"> | ||
<p className="feedContent">{feedData.content}</p> | ||
</div> | ||
<div className="feedDescriptionBox"> | ||
<div className="feedDescriptionTop"> | ||
<p>좋아요 {like}</p> | ||
<p>댓글 00</p> | ||
</div> | ||
<img | ||
onClick={handleHeartToggle} | ||
className="feedHeartImg" | ||
src={ | ||
heartToggle | ||
? process.env.PUBLIC_URL + '/images/fillheart.svg' | ||
: process.env.PUBLIC_URL + '/images/heart.svg' | ||
} | ||
alt="좋아요 버튼" | ||
llinjae marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/> | ||
</div> | ||
</div> | ||
{!hideFeedContent && ( | ||
<CommentItem feedData={feedData} feedDate={feedDate} /> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
export default Feed; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 PR에선 README.md 파일이 삭제되면 안됩니다.
다른 PR에서 README.md 파일이 수정된 후 이 PR이 병합되면, 수정한 내용까지 지워버릴 수도 있습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
새로 생성해서 깃헙에 있는 내용들 추가했는데 맞을까요..?