diff --git a/src/components/Home/SearchYoutube.tsx b/src/components/Home/SearchYoutube.tsx index 779cb9b..cdc8180 100644 --- a/src/components/Home/SearchYoutube.tsx +++ b/src/components/Home/SearchYoutube.tsx @@ -15,7 +15,8 @@ import { SearchContainer, } from '@/styles/HomepageStyle'; -import { recommendationModalState } from '@/stores/modal'; +import { recommendationModalState, errorModalState } from '@/stores/modal'; + import { modelingDataState, modelingProgressState, @@ -37,6 +38,7 @@ const SearchYoutube = ({ searchRef }: Props) => { const userToken = useRecoilValue(userTokenState); const setIsOpenModal = useSetRecoilState(recommendationModalState); + const setIsOpenErrorModal = useSetRecoilState(errorModalState); const setVideoLink = useSetRecoilState(videoLinkState); const setProgress = useSetRecoilState(modelingProgressState); const [status, setStatus] = useRecoilState(modelingStatusState); @@ -109,6 +111,7 @@ const SearchYoutube = ({ searchRef }: Props) => { setModelingData(null); } catch (e) { console.error(e); + setIsOpenErrorModal(true); } } else { navigate('/summary/guest'); diff --git a/src/components/layout/Layout.tsx b/src/components/layout/Layout.tsx index 00d149e..b828841 100644 --- a/src/components/layout/Layout.tsx +++ b/src/components/layout/Layout.tsx @@ -1,5 +1,5 @@ import { Outlet, useLocation } from 'react-router-dom'; -import { useRecoilValue } from 'recoil'; +import { useRecoilValue } from 'recoil'; import { isSideBarOpenState } from '@/stores/ui'; @@ -7,13 +7,17 @@ import Footer from './footer/Footer'; import Header from './header'; import SideBar from './sideBar'; import NicknameModal from '@/components/NicknameModal'; +import ErrorModal from '../modals/ErrorModal'; + import { useMemo, useEffect } from 'react'; import { userInfoState } from '@/stores/user'; +import { errorModalState } from '@/stores/modal'; const Layout = () => { const { pathname } = useLocation(); const isSideBarOpen = useRecoilValue(isSideBarOpenState); const userInfo = useRecoilValue(userInfoState); + const isErrorModalOpen = useRecoilValue(errorModalState) const isShowFooter = useMemo( () => pathname === '/' || /^(\/category)/g.test(pathname), @@ -38,6 +42,7 @@ const Layout = () => { {isShowFooter && } {userInfo && userInfo.nick_name === '' && } + {isErrorModalOpen && } > ); }; diff --git a/src/components/layout/sideBar/ConvertVideo.tsx b/src/components/layout/sideBar/ConvertVideo.tsx index aa5de8d..2b8cdca 100644 --- a/src/components/layout/sideBar/ConvertVideo.tsx +++ b/src/components/layout/sideBar/ConvertVideo.tsx @@ -11,7 +11,7 @@ import UpSvg from '@/assets/icons/up.svg?react'; import * as ConvertVideoStyle from '@/styles/layout/sideBar/ConvertVideo.style'; import { CommonTitle } from '@/styles/layout/sideBar/UserMode.style'; -import { recommendationModalState } from '@/stores/modal'; +import { errorModalState, recommendationModalState } from '@/stores/modal'; import { modelingDataState, modelingProgressState, @@ -31,6 +31,7 @@ const ConvertVideo = () => { const userToken = useRecoilValue(userTokenState); const setIsOpenModal = useSetRecoilState(recommendationModalState); const setVideoLink = useSetRecoilState(videoLinkState); + const setIsOpenErrorModal = useSetRecoilState(errorModalState); const [status, setStatus] = useRecoilState(modelingStatusState); const [progress, setProgress] = useRecoilState(modelingProgressState); const [modelingData, setModelingData] = useRecoilState(modelingDataState); @@ -51,6 +52,7 @@ const ConvertVideo = () => { navigate(`/summary/${video_id}`); setModelingData(null); } catch (e) { + setIsOpenErrorModal(true) console.error(e); } } else { diff --git a/src/components/modals/ErrorModal.tsx b/src/components/modals/ErrorModal.tsx new file mode 100644 index 0000000..90182ab --- /dev/null +++ b/src/components/modals/ErrorModal.tsx @@ -0,0 +1,39 @@ +import { useSetRecoilState } from 'recoil'; +import { errorModalState } from '@/stores/modal'; +import useOutsideClick from '@/hooks/useOutsideClick'; + +import CloseIcon from '@/assets/icons/close.svg?react'; +import errorImg from '@/assets/Error.png'; +import { ErrorModalContainer } from '@/styles/modals/ErrorModal.style'; + +const ErrorModal = () => { + const setIsOpenModal = useSetRecoilState(errorModalState); + const [modalRef] = useOutsideClick(() => + setIsOpenModal(false), + ); + + return ( + + + + setIsOpenModal(false)}> + + + + + + + 영상 업로드 중 오류 + + 업로드 중 알 수 없는 오류가 발생했어요다시 시도해주세요 + + + setIsOpenModal(false)}> + 다시 입력하기 + + + + ); +}; + +export default ErrorModal; \ No newline at end of file diff --git a/src/stores/modal.ts b/src/stores/modal.ts index ad21ac9..5adae7b 100644 --- a/src/stores/modal.ts +++ b/src/stores/modal.ts @@ -14,3 +14,8 @@ export const recommendationModalState = atom({ key: 'recommendation-modal', default: false, }); + +export const errorModalState = atom({ + key: 'error-modal', + default: false, +}); diff --git a/src/styles/modals/ErrorModal.style.ts b/src/styles/modals/ErrorModal.style.ts new file mode 100644 index 0000000..26f2543 --- /dev/null +++ b/src/styles/modals/ErrorModal.style.ts @@ -0,0 +1,85 @@ +import styled from 'styled-components'; +import theme from '../theme'; + +export const ErrorModalContainer = styled.div` + position: fixed; + z-index: 100; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + + .container { + width: 700px; + height: 384px; + background-color: ${theme.color.white}; + padding: 40px 50px; + display: flex; + flex-direction: column; + justify-content: space-between; + } + + .wrapper { + width: 600px; + height: 198px; + display: flex; + flex-direction: column; + justify-content: flex-start; + align-items: center; + } + + .close-btn { + align-self: flex-end; + cursor: pointer; + } + + .main { + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + } + + .modal-main { + width: 245px; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + } + + .modal-main h2 { + color: ${theme.color.gray500}; + font-style: ${theme.typography.Header6}; + font-size: 24px; + line-height: 1.6em; + margin-top: 12px; + margin-bottom: 12px; + } + + .main h4 { + color: ${theme.color.gray300}; + font-style: ${theme.typography.Body1}; + font-size: 16px; + line-height: 1.6em; + } + + .restart-btn { + width: 600px; + height: 58px; + font-style: ${theme.typography.Body1}; + font-size: 16px; + padding: 16px 24px; + color: ${theme.color.white}; + background-color: ${theme.color.gray500}; + border: none; + border-radius: 12px; + cursor: pointer; + } +`; \ No newline at end of file