Initial commit for new panel

This commit is contained in:
AmirReza Jamali
2025-09-09 11:20:26 +03:30
commit 1d4ccb3575
343 changed files with 20031 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
export * from "./useUsersQueries";
export * from "./useCompaniesQueries";
export * from "./useTenders";
export * from "./useCustomerQueries";
export * from "./useProfileQueries";
+107
View File
@@ -0,0 +1,107 @@
import { API_ENDPOINTS, companiesService } from "@/lib/api";
import {
useInfiniteQuery,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { useRouter } from "next/navigation";
import { useMemo } from "react";
import { toast } from "react-toastify";
export const useCreateCompany = () => {
const queryClient = useQueryClient();
const router = useRouter();
const mutationKey = useMemo(() => [API_ENDPOINTS.COMPANIES, "create"], []);
return useMutation({
mutationKey,
mutationFn: companiesService.createCompany,
onSuccess: () => {
toast.success("Company created successfully");
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.COMPANIES],
});
router.push("/companies");
},
});
};
export const useUpdateCompany = (id: string) => {
const queryClient = useQueryClient();
const router = useRouter();
const mutationKey = useMemo(
() => [API_ENDPOINTS.COMPANIES.UPDATE(id), "update"],
[id],
);
return useMutation({
mutationKey,
mutationFn: companiesService.updateCompany,
onSuccess: () => {
toast.success("Company updated successfully");
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.COMPANIES.READ_ALL],
});
router.push("/companies");
},
});
};
export const useCompanyDetails = (id: string) => {
const queryKey = useMemo(
() => [API_ENDPOINTS.COMPANIES.DETAILS(id), "details"],
[id],
);
return useQuery({
queryKey,
queryFn: () => companiesService.companyDetails(id),
});
};
export const useDeleteCompanyQuery = (successCallback?: () => void) => {
const queryClient = useQueryClient();
const mutationKey = useMemo(
() => [API_ENDPOINTS.COMPANIES.DELETE, "delete-company"],
[],
);
return useMutation({
mutationKey,
mutationFn: companiesService.deleteCompany,
onSuccess: (response: { data: { message: string } }) => {
toast.success(response.data.message);
if (successCallback) {
successCallback();
}
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.COMPANIES.READ_ALL],
});
},
});
};
export const useCompanyFullList = () => {
return useQuery({
queryKey: ["READ ALL Companies"],
queryFn: companiesService.getCompanies,
});
};
export const useCompaniesInfiniteQuery = (params?: Record<string, any>) => {
const queryKey = useMemo(
() => [API_ENDPOINTS.COMPANIES.READ_ALL, params],
[params],
);
return useInfiniteQuery({
queryKey,
queryFn: ({ pageParam = 0 }) =>
companiesService.getCompanies({ ...params, offset: pageParam }),
initialPageParam: 0,
getNextPageParam: (lastPage: any) => {
const { offset, limit, total } = lastPage.meta;
const nextOffset = offset + limit;
return nextOffset < total ? nextOffset : undefined;
},
});
};
+126
View File
@@ -0,0 +1,126 @@
"use client";
import {
useInfiniteQuery,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { useMemo } from "react";
import { useRouter } from "next/navigation";
import { toast } from "react-toastify";
import { API_ENDPOINTS } from "@/lib/api";
import { customersService } from "@/lib/api/services/customers-service";
export const useCustomersInfiniteQuery = (params?: Record<string, any>) => {
const queryKey = useMemo(
() => [API_ENDPOINTS.CUSTOMERS.READ_ALL, params],
[params],
);
return useInfiniteQuery({
queryKey,
queryFn: ({ pageParam = 0 }) =>
customersService.getCustomers({ ...params, offset: pageParam }),
initialPageParam: 0,
getNextPageParam: (lastPage) => {
const { offset, limit, total } = lastPage.meta;
const nextOffset = offset + limit;
return nextOffset < total ? nextOffset : undefined;
},
});
};
export const useGetAllCustomers = () => {
const queryKey = useMemo(() => ["GET ALL CUSTOMERS"], []);
return useQuery({
queryKey,
queryFn: () => customersService.getCustomers(),
});
};
export const useAssignCompany = (id: string, successCallback?: () => void) => {
const queryClient = useQueryClient();
const mutationKey = useMemo(
() => [API_ENDPOINTS.CUSTOMERS.ASSIGN_COMPANY_TO_CUSTOMER(id)],
[id],
);
return useMutation({
mutationKey,
mutationFn: customersService.assignCompanyToCustomer,
onSuccess: () => {
toast.success("Selected Companies were assigned");
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.CUSTOMERS.READ_ALL],
});
if (successCallback) {
successCallback();
}
},
});
};
export const useCreateCustomer = () => {
const queryClient = useQueryClient();
const router = useRouter();
const mutationKey = useMemo(
() => [API_ENDPOINTS.CUSTOMERS.CREATE, "create"],
[],
);
return useMutation({
mutationKey,
mutationFn: customersService.createCustomer,
onSuccess: () => {
toast.success("Customer created successfully");
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.CUSTOMERS.READ_ALL],
});
router.push("/customers");
},
});
};
export const useUpdateCustomer = (id: string) => {
const queryClient = useQueryClient();
const router = useRouter();
const mutationKey = useMemo(
() => [API_ENDPOINTS.CUSTOMERS.UPDATE(id), "update"],
[id],
);
return useMutation({
mutationKey,
mutationFn: customersService.updateCustomer,
onSuccess: (response) => {
toast.success("Customer updated successfully");
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.CUSTOMERS.READ_ALL],
});
router.push("/customers");
},
});
};
export const useDeleteCustomerQuery = (successCallback?: () => void) => {
const queryClient = useQueryClient();
const mutationKey = useMemo(
() => [API_ENDPOINTS.CUSTOMERS.DELETE, "delete-customer"],
[],
);
return useMutation({
mutationKey,
mutationFn: customersService.deleteCustomer,
onSuccess: (response) => {
toast.success(response.data.message);
if (successCallback) {
successCallback();
}
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.CUSTOMERS.READ_ALL],
});
},
});
};
+14
View File
@@ -0,0 +1,14 @@
import { API_ENDPOINTS, profileService } from "@/lib/api";
import { useQuery } from "@tanstack/react-query";
import { useMemo } from "react";
export const useProfileQuery = () => {
const queryKey = useMemo(
() => [API_ENDPOINTS.PROFILE.READ, "CURRENT_USER_PROFILE"],
[],
);
return useQuery({
queryKey,
queryFn: () => profileService.getProfile(),
});
};
+29
View File
@@ -0,0 +1,29 @@
import { API_ENDPOINTS, tendersService } from "@/lib/api";
import { useInfiniteQuery } from "@tanstack/react-query";
import { useMemo } from "react";
export const useTendersInfiniteQuery = (params?: Record<string, any>) => {
const queryKey = useMemo(
() => [API_ENDPOINTS.TENDERS.READ_ALL, "read-tenders", params],
[params],
);
return useInfiniteQuery({
queryKey,
queryFn: ({ pageParam = 0 }) =>
tendersService.tendersList({ ...params, offset: pageParam }),
initialPageParam: 0,
getNextPageParam: (lastPage) => {
if (lastPage.meta) {
const { offset, limit, total } = lastPage.meta;
const nextOffset = offset + limit;
return nextOffset < total ? nextOffset : undefined;
}
},
});
};
+123
View File
@@ -0,0 +1,123 @@
import { useUser } from "@/contexts";
import { API_ENDPOINTS, userService } from "@/lib/api";
import {
useInfiniteQuery,
useMutation,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { useRouter } from "next/navigation";
import { useMemo } from "react";
import { toast } from "react-toastify";
export const useLoginQuery = () => {
const mutationKey = useMemo(() => [API_ENDPOINTS.USER.LOGIN], []);
const { setAuthState } = useUser();
const router = useRouter();
return useMutation({
mutationKey,
mutationFn: userService.login,
onSuccess: (response) => {
if (response.success) {
setAuthState(response.data);
router.replace("/charts");
}
},
});
};
export const useDeleteAdmin = (onSuccessCallback: () => void) => {
const queryClient = useQueryClient();
const mutationKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, "delete"], []);
return useMutation({
mutationKey,
mutationFn: userService.deleteAdmin,
onSuccess: (response) => {
toast.info(response.data.message);
onSuccessCallback();
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.USER.ADMINS],
});
},
});
};
export const useLogoutQuery = () => {
const queryKey = useMemo(() => [API_ENDPOINTS.USER.LOGOUT], []);
return useQuery({
queryKey,
queryFn: userService.logout,
});
};
export const useCreateAdmin = () => {
const queryClient = useQueryClient();
const router = useRouter();
const mutationKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, "create"], []);
return useMutation({
mutationKey,
mutationFn: userService.createAdmin,
onSuccess: (response) => {
toast.success(response);
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.USER.ADMINS],
});
router.push("/admins");
},
});
};
export const useUpdateAdmin = (id: string) => {
const queryClient = useQueryClient();
const router = useRouter();
const mutationKey = useMemo(
() => [API_ENDPOINTS.USER.ADMINS, "update", id],
[id],
);
return useMutation({
mutationKey,
mutationFn: userService.updateAdmin,
onSuccess: (response) => {
toast.success(response);
queryClient.invalidateQueries({
queryKey: [API_ENDPOINTS.USER.ADMINS],
});
router.push("/admins");
},
});
};
export const useAdminDetails = (id: string) => {
const queryKey = useMemo(
() => [API_ENDPOINTS.USER.ADMINS, "details", id],
[id],
);
return useQuery({
queryKey,
queryFn: () => userService.adminDetails(id),
});
};
export const useAdminListInfiniteQuery = (params?: Record<string, any>) => {
const queryKey = useMemo(() => [API_ENDPOINTS.USER.ADMINS, params], [params]);
return useInfiniteQuery({
queryKey,
queryFn: ({ pageParam = 0 }) =>
userService.adminsList({ ...params, offset: pageParam }),
initialPageParam: 0,
getNextPageParam: (lastPage) => {
if (!lastPage.meta) {
return undefined;
}
const { offset, limit, total } = lastPage.meta;
const nextOffset = offset + limit;
return nextOffset < total ? nextOffset : undefined;
},
});
};
+21
View File
@@ -0,0 +1,21 @@
import { useEffect, useRef } from "react";
export function useClickOutside<T extends HTMLElement>(callback: () => void) {
const ref = useRef<T>(null);
useEffect(() => {
function handleEvent(event: MouseEvent) {
if (ref.current && !ref.current.contains(event.target as Node)) {
callback();
}
}
document.addEventListener("mousedown", handleEvent);
return () => {
document.removeEventListener("mousedown", handleEvent);
};
}, [callback, ref]);
return ref;
}
+22
View File
@@ -0,0 +1,22 @@
import { useEffect, useState } from "react";
export const MOBILE_BREAKPOINT = 850;
export function useIsMobile() {
const [isMobile, setIsMobile] = useState<boolean>();
useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
mql.addEventListener("change", onChange);
return () => mql.removeEventListener("change", onChange);
}, []);
return !!isMobile;
}
+19
View File
@@ -0,0 +1,19 @@
import { useState, useEffect } from "react";
function useDebounce<T>(value: T, delay: number): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}
export default useDebounce;