diff --git a/.github/workflows/closed-issue.yml b/.github/workflows/closed-issue.yml
deleted file mode 100644
index 375418c..0000000
--- a/.github/workflows/closed-issue.yml
+++ /dev/null
@@ -1,41 +0,0 @@
-name: Close Mentioned Issues if Checklist Complete
-
-on:
- pull_request:
- types: [closed]
-
-permissions:
- issues: write
- pull-requests: read
- contents: read
-
-jobs:
- close-mentioned-issues:
- if: github.event.pull_request.merged == true
- runs-on: ubuntu-latest
- steps:
- - name: Check if checklist is fully complete
- id: checklist
- run: |
- BODY="${{ github.event.pull_request.body }}"
- UNCHECKED=$(echo "$BODY" | grep -c '\[ \]')
- if [ "$UNCHECKED" -eq 0 ]; then
- echo "checklist-complete=true" >> $GITHUB_OUTPUT
- else
- echo "checklist-complete=false" >> $GITHUB_OUTPUT
- fi
-
- - name: Extract issue numbers
- id: issues
- run: |
- BODY="${{ github.event.pull_request.body }}"
- echo "ISSUES=$(echo "$BODY" | grep -oE '#[0-9]+' | tr -d '#' | tr '\n' ' ')" >> $GITHUB_OUTPUT
-
- - name: Close mentioned issues
- if: steps.checklist.outputs.checklist-complete == 'true'
- env:
- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: |
- for issue in ${{ steps.issues.outputs.ISSUES }}; do
- gh issue close "$issue" --repo "${{ github.repository }}"
- done
diff --git a/src/App.tsx b/src/App.tsx
index a45430c..f976809 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -12,6 +12,7 @@ import styled from "styled-components";
import WritingPage from "./pages/writing/WritingPage";
import Testpage from "./pages/Testpage";
import EditPage from "./pages/writing/EditPage";
+import HashtagDetail from "./pages/collection/HashtagDetail";
function App() {
return (
@@ -29,6 +30,7 @@ function App() {
} />
} />
+ } />
} />
diff --git a/src/components/diary/Header.tsx b/src/components/diary/Header.tsx
index 9d8ccf6..38dbf35 100644
--- a/src/components/diary/Header.tsx
+++ b/src/components/diary/Header.tsx
@@ -1,3 +1,84 @@
-const Header = () => {};
+import styled from "styled-components";
+import {
+ IoChevronBack,
+ IoChevronForward,
+ IoHomeOutline,
+} from "react-icons/io5";
+import { useNavigate } from "react-router-dom";
+
+interface HeaderProps {
+ characterList: string[];
+ currentIndex: number;
+ setCurrentIndex: React.Dispatch>;
+}
+
+const Header = ({
+ characterList,
+ currentIndex,
+ setCurrentIndex,
+}: HeaderProps) => {
+ const navigate = useNavigate();
+
+ const goPrev = () => {
+ setCurrentIndex(
+ (prev) => (prev - 1 + characterList.length) % characterList.length,
+ );
+ };
+
+ const goNext = () => {
+ setCurrentIndex((prev) => (prev + 1) % characterList.length);
+ };
+
+ return (
+
+ navigate("/")} />
+
+
+
+
+
+ {characterList[currentIndex]}
+
+
+
+
+
+
+
+ );
+};
export default Header;
+
+const HeaderWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 20px;
+`;
+
+const CenterContainer = styled.div`
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 160px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ color: #2d3552;
+ font-weight: 500;
+ font-size: 1.2rem;
+`;
+
+const Name = styled.span`
+ flex: 1;
+ text-align: center;
+`;
+
+const Placeholder = styled.div`
+ width: 28px;
+`;
+
+const ClickableIcon = styled.div`
+ cursor: pointer;
+`;
diff --git a/src/components/home/DiaryList.tsx b/src/components/home/DiaryList.tsx
index 1735393..1902116 100644
--- a/src/components/home/DiaryList.tsx
+++ b/src/components/home/DiaryList.tsx
@@ -93,13 +93,19 @@ export const DiaryTitle = styled.div`
export const TagWrapper = styled.div`
display: flex;
- gap: 8px;
- font-size: 14px;
- color: #3b82f6;
+ flex-wrap: nowrap;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
margin-bottom: 8px;
`;
-export const Tag = styled.span``;
+export const Tag = styled.span`
+ font-size: 14px;
+ color: #3b82f6;
+ margin-right: 8px;
+ flex-shrink: 0;
+`;
export const Content = styled.div`
font-size: 14px;
diff --git a/src/pages/DiaryDetail.tsx b/src/pages/DiaryDetail.tsx
index d0fe4ed..27f914f 100644
--- a/src/pages/DiaryDetail.tsx
+++ b/src/pages/DiaryDetail.tsx
@@ -1,6 +1,6 @@
import styled from "styled-components";
import { IoHomeOutline, IoTrashBinOutline } from "react-icons/io5";
-import { BsPencil } from "react-icons/bs";
+import { BsPencil, BsStar, BsStarFill } from "react-icons/bs";
import { useNavigate, useParams } from "react-router-dom";
import { useEffect, useState } from "react";
import { getDiary } from "../services/apis/diary/diary";
@@ -48,6 +48,8 @@ const DiaryDetail = () => {
}
}, [diary]);
+ const [starred, setStarred] = useState(false);
+
const formatDate = (rawDate: string) => {
const date = new Date(rawDate);
return `${date.getFullYear()}.${String(date.getMonth() + 1).padStart(2, "0")}.${String(date.getDate()).padStart(2, "0")}.`;
@@ -87,6 +89,11 @@ const DiaryDetail = () => {
alt={diary.character}
/>
{diary.character}
+ {starred ? (
+ setStarred(false)} />
+ ) : (
+ setStarred(true)} />
+ )}
{aiComment || "AI 코멘트를 생성 중입니다..."}
@@ -148,7 +155,7 @@ const EditIcon = styled(BsPencil)`
color: #1e2a52;
`;
-const Body = styled.div`
+export const Body = styled.div`
padding: 24px;
display: flex;
flex-direction: column;
@@ -162,13 +169,13 @@ const Title = styled.h2`
border-radius: 8px;
`;
-const TagBox = styled.div`
+export const TagBox = styled.div`
display: flex;
gap: 8px;
flex-wrap: wrap;
`;
-const Tag = styled.span`
+export const Tag = styled.span`
background: #ffffff;
color: #2563eb;
padding: 6px 12px;
@@ -191,34 +198,47 @@ const CommentTitle = styled.h3`
color: #1e2a52;
`;
-const CommentCard = styled.div`
+export const CommentCard = styled.div`
background: #fff;
border-radius: 16px;
padding: 16px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
`;
-const CharacterRow = styled.div`
+export const CharacterRow = styled.div`
display: flex;
align-items: center;
gap: 12px;
margin-bottom: 8px;
`;
-const CharacterImg = styled.img`
+export const CharacterImg = styled.img`
width: 40px;
height: 40px;
border-radius: 50%;
`;
-const CharacterName = styled.div`
+export const CharacterName = styled.div`
font-size: 16px;
font-weight: 600;
color: #1e2a52;
`;
-const CommentText = styled.p`
+export const CommentText = styled.p`
font-size: 14px;
color: #374151;
line-height: 1.6;
`;
+
+export const StarIcon = styled(BsStar)`
+ margin-left: auto;
+ font-size: 20px;
+ cursor: pointer;
+`;
+
+export const StarIconFill = styled(BsStarFill)`
+ margin-left: auto;
+ font-size: 20px;
+ color: #ffd600;
+ cursor: pointer;
+`;
diff --git a/src/pages/collection/Comments.tsx b/src/pages/collection/Comments.tsx
index 1de4d7f..3883190 100644
--- a/src/pages/collection/Comments.tsx
+++ b/src/pages/collection/Comments.tsx
@@ -1,9 +1,67 @@
+import { useState } from "react";
+import {
+ Body,
+ CharacterImg,
+ CharacterName,
+ CharacterRow,
+ CommentCard,
+ CommentText,
+ StarIcon,
+ StarIconFill,
+} from "../DiaryDetail";
+import Header from "../../components/diary/Header";
+
+const dummyComments = [
+ "오랜만에 영화관에서 좋은 시간 보냈다니 내가 다 기쁘다! 너의 여유로운 하루가 참 따뜻하게 느껴져 :)",
+ "오늘 하루도 수고 많았어! 너의 일상이 더 행복해지길 바랄게.",
+ "새로운 도전을 했다는 말에 나도 힘이 나! 계속 응원할게 :)",
+];
+
+const characterList = ["웅이", "앙글이", "티바노"];
+
const Comments = () => {
+ const [starred, setStarred] = useState(
+ new Array(dummyComments.length).fill(false),
+ );
+ const [currentIndex, setCurrentIndex] = useState(0);
+
return (
- <>
- <>Comments>
- 일단 없는 걸로
- >
+
+
+
+ 즐겨찾기 한 코멘트 목록
+ {dummyComments.map((comment, index) => (
+
+
+
+ 웅이
+ {starred[index] ? (
+ {
+ const newStars = [...starred];
+ newStars[index] = false;
+ setStarred(newStars);
+ }}
+ />
+ ) : (
+ {
+ const newStars = [...starred];
+ newStars[index] = true;
+ setStarred(newStars);
+ }}
+ />
+ )}
+
+ {comment}
+
+ ))}
+
);
};
+
export default Comments;
diff --git a/src/pages/collection/HashtagDetail.tsx b/src/pages/collection/HashtagDetail.tsx
new file mode 100644
index 0000000..73f1fd3
--- /dev/null
+++ b/src/pages/collection/HashtagDetail.tsx
@@ -0,0 +1,31 @@
+import { useState } from "react";
+import Header from "../../components/diary/Header";
+import { Body } from "../DiaryDetail";
+import DiaryList from "../../components/home/DiaryList";
+
+const characterList = [
+ "슬픔",
+ "행복",
+ "기쁨",
+ "사랑",
+ "우정",
+ "추억",
+ "여행",
+ "일상",
+ "꿈",
+];
+
+const HashtagDetail = () => {
+ const [currentIndex, setCurrentIndex] = useState(0);
+ return (
+
+
+
+
+ );
+};
+export default HashtagDetail;
diff --git a/src/pages/collection/Hashtags.tsx b/src/pages/collection/Hashtags.tsx
index e8e96d1..12afc32 100644
--- a/src/pages/collection/Hashtags.tsx
+++ b/src/pages/collection/Hashtags.tsx
@@ -1,9 +1,23 @@
+import { IoHomeOutline } from "react-icons/io5";
+import { Body, Tag, TagBox } from "../DiaryDetail";
+import { useNavigate } from "react-router-dom";
+
+const dummyHashtags = Array.from({ length: 50 }, (_, i) => `더미태그${i + 1}`);
+
const Hashtags = () => {
+ const navigate = useNavigate();
return (
- <>
- <>Hashtags>
- 일단 없는 걸로
- >
+
+ navigate("/")} />
+ 해시태그 목록
+
+ {dummyHashtags.map((tag, idx) => (
+ navigate(`/hashtag/${(idx + 1).toString()}`)}>
+ #{tag}
+
+ ))}
+
+
);
};
export default Hashtags;