From b52f85623102c5524d1a34f4ffb5fd8dba34e641 Mon Sep 17 00:00:00 2001 From: Chamsol Kim Date: Sat, 23 Aug 2025 13:54:32 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat=20[#78]=20Modal=20component=EA=B0=80?= =?UTF-8?q?=20content=EB=A5=BC=20=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8A=94=20?= =?UTF-8?q?=EC=B1=85=EC=9E=84=EB=A7=8C=20=EA=B0=96=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Modal 방식을 범용적으로 사용할 수 있도록 '확인' 버튼을 제거합니다. - MUI의 Modal component interface를 참고하였습니다. - 이 변경사항이 영향을 미치는 곳을 아직 수정하지 않았으므로, 이 commit에서는 error가 발생합니다. --- src/components/modal/modal.jsx | 29 +++-------------------------- src/hooks/use-modal.jsx | 3 +-- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/src/components/modal/modal.jsx b/src/components/modal/modal.jsx index deb75b5..631f61a 100644 --- a/src/components/modal/modal.jsx +++ b/src/components/modal/modal.jsx @@ -1,7 +1,4 @@ import styled from "styled-components"; -import { useModal } from "../../hooks/use-modal"; -import { PrimaryButton } from "../button/button"; -import BUTTON_SIZE from "../button/button-size"; import Portal from "../portal/portal"; const Content = styled.div` @@ -34,34 +31,14 @@ const ModalContainer = styled.div` align-items: center; `; -const ActionButton = styled.div` - cursor: pointer; -`; - -function Modal({ id, action, children }) { - const { showsModal, setShowsModal } = useModal({ - id: id, - type: "modal", - }); - - const handleClick = () => setShowsModal(true); - const handleConfirmClick = () => setShowsModal(false); - +function Modal({ shows, children }) { return ( <> - {action} - {showsModal && ( + {shows && ( - - {children} - - + {children} diff --git a/src/hooks/use-modal.jsx b/src/hooks/use-modal.jsx index 9a3a1ad..964b050 100644 --- a/src/hooks/use-modal.jsx +++ b/src/hooks/use-modal.jsx @@ -1,7 +1,6 @@ import { usePortal } from "./use-portal"; -function useModal({ id, type }) { - const key = `${type}_${id}`; +function useModal({ key }) { const { isOpen, setIsOpen } = usePortal({ key }); return { showsModal: isOpen, setShowsModal: setIsOpen }; } From ff3f562ba21380fe1ca50053d141777181bfb0d7 Mon Sep 17 00:00:00 2001 From: Chamsol Kim Date: Sat, 23 Aug 2025 13:55:06 +0900 Subject: [PATCH 2/3] =?UTF-8?q?refactor=20[#78]=20`TestComponentsPage`?= =?UTF-8?q?=EC=97=90=20`Modal`=20=EB=B3=80=EA=B2=BD=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tests/test-components-page.jsx | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/tests/test-components-page.jsx b/src/tests/test-components-page.jsx index 7e3cbb7..31cfe32 100644 --- a/src/tests/test-components-page.jsx +++ b/src/tests/test-components-page.jsx @@ -22,6 +22,7 @@ import POPOVER_ALIGNMENT from "../components/popover/popover-alignment"; import TextField from "../components/text-field/text-field"; import TEXT_FIELD_TYPE from "../components/text-field/text-field-type"; import Toast from "../components/toast/toast"; +import { useModal } from "../hooks/use-modal"; import { useToast } from "../hooks/use-toast"; const OutlinedHeader = styled(Header)` @@ -48,6 +49,13 @@ function TestComponentsPage() { const handleToastClick = () => setShowsToast(true); const handleToastDismiss = () => setShowsToast(false); + /* Modal */ + const { showsModal, setShowsModal } = useModal({ + key: "test-modal", + }); + const handleModalOpen = () => setShowsModal(true); + const handleModalClose = () => setShowsModal(false); + return (
- } - > + +

This is Modal.

