From eac16c423bf445c18e0db57e58431d7a46b8520b Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 9 Mar 2026 15:32:21 +0330 Subject: [PATCH] create catalog --- src/App.tsx | 9 +++- src/components/Toast.tsx | 73 +++++++++++++++++++++++++++ src/config/axios.ts | 2 +- src/config/func.ts | 20 +++----- src/pages/home/Home.tsx | 27 +++++++++- src/pages/home/hooks/useHomeData.ts | 2 +- src/pages/home/service/HomeService.ts | 2 +- src/pages/home/types/Types.ts | 1 + 8 files changed, 116 insertions(+), 20 deletions(-) create mode 100644 src/components/Toast.tsx diff --git a/src/App.tsx b/src/App.tsx index 147d8d8..4b89f66 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -5,6 +5,8 @@ import MainRouter from './router/MainRouter' import i18next from 'i18next' import FaJson from '@/langs/fa.json' import { I18nextProvider } from 'react-i18next' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import ToastContainer from './components/Toast' i18next.init({ interpolation: { escapeValue: false }, @@ -16,11 +18,16 @@ i18next.init({ } }) +const queryClient = new QueryClient() + const App: FC = () => { return ( - + + + + ) diff --git a/src/components/Toast.tsx b/src/components/Toast.tsx new file mode 100644 index 0000000..8a83b89 --- /dev/null +++ b/src/components/Toast.tsx @@ -0,0 +1,73 @@ +'use client' +import { CloseCircle, InfoCircle, TickCircle } from 'iconsax-react'; +import React, { useState, useEffect } from 'react'; + +interface Toast { + id: string; + message: string; + type?: 'success' | 'error' | 'info'; + isExiting?: boolean; +} + +let addToast: (toast: Toast) => void; + +const ToastContainer: React.FC = () => { + const [toasts, setToasts] = useState([]); + + // ثبت toast جدید + const showToast = (toast: Toast) => { + setToasts((prev) => [...prev, toast]); + + // حذف خودکار بعد از ۳ ثانیه + setTimeout(() => { + setToasts((prev) => prev.map(t => + t.id === toast.id ? { ...t, isExiting: true } : t + )); + + // حذف از DOM بعد از اتمام انیمیشن + setTimeout(() => { + setToasts((prev) => prev.filter((t) => t.id !== toast.id)); + }, 300); // مدت زمان انیمیشن خروج + }, 3000); + }; + + // تخصیص تابع نمایش toast به متغیر سراسری + useEffect(() => { + addToast = showToast; + }, []); + + return ( +
+ {toasts.map((toast) => ( +
+ { + toast.type === 'success' ? : + toast.type === 'error' ? : + + } + {toast.message} +
+ ))} +
+ ); +}; + +export const toast = (message?: string, type: 'success' | 'error' | 'info' = 'info') => { + addToast({ id: Date.now().toString(), message: message || '', type }); +}; + +export default ToastContainer; \ No newline at end of file diff --git a/src/config/axios.ts b/src/config/axios.ts index 3de59c5..9d529a0 100644 --- a/src/config/axios.ts +++ b/src/config/axios.ts @@ -3,7 +3,7 @@ import { getToken } from "./func"; // import { Pages } from "./Pages"; const axiosInstance = axios.create({ - baseURL: import.meta.env.VITE_BASE_URL, + baseURL: import.meta.env.VITE_API_URL, }); axiosInstance.interceptors.response.use( diff --git a/src/config/func.ts b/src/config/func.ts index 9d2216e..1ce6d70 100644 --- a/src/config/func.ts +++ b/src/config/func.ts @@ -31,35 +31,27 @@ export const timeAgo = (date: string | Date): string => { }; export const getToken = () => { - return localStorage.get(import.meta.env.VITE_TOKEN_NAME); + return localStorage.getItem(import.meta.env.VITE_TOKEN_NAME); }; export const getRefreshToken = () => { - return localStorage.get(import.meta.env.VITE_REFRESH_TOKEN_NAME); + return localStorage.getItem(import.meta.env.VITE_REFRESH_TOKEN_NAME); }; -const isProduction = import.meta.env.MODE === "production"; -const domain = isProduction ? ".danakcorp.com" : window.location.hostname; - export const setToken = (token: string) => { - localStorage.set(import.meta.env.VITE_TOKEN_NAME, token, { domain }); + localStorage.setItem(import.meta.env.VITE_TOKEN_NAME, token); }; export const setRefreshToken = (refreshToken: string) => { - localStorage.set(import.meta.env.VITE_REFRESH_TOKEN_NAME, refreshToken, { - domain, - }); + localStorage.setItem(import.meta.env.VITE_REFRESH_TOKEN_NAME, refreshToken); }; export const removeToken = () => { - localStorage.remove(import.meta.env.VITE_TOKEN_NAME, { domain, path: "/" }); + localStorage.removeItem(import.meta.env.VITE_TOKEN_NAME); }; export const removeRefreshToken = () => { - localStorage.remove(import.meta.env.VITE_REFRESH_TOKEN_NAME, { - domain, - path: "/", - }); + localStorage.removeItem(import.meta.env.VITE_REFRESH_TOKEN_NAME); }; export const getRedirectUrl = () => { diff --git a/src/pages/home/Home.tsx b/src/pages/home/Home.tsx index a4a9792..e71ea40 100644 --- a/src/pages/home/Home.tsx +++ b/src/pages/home/Home.tsx @@ -4,10 +4,31 @@ import { useState, type FC } from 'react' import PdfIcon from '@/assets/images/PDF.svg' import Button from '@/components/Button' import Input from '@/components/Input' +import { toast } from '@/components/Toast' +import { useCreateCatalog } from './hooks/useHomeData' const Home: FC = () => { - const [active, setActive] = useState('') + const [active, setActive] = useState('a4') + const [name, setName] = useState('') + const { mutate: createCatalog, isPending } = useCreateCatalog() + + const handleSubmit = () => { + if (!name) { + toast('نام کاتالوگ را وارد کنید', 'error') + } else { + createCatalog({ name: name, size: active, content: '' }, { + onSuccess: () => { + toast('کاتالوگ با موفقیت ساخته شد', 'success') + }, + onError: (err) => { + console.log(err); + + toast('خطا در ساخت کاتالوگ', 'error') + } + }) + } + } return (
@@ -69,11 +90,13 @@ const Home: FC = () => {
setName(e.target.value)} />
-