From 9d1b136384eb638115e673a86cbe6fa5b449d5aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 17:25:18 +0900 Subject: [PATCH 01/36] =?UTF-8?q?design:=20=ED=85=8D=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EA=B0=80=20=EC=9E=88=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20border?= =?UTF-8?q?=EC=83=89=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/SendButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/assets/SendButton.tsx b/src/assets/SendButton.tsx index 2294d4c..4613d95 100644 --- a/src/assets/SendButton.tsx +++ b/src/assets/SendButton.tsx @@ -7,7 +7,7 @@ export const SendButton = ({ hasText = false }: SendButtonProps) => { return ( ); From 6fabbb4c023d2fec194f97f76f8a1d59aa3175f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 17:26:00 +0900 Subject: [PATCH 02/36] =?UTF-8?q?feat:=20=EA=B3=B5=EC=9C=A0=EC=9D=BC?= =?UTF-8?q?=EA=B8=B0=20=EB=8C=93=EA=B8=80=EC=B0=BD=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=9D=B8=ED=92=8B=ED=95=84=EB=93=9C=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=EC=8B=9C=20=EB=8C=93=EA=B8=80=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/MessageInput.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/common/MessageInput.tsx b/src/components/common/MessageInput.tsx index d483d6b..75bb5e6 100644 --- a/src/components/common/MessageInput.tsx +++ b/src/components/common/MessageInput.tsx @@ -2,17 +2,22 @@ import { useState } from "react"; import { SendButton } from "@/assets/SendButton"; -export const MessageInput = () => { +interface MessageInputProps { + onClick?: React.MouseEventHandler; +} + +export const MessageInput = ({ onClick }: MessageInputProps) => { const [text, setText] = useState(""); const hasText = Boolean(text); return (
setText(e.target.value)} + onClick={onClick} />
From 506304baed4a9185a0cf31fbacb7881fc96b4335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 17:27:08 +0900 Subject: [PATCH 03/36] =?UTF-8?q?feat:=20=EA=B3=B5=EC=9C=A0=EC=9D=BC?= =?UTF-8?q?=EA=B8=B0=20=EB=8C=93=EA=B8=80=20=EB=AA=A9=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mock/diaryComment.json | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/mock/diaryComment.json diff --git a/src/mock/diaryComment.json b/src/mock/diaryComment.json new file mode 100644 index 0000000..d6fcd61 --- /dev/null +++ b/src/mock/diaryComment.json @@ -0,0 +1,23 @@ +[ + { + "id": 1, + "userName": "박혜미", + "profileImg": "/images/profile.jpg", + "comment": "코코넛커피도 마셔주세요", + "createdAt": "2025-12-30T09:12:00" + }, + { + "id": 2, + "userName": "신수진", + "profileImg": "/images/profile.jpg", + "comment": "코코넛커피도 마셔주세요2", + "createdAt": "2025-12-30T09:12:00" + }, + { + "id": 3, + "userName": "박영신", + "profileImg": "/images/profile.jpg", + "comment": "코코넛커피도 마셔주세요3", + "createdAt": "2025-12-30T09:12:00" + } +] From afaa8dee38c004b81af8e5ba3204e60c6e3fda66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 17:28:02 +0900 Subject: [PATCH 04/36] =?UTF-8?q?feat:=20=EC=9D=B8=ED=92=8B=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=ED=81=B4=EB=A6=AD=20props=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/shared-diary/[id]/comment/page.tsx | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/app/shared-diary/[id]/comment/page.tsx diff --git a/src/app/shared-diary/[id]/comment/page.tsx b/src/app/shared-diary/[id]/comment/page.tsx new file mode 100644 index 0000000..b5cc797 --- /dev/null +++ b/src/app/shared-diary/[id]/comment/page.tsx @@ -0,0 +1,7 @@ +import { SharedDiaryComment } from "@/components/dailyRecord/SharedDiaryChat"; + +const SharedDiaryChatPage = () => { + return ; +}; + +export default SharedDiaryChatPage; From 91ee31ccf603fe648a28a0de904c22b4cb4b0898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 17:28:33 +0900 Subject: [PATCH 05/36] =?UTF-8?q?rename:=20chat=EB=8C=80=EC=8B=A0=20commen?= =?UTF-8?q?t=EB=A1=9C=20=ED=8C=8C=EC=9D=BC=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/dailyRecord/ShareDiaryItem.tsx | 4 +- .../dailyRecord/SharedDiaryChat.tsx | 38 ++++++++++++++++--- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/components/dailyRecord/ShareDiaryItem.tsx b/src/components/dailyRecord/ShareDiaryItem.tsx index 4693992..a457355 100644 --- a/src/components/dailyRecord/ShareDiaryItem.tsx +++ b/src/components/dailyRecord/ShareDiaryItem.tsx @@ -13,7 +13,7 @@ import { Diary } from "@/types/diary.type"; import { getEmotionMeta } from "@/utils/getEmotionMeta"; import { getTimeAgo } from "@/utils/getTimeAgo"; -import { SharedDiaryChat } from "./SharedDiaryChat"; +import { SharedDiaryComment } from "./SharedDiaryChat"; interface SharedDiaryItemProps { item: Diary; @@ -89,7 +89,7 @@ export const SharedDiaryItem = ({ {commentMode && (
- +
)} diff --git a/src/components/dailyRecord/SharedDiaryChat.tsx b/src/components/dailyRecord/SharedDiaryChat.tsx index 323a636..38daca0 100644 --- a/src/components/dailyRecord/SharedDiaryChat.tsx +++ b/src/components/dailyRecord/SharedDiaryChat.tsx @@ -1,20 +1,44 @@ "use client"; import Image from "next/image"; -import { useRouter } from "next/navigation"; +import { useParams, useRouter } from "next/navigation"; + +import { useState } from "react"; import CloseIcon from "@/assets/close.svg"; +import { MessageInput } from "@/components/common/MessageInput"; + +import CommentData from "@/mock/diaryComment.json"; import MyProfile from "@/mock/myProfile.json"; -import { MessageInput } from "../common/MessageInput"; +interface SharedDiaryCommentProps { + variant?: "modal" | "page"; +} -export const SharedDiaryChat = () => { +export const SharedDiaryComment = ({ + variant = "modal", +}: SharedDiaryCommentProps) => { const profileImg = MyProfile.profileImg; const router = useRouter(); + const { id } = useParams<{ id: string }>(); + const numericId = Number(id); + + const isPage = variant === "page"; + const [hasComment, setHasComment] = useState(false); return ( -
-
+
+
From 99a9353c3b14c82f843cb38eb468164c96e50ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 18:15:02 +0900 Subject: [PATCH 06/36] =?UTF-8?q?feat:=20=EA=B3=B5=EC=9C=A0=EC=9D=BC?= =?UTF-8?q?=EA=B8=B0=20=EB=8C=93=EA=B8=80=20=ED=83=80=EC=9E=85=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/diaryComment.type.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/types/diaryComment.type.ts diff --git a/src/types/diaryComment.type.ts b/src/types/diaryComment.type.ts new file mode 100644 index 0000000..e877568 --- /dev/null +++ b/src/types/diaryComment.type.ts @@ -0,0 +1,7 @@ +export type DiaryComment = { + id: number; + userName: string; + profileImg: string; + comment: string; + createdAt: string; +}; From 528d81fe09db9e668489f6c641e53e48d778b813 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 18:15:31 +0900 Subject: [PATCH 07/36] =?UTF-8?q?feat:=20=EB=82=A0=EC=A7=9C=20=EB=85=84?= =?UTF-8?q?=EC=9B=94=EC=9D=BC=EB=A1=9C=20=ED=8F=AC=EB=A7=A4=ED=8C=85?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=ED=95=A8=EC=88=98=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/formatDate.ts | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/utils/formatDate.ts diff --git a/src/utils/formatDate.ts b/src/utils/formatDate.ts new file mode 100644 index 0000000..271c85b --- /dev/null +++ b/src/utils/formatDate.ts @@ -0,0 +1,8 @@ +export const formatDate = (createdAt: string): string => { + const date = new Date(createdAt); + const year = date.getFullYear().toString().slice(2); + const month = String(date.getMonth() + 1).padStart(2, "0"); + const day = String(date.getDate()).padStart(2, "0"); + + return `${year}년 ${month}월${day}일`; +}; From 10d3ab3e4d385ae911c6688d23ae3ba001cbaad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 18:17:44 +0900 Subject: [PATCH 08/36] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=98=81=EC=97=AD=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EB=B6=84=EB=A6=AC=20=ED=9B=84,=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EA=B8=B0=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/dailyRecord/CommentList.tsx | 45 +++++++++++++++++++ .../dailyRecord/SharedDiaryChat.tsx | 14 +++--- src/mock/diaryComment.json | 10 ++--- 3 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 src/components/dailyRecord/CommentList.tsx diff --git a/src/components/dailyRecord/CommentList.tsx b/src/components/dailyRecord/CommentList.tsx new file mode 100644 index 0000000..04acd14 --- /dev/null +++ b/src/components/dailyRecord/CommentList.tsx @@ -0,0 +1,45 @@ +import Image from "next/image"; + +import { DiaryComment } from "@/types/diaryComment.type"; + +import { formatDate } from "@/utils/formatDate"; + +interface CommentListProps { + comments: DiaryComment[]; +} + +export const CommentList = ({ comments }: CommentListProps) => { + if (comments.length === 0) { + return ( +
+

아직 댓글이 없습니다

+

댓글을 남겨보세요!

+
+ ); + } + + return ( +
    + {comments.map(comment => ( +
  • + {comment.userName} +
    +
    +

    {comment.userName}

    +

    {comment.comment}

    +
    +

    + {formatDate(comment.createdAt)} +

    +
    +
  • + ))} +
+ ); +}; diff --git a/src/components/dailyRecord/SharedDiaryChat.tsx b/src/components/dailyRecord/SharedDiaryChat.tsx index 38daca0..f91424c 100644 --- a/src/components/dailyRecord/SharedDiaryChat.tsx +++ b/src/components/dailyRecord/SharedDiaryChat.tsx @@ -2,8 +2,6 @@ import Image from "next/image"; import { useParams, useRouter } from "next/navigation"; -import { useState } from "react"; - import CloseIcon from "@/assets/close.svg"; import { MessageInput } from "@/components/common/MessageInput"; @@ -11,6 +9,8 @@ import { MessageInput } from "@/components/common/MessageInput"; import CommentData from "@/mock/diaryComment.json"; import MyProfile from "@/mock/myProfile.json"; +import { CommentList } from "./CommentList"; + interface SharedDiaryCommentProps { variant?: "modal" | "page"; } @@ -24,7 +24,6 @@ export const SharedDiaryComment = ({ const numericId = Number(id); const isPage = variant === "page"; - const [hasComment, setHasComment] = useState(false); return (
{ + if (!isPage) router.back(); + }} >
e.stopPropagation()} >
@@ -48,10 +51,7 @@ export const SharedDiaryComment = ({

댓글

-
-

아직 댓글이 없습니다

-

댓글을 남겨보세요!

-
+
Date: Tue, 6 Jan 2026 18:55:59 +0900 Subject: [PATCH 09/36] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=20=EC=A0=84?= =?UTF-8?q?=EC=86=A1=ED=81=B4=EB=A6=AD=20=EC=8B=9C,=20=EB=8C=93=EA=B8=80?= =?UTF-8?q?=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=EC=97=90=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/SendButton.tsx | 8 ++++++-- src/components/common/MessageInput.tsx | 20 +++++++++++++++++-- src/components/dailyRecord/CommentList.tsx | 2 +- .../dailyRecord/SharedDiaryChat.tsx | 19 ++++++++++++++++-- src/mock/diaryComment.json | 6 +++--- 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/assets/SendButton.tsx b/src/assets/SendButton.tsx index 4613d95..c775409 100644 --- a/src/assets/SendButton.tsx +++ b/src/assets/SendButton.tsx @@ -2,10 +2,14 @@ import SendIcon from "@/assets/messenger.svg"; interface SendButtonProps { hasText: boolean; + onClick: React.MouseEventHandler; } -export const SendButton = ({ hasText = false }: SendButtonProps) => { +export const SendButton = ({ hasText = false, onClick }: SendButtonProps) => { return ( -
diff --git a/src/mock/diaryComment.json b/src/mock/diaryComment.json index cebeb5a..aa88400 100644 --- a/src/mock/diaryComment.json +++ b/src/mock/diaryComment.json @@ -2,21 +2,21 @@ { "id": 1, "userName": "박혜미", - "profileImg": "/images/profile.jpg", + "profileImg": "/images/1.jpg", "comment": "코코넛 커피도 마셔주세요", "createdAt": "2025-12-30T09:12:00" }, { "id": 2, "userName": "신수진", - "profileImg": "/images/profile.jpg", + "profileImg": "/images/2.jpg", "comment": "코코넛 커피도 마셔주세요2", "createdAt": "2026-01-01T09:12:00" }, { "id": 3, "userName": "박영신", - "profileImg": "/images/profile.jpg", + "profileImg": "/images/3.jpg", "comment": "코코넛 커피도 마셔주세요3", "createdAt": "2026-01-03T09:12:00" } From 10d1bd549a3a3cda689b94db995372beb33244ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 19:02:27 +0900 Subject: [PATCH 10/36] =?UTF-8?q?refactor:=20=EC=9D=B8=ED=92=8B=ED=95=84?= =?UTF-8?q?=EB=93=9C=20onClick=20=EB=9D=BC=EC=9A=B0=ED=8C=85=EC=9D=B4=20?= =?UTF-8?q?=EC=95=84=EB=8B=8C=20onFocus=EB=A1=9C=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EA=B0=80=20=EC=95=84=EB=8B=8C=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=EC=97=90=20=EB=9D=BC=EC=9A=B0=ED=8C=85=EB=90=98=EB=8A=94?= =?UTF-8?q?=EA=B2=83=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/common/MessageInput.tsx | 6 +++--- src/components/dailyRecord/SharedDiaryChat.tsx | 6 +++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/common/MessageInput.tsx b/src/components/common/MessageInput.tsx index a1174ce..71e8213 100644 --- a/src/components/common/MessageInput.tsx +++ b/src/components/common/MessageInput.tsx @@ -3,11 +3,11 @@ import { useState } from "react"; import { SendButton } from "@/assets/SendButton"; interface MessageInputProps { - onClick?: React.MouseEventHandler; + onFocus?: React.FocusEventHandler; onSend?: (message: string) => void; } -export const MessageInput = ({ onClick, onSend }: MessageInputProps) => { +export const MessageInput = ({ onFocus, onSend }: MessageInputProps) => { const [text, setText] = useState(""); const [isComposing, setIsComposing] = useState(false); @@ -25,7 +25,7 @@ export const MessageInput = ({ onClick, onSend }: MessageInputProps) => { type="text" value={text} onChange={e => setText(e.target.value)} - onClick={onClick} + onFocus={onFocus} onCompositionStart={() => setIsComposing(true)} onCompositionEnd={() => setIsComposing(false)} onKeyDown={e => { diff --git a/src/components/dailyRecord/SharedDiaryChat.tsx b/src/components/dailyRecord/SharedDiaryChat.tsx index 3bb734d..0eaf4f0 100644 --- a/src/components/dailyRecord/SharedDiaryChat.tsx +++ b/src/components/dailyRecord/SharedDiaryChat.tsx @@ -65,7 +65,11 @@ export const SharedDiaryComment = ({ className="h-[53px] w-[53px] rounded-full object-cover" /> router.push(`/shared-diary/${numericId}/comment`)} + onFocus={() => { + if (!isPage) { + router.push(`/shared-diary/${numericId}/comment`); + } + }} onSend={message => { setComments(prev => [ ...prev, From 48dd0e831e39028b49185f7ad310d3abb661b7a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 21:57:04 +0900 Subject: [PATCH 11/36] =?UTF-8?q?chore:=20toss=20use-funnel=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/app/shared-diary/[id]/upload/page.tsx | 0 yarn.lock | 88 ++++------------------- 3 files changed, 14 insertions(+), 76 deletions(-) create mode 100644 src/app/shared-diary/[id]/upload/page.tsx diff --git a/package.json b/package.json index 45e2f17..52497d7 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ ] }, "dependencies": { - "@toss/use-funnel": "^1.4.2", + "@use-funnel/next": "^0.0.22", "axios": "^1.13.2", "next": "16.0.10", "react": "19.2.1", diff --git a/src/app/shared-diary/[id]/upload/page.tsx b/src/app/shared-diary/[id]/upload/page.tsx new file mode 100644 index 0000000..e69de29 diff --git a/yarn.lock b/yarn.lock index 4a6fba9..9eb2775 100644 --- a/yarn.lock +++ b/yarn.lock @@ -847,7 +847,7 @@ "@babel/plugin-transform-modules-commonjs" "^7.27.1" "@babel/plugin-transform-typescript" "^7.28.5" -"@babel/runtime@^7.14.8", "@babel/runtime@^7.19.0", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.8", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2": +"@babel/runtime@^7.23.8", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== @@ -1507,63 +1507,6 @@ postcss "^8.4.41" tailwindcss "4.1.18" -"@toss/assert@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@toss/assert/-/assert-1.2.2.tgz#78a96586e134edd38947553b20a18bc24a692c52" - integrity sha512-qK2G1LzI2ghY0aUOsz9mFiy2v/eNlMHG5qXdSogfGFLxHqFZ6KQWJQpnb9eN+dyHYIudBVWPZhbkljqnT8R3/g== - dependencies: - "@toss/utils" "^1.6.1" - -"@toss/react@^1.8.1": - version "1.8.1" - resolved "https://registry.yarnpkg.com/@toss/react/-/react-1.8.1.tgz#d69d9e5dfed21c8f9fa791473293239e31ac5dda" - integrity sha512-jH3oo/7yctexuutj/YgQrddaK1bU2s5659dkJIXOe23bEjkY+lbhvEz2FLEhRjSo6k6ktPagpxO4AcdhCi5k5A== - dependencies: - "@babel/runtime" "^7.14.8" - "@toss/storage" "^1.4.1" - "@toss/utils" "^1.6.1" - classnames "^2.3.1" - lodash.debounce "^4.0.8" - lodash.throttle "^4.1.1" - -"@toss/storage@^1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@toss/storage/-/storage-1.4.1.tgz#c7f03946244a35631dbd4f40a7c513c314750f86" - integrity sha512-jvnBXAQ/Fqqdt+gqYKeHYk7SzR2LX/FC50JIoVI0RldG1mDh1tebOqD7XkrZ89q77t/RwTuh60+8fjZDgend/g== - dependencies: - "@babel/runtime" "^7.19.0" - -"@toss/use-funnel@^1.4.2": - version "1.4.2" - resolved "https://registry.yarnpkg.com/@toss/use-funnel/-/use-funnel-1.4.2.tgz#08e7d681e4f200fb83159100c037fb195dd43e8e" - integrity sha512-qgfYhdoJh07D4+kyRgRE3Du5wEdecFOR9Ht3MjgFMYAJyGplNbD++hpD/FcXrGT5oa14KG0bB5bpp60KLmPkFw== - dependencies: - "@toss/assert" "^1.2.2" - "@toss/react" "^1.8.1" - "@toss/storage" "^1.4.1" - "@toss/use-query-param" "^1.3.1" - "@toss/utils" "^1.6.1" - fast-deep-equal "^3.1.3" - -"@toss/use-query-param@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@toss/use-query-param/-/use-query-param-1.3.1.tgz#a9bc67692972f300b8d011e00f0af17f6fa3d7d0" - integrity sha512-GRA+6st46/88KgmP9PGx8mV9sxxkewwLMzBl25TpXPjnqHz+tiZdybVZMQ5UHj0Kzf7bZnHGF3kd5oko492vxA== - -"@toss/utility-types@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@toss/utility-types/-/utility-types-1.2.1.tgz#3c67bea23b7aaffd4b4e7c2a518773ae22a496f6" - integrity sha512-1y8s1bvmuhuMX/d6qR9mmvcgFZIKYIQqJbAIshlGArXkjk/ec67gXc5uByEV1Y7in9ZhrGNRmjD8DTH0988vpQ== - -"@toss/utils@^1.6.1": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@toss/utils/-/utils-1.6.1.tgz#e1226b1274b3d7e04b5b648ef11accdc013568c3" - integrity sha512-x6m8jLKWtAmCbxTLXbgTzJ5wZyRSUQPLpR/oLJP1ZK9ytXcRf03oA46W/+78kErUkEw/yQz2L+t2xFDHSeZ6IQ== - dependencies: - "@babel/runtime" "^7.14.8" - "@toss/utility-types" "^1.2.1" - date-fns "^2.25.0" - "@trivago/prettier-plugin-sort-imports@^6.0.0": version "6.0.1" resolved "https://registry.yarnpkg.com/@trivago/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-6.0.1.tgz#b71c020c4069c0b7a75953227ad6c803cea3f568" @@ -1849,6 +1792,18 @@ resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777" integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g== +"@use-funnel/core@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@use-funnel/core/-/core-0.0.13.tgz#3ca3a124d1ec0055a736f44bab91ca4bb7e394e9" + integrity sha512-0cFqUs0Z5QWnTG5ua2FZloKyGn3KAbA9miaFOa6RAeBmm74lilyFk4ovLe/9g1W58ZZlR3+1wbjDzyAT9yIGig== + +"@use-funnel/next@^0.0.22": + version "0.0.22" + resolved "https://registry.yarnpkg.com/@use-funnel/next/-/next-0.0.22.tgz#9cc4573087e21d3592f614d58adbedf1049093c3" + integrity sha512-AFdROs+MfC+HxVnHNyI6jNuWmgV1YjUq6IG2ckps2PTqPLp7ZowtmVAa1k7iJxEBu/0PXqXiLstEku1V8kZACQ== + dependencies: + "@use-funnel/core" "^0.0.13" + "@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": version "1.14.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" @@ -2345,11 +2300,6 @@ chrome-trace-event@^1.0.2: resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== -classnames@^2.3.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" - integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== - cli-cursor@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-5.0.0.tgz#24a4831ecf5a6b01ddeb32fb71a4b2088b0dce38" @@ -2521,13 +2471,6 @@ data-view-byte-offset@^1.0.1: es-errors "^1.3.0" is-data-view "^1.0.1" -date-fns@^2.25.0: - version "2.30.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" - integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== - dependencies: - "@babel/runtime" "^7.21.0" - debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -3875,11 +3818,6 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.throttle@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" - integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== - log-update@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-6.1.0.tgz#1a04ff38166f94647ae1af562f4bd6a15b1b7cd4" From e763d5e5e29264938707aea8ad069acdbccb6b40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 6 Jan 2026 23:09:12 +0900 Subject: [PATCH 12/36] =?UTF-8?q?feat:=20=EB=8C=93=EA=B8=80=EC=9D=B4=20?= =?UTF-8?q?=EB=A7=8E=EC=9D=84=20=EA=B2=BD=EC=9A=B0=EC=97=90=20=EC=8A=A4?= =?UTF-8?q?=ED=81=AC=EB=A1=A4=EC=98=81=EC=97=AD=20ui=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailyRecord/SharedDiaryChat.tsx | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/components/dailyRecord/SharedDiaryChat.tsx b/src/components/dailyRecord/SharedDiaryChat.tsx index 0eaf4f0..c1c9181 100644 --- a/src/components/dailyRecord/SharedDiaryChat.tsx +++ b/src/components/dailyRecord/SharedDiaryChat.tsx @@ -3,6 +3,7 @@ import Image from "next/image"; import { useParams, useRouter } from "next/navigation"; import { useState } from "react"; +import { useEffect } from "react"; import CloseIcon from "@/assets/close.svg"; @@ -28,6 +29,16 @@ export const SharedDiaryComment = ({ const isPage = variant === "page"; const [comments, setComments] = useState(CommentData); + useEffect(() => { + if (!isPage) { + document.body.style.overflow = "hidden"; + } + + return () => { + document.body.style.overflow = ""; + }; + }, [isPage]); + return (
e.stopPropagation()} > -
-
- -
-

- 댓글 -

+
+ +
+

+ 댓글 +

+
+
Date: Tue, 6 Jan 2026 23:40:27 +0900 Subject: [PATCH 13/36] =?UTF-8?q?design:=20=ED=95=98=EB=A3=A8=ED=95=9C?= =?UTF-8?q?=EC=BB=B7=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EB=B0=B1=ED=97=A4?= =?UTF-8?q?=EB=8D=94=20text-white=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/day-story/upload/page.tsx | 11 +++++++++++ src/app/shared-diary/[id]/upload/page.tsx | 0 src/app/shared-diary/upload/page.tsx | 1 + src/assets/left-arrow.svg | 2 +- src/components/common/BackHeader.tsx | 14 +++++++++++--- 5 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 src/app/day-story/upload/page.tsx delete mode 100644 src/app/shared-diary/[id]/upload/page.tsx create mode 100644 src/app/shared-diary/upload/page.tsx diff --git a/src/app/day-story/upload/page.tsx b/src/app/day-story/upload/page.tsx new file mode 100644 index 0000000..dd850da --- /dev/null +++ b/src/app/day-story/upload/page.tsx @@ -0,0 +1,11 @@ +import { BackHeader } from "@/components/common/BackHeader"; + +//하루한컷 업로드 페이지 +const DayStoryUpload = () => { + return ( +
+ +
+ ); +}; +export default DayStoryUpload; diff --git a/src/app/shared-diary/[id]/upload/page.tsx b/src/app/shared-diary/[id]/upload/page.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/app/shared-diary/upload/page.tsx b/src/app/shared-diary/upload/page.tsx new file mode 100644 index 0000000..2635d6a --- /dev/null +++ b/src/app/shared-diary/upload/page.tsx @@ -0,0 +1 @@ +//공유일기 글쓰기 페이지 diff --git a/src/assets/left-arrow.svg b/src/assets/left-arrow.svg index e099fe1..fc0a3f2 100644 --- a/src/assets/left-arrow.svg +++ b/src/assets/left-arrow.svg @@ -1,3 +1,3 @@ - + diff --git a/src/components/common/BackHeader.tsx b/src/components/common/BackHeader.tsx index 1d9865d..dc69df6 100644 --- a/src/components/common/BackHeader.tsx +++ b/src/components/common/BackHeader.tsx @@ -9,9 +9,15 @@ interface HeaderProps { title: string; timeAgo?: string; // 하루한컷보기에서 사용 menuIcon?: boolean; // 채팅페이지에서 사용 + titleColor?: string; //하루한컷 업로드에서 사용 } -export const BackHeader = ({ title, timeAgo, menuIcon }: HeaderProps) => { +export const BackHeader = ({ + title, + timeAgo, + menuIcon, + titleColor = "black", +}: HeaderProps) => { const router = useRouter(); return ( @@ -21,9 +27,11 @@ export const BackHeader = ({ title, timeAgo, menuIcon }: HeaderProps) => { onClick={() => router.back()} className="absolute top-1/2 left-4 -translate-y-1/2 cursor-pointer" > - + -

+

{title}

{timeAgo && ( From 8f7b486998dc4203a637b83c9a212fd5539516d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Wed, 7 Jan 2026 02:40:17 +0900 Subject: [PATCH 14/36] =?UTF-8?q?feat:=20=EC=9A=94=EC=9D=BC=20=EB=B0=B0?= =?UTF-8?q?=EC=97=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/dayToKorean.ts | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/constants/dayToKorean.ts diff --git a/src/constants/dayToKorean.ts b/src/constants/dayToKorean.ts new file mode 100644 index 0000000..5244983 --- /dev/null +++ b/src/constants/dayToKorean.ts @@ -0,0 +1 @@ +export const WEEK_DAYS = ["월", "화", "수", "목", "금", "토", "일"] as const; From 3f99a50b638ae88fb6caa6b533926061f423743c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Wed, 7 Jan 2026 02:41:17 +0900 Subject: [PATCH 15/36] =?UTF-8?q?feat:=20=EA=B3=BC=EA=B1=B0,=20=ED=98=84?= =?UTF-8?q?=EC=9E=AC,=20=EB=AF=B8=EB=9E=98=20=EC=9A=94=EC=9D=BC=EC=9D=84?= =?UTF-8?q?=20=EC=95=8C=EC=95=84=EB=82=B4=EB=8A=94=20=EC=9C=A0=ED=8B=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/getCurrentDay.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/utils/getCurrentDay.ts diff --git a/src/utils/getCurrentDay.ts b/src/utils/getCurrentDay.ts new file mode 100644 index 0000000..f03fe2d --- /dev/null +++ b/src/utils/getCurrentDay.ts @@ -0,0 +1,18 @@ +// 월:0 ~ 일:6 +export const getMondayStartIndex = (day: number) => (day === 0 ? 6 : day - 1); + +// 오늘 요일 인덱스 +export const getTodayIndex = () => { + const today = new Date().getDay(); + return getMondayStartIndex(today); +}; + +type DayStatus = "past" | "today" | "future"; + +export const getWeekDayStatus = (targetIndex: number): DayStatus => { + const todayIndex = getTodayIndex(); + + if (targetIndex < todayIndex) return "past"; + if (targetIndex > todayIndex) return "future"; + return "today"; +}; From 5e6ef7611f6f905d74825b516a55926e040f7583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Wed, 7 Jan 2026 02:42:18 +0900 Subject: [PATCH 16/36] =?UTF-8?q?rename:=20=ED=95=98=EB=A3=A8=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=EB=B0=94=EB=80=90=20=EB=A7=81=ED=81=AC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/navBarItems.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants/navBarItems.ts b/src/constants/navBarItems.ts index fe8bc36..aa8a099 100644 --- a/src/constants/navBarItems.ts +++ b/src/constants/navBarItems.ts @@ -22,7 +22,7 @@ export const NAV_ITEMS = [ { key: "record", label: "하루기록", - href: "/record", + href: "/day-log", icons: { blank: RecordBlankIcon, fill: RecordFillIcon, From 95f3e7adc72660a4201ccc65f97968b9ea140afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Wed, 7 Jan 2026 02:42:58 +0900 Subject: [PATCH 17/36] =?UTF-8?q?feat:=20=ED=95=98=EB=A3=A8=ED=95=9C?= =?UTF-8?q?=EC=BB=B7=20=EB=AF=B8=EC=85=98=EC=A7=84=ED=96=89=ED=98=84?= =?UTF-8?q?=ED=99=A9=20=ED=94=BC=EB=93=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/day-story/upload/page.tsx | 2 + src/assets/questionMark.svg | 3 ++ .../dailyPhoto/DailyMissionProgress.tsx | 49 +++++++++++++++++++ .../dailyRecord/SharedDiaryChat.tsx | 2 +- 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 src/assets/questionMark.svg create mode 100644 src/components/dailyPhoto/DailyMissionProgress.tsx diff --git a/src/app/day-story/upload/page.tsx b/src/app/day-story/upload/page.tsx index dd850da..9d6cca8 100644 --- a/src/app/day-story/upload/page.tsx +++ b/src/app/day-story/upload/page.tsx @@ -1,10 +1,12 @@ import { BackHeader } from "@/components/common/BackHeader"; +import { DailyMissionProgress } from "@/components/dailyPhoto/DailyMissionProgress"; //하루한컷 업로드 페이지 const DayStoryUpload = () => { return (
+
); }; diff --git a/src/assets/questionMark.svg b/src/assets/questionMark.svg new file mode 100644 index 0000000..bbc61af --- /dev/null +++ b/src/assets/questionMark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/dailyPhoto/DailyMissionProgress.tsx b/src/components/dailyPhoto/DailyMissionProgress.tsx new file mode 100644 index 0000000..d8481ac --- /dev/null +++ b/src/components/dailyPhoto/DailyMissionProgress.tsx @@ -0,0 +1,49 @@ +"use client"; + +import CheckIcon from "@/assets/check.svg"; +import QuestionIcon from "@/assets/questionMark.svg"; + +import { WEEK_DAYS } from "@/constants/dayToKorean"; + +import { getWeekDayStatus } from "@/utils/getCurrentDay"; + +export const DailyMissionProgress = () => { + return ( +
    + {WEEK_DAYS.map((item, index) => { + const status = getWeekDayStatus(index); // past | today | future + const isTodayCompleted = false; + + const showCheck = + status === "past" || (status === "today" && isTodayCompleted); + + return ( +
  • +
    + {showCheck ? ( +
    + +
    + ) : ( +
    + +
    + )} + + {item} + +
    +
  • + ); + })} +
+ ); +}; diff --git a/src/components/dailyRecord/SharedDiaryChat.tsx b/src/components/dailyRecord/SharedDiaryChat.tsx index c1c9181..6dfe098 100644 --- a/src/components/dailyRecord/SharedDiaryChat.tsx +++ b/src/components/dailyRecord/SharedDiaryChat.tsx @@ -64,7 +64,7 @@ export const SharedDiaryComment = ({

댓글

-
+
From 57e3a87f25f45bcf03c38d837083e2477a3186c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Wed, 7 Jan 2026 04:31:36 +0900 Subject: [PATCH 18/36] =?UTF-8?q?feat:=20=ED=95=98=EB=A3=A8=ED=95=9C?= =?UTF-8?q?=EC=BB=B7=20=EC=97=85=EB=A1=9C=EB=93=9C=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/dailyRecord/Header.tsx | 2 +- src/components/dailyRecord/MissionFeed.tsx | 9 +++- src/components/dailyRecord/MissionInfo.tsx | 56 ++++++++++++---------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/components/dailyRecord/Header.tsx b/src/components/dailyRecord/Header.tsx index 850644e..56158af 100644 --- a/src/components/dailyRecord/Header.tsx +++ b/src/components/dailyRecord/Header.tsx @@ -13,7 +13,7 @@ export const Header = () => { return (
-

하루기록

+

하루기록

{isAlarmNew ? ( +
+ ); +}; From 0494d6ce7120a4841999254bc799d8b0b99e9f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Wed, 7 Jan 2026 04:46:44 +0900 Subject: [PATCH 23/36] =?UTF-8?q?design:=20=EB=AF=B8=EC=85=98=ED=85=8D?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=99=80=20=EB=B2=84=ED=8A=BC=20=EA=B0=84?= =?UTF-8?q?=EA=B2=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/dailyPhoto/DailyMissionCard.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/dailyPhoto/DailyMissionCard.tsx b/src/components/dailyPhoto/DailyMissionCard.tsx index 980f789..4c5be01 100644 --- a/src/components/dailyPhoto/DailyMissionCard.tsx +++ b/src/components/dailyPhoto/DailyMissionCard.tsx @@ -28,14 +28,16 @@ export const DailyMissionCard = () => {
{/* 아이콘 영역 */}
-
- 오늘의 하늘을 공유해주세요. +
+
+ 오늘의 하늘을 공유해주세요. +
+
- ); }; From 7dfdcac544577b9a97ad4fabd88e12aaa041d5a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Fri, 9 Jan 2026 23:55:43 +0900 Subject: [PATCH 24/36] =?UTF-8?q?feat:=20=EB=AF=B8=EC=85=98=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EC=A2=85=EB=A5=98=EC=9D=98=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=EC=BD=98=20=EB=B0=8F=20=EC=83=81=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/missionIcon/color.svg | 9 +++++++++ public/images/missionIcon/food.svg | 9 +++++++++ public/images/missionIcon/plant.svg | 9 +++++++++ public/images/missionIcon/time.svg | 9 +++++++++ public/images/missionIcon/tv.svg | 9 +++++++++ src/constants/missionCard.ts | 11 +++++++++++ 6 files changed, 56 insertions(+) create mode 100644 public/images/missionIcon/color.svg create mode 100644 public/images/missionIcon/food.svg create mode 100644 public/images/missionIcon/plant.svg create mode 100644 public/images/missionIcon/time.svg create mode 100644 public/images/missionIcon/tv.svg diff --git a/public/images/missionIcon/color.svg b/public/images/missionIcon/color.svg new file mode 100644 index 0000000..98fe240 --- /dev/null +++ b/public/images/missionIcon/color.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/missionIcon/food.svg b/public/images/missionIcon/food.svg new file mode 100644 index 0000000..a4c2552 --- /dev/null +++ b/public/images/missionIcon/food.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/missionIcon/plant.svg b/public/images/missionIcon/plant.svg new file mode 100644 index 0000000..f29c66d --- /dev/null +++ b/public/images/missionIcon/plant.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/missionIcon/time.svg b/public/images/missionIcon/time.svg new file mode 100644 index 0000000..4da007f --- /dev/null +++ b/public/images/missionIcon/time.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/images/missionIcon/tv.svg b/public/images/missionIcon/tv.svg new file mode 100644 index 0000000..55fb1b5 --- /dev/null +++ b/public/images/missionIcon/tv.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/constants/missionCard.ts b/src/constants/missionCard.ts index c52a560..2ee05d5 100644 --- a/src/constants/missionCard.ts +++ b/src/constants/missionCard.ts @@ -15,3 +15,14 @@ export const MISSION_STATUS = { buttonText: "확인", }, } as const; + +export const MISSION_SORT = [ + { sort: "food", icon: "/images/missionIcon/food.svg" }, + { + sort: "plant", + icon: "/images/missionIcon/plant.svg", + }, + { sort: "color", icon: "/images/missionIcon/color.svg" }, + { sort: "time", icon: "/images/missionIcon/time.svg" }, + { sort: "tv", icon: "/images/missionIcon/tv.svg" }, +]; From b6cc4865a429460b28b2aed9f0ee494defdba529 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Sun, 11 Jan 2026 18:36:49 +0900 Subject: [PATCH 25/36] =?UTF-8?q?feat:=20=ED=95=98=EB=A3=A8=ED=95=9C?= =?UTF-8?q?=EC=BB=B7=20=EB=AF=B8=EC=85=98=EC=B9=B4=EB=93=9C=20=EC=9D=B4?= =?UTF-8?q?=EB=AA=A8=EC=A7=80=20=EB=B0=8F=20=ED=83=80=EC=9D=B4=ED=8B=80=20?= =?UTF-8?q?=EB=AA=A9=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailyPhoto/DailyMissionCard.tsx | 28 +++++++++++++++---- src/mock/randomMission.json | 13 +++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 src/mock/randomMission.json diff --git a/src/components/dailyPhoto/DailyMissionCard.tsx b/src/components/dailyPhoto/DailyMissionCard.tsx index 4c5be01..3a656c7 100644 --- a/src/components/dailyPhoto/DailyMissionCard.tsx +++ b/src/components/dailyPhoto/DailyMissionCard.tsx @@ -1,8 +1,12 @@ "use client"; +import Image from "next/image"; + import { useState } from "react"; import { WEEK_DAYS } from "@/constants/dayToKorean"; -import { MISSION_STATUS } from "@/constants/missionCard"; +import { MISSION_SORT, MISSION_STATUS } from "@/constants/missionCard"; + +import missionCardData from "@/mock/randomMission.json"; import { getTodayIndex } from "@/utils/getCurrentDay"; @@ -17,6 +21,12 @@ export const DailyMissionCard = () => { ? `${MISSION_STATUS[status].subtitle(currentDay)}요일` : MISSION_STATUS[status].subtitle; + const missionKind = missionCardData[0].kind; + + const missionIcon = MISSION_SORT.find( + item => item.sort === missionKind, + )?.icon; + return (
@@ -25,12 +35,20 @@ export const DailyMissionCard = () => {

{subtitle}

-
- {/* 아이콘 영역 */} -
+ {missionIcon && ( +
+ 미션카드종류 이미지 +
+ )} +
- 오늘의 하늘을 공유해주세요. + {missionCardData[0].mission}

diff --git a/src/utils/getCurrentDay.ts b/src/utils/getCurrentDay.ts index f03fe2d..f0b1969 100644 --- a/src/utils/getCurrentDay.ts +++ b/src/utils/getCurrentDay.ts @@ -10,7 +10,7 @@ export const getTodayIndex = () => { type DayStatus = "past" | "today" | "future"; export const getWeekDayStatus = (targetIndex: number): DayStatus => { - const todayIndex = getTodayIndex(); + const todayIndex = 4; if (targetIndex < todayIndex) return "past"; if (targetIndex > todayIndex) return "future"; From 5137aacbe7865e827d067efd38c7be3aabb1c5d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Mon, 12 Jan 2026 23:58:02 +0900 Subject: [PATCH 27/36] =?UTF-8?q?feat:=20=ED=95=98=EB=A3=A8=ED=95=9C?= =?UTF-8?q?=EC=BB=B7=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=97=85=EB=A1=9C?= =?UTF-8?q?=EB=93=9C=20=EC=8B=9C=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dailyPhoto/DailyMissionCard.tsx | 47 ++++++++++++++++++- src/constants/missionCard.ts | 4 +- src/hooks/useImageUpload.ts | 42 +++++++++++++++++ src/utils/getCurrentDay.ts | 2 +- src/utils/uploadImage.util.ts | 35 ++++++++++++++ 5 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 src/hooks/useImageUpload.ts create mode 100644 src/utils/uploadImage.util.ts diff --git a/src/components/dailyPhoto/DailyMissionCard.tsx b/src/components/dailyPhoto/DailyMissionCard.tsx index 3a656c7..da1e9bc 100644 --- a/src/components/dailyPhoto/DailyMissionCard.tsx +++ b/src/components/dailyPhoto/DailyMissionCard.tsx @@ -1,11 +1,14 @@ "use client"; import Image from "next/image"; +import { useRouter } from "next/navigation"; import { useState } from "react"; import { WEEK_DAYS } from "@/constants/dayToKorean"; import { MISSION_SORT, MISSION_STATUS } from "@/constants/missionCard"; +import { useImageUpload } from "@/hooks/useImageUpload"; + import missionCardData from "@/mock/randomMission.json"; import { getTodayIndex } from "@/utils/getCurrentDay"; @@ -13,6 +16,8 @@ import { getTodayIndex } from "@/utils/getCurrentDay"; export const DailyMissionCard = () => { const [status, setStatus] = useState("NOT_STARTED"); + const [previewUrl, setPreviewUrl] = useState(null); + const currentDayIndex = getTodayIndex(); const currentDay = WEEK_DAYS[currentDayIndex]; // 현재 요일 @@ -27,6 +32,19 @@ export const DailyMissionCard = () => { item => item.sort === missionKind, )?.icon; + const onSelectImage = (file: File) => { + const url = URL.createObjectURL(file); + setPreviewUrl(url); + setStatus("IMAGE_UPLOADED"); + }; + + const { inputRef, openFilePicker, onChangeFile } = useImageUpload({ + onSelect: ({ file }) => { + onSelectImage(file); + }, + maxSizeMB: 10, + }); + const router = useRouter(); return (
@@ -35,7 +53,7 @@ export const DailyMissionCard = () => {

{subtitle}

- {missionIcon && ( + {status === "NOT_STARTED" && missionIcon && (
{ />
)} + {status !== "NOT_STARTED" && previewUrl && ( +
+ 하루한컷이미지 +
+ )}
{missionCardData[0].mission}
+ ); }; diff --git a/src/constants/missionCard.ts b/src/constants/missionCard.ts index 2ee05d5..13f537b 100644 --- a/src/constants/missionCard.ts +++ b/src/constants/missionCard.ts @@ -7,12 +7,12 @@ export const MISSION_STATUS = { IMAGE_UPLOADED: { title: "하루한컷 미션을 공유할까요?", subtitle: "확인을 누르면 미션이 완료돼요", - buttonText: "완료하기", + buttonText: "공유하기", }, IMAGE_CONFIRMED: { title: "미션이 완료되었어요", subtitle: "소중한 오늘의 한컷을 기록했어요", - buttonText: "확인", + buttonText: "보러가기", }, } as const; diff --git a/src/hooks/useImageUpload.ts b/src/hooks/useImageUpload.ts new file mode 100644 index 0000000..54d56d1 --- /dev/null +++ b/src/hooks/useImageUpload.ts @@ -0,0 +1,42 @@ +import { useRef } from "react"; + +import { UploadImageResult, uploadImage } from "@/utils/uploadImage.util"; + +interface UseImageUploadProps { + onSelect: (result: UploadImageResult) => void; + maxSizeMB?: number; +} + +export const useImageUpload = ({ + onSelect, + maxSizeMB, +}: UseImageUploadProps) => { + const inputRef = useRef(null); + + const openFilePicker = () => { + inputRef.current?.click(); + }; + + const onChangeFile = (e: React.ChangeEvent) => { + const file = e.target.files?.[0]; + if (!file) return; + + try { + const result = uploadImage(file, { maxSizeMB }); + onSelect(result); + } catch (error) { + if (error instanceof Error) { + alert(error.message); + } + } + + // 같은 파일 재선택 가능하게 + e.target.value = ""; + }; + + return { + inputRef, + openFilePicker, + onChangeFile, + }; +}; diff --git a/src/utils/getCurrentDay.ts b/src/utils/getCurrentDay.ts index f0b1969..f03fe2d 100644 --- a/src/utils/getCurrentDay.ts +++ b/src/utils/getCurrentDay.ts @@ -10,7 +10,7 @@ export const getTodayIndex = () => { type DayStatus = "past" | "today" | "future"; export const getWeekDayStatus = (targetIndex: number): DayStatus => { - const todayIndex = 4; + const todayIndex = getTodayIndex(); if (targetIndex < todayIndex) return "past"; if (targetIndex > todayIndex) return "future"; diff --git a/src/utils/uploadImage.util.ts b/src/utils/uploadImage.util.ts new file mode 100644 index 0000000..705b486 --- /dev/null +++ b/src/utils/uploadImage.util.ts @@ -0,0 +1,35 @@ +export interface UploadImageOptions { + maxSizeMB?: number; + allowedTypes?: string[]; +} + +export interface UploadImageResult { + file: File; + previewUrl: string; +} + +export const uploadImage = ( + file: File, + options: UploadImageOptions = {}, +): UploadImageResult => { + const { + maxSizeMB = 5, + allowedTypes = ["image/jpeg", "image/png", "image/webp"], + } = options; + + // 타입 검사 + if (!allowedTypes.includes(file.type)) { + throw new Error("지원하지 않는 이미지 형식입니다."); + } + + // 용량 검사 + const maxSize = maxSizeMB * 1024 * 1024; + if (file.size > maxSize) { + throw new Error(`이미지 용량은 ${maxSizeMB}MB 이하만 가능합니다.`); + } + + return { + file, + previewUrl: URL.createObjectURL(file), + }; +}; From 3f510c47cd655a408a0f2fa48e7387b8682f2f85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 13 Jan 2026 00:25:42 +0900 Subject: [PATCH 28/36] =?UTF-8?q?feat:=20=ED=95=98=EB=A3=A8=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=20=EC=A7=84=ED=96=89=EC=83=81=ED=99=A9=20=EB=AA=A9?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mock/dailyRecordProgress.json | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/mock/dailyRecordProgress.json diff --git a/src/mock/dailyRecordProgress.json b/src/mock/dailyRecordProgress.json new file mode 100644 index 0000000..26b76ba --- /dev/null +++ b/src/mock/dailyRecordProgress.json @@ -0,0 +1,9 @@ +{ + "monday": true, + "tuesday": false, + "wednesday": true, + "thursday": false, + "friday": false, + "saturday": true, + "sunday": false +} From df87e1efeaac98d2f39813065d79ceb9b6f88507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 13 Jan 2026 00:26:24 +0900 Subject: [PATCH 29/36] =?UTF-8?q?feat:=20=EC=9A=94=EC=9D=BC=20=ED=82=A4=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/constants/dayToKorean.ts | 1 - src/constants/weekDays.ts | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) delete mode 100644 src/constants/dayToKorean.ts create mode 100644 src/constants/weekDays.ts diff --git a/src/constants/dayToKorean.ts b/src/constants/dayToKorean.ts deleted file mode 100644 index 5244983..0000000 --- a/src/constants/dayToKorean.ts +++ /dev/null @@ -1 +0,0 @@ -export const WEEK_DAYS = ["월", "화", "수", "목", "금", "토", "일"] as const; diff --git a/src/constants/weekDays.ts b/src/constants/weekDays.ts new file mode 100644 index 0000000..8fb05b7 --- /dev/null +++ b/src/constants/weekDays.ts @@ -0,0 +1,19 @@ +export const WEEK_DAYS_KOR = [ + "월", + "화", + "수", + "목", + "금", + "토", + "일", +] as const; + +export const WEEK_DAY_KEYS = [ + "monday", + "tuesday", + "wednesday", + "thursday", + "friday", + "saturday", + "sunday", +] as const; From c916ad1f716200763adbf1ff52f02b0a27f37648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 13 Jan 2026 00:27:17 +0900 Subject: [PATCH 30/36] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=20=ED=9B=84=20=ED=95=98=EB=A3=A8?= =?UTF-8?q?=ED=95=9C=EC=BB=B7=20=EC=9E=91=EC=84=B1=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=EB=A1=9C=20=EC=83=81=ED=83=9C=20=EB=82=B4?= =?UTF-8?q?=EB=A0=A4=EC=A4=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/day-story/upload/page.tsx | 12 +++-- .../dailyPhoto/DailyMissionCard.tsx | 16 ++++--- .../dailyPhoto/DailyMissionProgress.tsx | 45 +++++++++++++------ 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/src/app/day-story/upload/page.tsx b/src/app/day-story/upload/page.tsx index ebc9d16..771bbb1 100644 --- a/src/app/day-story/upload/page.tsx +++ b/src/app/day-story/upload/page.tsx @@ -1,15 +1,21 @@ +"use client"; +import { useState } from "react"; + import { BackHeader } from "@/components/common/BackHeader"; import { DailyMissionCard } from "@/components/dailyPhoto/DailyMissionCard"; import { DailyMissionProgress } from "@/components/dailyPhoto/DailyMissionProgress"; -//하루한컷 업로드 페이지 +import { MISSION_STATUS } from "@/constants/missionCard"; + const DayStoryUpload = () => { + const [status, setStatus] = + useState("NOT_STARTED"); return (
- +
- +
); diff --git a/src/components/dailyPhoto/DailyMissionCard.tsx b/src/components/dailyPhoto/DailyMissionCard.tsx index da1e9bc..d28a075 100644 --- a/src/components/dailyPhoto/DailyMissionCard.tsx +++ b/src/components/dailyPhoto/DailyMissionCard.tsx @@ -4,8 +4,8 @@ import { useRouter } from "next/navigation"; import { useState } from "react"; -import { WEEK_DAYS } from "@/constants/dayToKorean"; import { MISSION_SORT, MISSION_STATUS } from "@/constants/missionCard"; +import { WEEK_DAYS_KOR } from "@/constants/weekDays"; import { useImageUpload } from "@/hooks/useImageUpload"; @@ -13,13 +13,19 @@ import missionCardData from "@/mock/randomMission.json"; import { getTodayIndex } from "@/utils/getCurrentDay"; -export const DailyMissionCard = () => { - const [status, setStatus] = - useState("NOT_STARTED"); +interface DailyMissionCardProps { + status: keyof typeof MISSION_STATUS; + setStatus: React.Dispatch>; +} + +export const DailyMissionCard = ({ + status, + setStatus, +}: DailyMissionCardProps) => { const [previewUrl, setPreviewUrl] = useState(null); const currentDayIndex = getTodayIndex(); - const currentDay = WEEK_DAYS[currentDayIndex]; // 현재 요일 + const currentDay = WEEK_DAYS_KOR[currentDayIndex]; // 현재 요일 const subtitle = typeof MISSION_STATUS[status].subtitle === "function" diff --git a/src/components/dailyPhoto/DailyMissionProgress.tsx b/src/components/dailyPhoto/DailyMissionProgress.tsx index c0c0728..0cd1d67 100644 --- a/src/components/dailyPhoto/DailyMissionProgress.tsx +++ b/src/components/dailyPhoto/DailyMissionProgress.tsx @@ -4,29 +4,44 @@ import CheckIcon from "@/assets/check.svg"; import CrossIcon from "@/assets/close.svg"; import QuestionIcon from "@/assets/questionMark.svg"; -import { WEEK_DAYS } from "@/constants/dayToKorean"; +import { MISSION_STATUS } from "@/constants/missionCard"; +import { WEEK_DAYS_KOR, WEEK_DAY_KEYS } from "@/constants/weekDays"; + +import dailyRecordProgress from "@/mock/dailyRecordProgress.json"; import { getWeekDayStatus } from "@/utils/getCurrentDay"; -export const DailyMissionProgress = () => { +type WeekDayKey = keyof typeof dailyRecordProgress; + +interface DailyMissionProgressProps { + status: keyof typeof MISSION_STATUS; +} + +export const DailyMissionProgress = ({ status }: DailyMissionProgressProps) => { return (
    - {WEEK_DAYS.map((item, index) => { - const status = getWeekDayStatus(index); // past | today | future - const isCompleted = false; + {WEEK_DAYS_KOR.map((item, index) => { + const dayStatus = getWeekDayStatus(index); // past | today | future + const dayKey = WEEK_DAY_KEYS[index] as WeekDayKey; + + const isCompleted = + dayStatus === "today" && status === "IMAGE_CONFIRMED" + ? true + : dailyRecordProgress[dayKey]; const showCheck = - (status === "past" && isCompleted) || - (status === "today" && isCompleted); + (dayStatus === "past" && isCompleted) || + (dayStatus === "today" && isCompleted); + + const showCross = dayStatus === "past" && !isCompleted; - const showCross = status === "past" && !isCompleted; const showQuestion = - status === "future" || (status === "today" && !isCompleted); + dayStatus === "future" || (dayStatus === "today" && !isCompleted); return (
  • {showCheck && (
    @@ -42,16 +57,20 @@ export const DailyMissionProgress = () => { {showQuestion && (
    )} {item} From c31ff2dbfacc6adc33f9635fa6cf387258a22f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=8B=A0=EC=88=98=EC=A7=84?= Date: Tue, 13 Jan 2026 00:37:16 +0900 Subject: [PATCH 31/36] =?UTF-8?q?design:=20=ED=95=98=EB=A3=A8=ED=95=9C?= =?UTF-8?q?=EC=BB=B7=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EB=94=94=EC=9E=90?= =?UTF-8?q?=EC=9D=B8=20=EB=B3=80=EA=B2=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/day-story/upload/page.tsx | 2 +- src/components/dailyPhoto/DailyMissionCard.tsx | 4 +++- src/constants/missionCard.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/app/day-story/upload/page.tsx b/src/app/day-story/upload/page.tsx index 771bbb1..8854fa0 100644 --- a/src/app/day-story/upload/page.tsx +++ b/src/app/day-story/upload/page.tsx @@ -14,7 +14,7 @@ const DayStoryUpload = () => {
    -
    +
    diff --git a/src/components/dailyPhoto/DailyMissionCard.tsx b/src/components/dailyPhoto/DailyMissionCard.tsx index d28a075..b049166 100644 --- a/src/components/dailyPhoto/DailyMissionCard.tsx +++ b/src/components/dailyPhoto/DailyMissionCard.tsx @@ -85,7 +85,9 @@ export const DailyMissionCard = ({
    - {missionCardData[0].mission} + {status === "IMAGE_CONFIRMED" + ? "미션이 완료되었어요!" + : missionCardData[0].mission}