diff --git a/src/app/(routes)/test/modal/page.tsx b/src/app/(routes)/test/modal/page.tsx new file mode 100644 index 0000000..d177b14 --- /dev/null +++ b/src/app/(routes)/test/modal/page.tsx @@ -0,0 +1,42 @@ +"use client" +import { useModalStore } from "@/store/modal" +import ConfirmModal from "@/components/modal/ConfirmModal" +import Button from "@/components/Button" +import CollectionModal from "@/components/modal/CollectionModal/CollectionModal" + +export default function Home() { + const { openModal, closeModal } = useModalStore() + + const openLogoutModal = () => { + openModal( + {}} onCancel={closeModal}> +

로그아웃 하시겠습니까?

+
+ ) + } + const openDeleteAccount = () => { + openModal( + {}} onCancel={closeModal}> +

탈퇴하면 모든 정보가 사라집니다.

+

탈퇴하시겠습니까?

+
+ ) + } + const openCollenctionModal = () => { + openModal() + } + + return ( +
+ + + +
+ ) +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 3ae5a1b..f0b0803 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,3 +1,4 @@ +import Modal from "@/components/modal/Modal" import Toast from "@/components/Toast" import { Pretendard } from "@/fonts" import "@/styles/globals.css" @@ -6,8 +7,8 @@ import { cn } from "@/utils/cn" import type { Metadata } from "next" export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app" + title: "Memez", + description: "welcome to memez party" } export default function RootLayout({ @@ -20,6 +21,7 @@ export default function RootLayout({ {children} + ) diff --git a/src/components/modal/CollectionModal/CollectionCreate.tsx b/src/components/modal/CollectionModal/CollectionCreate.tsx new file mode 100644 index 0000000..4f69a1b --- /dev/null +++ b/src/components/modal/CollectionModal/CollectionCreate.tsx @@ -0,0 +1,18 @@ +import Button from "@/components/Button" +import Textarea from "@/components/Textarea" + +export default function CollectionCreate() { + return ( + <> +
+

컬렉션 이름

+ +
+
+ +
+ + ) +} diff --git a/src/components/modal/CollectionModal/CollectionList.tsx b/src/components/modal/CollectionModal/CollectionList.tsx new file mode 100644 index 0000000..98e9605 --- /dev/null +++ b/src/components/modal/CollectionModal/CollectionList.tsx @@ -0,0 +1,38 @@ +import Button from "@/components/Button" +import { Plus } from "lucide-react" +const Collections = ["컬렉션1", "컬렉션2", "컬렉션3", "컬렉션4"] +type Props = { + onCreate: () => void +} + +export default function CollectionList({ onCreate }: Props) { + return ( + <> +
+
+ +

현재 “컬렉션 1”에 수록되어 있어요!

+
+
+
기본
+ {Collections.map((collection, idx) => ( +
+

{collection}

+
+ ))} +
+
+
+

메모 추가

+ +
+ + ) +} diff --git a/src/components/modal/CollectionModal/CollectionModal.tsx b/src/components/modal/CollectionModal/CollectionModal.tsx new file mode 100644 index 0000000..5cc3bea --- /dev/null +++ b/src/components/modal/CollectionModal/CollectionModal.tsx @@ -0,0 +1,32 @@ +import CollectionList from "./CollectionList" +import { useState } from "react" +import CollectionCreate from "./CollectionCreate" +import { ArrowLeft, X } from "lucide-react" +type Props = { + onCancel: () => void +} + +export default function CollectionModal({ onCancel }: Props) { + const [isCreateMode, setIsCreateMode] = useState(false) + + return ( +
+
+
setIsCreateMode(false)} className="cursor-pointer"> + {/* */} + +
+
컬렉션 추가
+
onCancel()} className="cursor-pointer"> + +
+
+
+
+
+ {isCreateMode ? : setIsCreateMode(true)} />} +
+
+
+ ) +} diff --git a/src/components/modal/ConfirmModal.tsx b/src/components/modal/ConfirmModal.tsx new file mode 100644 index 0000000..23b2a3a --- /dev/null +++ b/src/components/modal/ConfirmModal.tsx @@ -0,0 +1,27 @@ +import { ReactNode } from "react" +import Button from "../Button" + +type Props = { + children: ReactNode + onConfirm: () => void + onCancel: () => void +} + +export default function ConfirmModal({ children, onCancel, onConfirm }: Props) { + return ( +
+
{children}
+
+ + +
+
+ ) +} diff --git a/src/components/modal/Modal.tsx b/src/components/modal/Modal.tsx new file mode 100644 index 0000000..dca8916 --- /dev/null +++ b/src/components/modal/Modal.tsx @@ -0,0 +1,29 @@ +"use client" +import React from "react" +import ReactDOM from "react-dom" +import { motion } from "framer-motion" +import { useModalStore } from "@/store/modal" + +export default function Modal() { + const { isOpen, closeModal, content } = useModalStore() + + if (!isOpen) return null + + return ReactDOM.createPortal( +
+ e.stopPropagation()} + > + {content} + +
, + document.body + ) +} diff --git a/src/store/modal.ts b/src/store/modal.ts new file mode 100644 index 0000000..b66263d --- /dev/null +++ b/src/store/modal.ts @@ -0,0 +1,16 @@ +import { create } from "zustand" +import { ReactNode } from "react" + +interface ModalState { + isOpen: boolean + content: ReactNode | null + openModal: (content: ReactNode) => void + closeModal: () => void +} + +export const useModalStore = create((set) => ({ + isOpen: false, + content: null, + openModal: (content) => set({ isOpen: true, content }), + closeModal: () => set({ isOpen: false, content: null }) +}))