From 068a233976de27f6baee6d04fa3f4df42a290f37 Mon Sep 17 00:00:00 2001 From: luli Date: Mon, 1 Dec 2025 20:22:34 +0900 Subject: [PATCH 01/24] =?UTF-8?q?refactor:=20#192=20task=20add=20=EC=A3=BC?= =?UTF-8?q?=EA=B0=84=EB=B0=98=EB=B3=B5=20=EC=98=A4=EB=A5=98=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95.=20->=20=EB=A7=8C=EB=93=A4?= =?UTF-8?q?=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20=ED=81=B4=EB=A6=AD=EC=8B=9C?= =?UTF-8?q?=EC=97=90=20=EC=98=A4=EB=A5=98=EB=9C=A8=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../task-recurring-add-modal.tsx | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/components/features/tasklist/task-recurring/task-recurring-add-modal.tsx b/src/components/features/tasklist/task-recurring/task-recurring-add-modal.tsx index 66237dee..1bfb3569 100644 --- a/src/components/features/tasklist/task-recurring/task-recurring-add-modal.tsx +++ b/src/components/features/tasklist/task-recurring/task-recurring-add-modal.tsx @@ -109,7 +109,7 @@ function FormField({ const handleSelectValue = (option: DropdownOption) => { if (!option.value) return; - setValue("frequencyType", option.value, { shouldValidate: true }); + setValue("frequencyType", option.value); if (option.value === FrequencyType.Weekly) { setIsWeekpickerOpen(true); @@ -303,9 +303,21 @@ function FormField({ {isWeekpickerOpen && ( - - - + + ( + <> + + + + + )} + /> )} From 4db3ff854d150baad1ddf45be8ce28e9a0c6dc85 Mon Sep 17 00:00:00 2001 From: luli Date: Mon, 1 Dec 2025 20:23:23 +0900 Subject: [PATCH 02/24] =?UTF-8?q?refactor:=20#192=20reply=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=EB=90=A8=20css=20variant=EB=B3=84=EB=A1=9C=20?= =?UTF-8?q?=EB=8B=A4=EB=A5=B4=EA=B2=8C=20=EB=B3=B4=EC=9D=B4=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ui/reply/index.tsx | 38 +++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/src/components/ui/reply/index.tsx b/src/components/ui/reply/index.tsx index 1ed7d5ec..f45a5196 100644 --- a/src/components/ui/reply/index.tsx +++ b/src/components/ui/reply/index.tsx @@ -106,16 +106,34 @@ export default function Reply({ 작성자 {comment.user.nickname} - - {comment.createdAt !== comment.updatedAt && ( - (수정됨) + {variant === "primary" ? ( + <> + + {comment.createdAt !== comment.updatedAt && ( + (수정됨) + )} + + ) : ( +
+ {comment.createdAt !== comment.updatedAt && ( + (수정됨) + )} + +
)} {isAuthor && } From ca8db323248a464068e9d55b7f5a25a3ec82870f Mon Sep 17 00:00:00 2001 From: luli Date: Mon, 1 Dec 2025 20:23:55 +0900 Subject: [PATCH 03/24] =?UTF-8?q?refactor:=20#192=20tasklist=20=EA=B8=80?= =?UTF-8?q?=EC=9E=90=EC=88=98=20=EC=A0=9C=ED=95=9C=20cation=20=EC=9C=BC?= =?UTF-8?q?=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/features/tasklist/task-add-modal.tsx | 4 ++-- .../tasklist/task-recurring/task-recurring-update-modal.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/features/tasklist/task-add-modal.tsx b/src/components/features/tasklist/task-add-modal.tsx index aac8eeec..faa40ae0 100644 --- a/src/components/features/tasklist/task-add-modal.tsx +++ b/src/components/features/tasklist/task-add-modal.tsx @@ -70,7 +70,7 @@ function FormField() {
- + diff --git a/src/components/features/tasklist/task-recurring/task-recurring-update-modal.tsx b/src/components/features/tasklist/task-recurring/task-recurring-update-modal.tsx index 7edd956a..dbca46fd 100644 --- a/src/components/features/tasklist/task-recurring/task-recurring-update-modal.tsx +++ b/src/components/features/tasklist/task-recurring/task-recurring-update-modal.tsx @@ -83,7 +83,7 @@ function FormField({ type }: { type: FormFieldType }) {
- + From 06494668772ee43b56282be9aa8bb36a30013055 Mon Sep 17 00:00:00 2001 From: luli Date: Mon, 1 Dec 2025 20:24:08 +0900 Subject: [PATCH 04/24] =?UTF-8?q?refactor:=20#192=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20date=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../features/tasklist/task-detail/task-detail-main.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/features/tasklist/task-detail/task-detail-main.tsx b/src/components/features/tasklist/task-detail/task-detail-main.tsx index eb55fa0a..0631f699 100644 --- a/src/components/features/tasklist/task-detail/task-detail-main.tsx +++ b/src/components/features/tasklist/task-detail/task-detail-main.tsx @@ -145,11 +145,11 @@ export default function TaskDetailMain({
- + {taskDetail.writer.nickname}
- {formatDateToFullStr({ date: taskDetail.date, type: "korean" })} + {formatDateToFullStr({ date: taskDetail.recurring.startDate, type: "korean" })}
@@ -158,7 +158,7 @@ export default function TaskDetailMain({
- {formatDateToFullStr({ date: taskDetail.date, type: "korean" })} + {formatDateToFullStr({ date: taskDetail.recurring.startDate, type: "korean" })}
| @@ -167,7 +167,7 @@ export default function TaskDetailMain({ - {formatTimeToStr({ date: taskDetail.date, type: "meridiem" })} + {formatTimeToStr({ date: taskDetail.recurring.startDate, type: "meridiem" })} | From 9000a62c801add569bd91c97fd5f5cb9ce7b8f9c Mon Sep 17 00:00:00 2001 From: luli Date: Mon, 1 Dec 2025 20:24:23 +0900 Subject: [PATCH 05/24] =?UTF-8?q?refactor:=20#192=20=EC=83=81=EC=84=B8=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/features/tasklist/task-card-field.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/features/tasklist/task-card-field.tsx b/src/components/features/tasklist/task-card-field.tsx index 35d7a685..fc4f08f0 100644 --- a/src/components/features/tasklist/task-card-field.tsx +++ b/src/components/features/tasklist/task-card-field.tsx @@ -310,7 +310,7 @@ export default function TaskCardField({ {isLoadingTaskList ? ( ) : taskListData ? ( -
+
Date: Mon, 1 Dec 2025 20:24:42 +0900 Subject: [PATCH 06/24] =?UTF-8?q?refactor:=20#192=20=EC=83=81=EC=84=B8?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20=EB=92=A4?= =?UTF-8?q?=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20=EB=88=8C?= =?UTF-8?q?=EB=A0=80=EC=9D=84=EB=95=8C=20=EB=B9=88=EB=AA=A8=EB=8B=AC?= =?UTF-8?q?=EC=B0=BD=EB=A7=8C=20=EB=B3=B4=EC=9D=B4=EB=8A=94=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tasklist/[taskListId]/layout-content.tsx | 47 ++++++++++++++----- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/src/app/(routes)/team/[id]/tasklist/[taskListId]/layout-content.tsx b/src/app/(routes)/team/[id]/tasklist/[taskListId]/layout-content.tsx index e0b02028..e9da2337 100644 --- a/src/app/(routes)/team/[id]/tasklist/[taskListId]/layout-content.tsx +++ b/src/app/(routes)/team/[id]/tasklist/[taskListId]/layout-content.tsx @@ -5,6 +5,7 @@ import { layoutStyle } from "../index.styles"; import { usePathname } from "next/navigation"; import useModalStore from "@/store/modal.store"; import { createPortal } from "react-dom"; +import { motion, AnimatePresence } from "motion/react"; interface CommonProps { children: React.ReactNode; @@ -13,19 +14,23 @@ interface CommonProps { export default function LayoutContent({ children, detail }: CommonProps) { const pathname = usePathname(); - const { isOpen } = useModalStore(); - + const { isOpen, closeModal } = useModalStore(); const [isOpenDetailModal, setIsOpenDetailModal] = useState(false); - useEffect(() => { - const checkModal = () => { - if (isOpen) { - setIsOpenDetailModal(true); - } else { - setIsOpenDetailModal(false); - } - }; + const checkModal = () => { + if (isOpen) { + setIsOpenDetailModal(true); + } else { + setIsOpenDetailModal(false); + } + }; + const regexOnlyList = /^\/team\/\d+\/tasklist\/\d+$/; + + useEffect(() => { + if (regexOnlyList.test(pathname)) { + closeModal(); + } checkModal(); }, [pathname]); @@ -35,7 +40,27 @@ export default function LayoutContent({ children, detail }: CommonProps) {
{children}
{isOpenDetailModal && - createPortal(
{detail}
, document.body)} + createPortal( + + {isOpen && ( + + {detail} + + )} + , + document.body, + )} ); From a130be7fbecfdf5b0503dbc1735a224cf3600323 Mon Sep 17 00:00:00 2001 From: luli Date: Mon, 1 Dec 2025 20:25:14 +0900 Subject: [PATCH 07/24] =?UTF-8?q?refactor:=20#192=20=EA=B8=B0=ED=83=80=20?= =?UTF-8?q?=EC=83=81=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=95=A0?= =?UTF-8?q?=EB=8B=88=EB=A9=94=EC=9D=B4=EC=85=98=20=EC=8A=A4=ED=83=80?= =?UTF-8?q?=EC=9D=BC=EC=A0=81=EC=9A=A9=20.=20(=EB=8B=A4=EB=A5=B8=20?= =?UTF-8?q?=EC=BB=A4=EB=B0=8B=EC=97=90=20=EC=A1=B0=EA=B8=88=20=EC=84=9E?= =?UTF-8?q?=EC=9D=B8=EB=93=AF)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 50 ++++++++++++++----- .../tasklist/[taskListId]/tasklist-client.tsx | 4 +- .../team/[id]/tasklist/index.styles.ts | 2 +- src/components/ui/reply/index.styles.ts | 2 +- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7b1567d2..6aa3335d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -121,6 +121,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -4544,6 +4545,7 @@ "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -4680,6 +4682,7 @@ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.6.tgz", "integrity": "sha512-gB1sljYjcobZKxjPbKSa31FUTyr+ROaBdoH+wSSs9Dk+yDCmMs+TkTV3PybRRVLC7ax7q0erJ9LvRWnMktnRAw==", "license": "MIT", + "peer": true, "dependencies": { "@tanstack/query-core": "5.90.6" }, @@ -4714,7 +4717,6 @@ "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -4735,7 +4737,6 @@ "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", "dev": true, "license": "Apache-2.0", - "peer": true, "dependencies": { "dequal": "^2.0.3" } @@ -4819,8 +4820,7 @@ "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -5008,6 +5008,7 @@ "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -5092,6 +5093,7 @@ "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.3", "@typescript-eslint/types": "8.46.3", @@ -5622,6 +5624,7 @@ "integrity": "sha512-SdrcvwvP6q8n82cS2BthbZuHGFPHeKkjbpeIRhGaeV8hJ8P0swWFx5lUZ/Vnd7G0CsfL6m4/3lOaqd/n12vtZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/mocker": "4.0.6", "@vitest/utils": "4.0.6", @@ -5645,6 +5648,7 @@ "integrity": "sha512-u6DliDabPQYXz8U4ZwnCvr9q2kJnribkenO6FK0qv5Gu/m1X884JOf0IZ71x7rLrmSsoP3YD3hVnNutAbhEX3A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/browser": "4.0.6", "@vitest/mocker": "4.0.6", @@ -5916,6 +5920,7 @@ "integrity": "sha512-trPk5qpd7Jj+AiLZbV/e+KiiaGXZ8ECsRxtnPnCrJr9OW2mLB72Cb824IXgxVz/mVU3Aj4VebY+tDTPn++j1Og==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/utils": "4.0.6", "pathe": "^2.0.3" @@ -6221,6 +6226,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -6286,6 +6292,7 @@ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -7280,6 +7287,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -8326,7 +8334,6 @@ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6" } @@ -8413,8 +8420,7 @@ "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/dom-converter": { "version": "0.2.0", @@ -8846,6 +8852,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "bin": { "esbuild": "bin/esbuild" }, @@ -8910,6 +8917,7 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -9010,6 +9018,7 @@ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", + "peer": true, "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -9111,6 +9120,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -11693,6 +11703,7 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", + "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -12208,7 +12219,6 @@ "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", "dev": true, "license": "MIT", - "peer": true, "bin": { "lz-string": "bin/bin.js" } @@ -13753,6 +13763,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -14085,6 +14096,7 @@ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "dev": true, "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -14204,7 +14216,6 @@ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -14220,7 +14231,6 @@ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -14231,7 +14241,6 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=10" }, @@ -14244,8 +14253,7 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/process": { "version": "0.11.10", @@ -14409,6 +14417,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -14478,6 +14487,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -14490,6 +14500,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.66.0.tgz", "integrity": "sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -14522,6 +14533,7 @@ "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -15129,6 +15141,7 @@ "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -15365,6 +15378,7 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -15831,6 +15845,7 @@ "integrity": "sha512-s3qY17stuSxU9TFdSHWF2VWJiDKrhZsdlM9M9/APBLT+3kbTlfCPuaNONE0UETgz5tiZLIrC9K4RYjJ8c6PHPA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^1.6.0", @@ -16575,6 +16590,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -16766,6 +16782,7 @@ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "license": "(MIT OR CC0-1.0)", + "peer": true, "engines": { "node": ">=10" }, @@ -16857,6 +16874,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -17163,6 +17181,7 @@ "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -17256,6 +17275,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -17269,6 +17289,7 @@ "integrity": "sha512-gR7INfiVRwnEOkCk47faros/9McCZMp5LM+OMNWGLaDBSvJxIzwjgNFufkuePBNaesGRnLmNfW+ddbUJRZn0nQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@vitest/expect": "4.0.6", "@vitest/mocker": "4.0.6", @@ -17493,6 +17514,7 @@ "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -17571,6 +17593,7 @@ "integrity": "sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-html-community": "0.0.8", "html-entities": "^2.1.0", @@ -17965,6 +17988,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/src/app/(routes)/team/[id]/tasklist/[taskListId]/tasklist-client.tsx b/src/app/(routes)/team/[id]/tasklist/[taskListId]/tasklist-client.tsx index bc0e3cf6..1350de18 100644 --- a/src/app/(routes)/team/[id]/tasklist/[taskListId]/tasklist-client.tsx +++ b/src/app/(routes)/team/[id]/tasklist/[taskListId]/tasklist-client.tsx @@ -249,7 +249,9 @@ export default function TasklistClient({
- {titleCurrentDate} + + {titleCurrentDate ? titleCurrentDate : "로딩중..."} +
-
diff --git a/src/components/ui/input/input-password.tsx b/src/components/ui/input/input-password.tsx index 82db21d6..3a0a0447 100644 --- a/src/components/ui/input/input-password.tsx +++ b/src/components/ui/input/input-password.tsx @@ -28,6 +28,7 @@ export default function InputPassword({ inputStyle({ intent: "password", disabled, error: Boolean(ctx?.errorMsg) }), className, )} + autoComplete="off" {...props} />
); diff --git a/src/components/features/landing/intro-section.tsx b/src/components/features/landing/intro-section.tsx index d682a575..b84ec2f8 100644 --- a/src/components/features/landing/intro-section.tsx +++ b/src/components/features/landing/intro-section.tsx @@ -4,12 +4,28 @@ import Logo from "@/assets/landing/logo-flat.svg"; import cn from "@/lib/cn"; import { Button } from "@/components/ui"; import { introContainer, introWave, introWaveWrapper } from "./landing.style"; +import { motion } from "motion/react"; export default function IntroBanner() { return (
-

함께 계획하고 완성하는 ✨

+

+ 함께 계획하고 완성하는{" "} + + ✨ + +

혼자서는 힘들었던 목표, 이제 친구들과 함께 재밌게!
diff --git a/src/components/features/landing/landing.style.ts b/src/components/features/landing/landing.style.ts index 8ec387e4..abb5cd1e 100644 --- a/src/components/features/landing/landing.style.ts +++ b/src/components/features/landing/landing.style.ts @@ -14,7 +14,7 @@ export const introWave = [ "tablet:h-[140px] tablet:bg-[auto_140px] ", "desktop:h-[250px] desktop:bg-[auto_250px] ", ].join(""); -export const sectionWrapper = "py-10 tablet:py-24 px-[1.25rem] tablet:px-6"; +export const sectionWrapper = "py-16 tablet:py-24 px-[1.25rem] tablet:px-6 overflow-hidden"; export const sectionTitle = "text-center text-3xl tablet:text-5xl font-bold break-keep"; export const sectionTitleGradient = cva("bg-gradient-to-r bg-clip-text text-transparent", { variants: { @@ -29,7 +29,7 @@ export const sectionTitleGradient = cva("bg-gradient-to-r bg-clip-text text-tran export const sectionInnerContainer = cva("mx-auto max-w-[760px] flex", { variants: { layout: { - problem: "flex-col items-center gap-10 pt-10 tablet:pt-24", + problem: "flex-col items-center gap-10 tablet:gap-20 pt-10 tablet:pt-24", whyPlango: "flex-col", solution: "flex-col gap-10 pt-10 tablet:gap-20 tablet:pt-24", dailySummary: @@ -54,7 +54,7 @@ export const sectionContentBox = cva("flex flex-col rounded-3xl border p-5 table problem: "w-full tablet:max-w-[360px] gap-2 tablet:gap-4 text-center odd:mr-auto even:ml-auto", solution: "flex flex-1 gap-3 tablet:gap-6 ", - whyPlango: "p-3 rounded-2xl tablet:rounded-3xl", + whyPlango: "rounded-2xl tablet:rounded-3xl", }, }, }); diff --git a/src/components/features/landing/problem-section.tsx b/src/components/features/landing/problem-section.tsx index 60fbcf86..fe55c2e6 100644 --- a/src/components/features/landing/problem-section.tsx +++ b/src/components/features/landing/problem-section.tsx @@ -7,6 +7,7 @@ import { sectionTitleGradient, sectionWrapper, } from "./landing.style"; +import { motion } from "motion/react"; const values = [ { @@ -25,35 +26,68 @@ const values = [ icon: "🤷", title: "일정 공유 누락", description: "친구들과 계획 체크리스트를 공유하고 싶어요", - solution: "“카톡에 흩어져버린 체크리스트, 결국 아무도 기억 못 하죠”", + solution: "“카톡에 흩어진 체크리스트, 결국 아무도 기억 못 하죠”", }, ]; export default function ProblemSection() { return (

-

- 🤔 - - 이런 고민 있으신가요? - -

-
    - {values.map(v => { + + + 🤔 + + 이런 고민 있으신가요? + + + + + {values.map((v, index) => { const { icon, title, description, solution } = v; + const isOdd = index % 2 === 0; return ( -
  • +

    {icon}
    {title}

    {description}

    {solution}

    -
  • + ); })} -
  • -
+
); } diff --git a/src/components/features/landing/solution-section.tsx b/src/components/features/landing/solution-section.tsx index ae715d43..a26501ad 100644 --- a/src/components/features/landing/solution-section.tsx +++ b/src/components/features/landing/solution-section.tsx @@ -10,6 +10,7 @@ import { sectionWrapper, } from "./landing.style"; import IcDone from "@/assets/icons/ic-done.svg"; +import { motion } from "motion/react"; type Color = "orange" | "blue" | "green" | "purple"; type ContentValueType = { @@ -76,24 +77,46 @@ type ChecklistProps = { function SectionH3() { return (

- 🪴
- Plango에서
- + 🪴 + + + Plango에서 + + 친구들과 이런 걸 함께해요 - +

); } function SectionH4() { return (

- 다양한 활동들을 함께해요
- 운동, 여행, 공부, 취미 뭐든지 함께하면 더 즐거워져요 + + 다양한 활동들을 함께해요
+ 운동, 여행, 공부, 취미 뭐든지 함께하면 더 즐거워져요 +

); } @@ -110,15 +133,23 @@ function CheckList({ color, checkList }: ChecklistProps) {
    {checkList.map((v, index) => { return ( -
  • {v} -
  • + ); })}
@@ -127,10 +158,20 @@ function CheckList({ color, checkList }: ChecklistProps) { function SolutionList() { return (
    - {values.map(v => { + {values.map((v, index) => { const { icon, theme, description, solution2, solution, color, percent, checkList } = v; return ( -
  • +
    {icon} {description} @@ -147,7 +188,7 @@ function SolutionList() {
- + ); })} diff --git a/src/components/features/landing/why-plango-section.tsx b/src/components/features/landing/why-plango-section.tsx index 67f28ac0..e8c846f9 100644 --- a/src/components/features/landing/why-plango-section.tsx +++ b/src/components/features/landing/why-plango-section.tsx @@ -7,6 +7,7 @@ import { sectionTitleGradient, sectionWrapper, } from "./landing.style"; +import { motion } from "motion/react"; const values = [ "🧑‍🤝‍🧑 같은 목표를 가진 친구들과", @@ -18,34 +19,62 @@ export default function WhyPlangoSection() { return (
-

- Plango가 준비했어요 ✨ -

+ Plango가 준비했어요 + + ✨ + +
다같이 꾸준히 이어가기 위한 공간
혼자서는 어렵지만,
- 함께라면 달라져요 💪 + 함께라면 달라져요 💪
-
    + {values.map((v, index) => ( -
  • {v} -
  • + ))} -
+
); From 6a6271e1b4b037f6ee76732f1ae1c2d30ec59233 Mon Sep 17 00:00:00 2001 From: sejin5 Date: Tue, 2 Dec 2025 03:27:48 +0900 Subject: [PATCH 14/24] =?UTF-8?q?refactor:=20#198=20=EB=A9=A4=EB=B2=84?= =?UTF-8?q?=EC=B9=B4=EB=93=9C=20=ED=94=84=EB=A1=9C=ED=95=84=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80=20=EB=85=B8=EC=B6=9C=EB=90=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/features/team/member-card.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/features/team/member-card.tsx b/src/components/features/team/member-card.tsx index 19b15cb7..deeef634 100644 --- a/src/components/features/team/member-card.tsx +++ b/src/components/features/team/member-card.tsx @@ -1,3 +1,4 @@ +"use client"; import { useCallback } from "react"; import cn from "@/lib/cn"; import IcKebab from "@/assets/icons/ic-kebab.svg"; @@ -34,7 +35,6 @@ export default function MemberCard({ member, userRole, userId }: MemberCardProps const useDeleteMember = useMutation({ mutationFn: deleteMember, onSuccess: (res, param) => { - console.log(res); const { groupId } = param; if (isAdmin) { queryClient.invalidateQueries({ @@ -54,6 +54,11 @@ export default function MemberCard({ member, userRole, userId }: MemberCardProps const handlerMemberDelete = useCallback( async (groupId: number, userId: number, message: string) => { + if (isAdmin && mySelf) { + showAlert(`팀장은 스스로 내보내기를 할 수 없습니다.`); + return; + } + const confirmed = await showAlert(message); if (confirmed) { useDeleteMember.mutate({ groupId, userId }); @@ -65,7 +70,10 @@ export default function MemberCard({ member, userRole, userId }: MemberCardProps return (
- +

{member.userName}

{dropdownCheck && ( From 8c1b702cff70ccf66a7ab3f533a93f4eeef63cdc Mon Sep 17 00:00:00 2001 From: sejin5 Date: Tue, 2 Dec 2025 03:29:21 +0900 Subject: [PATCH 15/24] =?UTF-8?q?refactor:=20#198=20=ED=8C=80=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1/=EC=88=98=EC=A0=95=20modal=20alert=20=EC=88=98?= =?UTF-8?q?=EC=A0=95,=20=ED=83=80=EC=9D=B4=ED=8B=80=20maxLength=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../features/team/modal/todo-create-modal.tsx | 13 ++++++++++++ .../features/team/modal/todo-edit-modal.tsx | 20 ++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/components/features/team/modal/todo-create-modal.tsx b/src/components/features/team/modal/todo-create-modal.tsx index b6271e49..b2b4801c 100644 --- a/src/components/features/team/modal/todo-create-modal.tsx +++ b/src/components/features/team/modal/todo-create-modal.tsx @@ -5,10 +5,12 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; import { TeamModalProps } from "../team.props"; import { useToast } from "@/providers/toast-provider"; import { devConsoleError } from "@/lib/error"; +import { useAlert } from "@/providers/alert-provider"; export const TodoListCreateModal = ({ isOpen, groupId, onClose }: TeamModalProps) => { const queryClient = useQueryClient(); const { showToast } = useToast(); + const { showAlert } = useAlert(); const [todoName, setTodoName] = useState(""); @@ -34,6 +36,15 @@ export const TodoListCreateModal = ({ isOpen, groupId, onClose }: TeamModalProps const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); + if (!todoName) { + showAlert("할 일 목록의 이름은 빈칸 일 수 없습니다."); + return; + } + if (todoName.length > 30) { + showAlert("할 일 목록의 제목은 최대 30자 입니다."); + return; + } + mutate({ groupId, param: todoName }); }; @@ -48,6 +59,8 @@ export const TodoListCreateModal = ({ isOpen, groupId, onClose }: TeamModalProps placeholder="목록 명을 입력해주세요." onChange={handleNameChange} value={todoName} + maxLength="30" + autoComplete="off" /> diff --git a/src/components/features/team/modal/todo-edit-modal.tsx b/src/components/features/team/modal/todo-edit-modal.tsx index 28bbc5f3..76bfdae0 100644 --- a/src/components/features/team/modal/todo-edit-modal.tsx +++ b/src/components/features/team/modal/todo-edit-modal.tsx @@ -4,6 +4,7 @@ import patchTodo from "@/api/team/patch-todo"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import { TodoEditProps } from "../team.props"; import { useToast } from "@/providers/toast-provider"; +import { useAlert } from "@/providers/alert-provider"; import { devConsoleError } from "@/lib/error"; export const TodoListEditModal = ({ @@ -15,10 +16,11 @@ export const TodoListEditModal = ({ }: TodoEditProps) => { const queryClient = useQueryClient(); const { showToast } = useToast(); + const { showAlert } = useAlert(); const [todoName, setTodoName] = useState(taskListName); - const { mutate, isPending, isSuccess } = useMutation({ + const { mutate, isPending } = useMutation({ mutationFn: patchTodo, onSuccess: () => { queryClient.invalidateQueries({ @@ -41,22 +43,30 @@ export const TodoListEditModal = ({ const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!todoName) { - alert("할 일 목록의 제목은 공란일 수 없습니다."); + showAlert("할 일 목록의 제목은 공란일 수 없습니다."); + return; + } + if (todoName.length > 30) { + showAlert("할 일 목록의 제목은 최대 30자 입니다."); return; } mutate({ groupId, taskListId, name: todoName }); }; - if (isSuccess) onClose(); - return (
- + From 9d36818a43ad5ad2ac3c5c603b943ebf559dce3d Mon Sep 17 00:00:00 2001 From: sejin5 Date: Tue, 2 Dec 2025 03:31:21 +0900 Subject: [PATCH 16/24] =?UTF-8?q?refactor:=20#198=20=ED=8C=80=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=ED=95=98=EA=B8=B0=EC=8B=9C=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=EA=B0=92=20400=20status=20code=EC=9D=B4=EB=A9=B4=20message=20?= =?UTF-8?q?=EB=85=B8=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(routes)/team/join/page.tsx | 19 +++++++++++++++---- .../features/team/modal/invite-modal.tsx | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/app/(routes)/team/join/page.tsx b/src/app/(routes)/team/join/page.tsx index f521cbe5..2bb8bcf6 100644 --- a/src/app/(routes)/team/join/page.tsx +++ b/src/app/(routes)/team/join/page.tsx @@ -7,6 +7,8 @@ import { GroupJoinRequest } from "@/types/group"; import { useAuthStore } from "@/store/auth.store"; import postTeamJoin from "@/api/team/post-join-team"; import { useToast } from "@/providers/toast-provider"; +import axios from "axios"; +import { devConsoleError } from "@/lib/error"; export default function TeamJoinPage() { const router = useRouter(); @@ -22,8 +24,9 @@ export default function TeamJoinPage() { const sessionToken = sessionStorage.getItem("joinToken") || null; if (sessionToken) { setFormData(fd => ({ ...fd, token: sessionToken })); + sessionStorage.removeItem("joinToken"); } - }); + }, []); useEffect(() => { if (user) { @@ -35,11 +38,18 @@ export default function TeamJoinPage() { mutationFn: postTeamJoin, onSuccess: res => { sessionStorage.setItem("teamJoinMessage", "팀에 합류했습니다."); - router.push(`/team/${res.groupId}`); + setFormData(fd => ({ ...fd, token: "" })); + router.replace(`/team/${res.groupId}`); }, onError: error => { - console.log(error); - showToast("오류가 발생했습니다", "error"); + devConsoleError(error); + if (axios.isAxiosError(error)) { + if (error.response?.status === 400) { + showToast(error.response?.data.message, "error"); + return; + } + } + showToast("팀 가입에 문제가 발생했습니다.", "error"); }, }); @@ -64,6 +74,7 @@ export default function TeamJoinPage() { placeholder="팀 토큰을 입력해주세요." onChange={handleNameToken} value={formData.token} + autoComplete="off" />
- +