Skip to content

Commit 8f56361

Browse files
authored
Merge pull request #40 from OpenKetchupSource/feat/36
Feat/36 : 댓글 저장 기능 api 제외 프론트엔드 완성
2 parents 44b410c + 4d66497 commit 8f56361

File tree

2 files changed

+152
-11
lines changed

2 files changed

+152
-11
lines changed

src/pages/DiaryDetail.tsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import styled from "styled-components";
22
import { IoHomeOutline, IoTrashBinOutline } from "react-icons/io5";
3-
import { BsPencil } from "react-icons/bs";
3+
import { BsPencil, BsStar, BsStarFill } from "react-icons/bs";
44
import { useNavigate, useParams } from "react-router-dom";
55
import { useEffect, useState } from "react";
66
import { getDiary } from "../services/apis/diary/diary";
@@ -48,6 +48,8 @@ const DiaryDetail = () => {
4848
}
4949
}, [diary]);
5050

51+
const [starred, setStarred] = useState(false);
52+
5153
const formatDate = (rawDate: string) => {
5254
const date = new Date(rawDate);
5355
return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, "0")}.${String(date.getDate()).padStart(2, "0")}.`;
@@ -87,6 +89,11 @@ const DiaryDetail = () => {
8789
alt={diary.character}
8890
/>
8991
<CharacterName>{diary.character}</CharacterName>
92+
{starred ? (
93+
<StarIconFill onClick={() => setStarred(false)} />
94+
) : (
95+
<StarIcon onClick={() => setStarred(true)} />
96+
)}
9097
</CharacterRow>
9198
<CommentText>
9299
{aiComment || "AI 코멘트를 생성 중입니다..."}
@@ -148,7 +155,7 @@ const EditIcon = styled(BsPencil)`
148155
color: #1e2a52;
149156
`;
150157

151-
const Body = styled.div`
158+
export const Body = styled.div`
152159
padding: 24px;
153160
display: flex;
154161
flex-direction: column;
@@ -191,34 +198,47 @@ const CommentTitle = styled.h3`
191198
color: #1e2a52;
192199
`;
193200

194-
const CommentCard = styled.div`
201+
export const CommentCard = styled.div`
195202
background: #fff;
196203
border-radius: 16px;
197204
padding: 16px;
198205
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
199206
`;
200207

201-
const CharacterRow = styled.div`
208+
export const CharacterRow = styled.div`
202209
display: flex;
203210
align-items: center;
204211
gap: 12px;
205212
margin-bottom: 8px;
206213
`;
207214

208-
const CharacterImg = styled.img`
215+
export const CharacterImg = styled.img`
209216
width: 40px;
210217
height: 40px;
211218
border-radius: 50%;
212219
`;
213220

214-
const CharacterName = styled.div`
221+
export const CharacterName = styled.div`
215222
font-size: 16px;
216223
font-weight: 600;
217224
color: #1e2a52;
218225
`;
219226

220-
const CommentText = styled.p`
227+
export const CommentText = styled.p`
221228
font-size: 14px;
222229
color: #374151;
223230
line-height: 1.6;
224231
`;
232+
233+
export const StarIcon = styled(BsStar)`
234+
margin-left: auto;
235+
font-size: 20px;
236+
cursor: pointer;
237+
`;
238+
239+
export const StarIconFill = styled(BsStarFill)`
240+
margin-left: auto;
241+
font-size: 20px;
242+
color: #ffd600;
243+
cursor: pointer;
244+
`;

src/pages/collection/Comments.tsx

