Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 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
1 change: 1 addition & 0 deletions components/modal/AddFolderModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ const AddFolderModal = ({ folderName }: { folderName: string }) => {
</ModalContainer>
);
};

export default AddFolderModal;
14 changes: 2 additions & 12 deletions components/modal/AddModal.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
import { FolderItemType } from "@/types/modalTypes";
import FolderList from "./modalComponents/FolderList";
import ModalContainer from "./modalComponents/ModalContainer";
interface ItemType {
id: number;
title: string;
totalCount: number;
}
const list: ItemType[] = [
{ id: 1, title: "코딩팁", totalCount: 7 },
{ id: 2, title: "채용 사이트", totalCount: 7 },
{ id: 3, title: "유용한 글", totalCount: 7 },
{ id: 4, title: "나만의 장소", totalCount: 7 },
];

const AddModal = ({ list }: { list: ItemType[] }) => {
const AddModal = ({ list }: { list: FolderItemType[] }) => {
return (
<ModalContainer
title="폴더에 추가"
Expand Down
8 changes: 2 additions & 6 deletions components/modal/modalComponents/FolderItem.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { cls } from "@/lib/utils";
import { FolderItemType } from "@/types/modalTypes";
import { useState } from "react";
import { FaCheck } from "react-icons/fa6";

interface ItemType {
id: number;
title: string;
totalCount: number;
}
const FolderItem = ({ item }: { item: ItemType }) => {
const FolderItem = ({ item }: { item: FolderItemType }) => {
const [selected, setSelected] = useState(false);

const bgColor = selected ? "bg-gray100" : "bg-white";
Expand Down
20 changes: 4 additions & 16 deletions components/modal/modalComponents/FolderList.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
import { FolderItemType } from "@/types/modalTypes";
import FolderItem from "./FolderItem";
interface ItemType {
id: number;
title: string;
totalCount: number;
}

const list: ItemType[] = [
{ id: 1, title: "코딩팁", totalCount: 7 },
{ id: 2, title: "채용 사이트", totalCount: 7 },
{ id: 3, title: "유용한 글", totalCount: 7 },
{ id: 4, title: "나만의 장소", totalCount: 7 },
];
const FolderList = ({ list }: { list: ItemType[] }) => {
const FolderList = ({ list }: { list: FolderItemType[] | undefined }) => {
return (
<ul className="mb-6 flex flex-col gap-1 min-w-[280px] w-full">
{list.map((item) => (
<FolderItem key={item.id} item={item} />
))}
<ul className="mb-6 flex flex-col gap-1 w-full">
{list?.map((item) => <FolderItem key={item.id} item={item} />)}
</ul>
);
};
Expand Down
41 changes: 25 additions & 16 deletions components/modal/modalComponents/ModalContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
import { MouseEvent, ReactNode } from "react";
import { IoIosClose } from "react-icons/io";
import Button from "../../Button";
import { ModalPropType } from "@/types/modalTypes";
import useModalStore from "@/store/useModalStore";
import { MouseEvent, useRef } from "react";

const ModalContainer = ({
title,
subtitle,
children,
buttonText,
buttonColor,
onClick,
}: {
title: string;
subtitle?: string;
children?: ReactNode;
buttonText?: string;
buttonColor?: "positive" | "negative";
onClick?: (e: MouseEvent<HTMLButtonElement>) => void;
}) => {
}: ModalPropType) => {
const { closeModal } = useModalStore();
const modalRef = useRef<HTMLDivElement | null>(null);
const onClickBackDrop = (e: MouseEvent<HTMLDivElement>) => {
if (modalRef.current && !modalRef.current.contains(e.target as Node))
closeModal();
};

return (
<div className="z-30 absolute top-0 left-0 flex justify-center items-center bg-black/40 h-screen w-screen">
<div className="z-20 relative w-[360px] py-8 px-10 flex flex-col gap-6 bg-white rounded-[15px] border border-gray300">
<div
onClick={onClickBackDrop}
className="z-30 absolute top-0 left-0 flex justify-center items-center bg-black/40 h-screen w-screen"
>
<div
ref={modalRef}
className="z-20 relative w-[330px] md:w-[360px] py-8 px-10 flex flex-col gap-6 bg-white rounded-[15px] border border-gray300"
>
{/* 제목 + 부제목 */}
<div className="flex flex-col items-center justify-center gap-2">
<div className="text-center w-[280px] gap-2 text-black300 text-xl leading-6 font-bold">
{title}
</div>
{title && (
<div className="text-center w-[250px] md:w-[280px] gap-2 text-black300 text-xl leading-6 font-bold">
{title}
</div>
)}
{subtitle && (
<div className="text-sm leading-[22px] font-normal text-gray400">
{subtitle}
Expand All @@ -51,7 +60,7 @@ const ModalContainer = ({
{/* 모달 닫기 버튼 */}
<button
type="button"
onClick={onClick}
onClick={() => closeModal()}
className="bg-gray200 absolute top-4 right-4 rounded-full size-6 flex justify-center items-center"
>
<IoIosClose className="text-gray400" strokeWidth={2} />
Expand Down
2 changes: 1 addition & 1 deletion components/modal/modalComponents/ModalInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const ModalInput = ({
placeholder,
name,
}: {
placeholder?: string;
placeholder: string;
name: string;
}) => {
return (
Expand Down
50 changes: 50 additions & 0 deletions components/modal/modalManager/ModalManager.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import useModalStore from "@/store/useModalStore";
import AddModal from "../AddModal";
import DeleteFolderModal from "../DeleteFolderModal";
import AddFolderModal from "../AddFolderModal";
import DeleteLinkModal from "../DeleteLinkModal";
import EditModal from "../EditModal";
import SNSModal from "../SNSModal";

export const ModalType = {
AddFolderModal: "AddFolderModal",
AddModal: "AddModal",
DeleteFolderModal: "DeleteFolderModal",
DeleteLinkModal: "DeleteLinkModal",
EditModal: "EditModal",
SNSModal: "SNSModal",
} as const;

export type ModalKeysType = keyof typeof ModalType;

export const Modal = () => {
const { modalType, isOpen, props } = useModalStore();

if (!modalType || !isOpen) return null;

switch (modalType) {
case "AddFolderModal":
return <AddFolderModal folderName={props.folderName || ""} />;
case "AddModal":
return (
<AddModal
list={
props.list || [
{ id: 1, title: "코딩팁", totalCount: 7 },
{ id: 2, title: "채용 사이트", totalCount: 7 },
{ id: 3, title: "유용한 글", totalCount: 7 },
{ id: 4, title: "나만의 장소", totalCount: 7 },
]
}
/>
);
case "DeleteFolderModal":
return <DeleteFolderModal folderName={props.folderName || ""} />;
case "DeleteLinkModal":
return <DeleteLinkModal link={props.link || ""} />;
case "EditModal":
return <EditModal folderName={props.folderName || ""} />;
case "SNSModal":
return <SNSModal folderName={props.folderName || ""} />;
}
};
75 changes: 55 additions & 20 deletions package-lock.json

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

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
"dependencies": {
"axios": "^1.7.7",
"next": "15.0.2",
"react": "19.0.0-rc-02c0e824-20241028",
"react-dom": "19.0.0-rc-02c0e824-20241028",
"react-icons": "^5.3.0"
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^5.3.0",
"zustand": "^5.0.1"
},
"devDependencies": {
"@types/node": "^20",
Expand Down
30 changes: 30 additions & 0 deletions pages/test/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Modal } from "@/components/modal/modalManager/ModalManager";
import useModalStore from "@/store/useModalStore";

export default function Test() {
const { isOpen, openModal } = useModalStore();

return (
<div className="m-20 w-200 flex flex-col gap-4">
<button type="button" onClick={() => openModal("AddFolderModal")}>
폴더 추가 버튼
</button>
<button type="button" onClick={() => openModal("AddModal")}>
폴더에 추가 버튼
</button>
<button type="button" onClick={() => openModal("DeleteFolderModal")}>
폴더 삭제 버튼
</button>
<button type="button" onClick={() => openModal("DeleteLinkModal")}>
링크 삭제 버튼
</button>
<button type="button" onClick={() => openModal("EditModal")}>
폴더 이름 수정 버튼
</button>
<button type="button" onClick={() => openModal("SNSModal")}>
공유 버튼
</button>
{isOpen && <Modal />}
</div>
);
}
Loading
Loading