From da55485ed99ca22f2110964d4979703b5997ed0c Mon Sep 17 00:00:00 2001
From: kyu <2066apple@naver.com>
Date: Sat, 16 Sep 2023 12:47:02 +0900
Subject: [PATCH] =?UTF-8?q?[=20fix=20]=20=EC=A2=85=EB=A3=8C=EB=90=9C=20?=
 =?UTF-8?q?=EB=82=AB=ED=88=AC=EB=91=90=EB=8A=94=20=EB=88=84=EB=A5=B4?=
 =?UTF-8?q?=EB=A9=B4=20=EB=94=94=ED=85=8C=EC=9D=BC=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/card/Card.tsx            | 11 +++++++++--
 src/components/common/input/Input.tsx   |  8 +++++---
 src/components/layout/DefaultLayout.tsx |  3 +++
 src/constant/route.ts                   |  6 ++++++
 src/pages/nottodo/NotTodoCreatePage.tsx | 21 ++++++++++++++++-----
 src/pages/nottodo/index.tsx             |  6 ++++++
 src/utils/location.ts                   |  7 +++++--
 7 files changed, 50 insertions(+), 12 deletions(-)

diff --git a/src/components/card/Card.tsx b/src/components/card/Card.tsx
index 2cea67b..c846da3 100644
--- a/src/components/card/Card.tsx
+++ b/src/components/card/Card.tsx
@@ -12,14 +12,21 @@ interface CardProps {
 }
 
 export const Card = (props: CardProps) => {
-    const { title, goal, openMenu, startDate, endDate, className } = props;
+    const { title, goal, openMenu, onClick, startDate, endDate, className } = props;
+
+    const handleOpenMenu = (event: React.MouseEvent<HTMLDivElement>) => {
+        event.stopPropagation();
+        if (openMenu) openMenu(event);
+    };
+
     return (
         <div
             className={`card w-full min-h-[128px] flex flex-col jusitfy-center px-[20px] py-[24px] bg-white ${className}`}
+            onClick={onClick}
         >
             <div className="flex justify-between mb-[8px]">
                 <Tag startDate={startDate} endDate={endDate} />
-                <div onClick={openMenu}>
+                <div onClick={handleOpenMenu}>
                     <More />
                 </div>
             </div>
diff --git a/src/components/common/input/Input.tsx b/src/components/common/input/Input.tsx
index 9713ae1..fb4c043 100644
--- a/src/components/common/input/Input.tsx
+++ b/src/components/common/input/Input.tsx
@@ -19,6 +19,7 @@ export interface InputProps {
     rows?: number;
     maxLength?: number;
     isScroll?: boolean;
+    readOnly?: boolean;
 }
 export const Input = (props: InputProps) => {
     const {
@@ -39,6 +40,7 @@ export const Input = (props: InputProps) => {
         maxLength,
         name,
         isScroll,
+        readOnly,
     } = props;
     const textareaRef = useRef<HTMLTextAreaElement>(null);
     const [isWrapperFocus, setIsWrapperFocus] = useState<boolean>(false);
@@ -103,6 +105,7 @@ export const Input = (props: InputProps) => {
                         name={name}
                         className="w-full outline-none body1"
                         inputMode={isInputModeNone ? 'none' : 'text'}
+                        readOnly={readOnly}
                     />
                 ) : (
                     <textarea
@@ -117,12 +120,11 @@ export const Input = (props: InputProps) => {
                         rows={rows}
                         maxLength={maxLength}
                         inputMode={isInputModeNone ? 'none' : 'text'}
+                        readOnly={readOnly}
                     />
                 )}
                 {value && value.toString().length > 0 && !disabled ? (
-                    <div onClick={handleDelete}>
-                        <Delete />
-                    </div>
+                    <div onClick={handleDelete}>{!readOnly ? <Delete /> : null}</div>
                 ) : null}
                 {Icon(icon)}
             </div>
diff --git a/src/components/layout/DefaultLayout.tsx b/src/components/layout/DefaultLayout.tsx
index 894764a..4d4de54 100644
--- a/src/components/layout/DefaultLayout.tsx
+++ b/src/components/layout/DefaultLayout.tsx
@@ -84,6 +84,9 @@ export default function DefaultLayout({ children }: DefaultLayoutProp) {
 
     const handleBack = () => {
         if (location.pathname.startsWith('/nottodo/edit')) {
+            const params = new URLSearchParams(location.search);
+            if (params.get('state') === 'complete') return router(-1);
+
             return setIsEditPopup(true);
         } else {
             return router(-1);
diff --git a/src/constant/route.ts b/src/constant/route.ts
index 26570c3..d82e642 100644
--- a/src/constant/route.ts
+++ b/src/constant/route.ts
@@ -12,6 +12,12 @@ export const routeTitle = [
     { path: '/profile/contact', en: 'Contact Us', ko: '문의/건의하기', img: false },
     { path: '/badge', en: 'badge', ko: '뱃지', img: false },
 ];
+export const completeJson = {
+    path: '/nottodo/edit/state',
+    en: 'complete',
+    ko: '종료된 낫투두',
+    img: false,
+};
 
 export const headerHiddenPaths = ['/login', '/profile', '/'];
 export const headerBackPaths = [
diff --git a/src/pages/nottodo/NotTodoCreatePage.tsx b/src/pages/nottodo/NotTodoCreatePage.tsx
index d37570d..d30f0d4 100644
--- a/src/pages/nottodo/NotTodoCreatePage.tsx
+++ b/src/pages/nottodo/NotTodoCreatePage.tsx
@@ -41,11 +41,13 @@ export default function NotTodoCreatePage() {
 
     const [titleHelpText, setTitleHelpText] = useState<string>('');
     const [dateHelpText, setDateHelpText] = useState<string>('');
+    const [isComplete, setIsComplete] = useState<boolean>(false);
 
     useEffect(() => {
         if (params && params.id) {
             setIsEditPage(true);
             if (currentNottodo) {
+                setIsComplete(currentNottodo.progressState === 'COMPLETE');
                 setTitle(currentNottodo.notToDoText);
                 setStartDate(new Date(currentNottodo.startDate));
                 setEndDate(new Date(currentNottodo.endDate));
@@ -260,6 +262,7 @@ export default function NotTodoCreatePage() {
                     helperText={titleHelpText}
                     onChange={(e: React.ChangeEvent<HTMLInputElement>) => handleTitle(e)}
                     placeHolder="ex. 저녁 먹은 후 야식 참기"
+                    readOnly={isComplete}
                 />
                 <div className="h-[60px] w-full" />
                 <div className="flex items-center mb-3">
@@ -276,9 +279,10 @@ export default function NotTodoCreatePage() {
                         setValue={setInputStartDate}
                         isWarning={!!dateHelpText}
                         isInputModeNone
-                        onFocus={() => handleFocus('start')}
+                        onFocus={!isComplete ? () => handleFocus('start') : () => null}
                         onChange={() => null}
                         placeHolder="시작일 입력"
+                        readOnly={isComplete}
                     />
                     <div className="mx-3 body1 text-gray-500">~</div>
                     <Input
@@ -288,9 +292,10 @@ export default function NotTodoCreatePage() {
                         setValue={setInputEndDate}
                         isWarning={!!dateHelpText}
                         isInputModeNone
-                        onFocus={() => handleFocus('end')}
+                        onFocus={!isComplete ? () => handleFocus('end') : () => null}
                         onChange={() => null}
                         placeHolder="종료일 입력"
+                        readOnly={isComplete}
                     />
                 </div>
                 {dateHelpText ? <div className="mt-1 title3 text-negative">{dateHelpText}</div> : null}
@@ -331,6 +336,7 @@ export default function NotTodoCreatePage() {
                     setValue={setGoal}
                     onChange={(e) => setGoal(e.target.value)}
                     placeHolder="ex. 3kg 감량하기"
+                    readOnly={isComplete}
                 />
                 <div className="body2 text-gray-600 mt-2">목표가 명확할수록 성공 확률이 높아져요!</div>
                 <div className="h-[60px] w-full" />
@@ -348,6 +354,7 @@ export default function NotTodoCreatePage() {
                         placeHolder="절제할 나를 응원할 메시지를 입력해주세요."
                         rows={1}
                         maxLength={100}
+                        readOnly={isComplete}
                     />
                     <Input
                         type="textarea"
@@ -358,6 +365,7 @@ export default function NotTodoCreatePage() {
                         placeHolder="절제할 나를 응원할 메시지를 입력해주세요."
                         rows={1}
                         maxLength={100}
+                        readOnly={isComplete}
                     />
                     <Input
                         type="textarea"
@@ -368,15 +376,18 @@ export default function NotTodoCreatePage() {
                         placeHolder="절제할 나를 응원할 메시지를 입력해주세요."
                         rows={1}
                         maxLength={100}
+                        readOnly={isComplete}
                     />
                 </div>
                 <div className="w-full mb-24"></div>
             </div>
 
             {/* next button */}
-            <div className="fixed bottom-0 left-0 w-full h-[88px] border-t border-t-gray bg-white">
-                {renderButton(isEditPage)}
-            </div>
+            {!isComplete && (
+                <div className="fixed bottom-0 left-0 w-full h-[88px] border-t border-t-gray bg-white">
+                    {renderButton(isEditPage)}
+                </div>
+            )}
         </div>
     );
 }
diff --git a/src/pages/nottodo/index.tsx b/src/pages/nottodo/index.tsx
index e4b8eb4..2cc234d 100644
--- a/src/pages/nottodo/index.tsx
+++ b/src/pages/nottodo/index.tsx
@@ -74,6 +74,11 @@ export default function NotTodoPage() {
         setIsMenuOpen(true);
     };
 
+    const handleMoveDetailPage = (nottodo: nottodoProps) => {
+        setCurrentNottodo(nottodo);
+        router(`/nottodo/edit/${nottodo.notToDoId}?state=complete`);
+    };
+
     return (
         <div className="flex flex-col min-h-[calc((100vh-60px)-56px)] bg-gray-50">
             <div className="sticky top-0">
@@ -114,6 +119,7 @@ export default function NotTodoPage() {
                         endDate={new Date(v.endDate)}
                         goal={v.goal}
                         openMenu={() => handleOpenMenu(v)}
+                        onClick={v.progressState === 'COMPLETE' ? () => handleMoveDetailPage(v) : () => null}
                     />
                 ))}
             {nottodoList.filter((v) => (progressState !== '' ? v.progressState === progressState : true)).length < 3 ? (
diff --git a/src/utils/location.ts b/src/utils/location.ts
index d79322d..aa7cd8f 100644
--- a/src/utils/location.ts
+++ b/src/utils/location.ts
@@ -5,6 +5,7 @@ import {
     routeTitle,
     headerBackPaths,
     headerClosePaths,
+    completeJson,
 } from '@/constant/route';
 
 export const useIsBack = () => {
@@ -30,15 +31,17 @@ export const useHasBottomNavBar = () => {
 export const useTitle = (lang: 'en' | 'ko'): [string, boolean] => {
     const location = useLocation();
 
-    const result = routeTitle.find((route) => {
+    let result = routeTitle.find((route) => {
         // 예외 사항
         if (location.pathname.startsWith('/nottodo/edit') && route.path === '/nottodo/edit') {
-            return route;
+            return true;
         }
         return location.pathname === route.path;
     });
 
     if (result) {
+        // 예외 사항
+        if (location.search) result = completeJson;
         if (lang === 'ko') {
             return [result.ko, result.img];
         } else {