diff --git a/src/pages/Announcement/index.tsx b/src/pages/Announcement/index.tsx index fda074d6..17f01d93 100644 --- a/src/pages/Announcement/index.tsx +++ b/src/pages/Announcement/index.tsx @@ -4,19 +4,35 @@ import AnnounceList from '@components/Card/AnnounceCard/AnnounceList'; import AnnounceCardSkeleton from '@components/Card/AnnounceCard/Skeleton'; import AlertModal from '@components/Modal/AlertModal'; import { MODAL_MESSAGE } from '@constants/modal-messages'; -import { css } from '@emotion/react'; +import { css, keyframes } from '@emotion/react'; +import styled from '@emotion/styled'; import useMajor from '@hooks/useMajor'; import useModals from '@hooks/useModals'; import useRouter from '@hooks/useRouter'; import { THEME } from '@styles/ThemeProvider/theme'; -import { Suspense } from 'react'; +import { Suspense, useState } from 'react'; + +type AnimationType = 'bottomBar' | 'announce'; +type GetAnimationType = (type: AnimationType) => string; const Announcement = () => { const { major } = useMajor(); const { routerTo } = useRouter(); const { openModal, closeModal } = useModals(); + const [activeAnimation, setActiveAnimation] = useState(false); + const routerToMajorDecision = () => routerTo('/major-decision'); + const announceKeyword = decodeURI(window.location.pathname.split('/')[2]); + const isKeywordUndefined = () => announceKeyword === 'undefined'; + + const getAnimationType: GetAnimationType = (type) => { + if (!activeAnimation) return 'none'; + if (type === 'bottomBar') { + return !isKeywordUndefined() ? BottomBarSlideRight : BottomBarSlideLeft; + } + return !isKeywordUndefined() ? AnnounceSlideRight : AnnounceSlideLeft; + }; const handleMajorAnnouncements = () => { if (!major) { @@ -32,23 +48,25 @@ const Announcement = () => { }); return; } + if (!activeAnimation) { + setActiveAnimation((prev) => !prev); + } routerTo(`${major}`); }; - const isKeywordUndefined = () => announceKeyword === 'undefined'; - return ( <>
+
- }> - - + + }> + + + ); }; + export default Announcement; + +const BottomBar = styled.span<{ getAnimationType: GetAnimationType }>` + position: absolute; + bottom: 0; + left: 0; + width: 50%; + height: 3px; + background-color: ${THEME.PRIMARY}; + animation: ${({ getAnimationType }) => getAnimationType('bottomBar')} 0.3s + forwards; +`; + +const AnnounceContainer = styled.div<{ getAnimationType: GetAnimationType }>` + width: 100%; + animation: ${({ getAnimationType }) => getAnimationType('announce')} 0.3s + forwards; +`; + +const BottomBarSlideRight = keyframes` + from { + transform: translateX(0); + } + to { + transform: translateX(100%); + } +`; + +const BottomBarSlideLeft = keyframes` + from { + transform: translateX(100%); + } + to { + transform: translateX(0%); + } +`; + +const AnnounceSlideRight = keyframes` + from { + transform: translateX(-100%); + display: none; + } + to { + transform: translateX(0%); + } +`; + +const AnnounceSlideLeft = keyframes` + from { + transform: translateX(200%); + display: none; + } + to { + transform: translateX(0%); + } +`;