diff --git a/src/components/ReviewResult/ReviewResult.module.scss b/src/components/ReviewResult/ReviewResult.module.scss
index 45fa96d..24b5190 100644
--- a/src/components/ReviewResult/ReviewResult.module.scss
+++ b/src/components/ReviewResult/ReviewResult.module.scss
@@ -34,6 +34,12 @@
}
.Bottom {
+ display: flex;
+ flex-direction: column;
+ gap: 1.25rem;
+}
+
+.ButtonBox {
align-items: center;
gap: 0.875rem;
z-index: 1;
diff --git a/src/components/ReviewResult/ReviewResult.tsx b/src/components/ReviewResult/ReviewResult.tsx
index 14df758..a065e78 100644
--- a/src/components/ReviewResult/ReviewResult.tsx
+++ b/src/components/ReviewResult/ReviewResult.tsx
@@ -7,13 +7,23 @@ import styles from "@/components/ReviewResult/ReviewResult.module.scss";
import Button from "@/components/ui/Button/Button";
import IconButton from "@/components/ui/IconButton/IconButton";
import Text from "@/components/ui/Text/Text";
+import Toast from "@/components/ui/Toast/Toast";
import { useOverlay } from "@/hooks/common/useOverlay";
+import useToast from "@/hooks/common/useToast";
import type { Options as ConfettiOptions } from "canvas-confetti";
const ReviewResult = () => {
const { isOpen, handleClose, handleOpen } = useOverlay();
+ const { isToast, showToast } = useToast(1000);
+
+ const reviewText = `오늘 처음으로 청담커피 앤 토스트에서 주문했어요.. 매장도 깔끔하고 직원들도 친절해요!
+ 음료랑 토스트 세트 시켰는데 가성비가 좋네요… 맛도 좋고 양도 많아요!! 다음에도 또 시켜먹을 거예요.`;
+
+ const handleCopy = () => {
+ showToast();
+ };
const handleConfetti = () => {
const setting: ConfettiOptions = {
@@ -24,9 +34,7 @@ const ReviewResult = () => {
ticks: 50,
};
- confetti({
- ...setting,
- });
+ confetti(setting);
};
useEffect(() => {
@@ -46,17 +54,19 @@ const ReviewResult = () => {
- 오늘 처음으로 청담커피 앤 토스트에서 주문했어요.. 매장도 깔끔하고 직원들도 친절해요!
- 음료랑 토스트 세트 시켰는데 가성비가 좋네요… 맛도 좋고 양도 많아요!! 다음에도 또 시켜먹을
- 거예요.
+ {reviewText}
-
+
+
-
-
+ {isToast &&
}
+
+
+
+
diff --git a/src/components/ui/Toast/Toast.module.scss b/src/components/ui/Toast/Toast.module.scss
new file mode 100644
index 0000000..52576ab
--- /dev/null
+++ b/src/components/ui/Toast/Toast.module.scss
@@ -0,0 +1,39 @@
+.ToastStory {
+ display: flex;
+ align-items: center;
+ gap: 4rem;
+
+ .Wrapper {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 1rem;
+
+ .InnerWrapper {
+ width: 1.5rem;
+ height: 1.5rem;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ }
+ }
+}
+
+.Toast {
+ width: 100%;
+ height: 3.25rem;
+ z-index: 1;
+ border-radius: 0.75rem;
+ background-color: white;
+ padding: 0.875rem 1.125rem;
+
+ transform: translateY(-20px);
+ transition:
+ opacity 0.3s,
+ transform 0.3s;
+}
+
+.show {
+ opacity: 1;
+ transform: translateY(0);
+}
diff --git a/src/components/ui/Toast/Toast.stories.tsx b/src/components/ui/Toast/Toast.stories.tsx
new file mode 100644
index 0000000..2578950
--- /dev/null
+++ b/src/components/ui/Toast/Toast.stories.tsx
@@ -0,0 +1,20 @@
+import Toast from "@/components/ui/Toast/Toast";
+
+import type { Meta, StoryObj } from "@storybook/react";
+
+type ToastProps = {
+ text: string;
+};
+
+const meta: Meta = {
+ title: "Example/Toast",
+ component: Toast,
+};
+
+export default meta;
+
+export const Primary: StoryObj = {
+ args: {
+ text: "링크가 복사되었어요.",
+ },
+};
diff --git a/src/components/ui/Toast/Toast.tsx b/src/components/ui/Toast/Toast.tsx
new file mode 100644
index 0000000..6b9aebe
--- /dev/null
+++ b/src/components/ui/Toast/Toast.tsx
@@ -0,0 +1,20 @@
+import { forwardRef } from "react";
+
+import classNames from "classnames";
+
+import Text from "@/components/ui/Text/Text";
+import styles from "@/components/ui/Toast/Toast.module.scss";
+
+export interface ToastProps extends React.HTMLAttributes {
+ text: string;
+}
+
+const Toast = forwardRef(({ text, className, ...props }, ref) => {
+ return (
+
+ {text}
+
+ );
+});
+
+export default Toast;
diff --git a/src/hooks/common/useToast.ts b/src/hooks/common/useToast.ts
new file mode 100644
index 0000000..ffe0ed3
--- /dev/null
+++ b/src/hooks/common/useToast.ts
@@ -0,0 +1,21 @@
+import { useState } from "react";
+
+interface UseToastReturn {
+ isToast: boolean;
+ showToast: () => void;
+}
+
+const useToast = (duration: number = 1000): UseToastReturn => {
+ const [isToast, setIsToast] = useState(false);
+
+ const showToast = () => {
+ setIsToast(true);
+ setTimeout(() => {
+ setIsToast(false);
+ }, duration);
+ };
+
+ return { isToast, showToast };
+};
+
+export default useToast;