+
From 4efcaf4a2cc70d0bce7204df5f699cba4245925f Mon Sep 17 00:00:00 2001 From: Chamsol Kim Date: Sat, 23 Aug 2025 13:55:29 +0900 Subject: [PATCH 3/3] =?UTF-8?q?refactor=20[#78]=20`MessagesGrid`=EC=97=90?= =?UTF-8?q?=20`Modal`=20=EB=B3=80=EA=B2=BD=EC=82=AC=ED=95=AD=20=EB=B0=98?= =?UTF-8?q?=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/message-card-detail.jsx | 23 +++++++- .../message/components/message-card.jsx | 17 +++++- .../message/components/messages-grid.jsx | 58 ++++++++++++------- 3 files changed, 71 insertions(+), 27 deletions(-) diff --git a/src/features/message/components/message-card-detail.jsx b/src/features/message/components/message-card-detail.jsx index 2f90ae9..68f8ad0 100644 --- a/src/features/message/components/message-card-detail.jsx +++ b/src/features/message/components/message-card-detail.jsx @@ -1,9 +1,12 @@ import styled from "styled-components"; +import { PrimaryButton } from "../../../components/button/button"; +import BUTTON_SIZE from "../../../components/button/button-size"; import Colors from "../../../components/color/colors"; import { formatDate } from "../../../utils/formatter"; import MessageSender from "./message-sender"; const Header = styled.header` + width: 100%; display: flex; justify-content: space-between; align-items: center; @@ -12,6 +15,7 @@ const Header = styled.header` `; const Content = styled.div` + width: 100%; margin-top: 16px; font-size: 18px; font-weight: 400; @@ -34,6 +38,10 @@ const Content = styled.div` } `; +const Action = styled.div` + padding-top: 24px; +`; + const CreatedDate = styled.span` font-size: 14px; font-weight: 400; @@ -41,9 +49,13 @@ const CreatedDate = styled.span` color: ${Colors.gray(400)}; `; -const StyledMessageCardDetail = styled.div``; +const StyledMessageCardDetail = styled.div` + display: flex; + flex-direction: column; + align-items: center; +`; -function MessageCardDetail({ message }) { +function MessageCardDetail({ message, onConfirm }) { return (
@@ -55,6 +67,13 @@ function MessageCardDetail({ message }) { {formatDate(message.createdAt, ".")}
{message.content} + + +
); } diff --git a/src/features/message/components/message-card.jsx b/src/features/message/components/message-card.jsx index d20a7cd..f1db29b 100644 --- a/src/features/message/components/message-card.jsx +++ b/src/features/message/components/message-card.jsx @@ -50,11 +50,22 @@ const StyledMessageCard = styled.article` border-radius: 16px; background-color: white; box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.08); + cursor: ${({ $isEditing }) => ($isEditing ? "default" : "pointer")}; `; -function MessageCard({ isEditing, message, onDelete }) { +function MessageCard({ isEditing, message, onClick, onDelete }) { + const handleClick = () => { + if (isEditing) return; + onClick(message); + }; + + const handleDeleteClick = (event) => { + event.stopPropagation(); + onDelete(message.id); + }; + return ( - +
)}
diff --git a/src/features/message/components/messages-grid.jsx b/src/features/message/components/messages-grid.jsx index 0e42b5e..47f7729 100644 --- a/src/features/message/components/messages-grid.jsx +++ b/src/features/message/components/messages-grid.jsx @@ -1,8 +1,9 @@ -import { useRef } from "react"; +import { useRef, useState } from "react"; import { useNavigate, useParams } from "react-router"; import styled from "styled-components"; import Modal from "../../../components/modal/modal.jsx"; import { useIntersectionObserver } from "../../../hooks/use-intersection-observer.jsx"; +import { useModal } from "../../../hooks/use-modal.jsx"; import { media } from "../../../utils/media.js"; import MessageCardAdd from "./message-card-add.jsx"; import MessageCardDetail from "./message-card-detail.jsx"; @@ -28,6 +29,10 @@ function MessagesGrid({ isEditing, messages, onDelete, onInfiniteScroll }) { const navigate = useNavigate(); const { id } = useParams(); const infiniteScrollTargetRef = useRef(); + const { showsModal, setShowsModal } = useModal({ + key: "message-modal", + }); + const [modalMessage, setModalMessage] = useState(null); const observerCallback = (entry) => { if (!entry.isIntersecting) return; @@ -39,33 +44,42 @@ function MessagesGrid({ isEditing, messages, onDelete, onInfiniteScroll }) { navigate(`/post/${id}/message`); }; + const handleMessageClick = (message) => { + setShowsModal(true); + setModalMessage(message); + }; + const handleDeleteClick = (messageId) => { onDelete(messageId); }; - const messageCard = (message) => ( - handleDeleteClick(message.id)} - /> - ); + const handleModalConfirm = () => { + setShowsModal(false); + setModalMessage(null); + }; return ( - - - {messages.map((message) => - isEditing ? ( - messageCard(message) - ) : ( - - - - ) - )} -
-
+ <> + + + {messages.map((message) => ( + + ))} +
+
+ + + + ); }