From 12219b8e26841a5a65e00064cc0fae3b5afaa6ce Mon Sep 17 00:00:00 2001 From: Mahi11Patel <24bce336@nirmaui.ac.in> Date: Thu, 11 Jun 2026 11:57:26 +0530 Subject: [PATCH] feat: add toast notifications for export and copy events --- src/app/globals.css | 20 +++++++++ src/components/Toast.tsx | 81 ++++++++++++++++++++++++++++++++++ src/components/VideoEditor.tsx | 26 ++++++++++- src/hooks/useToast.ts | 44 ++++++++++++++++++ 4 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 src/components/Toast.tsx create mode 100644 src/hooks/useToast.ts diff --git a/src/app/globals.css b/src/app/globals.css index 2f27ce26..d73f6f08 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -168,4 +168,24 @@ detail > summary { } details > summary::-webkit-details-marker { display: none; +} +@keyframes toast-in { + from { + opacity: 0; + transform: translateY(8px) scale(0.97); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +.animate-toast-in { + animation: toast-in 0.2s ease-out both; +} + +@media (prefers-reduced-motion: reduce) { + .animate-toast-in { + animation: none; + } } \ No newline at end of file diff --git a/src/components/Toast.tsx b/src/components/Toast.tsx new file mode 100644 index 00000000..5692432b --- /dev/null +++ b/src/components/Toast.tsx @@ -0,0 +1,81 @@ +"use client"; + +import { useEffect, useRef } from "react"; +import { cn } from "@/lib/utils"; +import { CheckCircle, XCircle, Loader2, X } from "lucide-react"; +import type { Toast } from "@/hooks/useToast"; + +interface ToastItemProps { + toast: Toast; + onDismiss: (id: string) => void; +} + +function ToastItem({ toast, onDismiss }: ToastItemProps) { + const timerRef = useRef | null>(null); + + useEffect(() => { + if (toast.duration !== Infinity) { + timerRef.current = setTimeout(() => { + onDismiss(toast.id); + }, toast.duration ?? 5000); + } + return () => { + if (timerRef.current) clearTimeout(timerRef.current); + }; + }, [toast.id, toast.duration, onDismiss]); + + const icons = { + success: