diff --git a/next.config.ts b/next.config.ts index 76fe1d3e..4d6e90fe 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,12 @@ const nextConfig = { images: { - domains: ["k.kakaocdn.net"], // 카카오 CDN 도메인 추가 + domains: ["img1.kakaocdn.net", "k.kakaocdn.net"], // 카카오 CDN 도메인 추가 remotePatterns: [ + { + protocol: "http", + hostname: "img1.kakaocdn.net", + pathname: "/**", + }, { protocol: "http", hostname: "k.kakaocdn.net", diff --git a/public/icons/mypage/clap.svg b/public/icons/mypage/clap.svg new file mode 100644 index 00000000..5028104a --- /dev/null +++ b/public/icons/mypage/clap.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/icons/mypage/mypage-character.png b/public/icons/mypage/mypage-character.png new file mode 100644 index 00000000..658e1526 Binary files /dev/null and b/public/icons/mypage/mypage-character.png differ diff --git a/src/app/(protected)/my-page/_component/TaskContainer.tsx b/src/app/(protected)/my-page/_component/TaskContainer.tsx index 312032f7..d247e3dc 100644 --- a/src/app/(protected)/my-page/_component/TaskContainer.tsx +++ b/src/app/(protected)/my-page/_component/TaskContainer.tsx @@ -1,17 +1,25 @@ +import { useExpiredTaskStore } from "@/store/useTaskStore"; import type { TaskOrigin } from "@/types/myPage"; import { format } from "date-fns"; import { ko } from "date-fns/locale"; +import { useRouter } from "next/navigation"; import React, { useState } from "react"; const TaskItem = ({ task }: { task: TaskOrigin }) => { + const router = useRouter(); const date = new Date(task.dueDatetime); const formattedDate = format(date, "M월 d일 (eee)ㆍa hh:mm까지", { locale: ko, }); + const { setCurrentTask } = useExpiredTaskStore(); + + const handleTaskClick = () => { + setCurrentTask(task); + router.push(`/my-page/task-detail/${task.id}`); + }; return ( - // TODO : 여기에 완료한 일 또는 미룬 일 눌렀을때 해당 화면 전환 함수 추가 필요 -
+
{task.name}
{formattedDate}
diff --git a/src/app/(protected)/my-page/task-detail/[taskId]/ExpiredTaskDetailPage.tsx b/src/app/(protected)/my-page/task-detail/[taskId]/ExpiredTaskDetailPage.tsx new file mode 100644 index 00000000..52058730 --- /dev/null +++ b/src/app/(protected)/my-page/task-detail/[taskId]/ExpiredTaskDetailPage.tsx @@ -0,0 +1,299 @@ +"use client"; + +import RetrospectItem from "@/app/(protected)/retrospection/[taskId]/_components/RetrospectItem"; +import { Badge } from "@/components/component/Badge"; +import CustomBackHeader from "@/components/customBackHeader/CustomBackHeader"; +import { useUserStore } from "@/store"; +import type { TaskWithRetrospection } from "@/types/myPage"; +import { + convertIsoToMonthDayTimeText, + formatTimeFromMinutes, +} from "@/utils/dateFormat"; +import Image from "next/image"; +import { useRouter } from "next/navigation"; + +type Props = { + task: TaskWithRetrospection; +}; + +const retrospectItems: RetrospectItems = { + result: { + title: "몰입한 결과에 얼마나 만족하시나요?", + required: true, + }, + focus: { + title: "몰입하는 동안 나의 집중력은?", + required: true, + }, + keepAndTry: { + title: "이번 몰입의 좋았던 점과 개선할 점은?", + required: false, + }, +}; + +const RESULT_CONTENT = [0, 1, 2, 3, 4]; +const FOCUS_STEPS = [0, 1, 2, 3, 4, 5]; +const BAR = { + HEIGHT: 18, + SLIDER_RADIUS: 9, +}; + +export default function ExpiredTaskDetailPage({ task }: Props) { + const router = useRouter(); + const { userData } = useUserStore(); + + const satisfaction = task.satisfaction / 20 - 1; + + const taskStatus = task.status === "COMPLETE" ? "COMPLETE" : "FAIL"; + + const PHRASE = { + COMPLETE: { + topBar: "완료한 일", + main: "잘 완료하셨어요!", + }, + FAIL: { + topBar: "미룬 일", + main: "완료를 안하셨네요. 다음엔 꼭 완료해요!", + }, + }; + + const keys = [ + { + name: "작은 행동", + onlyComplete: false, + content: task.triggerAction, + }, + { + name: "예상 소요시간", + onlyComplete: false, + content: formatTimeFromMinutes(task.estimatedTime), + }, + { + name: "마감일", + onlyComplete: false, + content: convertIsoToMonthDayTimeText(task.dueDateTime), + }, + ]; + + const filtered = keys.filter((item) => { + if (!item.onlyComplete) { + return item.onlyComplete === false; + } + // onlyComplete === true 인 경우, 조건 함수까지 만족해야 함 + return item.onlyComplete === true && taskStatus === "COMPLETE"; + }); + + return ( +
+ {/* 헤더 부분 */} + + + {/* Contents 부분 */} +
+ {/* Contents - 작업 개요 */} +
+ {/* Contents - 작업 개요 - 문구*/} +
+

+ {task.name}
{" "} + {/* TODO: 이 task.name 이 새로고침 해야 나옴.. 뭔가 고쳐야 함*/} + {PHRASE[taskStatus].main} +

+
+ + {/* Contents - 작업 개요 - 작업 정보 */} +
+ {/* Contents - 작업 개요 - 작업 정보 - 페르소나 */} +
+
+
+ mypage-character +
+
+
+ + {task.personaName} {userData.nickname} + +
+
+ + {/* Contents - 작업 개요 - 작업 정보 - 페르소나 제외 작업 정보 */} +
+ {keys.map((item, index) => ( +
+ {item.name} + {item.content} +
+ ))} + {/* 완료일 정보는 따로 */} + {taskStatus === "COMPLETE" && ( +
+ 완료 일 +
+ mypage-character + + {" "} + {convertIsoToMonthDayTimeText(task.updatedAt)} + + mypage-character +
+
+ )} +
+
+
+ + {/* Contents - 작업 회고 내용 */} +
+ {/* Contents - 작업 회고 내용 - 제목 문구 */} +
+
+

나의 회고

+
+
+ + {/* Contents - 작업 회고 내용 - 회고 내용 */} +
+ {" "} + {/* 실제 유저 회고 부분 */} + {/* 몰입 결과 회고 */} + +
+ {RESULT_CONTENT.map((num, index) => ( + // biome-ignore lint/suspicious/noArrayIndexKey: +
+ retro content index +
+ ))} +
+
+ {/* 몰입하는 동안 나의 집중력 */} + +
+
+ {/* 전체 바 배경 */} +
+ + {/* 선택된 채워진 부분 */} +
+ + {/* 점들 */} +
+ {FOCUS_STEPS.map((step, i) => ( +
+ key={i} + className={`w-[6px] h-[6px] rounded-full transition-all duration-200 ${ + task.concentration >= step + ? "bg-background-skyblue opacity-90" + : "bg-background-skyblue opacity-30" + }`} + /> + ))} +
+ + {/* 슬라이더 핸들 */} +
+
+ + {/* 아래 숫자 레이블 */} +
+ {FOCUS_STEPS.map((step, i) => ( + // biome-ignore lint/suspicious/noArrayIndexKey: +
+ + key={i} + className={ + task.concentration === step + ? "text-gray-alternative" + : "" + } + > + {`${step * 20}`} + +
+ ))} +
+
+ + {/* 몰입 회고 텍스트 */} + +
+