diff --git a/src/contexts/ModalProvider.jsx b/src/contexts/ModalProvider.jsx index 74792a0..c7705cc 100644 --- a/src/contexts/ModalProvider.jsx +++ b/src/contexts/ModalProvider.jsx @@ -13,6 +13,8 @@ export const ModalProvider = ({ children }) => { const [isOpen, setIsOpen] = useState(false); const [isClosing, setIsClosing] = useState(false); + const onModalCloseEventRef = useRef(null); + const modalWrapperRef = useRef(null); const isMouseDownInsideModal = useRef(false); @@ -27,17 +29,20 @@ export const ModalProvider = ({ children }) => { const pendingForClosingAnimation = () => { closeTimeoutRef.current = setTimeout(() => { - setIsOpen(false); - setIsClosing(false); - closeTimeoutRef.current = null; + if (isClosing) { + setIsOpen(false); + setIsClosing(false); + closeTimeoutRef.current = null; + } }, MODAL_CLOSE_DELAY); }; - const showModal = (ModalComponent) => { + const showModal = (ModalComponent, { onModalClose } = {}) => { resetTimer(); setModal(ModalComponent); setIsOpen(true); setIsClosing(false); + onModalCloseEventRef.current = onModalClose; }; const closeModal = () => { @@ -64,7 +69,12 @@ export const ModalProvider = ({ children }) => { !modalWrapperRef.current?.contains(e.target) && isMouseDownInsideModal.current === false ) { - closeModal(); + if (typeof onModalCloseEventRef.current === 'function') { + onModalCloseEventRef.current(); + closeModal(); + } else { + closeModal(); + } } }; diff --git a/src/pages/RollingPaperItemPage/RollingPaperItemPage.jsx b/src/pages/RollingPaperItemPage/RollingPaperItemPage.jsx index a2b2351..fdafe19 100644 --- a/src/pages/RollingPaperItemPage/RollingPaperItemPage.jsx +++ b/src/pages/RollingPaperItemPage/RollingPaperItemPage.jsx @@ -14,6 +14,7 @@ import ListButtonGroup from '@/pages/RollingPaperItemPage/components/ListButtonG import RequestDeletePaperModal from '@/pages/RollingPaperItemPage/components/RequestDeletePaperModal'; import DeletePaperSuccessModal from '@/pages/RollingPaperItemPage/components/DeletePaperSuccessModal'; import InfinityScrollWrapper from '@/components/InfinityScrollWrapper/InfinityScrollWrapper'; +import { getBackgroundStylesFromPostData } from '../../utils/getBackgroundStylesFromPostData'; const RollingPaperItemPage = () => { const navigate = useNavigate(); @@ -35,19 +36,10 @@ const RollingPaperItemPage = () => { } = useMessageItemsList(id); // 리스트 데이터 API 및 동작 /* 전체 배경 스타일 적용 */ - const containerStyle = recipientData - ? { - backgroundColor: !recipientData?.backgroundImageURL - ? COLOR_STYLES[recipientData?.backgroundColor]?.primary - : '', - backgroundImage: recipientData?.backgroundImageURL - ? `url(${recipientData?.backgroundImageURL})` - : 'none', - backgroundRepeat: 'no-repeat', - backgroundPosition: 'center', - backgroundSize: 'cover', - } - : {}; + const containerStyle = getBackgroundStylesFromPostData({ + backgroundColor: recipientData?.backgroundColor, + backgroundImageURL: recipientData?.backgroundImageURL, + }); const paperDeleteModalData = { title: ( @@ -145,14 +137,17 @@ const RollingPaperItemPage = () => { ); }; - if (showOverlay || isLoading) { + if (showOverlay) { return ; } return ( <> {/* 헤더 영역 */} - + { {!isEditMode && } {isEditMode && } + {itemList.length === 0 && + isLoading && + new Array(5).fill(0).map((_, i) => )} {itemList?.map((item) => ( { ); }; +const Skeleton = () => { + return ( + + + + + + + + + ); +}; + +ListCard.skeleton = Skeleton; + export default ListCard; diff --git a/src/pages/RollingPaperItemPage/components/ListCard.module.scss b/src/pages/RollingPaperItemPage/components/ListCard.module.scss index 6c2f686..f19609d 100644 --- a/src/pages/RollingPaperItemPage/components/ListCard.module.scss +++ b/src/pages/RollingPaperItemPage/components/ListCard.module.scss @@ -131,3 +131,44 @@ font-size: var(--font-size-18); color: var(--color-gray-600); } + +.skeleton-card { + min-width: 272px; + width: 100%; + max-width: 384px; + aspect-ratio: 320 / 230; + background-color: var(--color-white); + border-radius: 16px; + padding: 24px; + display: flex; + justify-content: center; + align-items: center; + box-shadow: 0px 2px 12px 0px #00000014; + + &__container { + width: clamp(272px, 80vw, 384px); + height: 100%; + display: flex; + flex-direction: column; + justify-content: space-between; + } + + &__profile { + @include skeleton-style; + width: 100%; + height: 56px; + } + + &__context { + @include skeleton-style; + width: 100%; + flex-grow: 1; + margin-bottom: 10px; + } + + &__date { + @include skeleton-style; + width: 70px; + height: 12px; + } +} \ No newline at end of file