From 2fb5f5eeb7e7eef101166c99f8d208afb67cbfeb Mon Sep 17 00:00:00 2001 From: joojjang Date: Sun, 29 Sep 2024 07:53:21 +0900 Subject: [PATCH 01/53] =?UTF-8?q?refactor(verification):=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=9D=98=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=ED=95=98=EA=B8=B0=20=ED=83=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/verification/index.tsx | 240 ++++++++++-------- src/pages/challenge-record/index.tsx | 15 +- 2 files changed, 141 insertions(+), 114 deletions(-) diff --git a/src/pages/challenge-record/components/verification/index.tsx b/src/pages/challenge-record/components/verification/index.tsx index a00d96f..c8c5e19 100644 --- a/src/pages/challenge-record/components/verification/index.tsx +++ b/src/pages/challenge-record/components/verification/index.tsx @@ -1,40 +1,35 @@ -import { useRef, useState } from 'react'; -import { useNavigate } from 'react-router-dom'; +import { useRef, useState, useEffect } from 'react'; import { postVerification } from '@/apis/challenge-record/challenge.record.api'; -import { RouterPath } from '@/routes/path'; -import { Image, Text } from '@chakra-ui/react'; +import CTA, { CTAContainer } from '@/components/common/cta'; +import Textarea from '@/components/common/form/textarea'; +import { Image } from '@chakra-ui/react'; import styled from '@emotion/styled'; +const MIN_CONTENT_LENGTH = 20; + const Verification = () => { const fileInput = useRef(null); - const [previewImg, setPreviewImg] = useState(null); - const [text, setText] = useState(''); - const navigate = useNavigate(); - - const saveHandler = async () => { - try { - if (previewImg) { - const response = await postVerification(18, previewImg, text); - if (response.status === 200) { - console.log('응답: ', response); - alert('성공적으로 저장했습니다.'); - navigate(RouterPath.root); - } - } else { - alert('이미지를 선택하세요.'); - } - } catch (error) { - alert('저장에 실패했습니다.'); + const [content, setContent] = useState(''); + const [isContentValid, setIsContentValid] = useState(true); + const [image, setImage] = useState(null); + const [isUploadDisabled, setIsUploadDisabled] = useState(true); + + // 폼 유효성 검사 -> 버튼 상태 관리 + useEffect(() => { + if (image && content.trim() && content.length >= MIN_CONTENT_LENGTH) { + setIsUploadDisabled(false); + } else { + setIsUploadDisabled(true); } - }; + }, [image, content]); - const handleButtonClick = () => { + const handleUploadImage = () => { fileInput.current?.click(); }; - const imageHandler = (fileBlob: File) => { - setPreviewImg(fileBlob); // File 객체를 직접 설정합니다. + const handleImage = (fileBlob: File) => { + setImage(fileBlob); // File 객체를 직접 설정합니다. // 미리보기를 위해 FileReader를 사용합니다. const reader = new FileReader(); @@ -52,48 +47,90 @@ const Verification = () => { }; }; + // 내용 유효성 검사 + const handleContentChange = (e: React.ChangeEvent) => { + const newContent = e.target.value; + setContent(newContent); + // console.log(content); // test + + if (newContent.trim() && newContent.length >= MIN_CONTENT_LENGTH) { + setIsContentValid(true); + } else { + setIsContentValid(false); + } + // console.log(isContentValid); // test + }; + + const handleSave = async () => { + if (image) { + postVerification(18, image, content) + .then(() => { + // console.log('응답: ', response); + alert('챌린지 인증이 등록되었습니다!'); + handleSelectedTab(0); // 인증 기록 탭으로 이동 + }) + .catch((error) => { + // API에서 받은 오류 객체일 경우 + if (error?.result === 'FAIL') { + alert(error.message || '다시 시도해주세요.'); + } else { + // 예상치 못한 오류 처리 + alert('다시 시도해주세요.'); + } + }); + } + }; + + const handleSelectedTab = (value: number) => { + // setActiveTab(value as 0 | 1); + sessionStorage.setItem('activeTab', String(value)); + }; + return ( - - - 길에 떨어진 쓰레기 줍기 챌린지 - - setText(e.target.value)} - /> - {!previewImg && ( - - { - if (e.target.files) { - imageHandler(e.target.files[0]); - } - }} - /> - 사진추가 - - )} - {previewImg && }{' '} - {/* 미리보기 이미지 */} - 참여하기 - + <> + +