Lines changed: 125 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,130 @@
1+
import { useState } from "react";
2+
import {
3+
Body,
4+
CharacterImg,
5+
CharacterName,
6+
CharacterRow,
7+
CommentCard,
8+
CommentText,
9+
StarIcon,
10+
StarIconFill,
11+
} from "../DiaryDetail";
12+
import styled from "styled-components";
13+
import {
14+
IoChevronBack,
15+
IoChevronForward,
16+
IoHomeOutline,
17+
} from "react-icons/io5";
18+
import { useNavigate } from "react-router-dom";
19+
20+
const dummyComments = [
21+
"오랜만에 영화관에서 좋은 시간 보냈다니 내가 다 기쁘다! 너의 여유로운 하루가 참 따뜻하게 느껴져 :)",
22+
"오늘 하루도 수고 많았어! 너의 일상이 더 행복해지길 바랄게.",
23+
"새로운 도전을 했다는 말에 나도 힘이 나! 계속 응원할게 :)",
24+
];
25+
126
const Comments = () => {
27+
const [starred, setStarred] = useState<boolean[]>(
28+
new Array(dummyComments.length).fill(false),
29+
);
30+
const [currentIndex, setCurrentIndex] = useState(0);
31+
const navigate = useNavigate();
32+
33+
const goPrev = () => {
34+
setCurrentIndex(
35+
(prev) => (prev - 1 + characterList.length) % characterList.length,
36+
);
37+
};
38+
39+
const goNext = () => {
40+
setCurrentIndex((prev) => (prev + 1) % characterList.length);
41+
};
42+
243
return (
3-
<>
4-
<>Comments</>
5-
<p>일단 없는 걸로</p>
6-
</>
44+
<Body>
45+
<HeaderWrapper>
46+
<IoHomeOutline
47+
size={24}
48+
color="#2d3552"
49+
onClick={() => navigate("/")}
50+
/>
51+
52+
<CenterContainer>
53+
<ClickableIcon onClick={goPrev}>
54+
<IoChevronBack />
55+
</ClickableIcon>
56+
<Name>{characterList[currentIndex]}</Name>
57+
<ClickableIcon onClick={goNext}>
58+
<IoChevronForward />
59+
</ClickableIcon>
60+
</CenterContainer>
61+
62+
<Placeholder />
63+
</HeaderWrapper>
64+
<div>즐겨찾기 한 코멘트 목록</div>
65+
{dummyComments.map((comment, index) => (
66+
<CommentCard key={index}>
67+
<CharacterRow>
68+
<CharacterImg src={`/images/characters/웅이.png`} alt="웅이" />
69+
<CharacterName>웅이</CharacterName>
70+
{starred[index] ? (
71+
<StarIconFill
72+
onClick={() => {
73+
const newStars = [...starred];
74+
newStars[index] = false;
75+
setStarred(newStars);
76+
}}
77+
/>
78+
) : (
79+
<StarIcon
80+
onClick={() => {
81+
const newStars = [...starred];
82+
newStars[index] = true;
83+
setStarred(newStars);
84+
}}
85+
/>
86+
)}
87+
</CharacterRow>
88+
<CommentText>{comment}</CommentText>
89+
</CommentCard>
90+
))}
91+
</Body>
792
);
893
};
94+
995
export default Comments;
96+
97+
const characterList = ["웅이", "앙글이", "티바노"];
98+
99+
const HeaderWrapper = styled.div`
100+
display: flex;
101+
align-items: center;
102+
justify-content: space-between;
103+
margin-bottom: 20px;
104+
`;
105+
106+
const CenterContainer = styled.div`
107+
position: absolute;
108+
left: 50%;
109+
transform: translateX(-50%);
110+
width: 160px; /* 고정 너비로 좌우 아이콘 위치 유지 */
111+
display: flex;
112+
align-items: center;
113+
justify-content: space-between;
114+
color: #2d3552;
115+
font-weight: 500;
116+
font-size: 1.2rem;
117+
`;
118+
119+
const Name = styled.span`
120+
flex: 1;
121+
text-align: center;
122+
`;
123+
124+
const Placeholder = styled.div`
125+
width: 28px; /* 오른쪽 균형용 */
126+
`;
127+
128+
const ClickableIcon = styled.div`
129+
cursor: pointer;
130+
`;

0 commit comments

Comments
 (0)