diff --git a/src/app/[name]/(Main)/[id]/page.tsx b/src/app/[name]/(Main)/[id]/page.tsx
index 83d611b..919df6e 100644
--- a/src/app/[name]/(Main)/[id]/page.tsx
+++ b/src/app/[name]/(Main)/[id]/page.tsx
@@ -3,7 +3,7 @@
import { useCart } from "@/app/[name]/(Main)/cart/hook/useCart";
import MinusIcon from "@/components/icons/MinusIcon";
import PlusIcon from "@/components/icons/PlusIcon";
-import { toast } from "@/components/Toast";
+import { toast, toastLoginRequired } from "@/components/Toast";
import { getToken } from "@/lib/api/func";
import { ef } from "@/lib/helpers/utfNumbers";
import { motion } from "framer-motion";
@@ -52,7 +52,7 @@ function FoodPage({}: Props) {
const token = await getToken();
if (!token || !isSuccess) {
- toast("ابتدا لاگین کنید", "error");
+ toastLoginRequired(() => router.push(`/${name}/auth`), "error");
return;
}
diff --git a/src/components/Toast.tsx b/src/components/Toast.tsx
index 8a83b89..a7c4cf6 100644
--- a/src/components/Toast.tsx
+++ b/src/components/Toast.tsx
@@ -2,11 +2,17 @@
import { CloseCircle, InfoCircle, TickCircle } from 'iconsax-react';
import React, { useState, useEffect } from 'react';
+interface ToastAction {
+ label: string;
+ onClick: () => void;
+}
+
interface Toast {
id: string;
message: string;
type?: 'success' | 'error' | 'info';
isExiting?: boolean;
+ action?: ToastAction;
}
let addToast: (toast: Toast) => void;
@@ -18,7 +24,8 @@ const ToastContainer: React.FC = () => {
const showToast = (toast: Toast) => {
setToasts((prev) => [...prev, toast]);
- // حذف خودکار بعد از ۳ ثانیه
+ const dismissAfter = toast.action ? 6000 : 3000;
+
setTimeout(() => {
setToasts((prev) => prev.map(t =>
t.id === toast.id ? { ...t, isExiting: true } : t
@@ -28,7 +35,16 @@ const ToastContainer: React.FC = () => {
setTimeout(() => {
setToasts((prev) => prev.filter((t) => t.id !== toast.id));
}, 300); // مدت زمان انیمیشن خروج
- }, 3000);
+ }, dismissAfter);
+ };
+
+ const dismissToast = (id: string) => {
+ setToasts((prev) => prev.map((t) =>
+ t.id === id ? { ...t, isExiting: true } : t
+ ));
+ setTimeout(() => {
+ setToasts((prev) => prev.filter((t) => t.id !== id));
+ }, 300);
};
// تخصیص تابع نمایش toast به متغیر سراسری
@@ -38,36 +54,76 @@ const ToastContainer: React.FC = () => {
return (
- {toasts.map((toast) => (
-
{
+ const handleAction = () => {
+ toast.action?.onClick();
+ dismissToast(toast.id);
+ };
+
+ return (
+
{
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ handleAction();
+ }
+ } : undefined}
+ className={`px-4 flex items-center gap-2 backdrop-blur-2xl h-16 min-w-[300px] rounded-2xl shadow-md
${toast.isExiting ? 'animate-slide-out-right' : 'animate-slide-in-right'} ${toast.type === 'success'
? 'bg-white/70 text-black'
: toast.type === 'error'
? 'bg-white/70 text-black'
: 'bg-white/70 text-black'
- }`}
- style={{
- animationFillMode: 'forwards',
- animationDuration: '0.3s',
- animationTimingFunction: 'ease-out'
- }}
- >
- {
- toast.type === 'success' ? :
- toast.type === 'error' ? :
-
- }
- {toast.message}
-
- ))}
+ } ${toast.action ? 'cursor-pointer active:scale-[0.98] transition-transform' : ''}`}
+ style={{
+ animationFillMode: 'forwards',
+ animationDuration: '0.3s',
+ animationTimingFunction: 'ease-out'
+ }}
+ >
+
+ {
+ toast.type === 'success' ? :
+ toast.type === 'error' ? :
+
+ }
+ {toast.message}
+
+ {toast.action && (
+
+ {toast.action.label}
+
+ )}
+
+ );
+ })}
);
};
-export const toast = (message?: string, type: 'success' | 'error' | 'info' = 'info') => {
- addToast({ id: Date.now().toString(), message: message || '', type });
+type ToastOptions = {
+ action?: ToastAction;
+};
+
+export const toast = (
+ message?: string,
+ type: 'success' | 'error' | 'info' = 'info',
+ options?: ToastOptions
+) => {
+ addToast({ id: Date.now().toString(), message: message || '', type, action: options?.action });
+};
+
+export const toastLoginRequired = (
+ onLogin: () => void,
+ type: 'success' | 'error' | 'info' = 'info'
+) => {
+ toast('ابتدا لاگین کنید', type, {
+ action: { label: 'ورود', onClick: onLogin },
+ });
};
export default ToastContainer;
\ No newline at end of file
diff --git a/src/components/menu/SideMenu.tsx b/src/components/menu/SideMenu.tsx
index ec1f926..cae2e4c 100644
--- a/src/components/menu/SideMenu.tsx
+++ b/src/components/menu/SideMenu.tsx
@@ -18,7 +18,7 @@ import useToggle from '@/hooks/helpers/useToggle';
import { useGetAbout } from '@/app/[name]/(Main)/about/hooks/useAboutData';
import Image from 'next/image';
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
-import { toast } from '../Toast';
+import { toast, toastLoginRequired } from '../Toast';
type MenuItemType = {
href: string | undefined;
@@ -203,7 +203,7 @@ function SideMenu({ menuState, toggleMenuState, nightModeState, togglenightModeS
const handleNotificationClick = (e: React.MouseEvent) => {
e.preventDefault();
if (!isLoggedIn) {
- toast('ابتدا لاگین کنید', 'info');
+ toastLoginRequired(() => router.push(`/${name}/auth`), 'info');
} else {
router.push(`/${name}/notifications`);
}
diff --git a/src/components/navigation/BottomNavBar.tsx b/src/components/navigation/BottomNavBar.tsx
index 0183765..aafa1a7 100644
--- a/src/components/navigation/BottomNavBar.tsx
+++ b/src/components/navigation/BottomNavBar.tsx
@@ -14,7 +14,7 @@ import { useCart } from '@/app/[name]/(Main)/cart/hook/useCart';
import { Building } from 'iconsax-react';
import clsx from 'clsx';
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData';
-import { toast } from '../Toast';
+import { toastLoginRequired } from '../Toast';
type BottomNavBarProps = {
onPagerClick?: () => void;
@@ -49,8 +49,7 @@ function BottomNavBar({ onPagerClick }: BottomNavBarProps) {
router.push(`/${name}/favorite`);
} else {
e.stopPropagation();
- toast('ابتدا لاگین کنید', 'error');
- router.replace(`/${name}/auth`);
+ toastLoginRequired(() => router.push(`/${name}/auth`), 'error');
}
}
diff --git a/src/components/topbar/TopBar.tsx b/src/components/topbar/TopBar.tsx
index 610852e..74d03dc 100644
--- a/src/components/topbar/TopBar.tsx
+++ b/src/components/topbar/TopBar.tsx
@@ -12,7 +12,7 @@ import useToggle from '@/hooks/helpers/useToggle'
import LogoutPrompt from '@/features/general/LogoutPrompt'
import { useGetProfile } from '@/app/[name]/(Profile)/profile/hooks/userProfileData'
import { useGetNotificationsCount } from '@/app/[name]/(Main)/hooks/useMenuData'
-import { toast } from '../Toast'
+import { toastLoginRequired } from '../Toast'
type Props = {
profileDropState: boolean,
@@ -40,7 +40,7 @@ function TopBar({ profileDropState, toggleProfileDropState, toggleMenuState }: P
const handleNotificationClick = (e: React.MouseEvent) => {
e.preventDefault();
if (!isLoggedIn) {
- toast('ابتدا لاگین کنید', 'info');
+ toastLoginRequired(() => router.push(`/${name}/auth`), 'info');
} else {
router.push(`/${name}/notifications`);
}