Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/modal #10

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"react": "^19.0.0",
"react-dom": "^19.0.0",
"sonner": "^1.7.4",
"react-icons": "^5.4.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkdtmddnjs97

아이콘은 나중에 @haedawn 님이 만들어주신거를 한번에 적용하기로 하고,

그전까지는 이전에 설치된 lucide-react 를 사용하는것도 좋을 것 같습니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 이게 있었군요 고치겠습니다

"tailwind-merge": "^2.6.0",
"zustand": "^5.0.2"
},
Expand Down
42 changes: 42 additions & 0 deletions src/app/(routes)/test/modal/page.tsx
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkdtmddnjs97

해당 페이지 text 에 설정한 내용들 디자인 시스템 적용 부탁드립니다!

테스트 페이지라 임의로 사용하신거면 무시하셔도 됩니다. 🙇‍♂️

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

임의 사용이라 무시해도 될 것 같아요 어차피 쓸 일이 없는 버튼이라

Original file line number Diff line number Diff line change
@@ -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(
<ConfirmModal onConfirm={() => {}} onCancel={closeModal}>
<p className="text-xl font-medium text-white">로그아웃 하시겠습니까?</p>
</ConfirmModal>
)
}
const openDeleteAccount = () => {
openModal(
<ConfirmModal onConfirm={() => {}} onCancel={closeModal}>
<p className="text-xl font-medium text-white">탈퇴하면 모든 정보가 사라집니다.</p>
<p className="text-xl font-medium text-white">탈퇴하시겠습니까?</p>
</ConfirmModal>
)
}
const openCollenctionModal = () => {
openModal(<CollectionModal onCancel={closeModal} />)
}

