diff --git a/src/components/layout/footer.tsx b/src/components/layout/footer.tsx
deleted file mode 100644
index 6874b51..0000000
--- a/src/components/layout/footer.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-const Footer = () => {
- return
footer
;
-};
-
-export default Footer;
diff --git a/src/components/layout/frame/frame.tsx b/src/components/layout/frame/frame.tsx
new file mode 100644
index 0000000..df6c514
--- /dev/null
+++ b/src/components/layout/frame/frame.tsx
@@ -0,0 +1,20 @@
+interface FrameProps {
+ title: string;
+ content: string;
+}
+
+const Frame = ({ title, content }: FrameProps) => {
+ return (
+ <>
+
+ {title}
+
+
{content}
+ {/* 버튼 컴포넌트 넣을 자리 */}
+
+
+ >
+ );
+};
+
+export default Frame;
diff --git a/src/components/layout/frame/index.ts b/src/components/layout/frame/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/components/ui/frame.tsx b/src/components/ui/frame.tsx
deleted file mode 100644
index 1fa2fb4..0000000
--- a/src/components/ui/frame.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import { useRouter } from 'next/router';
-
-interface FrameProps {
- title: string;
- content: string;
- buttonText: string;
- address: string;
-}
-
-const Frame = ({ title, content, buttonText, address }: FrameProps) => {
- const router = useRouter();
- return (
- <>
-
- {title}
-
-
{content}
-
-
-
- >
- );
-};
-
-export default Frame;
diff --git a/src/context/toastContext/index.ts b/src/context/toastContext/index.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/context/toastContext/toastContext.tsx b/src/context/toastContext/toastContext.tsx
new file mode 100644
index 0000000..1aa5333
--- /dev/null
+++ b/src/context/toastContext/toastContext.tsx
@@ -0,0 +1,58 @@
+import { createContext, ReactNode, useContext, useEffect, useState } from 'react';
+import { createPortal } from 'react-dom';
+
+interface ToastContextType {
+ showToast: (message: string) => void;
+}
+
+const ToastContext = createContext(null);
+
+export const useToast = () => {
+ const ctx = useContext(ToastContext);
+ if (!ctx) throw new Error('useToast 는 Provider 안에서 사용해주세요');
+ return ctx;
+};
+
+const ToastProvider = ({ children }: { children: ReactNode }) => {
+ const [message, setMessage] = useState(null);
+
+ const showToast = (msg: string) => {
+ setMessage(msg);
+ };
+
+ useEffect(() => {
+ if (!message) return;
+
+ const timer = setTimeout(() => {
+ setMessage(null);
+ }, 3000);
+
+ return () => {
+ clearTimeout(timer);
+ };
+ });
+
+ const toastRoot = typeof window !== 'undefined' ? document.getElementById('toast-root') : null;
+
+ return (
+ <>
+
+ {children}
+ {toastRoot &&
+ createPortal(
+ message ? (
+
+ {message}
+
+ ) : null,
+ toastRoot
+ )}
+
+ >
+ );
+};
+
+export default ToastProvider;
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 02bb329..e17e9d1 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,4 +1,5 @@
import { Container, Header, Wrapper } from '@/components/layout';
+import ToastProvider from '@/context/toastContext/toastContext';
import '@/styles/fonts.css';
import '@/styles/globals.css';
import type { NextPage } from 'next';
@@ -29,7 +30,7 @@ export default function App({ Component, pageProps }: AppPropsWithLayout) {
- {getLayout()}
+ {getLayout()}
>
);
}
diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx
index 85e9dc5..214a726 100644
--- a/src/pages/_document.tsx
+++ b/src/pages/_document.tsx
@@ -6,6 +6,7 @@ export default function Document() {
+