From b60a38e21d56aa6d638f52d972573bc606b4251d Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sat, 25 Jul 2026 16:36:35 +0330 Subject: [PATCH] ticket master --- src/config/Pages.ts | 3 + src/langs/fa.json | 6 +- src/pages/ticket/hooks/useTicketData.ts | 51 ++++++++++++ src/pages/ticket/masters/Create.tsx | 72 +++++++++++++++++ src/pages/ticket/masters/List.tsx | 94 +++++++++++++++++++++++ src/pages/ticket/masters/Update.tsx | 89 +++++++++++++++++++++ src/pages/ticket/service/TicketServiec.ts | 26 +++++++ src/pages/ticket/types/TicketTypes.ts | 18 +++++ src/pages/users/hooks/useUserData.ts | 7 ++ src/pages/users/service/UserService.ts | 5 ++ src/router/Main.tsx | 15 ++++ src/shared/components/SupportSubMenu.tsx | 6 ++ 12 files changed, 391 insertions(+), 1 deletion(-) create mode 100644 src/pages/ticket/masters/Create.tsx create mode 100644 src/pages/ticket/masters/List.tsx create mode 100644 src/pages/ticket/masters/Update.tsx diff --git a/src/config/Pages.ts b/src/config/Pages.ts index 8cf7feb..7bdda5d 100644 --- a/src/config/Pages.ts +++ b/src/config/Pages.ts @@ -36,6 +36,9 @@ export const Pages = { create: "/tickets/create", detail: "/tickets/messages/", category: "/tickets/category", + masters: "/tickets/masters", + mastersCreate: "/tickets/masters/create", + mastersUpdate: "/tickets/masters/update/", }, announcement: { list: "/announcement", diff --git a/src/langs/fa.json b/src/langs/fa.json index 9817035..7ff8ed5 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -143,6 +143,7 @@ "representative_list": "لیست نمایندگان", "ticket_list": "لیست تیکت ها", "ticket_category": "دسته بندی تیکت ها", + "ticket_masters": "مستر", "send_ticket": "ارسال تیکت", "category": "دسته بندی", "user_list": "لیست کاربران", @@ -377,7 +378,10 @@ "column": "ستون", "select_workspace_required": "فضای کاری را انتخاب کنید", "select_project_required": "پروژه را انتخاب کنید", - "select_column_required": "ستون را انتخاب کنید" + "select_column_required": "ستون را انتخاب کنید", + "masters": "مستر", + "add_master": "افزودن مستر", + "edit_master": "ویرایش مستر" }, "active": "فعال", "inactive": "غیرفعال", diff --git a/src/pages/ticket/hooks/useTicketData.ts b/src/pages/ticket/hooks/useTicketData.ts index 9336cd4..c6c0dc0 100644 --- a/src/pages/ticket/hooks/useTicketData.ts +++ b/src/pages/ticket/hooks/useTicketData.ts @@ -4,6 +4,7 @@ import { AddMessageTicketType, CreateCategoryType, CreateTicketAdminType, + CreateTicketMasterType, } from "../types/TicketTypes"; export const useGetTickets = ( @@ -78,3 +79,53 @@ export const useCreateTicket = () => { api.createTicket(variables), }); }; + +export const useGetMasters = () => { + return useQuery({ + queryKey: ["ticket-masters"], + queryFn: () => api.getMasters(), + }); +}; + +export const useGetMasterById = (id: string) => { + return useQuery({ + queryKey: ["ticket-master", id], + queryFn: () => api.getMasterById(id), + enabled: !!id, + }); +}; + +export const useCreateMaster = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (variables: CreateTicketMasterType) => + api.createMaster(variables), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["ticket-masters"] }); + }, + }); +}; + +export const useUpdateMaster = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (variables: { id: string; params: CreateTicketMasterType }) => + api.updateMaster(variables.id, variables.params), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["ticket-masters"] }); + }, + }); +}; + +export const useDeleteMaster = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: (id: string) => api.deleteMaster(id), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["ticket-masters"] }); + }, + }); +}; diff --git a/src/pages/ticket/masters/Create.tsx b/src/pages/ticket/masters/Create.tsx new file mode 100644 index 0000000..f7a0a4d --- /dev/null +++ b/src/pages/ticket/masters/Create.tsx @@ -0,0 +1,72 @@ +import { useFormik } from "formik"; +import { FC } from "react"; +import { useTranslation } from "react-i18next"; +import { useNavigate } from "react-router-dom"; +import * as Yup from "yup"; +import Button from "../../../components/Button"; +import Select from "../../../components/Select"; +import { toast } from "../../../components/Toast"; +import { Pages } from "../../../config/Pages"; +import { ErrorType } from "../../../helpers/types"; +import { useGetAdminsListAll } from "../../users/hooks/useUserData"; +import { UserItemType } from "../../users/types/UserTypes"; +import { useCreateMaster } from "../hooks/useTicketData"; +import { CreateTicketMasterType } from "../types/TicketTypes"; + +const CreateTicketMaster: FC = () => { + const { t } = useTranslation("global"); + const navigate = useNavigate(); + const getAdmins = useGetAdminsListAll(); + const createMaster = useCreateMaster(); + + const formik = useFormik({ + initialValues: { + userId: "", + }, + validationSchema: Yup.object({ + userId: Yup.string().required(t("errors.required")), + }), + onSubmit: (values) => { + createMaster.mutate(values, { + onSuccess: () => { + toast(t("success"), "success"); + navigate(Pages.ticket.masters); + }, + onError: (error: ErrorType) => { + toast(error.response?.data?.error.message[0], "error"); + }, + }); + }, + }); + + return ( +
+
{t("ticket.add_master")}
+ +
+ ({ + label: `${item.firstName} ${item.lastName}`, + value: item.id, + }))} + {...formik.getFieldProps("userId")} + error_text={formik.touched.userId && formik.errors.userId ? formik.errors.userId : ""} + /> + +
+
+
+
+ ); +}; + +export default UpdateTicketMaster; diff --git a/src/pages/ticket/service/TicketServiec.ts b/src/pages/ticket/service/TicketServiec.ts index 27c9758..5a11630 100644 --- a/src/pages/ticket/service/TicketServiec.ts +++ b/src/pages/ticket/service/TicketServiec.ts @@ -3,6 +3,7 @@ import { AddMessageTicketType, CreateCategoryType, CreateTicketAdminType, + CreateTicketMasterType, } from "../types/TicketTypes"; export const getTickets = async ( @@ -63,3 +64,28 @@ export const createTicket = async (params: CreateTicketAdminType) => { const { data } = await axios.post(`/tickets/admin`, params); return data; }; + +export const getMasters = async () => { + const { data } = await axios.get(`/tickets/masters`); + return data; +}; + +export const getMasterById = async (id: string) => { + const { data } = await axios.get(`/tickets/masters/${id}`); + return data; +}; + +export const createMaster = async (params: CreateTicketMasterType) => { + const { data } = await axios.post(`/tickets/masters`, params); + return data; +}; + +export const updateMaster = async (id: string, params: CreateTicketMasterType) => { + const { data } = await axios.patch(`/tickets/masters/${id}`, params); + return data; +}; + +export const deleteMaster = async (id: string) => { + const { data } = await axios.delete(`/tickets/masters/${id}`); + return data; +}; diff --git a/src/pages/ticket/types/TicketTypes.ts b/src/pages/ticket/types/TicketTypes.ts index 24687b4..75dc8bf 100644 --- a/src/pages/ticket/types/TicketTypes.ts +++ b/src/pages/ticket/types/TicketTypes.ts @@ -89,3 +89,21 @@ export type CreateTicketAdminType = { attachmentUrls?: string[]; userId: string; }; + +export type CreateTicketMasterType = { + userId: string; +}; + +export type TicketMasterItemType = { + id: string; + userId: string; + user?: { + id: string; + firstName: string; + lastName: string; + email?: string; + phone?: string; + }; + createdAt?: string; + updatedAt?: string; +}; diff --git a/src/pages/users/hooks/useUserData.ts b/src/pages/users/hooks/useUserData.ts index e6b5aa4..a4c69d5 100644 --- a/src/pages/users/hooks/useUserData.ts +++ b/src/pages/users/hooks/useUserData.ts @@ -54,6 +54,13 @@ export const useGetUsers = (search: string, permission?: string, page = 1) => { }); }; +export const useGetAdminsListAll = () => { + return useQuery({ + queryKey: ["admins-list-all"], + queryFn: () => api.getAdminsListAll(), + }); +}; + export const useGetUsersInfinite = (search: string, permission?: string, enabled = true) => { return useInfiniteQuery({ queryKey: ["users-infinite", search, permission], diff --git a/src/pages/users/service/UserService.ts b/src/pages/users/service/UserService.ts index 87bfd63..de19ea6 100644 --- a/src/pages/users/service/UserService.ts +++ b/src/pages/users/service/UserService.ts @@ -42,6 +42,11 @@ export const getUsers = async (search: string, permission?: string, page = 1) => return data; }; +export const getAdminsListAll = async () => { + const { data } = await axios.get(`/users/admins-list/all`); + return data; +}; + export const getUserDetail = async (id: string) => { const { data } = await axios.get(`/users/admins/${id}`); return data; diff --git a/src/router/Main.tsx b/src/router/Main.tsx index 066912a..7294e7c 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -89,6 +89,9 @@ import TicketCategory from "../pages/ticket/Category"; import CreateTicket from "../pages/ticket/CreateTicket"; import TicketDetail from "../pages/ticket/Detail"; import TicketList from "../pages/ticket/TicketList"; +import CreateTicketMaster from "../pages/ticket/masters/Create"; +import TicketMastersList from "../pages/ticket/masters/List"; +import UpdateTicketMaster from "../pages/ticket/masters/Update"; import TransactionList from "../pages/transaction/List"; import CreateUser from "../pages/users/Create"; import GroupCreate from "../pages/users/GroupCreate"; @@ -169,6 +172,18 @@ const MainRouter: FC = () => { path={Pages.ticket.category} element={} /> + } + /> + } + /> + } + /> } diff --git a/src/shared/components/SupportSubMenu.tsx b/src/shared/components/SupportSubMenu.tsx index 783a8ba..2e60f81 100644 --- a/src/shared/components/SupportSubMenu.tsx +++ b/src/shared/components/SupportSubMenu.tsx @@ -41,6 +41,12 @@ const SupportSubMenu: FC = () => { link={Pages.ticket.category} activeName="tickets" /> + );