return (
<div className="flex min-h-screen items-center justify-center gap-10 bg-gray-100">
<Button className="text-white" onClick={openLogoutModal}>
로그아웃 모달 열기
</Button>
<Button className="text-white" onClick={openDeleteAccount}>
탈퇴 모달 열기
</Button>
<Button className="text-white" onClick={openCollenctionModal}>
컬렉션 모달 열기
</Button>
</div>
)
}
6 changes: 4 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Modal from "@/components/modal/Modal"
import Toast from "@/components/Toast"
import { Pretendard } from "@/fonts"
import "@/styles/globals.css"
Expand All @@ -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({
Expand All @@ -20,6 +21,7 @@ export default function RootLayout({
<body className={cn(Pretendard.variable)}>
{children}
<Toast />
<Modal />
</body>
</html>
)
Expand Down
18 changes: 18 additions & 0 deletions src/components/modal/CollectionModal/CollectionCreate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Button from "@/components/Button"
import Textarea from "@/components/Textarea"

export default function CollectionCreate() {
return (
<>
<div className="flex flex-col gap-[16px]">
<p>컬렉션 이름</p>
<Textarea placeholder="컬렉션 이름을 입력해주세요" rows={1}></Textarea>
</div>
<div className="flex items-center justify-end">
<Button className="h-[40px] w-[148px] bg-gray-scale-700 p-0">
<p className="text-h1-m text-gray-100">완료</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkdtmddnjs97

gray 대신 gray-scale 로 사용해주시면 좋을 것 같습니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 이거 깜빡했네요

</Button>
</div>
</>
)
}
37 changes: 37 additions & 0 deletions src/components/modal/CollectionModal/CollectionList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Button from "@/components/Button"
import { FaPlus } from "react-icons/fa6"

const Collections = ["컬렉션1", "컬렉션2", "컬렉션3", "컬렉션4"]

type Props = {
onCreate: () => void
}

export default function CollectionList({ onCreate }: Props) {
return (
<>
<div className="mt-[28px] flex flex-col gap-[40px]">
<Button className="w-[148px] bg-gray-scale-700 px-[24px] py-[10px] text-primary-300">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkdtmddnjs97

py-[8px] or py-[12px]로 바꿔주시면 좋을 것 같아요!

<div className="flex items-center gap-[20px] text-h3-sb" onClick={() => onCreate()}>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkdtmddnjs97

onCreate 타입이 () => void 이므로,

onClick={onCreate} 로 지정해주셔도 될 것 같습니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인정합니다

<p>컬랙션 추가</p>
<FaPlus size={"14px"} />
</div>
</Button>
<div>
<div className="border-b-[1px] border-gray-scale-700 px-[8px] py-[8px]">기본</div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkdtmddnjs97

px-[8px] py-[8px] -> p-[8px]

{Collections.map((collection, idx) => (
<div className="border-b-[1px] border-gray-scale-700 p-[8px] py-[16px]" key={idx}>
<p className="">{collection}</p>
</div>
))}
</div>
</div>
<div className="flex items-center justify-end gap-[24px]">
<p className="text-h2-sb text-primary-300">메모 추가</p>
<Button className="h-[40px] w-[148px] bg-primary-400 p-0">
<p className="text-h1-m text-gray-100">완료</p>
</Button>
</div>
</>
)
}
31 changes: 31 additions & 0 deletions src/components/modal/CollectionModal/CollectionModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { IoIosArrowBack, IoMdClose } from "react-icons/io"
import CollectionList from "./CollectionList"
import { useState } from "react"
import CollectionCreate from "./CollectionCreate"
type Props = {
onCancel: () => void
}

export default function CollectionModal({ onCancel }: Props) {
const [isCreateMode, setIsCreateMode] = useState(false)

return (
<div className="flex min-h-[600px] w-[720px] flex-col gap-[32px] rounded-lg bg-gray-scale-800 stroke-primary-300 stroke-[1px] px-[24px] py-[36px]">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkdtmddnjs97

  1. roundedpixel 을 명시해주기로 했으니 rounded-lg 대신에 Figma 값으로 설정 부탁드립니다! 🙇‍♂️

  2. div 에는 stroke 속성이 아닌, border 속성을 사용해야 하는걸로 알고있는데, 확인 부탁드려도 될까요?

stroke 는 HTML 요소에 적용이 안되는걸로 알고있는데 확인 한번 부탁드립니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 figma 그대로 디자인넣다보니 stroke를 넣었군요 어쩐지 안되더라고요... 나중에 고칠려고 했는데 알려주셔서 감사합니다

<div className="flex justify-between">
<div onClick={() => setIsCreateMode(false)} className="cursor-pointer">
<IoIosArrowBack />
</div>
<div>컬렉션 추가</div>
<div onClick={() => onCancel()} className="cursor-pointer">
<IoMdClose />
</div>
</div>
<div className="flex flex-1 gap-6">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gap-6 -> gap-[_px]

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이것도 누락됬었네요

<div className="w-64 flex-1 rounded-xl bg-black"></div>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

w-64 -> w-[_px]

<div className="flex flex-1 flex-col justify-between">
{isCreateMode ? <CollectionCreate /> : <CollectionList onCreate={() => setIsCreateMode(true)} />}
</div>
</div>
</div>
)
}
27 changes: 27 additions & 0 deletions src/components/modal/ConfirmModal.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="flex flex-col gap-[56px] rounded-lg bg-gray-scale-800 stroke-primary-300 stroke-[1px] px-[38px] py-[44px] text-center">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rkdtmddnjs97

CollectionModal 에 달아놓은 댓글과 동일한 내용 확인 부탁드립니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 확인이요

<div>{children}</div>
<div className="flex justify-center gap-[24px]">
<Button
className="h-[48px] w-[148px] bg-gray-scale-700 text-h1-m text-gray-scale-500"
onClick={() => onConfirm()}
>
</Button>
<Button className="h-[48px] w-[148px] text-h1-m text-white" onClick={() => onCancel()}>
아니요
</Button>
</div>
</div>
)
}
29 changes: 29 additions & 0 deletions src/components/modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -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(
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-gray-scale-900 backdrop-blur-2xl"
onClick={closeModal}
>
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9 }}
className="relative"
onClick={(e) => e.stopPropagation()}
>
{content}
</motion.div>
</div>,
document.body
)
}
16 changes: 16 additions & 0 deletions src/store/modal.ts
Original file line number Diff line number Diff line change
@@ -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<ModalState>((set) => ({
isOpen: false,
content: null,
openModal: (content) => set({ isOpen: true, content }),
closeModal: () => set({ isOpen: false, content: null })
}))