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 {