diff --git a/src/app/api/email/route.ts b/src/app/api/email/route.ts new file mode 100644 index 0000000..e4ff61a --- /dev/null +++ b/src/app/api/email/route.ts @@ -0,0 +1,20 @@ +import { NextRequest, NextResponse } from 'next/server'; + +export const POST = async (request: NextRequest) => { + const { headers } = request; + + const body = await request.json(); + + const response = await fetch( + `${process.env.NEXT_PUBLIC_SERVER_ADDRESS}:${process.env.NEXT_PUBLIC_SERVER_PORT}/api/photo-request`, + { + method: 'POST', + headers, + body: JSON.stringify(body), + }, + ); + const jsonData = await response.json(); + return NextResponse.json(jsonData, { + status: jsonData.code, + }); +}; diff --git a/src/app/email/page.tsx b/src/app/email/page.tsx index 0072674..3758d4f 100644 --- a/src/app/email/page.tsx +++ b/src/app/email/page.tsx @@ -1,19 +1,39 @@ 'use client'; +import { useAtom, useSetAtom } from 'jotai'; +import dynamic from 'next/dynamic'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; import { CompoundModal } from '@/components/Modal/ModalMain'; import PreviousPage from '@/components/PreviousPage'; -import { ENTER_EMAIL_TITLE } from '@/constants'; +import { + ENTER_EMAIL_TITLE, + GENDER_FEMALE, + GENDER_MALE, + IMG_GENERATED_ERROR_CHECK_MSG, + IMG_GENERATED_ERROR_MSG, +} from '@/constants'; import { ROUTE_TYPES } from '@/interfaces'; +import { + errorCheckMessageAtom, + errorMessageAtom, +} from '@/store/atoms/errorMessageAtom'; +import { imageUrlsAtom } from '@/store/atoms/imageUrlAtom'; +import { selectedBoxAtom } from '@/store/atoms/selectedBoxAtom'; import useModal from '../hooks/useModal'; -export default function EmailEnterView() { +export function EmailEnterView() { const router = useRouter(); const [email, setEmail] = useState(''); const [isEmailValid, setIsEmailValid] = useState(false); + const [genderString] = useAtom(selectedBoxAtom); + const [photoOriginUrls] = useAtom(imageUrlsAtom); const { isOpen, handleOpenModal, handleCloseModal } = useModal(); + const setErrorMessage = useSetAtom(errorMessageAtom); + const setErrorCheckMessage = useSetAtom(errorCheckMessageAtom); + const storedToken = window.sessionStorage.getItem('accessToken') || ''; + const gender = genderString === 'female' ? GENDER_FEMALE : GENDER_MALE; const handleEmailEntered = (e: React.ChangeEvent) => { const emailValue = e.target.value; setEmail(emailValue); @@ -21,16 +41,45 @@ export default function EmailEnterView() { const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; setIsEmailValid(emailPattern.test(emailValue)); }; + const submitPhotoData = async () => { + if (storedToken !== '') { + try { + const response = await fetch(`/api/email?code=${storedToken}`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${storedToken}`, + }, + body: JSON.stringify({ + email: email || null, + gender, + photoOriginUrls, + }), + }); - const handleEmailSubmit = (event: React.FormEvent) => { - event.preventDefault(); - if (isEmailValid) { - router.push(ROUTE_TYPES.WAITING); + if (response.status === 200) { + router.push(ROUTE_TYPES.WAITING); + } else { + setErrorMessage(IMG_GENERATED_ERROR_MSG); + setErrorCheckMessage(IMG_GENERATED_ERROR_CHECK_MSG); + router.push(ROUTE_TYPES.ERROR); + } + } catch (error) { + setErrorMessage(IMG_GENERATED_ERROR_MSG); + setErrorCheckMessage(IMG_GENERATED_ERROR_CHECK_MSG); + router.push(ROUTE_TYPES.ERROR); + } } }; - const handleMovePage = () => { + const handleEmailSubmit = async (event: React.FormEvent) => { + event.preventDefault(); + await submitPhotoData(); + }; + + const handleMovePage = async () => { router.push(ROUTE_TYPES.WAITING); + await submitPhotoData(); }; return ( @@ -105,3 +154,6 @@ export default function EmailEnterView() { ); } +export default dynamic(() => Promise.resolve(EmailEnterView), { + ssr: false, +}); diff --git a/src/app/list/page.tsx b/src/app/list/page.tsx index 9dfca99..6347b2a 100644 --- a/src/app/list/page.tsx +++ b/src/app/list/page.tsx @@ -2,6 +2,7 @@ import { useSetAtom } from 'jotai/index'; import dynamic from 'next/dynamic'; +import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import PreviousPage from '@/components/PreviousPage'; import { @@ -16,6 +17,7 @@ import { } from '@/store/atoms/errorMessageAtom'; import EmptyList from './_components/EmptyList'; import ImageList from './_components/ImageList'; +import { ROUTE_TYPES } from '@/interfaces'; export function ListView() { const [list, setList] = useState([]); @@ -24,6 +26,7 @@ export function ListView() { const setErrorCheckMessage = useSetAtom(errorCheckMessageAtom); const setCreatedPhoto = useSetAtom(createdPhotoAtomWithStorage); const storedToken = window.sessionStorage.getItem('accessToken') || ''; + const router = useRouter(); useEffect(() => { if (storedToken !== '') { @@ -40,11 +43,13 @@ export function ListView() { } else { setErrorMessage(NO_GENERATED_IMAGE_MSG); setErrorCheckMessage(GENERATION_ERROR_CHECK_MSG); + router.push(ROUTE_TYPES.ERROR); } }) .catch(() => { setErrorMessage(IMG_LIST_ERROR_MSG); setErrorCheckMessage(GENERATION_ERROR_CHECK_MSG); + router.push(ROUTE_TYPES.ERROR); }) .finally(() => setLoading(false)); } diff --git a/src/app/waiting/page.tsx b/src/app/waiting/page.tsx index 8542ba3..d21dc2e 100644 --- a/src/app/waiting/page.tsx +++ b/src/app/waiting/page.tsx @@ -48,11 +48,13 @@ export function WaitingView() { } else { setErrorMessage(IMG_NOT_READY_MSG); setErrorCheckMessage(GENERATION_ERROR_CHECK_MSG); + router.push(ROUTE_TYPES.ERROR); } }) .catch(() => { setErrorMessage(GENERATION_STATUS_ERROR_MSG); setErrorCheckMessage(GENERATION_ERROR_CHECK_MSG); + router.push(ROUTE_TYPES.ERROR); }); } }, [setErrorCheckMessage, setErrorMessage, storedToken]); diff --git a/src/constants/errorMessages.ts b/src/constants/errorMessages.ts index b6143e6..ea3e150 100644 --- a/src/constants/errorMessages.ts +++ b/src/constants/errorMessages.ts @@ -10,4 +10,7 @@ export const GENERATION_ERROR_MSG: string = '프로필을 생성하는 실패했 export const GENERATION_ERROR_CHECK_MSG: string = '이미지를 다시 확인해주세요'; export const UPLOAD_ERROR_MSG: string = '이미지 업로드에 실패했습니다.'; export const UPLOAD_ERROR_CHECK_MSG: string = '이미지를 다시 확인해주세요'; - +export const IMG_GENERATED_ERROR_CHECK_MSG: string = + '이미지 데이터를 처리하는 중 오류가 발생했습니다'; +export const IMG_GENERATED_ERROR_MSG: string = + '정보를 올바르게 입력하셨는지 확인해주세요'; diff --git a/src/constants/genderValue.ts b/src/constants/genderValue.ts new file mode 100644 index 0000000..d1cd4ec --- /dev/null +++ b/src/constants/genderValue.ts @@ -0,0 +1,2 @@ +export const GENDER_MALE = 0; +export const GENDER_FEMALE = 1; diff --git a/src/constants/index.ts b/src/constants/index.ts index fb62d7b..d92d52d 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -5,3 +5,4 @@ export * from './modalText'; export * from './guideImage'; export * from './privatePolicyContent'; export * from './image'; +export * from './genderValue';