From c0b6f1577ce4bcd5a491e08a8c047072c3b26a1f Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Wed, 24 Sep 2025 10:32:51 +0330 Subject: [PATCH] crd warranty --- src/config/Pages.ts | 5 + src/pages/warranty/Create.tsx | 123 ++++++++++++++++++ src/pages/warranty/List.tsx | 117 +++++++++++++++++ src/pages/warranty/hooks/useWarrantyData.ts | 20 ++- src/pages/warranty/service/WarrantyService.ts | 16 ++- src/pages/warranty/types/Types.ts | 10 +- src/router/Main.tsx | 4 + src/shared/SideBar.tsx | 4 +- 8 files changed, 290 insertions(+), 9 deletions(-) create mode 100644 src/pages/warranty/Create.tsx create mode 100644 src/pages/warranty/List.tsx diff --git a/src/config/Pages.ts b/src/config/Pages.ts index bce9189..fedc06c 100644 --- a/src/config/Pages.ts +++ b/src/config/Pages.ts @@ -134,5 +134,10 @@ export const Pages = { update: "/products/brands/update/", create: "/products/brands/create", }, + warranty: { + list: "/products/warranty", + create: "/products/warranty/create", + update: "/products/warranty/update/", + }, }, }; diff --git a/src/pages/warranty/Create.tsx b/src/pages/warranty/Create.tsx new file mode 100644 index 0000000..f2cd52e --- /dev/null +++ b/src/pages/warranty/Create.tsx @@ -0,0 +1,123 @@ +import { type FC, useState } from 'react' +import { useFormik } from 'formik' +import { type CreateWarrantyType } from './types/Types' +import * as Yup from 'yup' +import { useCreateWarranty } from './hooks/useWarrantyData' +import { useNavigate } from 'react-router-dom' +import Input from '../../components/Input' +import Button from '../../components/Button' +import { TickCircle } from 'iconsax-react' +import { useUploadSingle } from '../uploader/hooks/useUploaderData' +import UploadBoxDraggble from '@/components/UploadBoxDraggble' +import { toast } from 'react-toastify' +import { extractErrorMessage } from '@/helpers/utils' +import { Pages } from '@/config/Pages' + +const CreateWarranty: FC = () => { + const navigate = useNavigate() + const uploadSingle = useUploadSingle() + const createWarrantyMutation = useCreateWarranty() + + const [logoFile, setLogoFile] = useState([]) + + const formik = useFormik({ + initialValues: { + name: '', + duration: '', + logoUrl: '', + }, + validationSchema: Yup.object({ + name: Yup.string().required('عنوان گارانتی الزامی است'), + duration: Yup.string().required('مدت زمان گارانتی الزامی است'), + }), + onSubmit: async (values) => { + let logoUrl = values.logoUrl + + if (logoFile.length > 0) { + const logoResponse = await uploadSingle.mutateAsync(logoFile[0]) + logoUrl = logoResponse.results?.url?.url || '' + } + + const submitData = { + ...values, + logoUrl + } + + createWarrantyMutation.mutate(submitData, { + onSuccess: () => { + toast.success('گارانتی با موفقیت ایجاد شد') + navigate(Pages.products.warranty.list) + }, + onError: (error) => { + toast.error(extractErrorMessage(error)) + } + }) + }, + }) + + return ( +
+
+
+

ساخت گارانتی جدید

+
+
+ +
+
+ +
+ {/* اطلاعات اصلی */} +
+

اطلاعات اصلی

+ +
+
+ + +
+
+
+ + {/* فایل‌ها */} +
+
+

فایل‌ها

+ +
+
+ setLogoFile(files)} + /> +
+
+
+
+
+
+ ) +} + +export default CreateWarranty \ No newline at end of file diff --git a/src/pages/warranty/List.tsx b/src/pages/warranty/List.tsx new file mode 100644 index 0000000..4bb5f7c --- /dev/null +++ b/src/pages/warranty/List.tsx @@ -0,0 +1,117 @@ +import { type FC, useState } from 'react' +import { useGetWarranties, useDeleteWarranty } from './hooks/useWarrantyData' +import { type Warranty } from './types/Types' +import PageLoading from '@/components/PageLoading' +import Error from '@/components/Error' +import PaginationUi from '@/components/PaginationUi' +import Td from '@/components/Td' +import TrashWithConfrim from '@/components/TrashWithConfrim' +import Button from '@/components/Button' +import { useNavigate } from 'react-router-dom' +import { Pages } from '@/config/Pages' + +const WarrantyList: FC = () => { + + const navigate = useNavigate() + const [currentPage, setCurrentPage] = useState(1); + const { data: warrantiesData, isLoading, error, refetch } = useGetWarranties(currentPage) + const deleteWarrantyMutation = useDeleteWarranty(); + + if (isLoading) { + return ( +
+ +
+ ); + } + + if (error) { + return ( +
+ +
+ ); + } + + const handleDeleteWarranty = async (warrantyId: string) => { + await deleteWarrantyMutation.mutateAsync(warrantyId); + refetch() + }; + + const warranties = warrantiesData?.results?.warranties || []; + const pager = warrantiesData?.results?.pager; + + return ( +
+
+
+
+ + + + + + + {warranties.length === 0 ? ( + + + + ) : ( + warranties.map((warranty: Warranty) => ( + + + + + + )) + )} + +
+ + + + +
+ هیچ گارانتی یافت نشد +
+
+ {warranty.name} +
+
+ + +
+ + {warranty.status} + +
+
+
+ handleDeleteWarranty(warranty._id.toString())} + isLoading={deleteWarrantyMutation.isPending} + /> +
+
+
+ + { + setCurrentPage(page); + }} + /> +
+ ) +} + +export default WarrantyList \ No newline at end of file diff --git a/src/pages/warranty/hooks/useWarrantyData.ts b/src/pages/warranty/hooks/useWarrantyData.ts index f309d0c..5912b35 100644 --- a/src/pages/warranty/hooks/useWarrantyData.ts +++ b/src/pages/warranty/hooks/useWarrantyData.ts @@ -1,10 +1,22 @@ -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; import * as api from "../service/WarrantyService"; import type { WarrantyResponse } from "../types/Types"; -export const useGetWarranties = () => { +export const useGetWarranties = (page: number = 1, limit: number = 10) => { return useQuery({ - queryKey: ["warranties"], - queryFn: () => api.getWarranties(), + queryKey: ["warranties", page, limit], + queryFn: () => api.getWarranties({ page, limit }), + }); +}; + +export const useDeleteWarranty = () => { + return useMutation({ + mutationFn: (id: string) => api.deleteWarranty(id), + }); +}; + +export const useCreateWarranty = () => { + return useMutation({ + mutationFn: api.createWarranty, }); }; diff --git a/src/pages/warranty/service/WarrantyService.ts b/src/pages/warranty/service/WarrantyService.ts index 707ff0a..2f6390f 100644 --- a/src/pages/warranty/service/WarrantyService.ts +++ b/src/pages/warranty/service/WarrantyService.ts @@ -1,5 +1,9 @@ import axios from "../../../config/axios"; -import type { GetWarrantiesParams, WarrantyResponse } from "../types/Types"; +import type { + GetWarrantiesParams, + WarrantyResponse, + CreateWarrantyType, +} from "../types/Types"; export const getWarranties = async ( params?: GetWarrantiesParams @@ -7,3 +11,13 @@ export const getWarranties = async ( const { data } = await axios.get("/warranty", { params }); return data; }; + +export const deleteWarranty = async (id: string) => { + const { data } = await axios.delete(`/admin/warranty/${id}`); + return data; +}; + +export const createWarranty = async (params: CreateWarrantyType) => { + const { data } = await axios.post(`/admin/warranty`, params); + return data; +}; diff --git a/src/pages/warranty/types/Types.ts b/src/pages/warranty/types/Types.ts index 34c1630..e6f481c 100644 --- a/src/pages/warranty/types/Types.ts +++ b/src/pages/warranty/types/Types.ts @@ -14,8 +14,8 @@ export interface Pager { limit: number; totalItems: number; totalPages: number; - prevPage: boolean; - nextPage: boolean; + prevPage: boolean | null; + nextPage: string | null; } export interface WarrantyResults { @@ -33,3 +33,9 @@ export interface GetWarrantiesParams { page?: number; limit?: number; } + +export type CreateWarrantyType = { + name: string; + duration: string; + logoUrl: string; +}; diff --git a/src/router/Main.tsx b/src/router/Main.tsx index b939487..27e5075 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -17,6 +17,8 @@ import UpdateProduct from '../pages/products/Update' import ProductVariant from '@/pages/products/ProductVariant' import BrandList from '@/pages/brand/List' import BrandCreate from '@/pages/brand/Create' +import WarrantyList from '@/pages/warranty/List' +import CreateWarranty from '@/pages/warranty/Create' const MainRouter: FC = () => { @@ -46,6 +48,8 @@ const MainRouter: FC = () => { } /> } /> } /> + } /> + } /> diff --git a/src/shared/SideBar.tsx b/src/shared/SideBar.tsx index 5fa899b..9cfbbbf 100644 --- a/src/shared/SideBar.tsx +++ b/src/shared/SideBar.tsx @@ -379,8 +379,8 @@ const ProductsSubMenu: FC = () => { />