first commit
This commit is contained in:
61
src/utils/axios.ts
Normal file
61
src/utils/axios.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import axios from "axios";
|
||||
import { useUserStore } from "../context/zustand-store/userStore";
|
||||
import { toast } from "react-toastify";
|
||||
import { checkIsMobile } from "./checkIsMobile";
|
||||
|
||||
let hasShownUnauthorizedToast = false;
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: "https://inspectionbackend.rasadyar.com/",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Accept: "application/json",
|
||||
},
|
||||
withCredentials: true,
|
||||
});
|
||||
|
||||
api.interceptors.request.use(
|
||||
(config) => {
|
||||
const token = useUserStore.getState().auth;
|
||||
if (token) {
|
||||
config.headers.Authorization = `${token}`;
|
||||
}
|
||||
|
||||
// If URL is a full URL (starts with http:// or https://), it's an external API
|
||||
// Clear baseURL and disable credentials to avoid CORS issues
|
||||
if (
|
||||
config.url?.startsWith("http://") ||
|
||||
config.url?.startsWith("https://")
|
||||
) {
|
||||
config.baseURL = "";
|
||||
config.withCredentials = false;
|
||||
}
|
||||
|
||||
return config;
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
);
|
||||
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response?.status === 401 && useUserStore.getState().auth) {
|
||||
const logOut = useUserStore.getState().logOut;
|
||||
|
||||
if (!hasShownUnauthorizedToast) {
|
||||
hasShownUnauthorizedToast = true;
|
||||
toast.error("مجددا وارد شوید!", {
|
||||
position: checkIsMobile() ? "bottom-center" : "top-center",
|
||||
theme: "light",
|
||||
rtl: true,
|
||||
});
|
||||
if (typeof logOut === "function") {
|
||||
logOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default api;
|
||||
9
src/utils/checkIsMobile.ts
Normal file
9
src/utils/checkIsMobile.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export function checkIsMobile(): boolean {
|
||||
if (typeof navigator === "undefined") return false;
|
||||
|
||||
const userAgent =
|
||||
navigator.userAgent || navigator.vendor || (window as any).opera;
|
||||
return /android|iphone|ipad|ipod|opera mini|iemobile|mobile/i.test(userAgent);
|
||||
}
|
||||
|
||||
|
||||
47
src/utils/checkMenuPermission.ts
Normal file
47
src/utils/checkMenuPermission.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
export const checkMenuPermission = (
|
||||
menuItemName: string,
|
||||
userPermissions: string[] = []
|
||||
): boolean => {
|
||||
if (userPermissions.includes("admin")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const permissionMap: Record<string, string[]> = {
|
||||
users: ["admin", "add"],
|
||||
inspections: ["admin", "submit"],
|
||||
statics: [],
|
||||
nationalinfo: ["admin"],
|
||||
};
|
||||
|
||||
const requiredPermissions = permissionMap[menuItemName] || [];
|
||||
|
||||
if (requiredPermissions.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return requiredPermissions.some((perm) => userPermissions.includes(perm));
|
||||
};
|
||||
|
||||
export const checkRoutePermission = (
|
||||
routePath: string,
|
||||
userPermissions: string[] = []
|
||||
): boolean => {
|
||||
if (userPermissions.includes("admin")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const routePermissionMap: Record<string, string[]> = {
|
||||
"/users": ["admin", "add"],
|
||||
"/inspections": ["admin", "submit"],
|
||||
"/statics": [],
|
||||
"/nationalinfo": ["admin"],
|
||||
};
|
||||
|
||||
const requiredPermissions = routePermissionMap[routePath] || [];
|
||||
|
||||
if (requiredPermissions.length === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return requiredPermissions.some((perm) => userPermissions.includes(perm));
|
||||
};
|
||||
90
src/utils/formatTime.ts
Normal file
90
src/utils/formatTime.ts
Normal file
@@ -0,0 +1,90 @@
|
||||
import { format } from "date-fns-jalali";
|
||||
|
||||
export const formatTime = (time: any) => {
|
||||
const date = new Date(time);
|
||||
const hours = date.getHours().toString().padStart(2, "0");
|
||||
const minutes = date.getMinutes().toString().padStart(2, "0");
|
||||
|
||||
return format(new Date(time), "yyyy/MM/dd ") + `(${hours}:${minutes})`;
|
||||
};
|
||||
|
||||
export const formatJustDate = (time: any) => {
|
||||
if (time) {
|
||||
return format(new Date(time), "yyyy/MM/dd");
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const formatJustTime = (time: any) => {
|
||||
return format(new Date(time), "HH:MM");
|
||||
};
|
||||
|
||||
export function formatStampDate(timestamp: number) {
|
||||
const date = new Date(timestamp);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
return `${year}/${month}/${day}`;
|
||||
}
|
||||
|
||||
export function formatStampDateTime(timestamp: number) {
|
||||
const date = new Date(timestamp);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
const hours = date.getHours().toString().padStart(2, "0");
|
||||
const minutes = date.getMinutes().toString().padStart(2, "0");
|
||||
return `${year}/${month}/${day} ${hours}:${minutes}`;
|
||||
}
|
||||
|
||||
export const formatAgeCalcuation = (dateString: string) => {
|
||||
const birthDate = new Date(dateString);
|
||||
const currentDate = new Date();
|
||||
|
||||
let years = currentDate.getFullYear() - birthDate.getFullYear();
|
||||
let months = currentDate.getMonth() - birthDate.getMonth();
|
||||
let days = currentDate.getDate() - birthDate.getDate();
|
||||
|
||||
if (days < 0) {
|
||||
months--;
|
||||
const lastMonth = new Date(
|
||||
currentDate.getFullYear(),
|
||||
currentDate.getMonth(),
|
||||
0
|
||||
);
|
||||
days += lastMonth.getDate();
|
||||
}
|
||||
|
||||
if (months < 0) {
|
||||
years--;
|
||||
months += 12;
|
||||
}
|
||||
|
||||
const parts: string[] = [];
|
||||
|
||||
if (years > 0) {
|
||||
parts.push(`${years} سال`);
|
||||
}
|
||||
|
||||
if (months > 0) {
|
||||
parts.push(`${months} ماه`);
|
||||
}
|
||||
|
||||
if (days > 0) {
|
||||
parts.push(`${days} روز`);
|
||||
}
|
||||
|
||||
if (parts.length === 0) {
|
||||
return "0 روز";
|
||||
}
|
||||
|
||||
return parts.join(" و ");
|
||||
};
|
||||
|
||||
export function convertToIranianTime(dateString: Date | string): string {
|
||||
const gregorianDate = new Date(dateString);
|
||||
const jalaliDate = format(gregorianDate, "yyyy/MM/dd");
|
||||
return jalaliDate;
|
||||
}
|
||||
|
||||
8
src/utils/getBase64ImageSrc.ts
Normal file
8
src/utils/getBase64ImageSrc.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export function getBase64ImageSrc(
|
||||
base64: string,
|
||||
mimeType = "image/png"
|
||||
): string {
|
||||
return `data:${mimeType};base64,${base64}`;
|
||||
}
|
||||
|
||||
|
||||
32
src/utils/getCitiesOfProvince.ts
Normal file
32
src/utils/getCitiesOfProvince.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
export function getCitiesOfProvince(province: string): string[] {
|
||||
if (province === "hamedan") {
|
||||
return [
|
||||
"همدان",
|
||||
"فامنین",
|
||||
"رزن",
|
||||
"درگزین",
|
||||
"اسدآباد",
|
||||
"بهار",
|
||||
"تویسرکان",
|
||||
"نهاوند",
|
||||
"ملایر",
|
||||
"کبودر آهنگ",
|
||||
];
|
||||
} else if (province === "markazi") {
|
||||
return [
|
||||
"اراك",
|
||||
"خمین",
|
||||
"دلیجان",
|
||||
"شازند",
|
||||
"خنداب",
|
||||
"کمیجان",
|
||||
"فراهان",
|
||||
"تفرش",
|
||||
"آشتیان",
|
||||
"ساوه",
|
||||
"زرندیه",
|
||||
];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
37
src/utils/getCitiesOfProvinceInfo.ts
Normal file
37
src/utils/getCitiesOfProvinceInfo.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
export interface CityInfo {
|
||||
fa: string;
|
||||
en: string;
|
||||
}
|
||||
|
||||
export function getCitiesOfProvinceInfo(province: string): CityInfo[] {
|
||||
if (province === "hamedan") {
|
||||
return [
|
||||
{ fa: "همدان", en: "hamedan" },
|
||||
{ fa: "فامنین", en: "famenin" },
|
||||
{ fa: "رزن", en: "razan" },
|
||||
{ fa: "درگزین", en: "dargazin" },
|
||||
{ fa: "اسدآباد", en: "asadabad" },
|
||||
{ fa: "بهار", en: "bahar" },
|
||||
{ fa: "تویسرکان", en: "tuyserkan" },
|
||||
{ fa: "نهاوند", en: "nehavand" },
|
||||
{ fa: "ملایر", en: "malayer" },
|
||||
{ fa: "کبودر آهنگ", en: "kabudar-ahang" },
|
||||
];
|
||||
} else if (province === "markazi") {
|
||||
return [
|
||||
{ fa: "اراک", en: "arak" },
|
||||
{ fa: "خمین", en: "khomein" },
|
||||
{ fa: "دلیجان", en: "delijan" },
|
||||
{ fa: "شازند", en: "shazand" },
|
||||
{ fa: "خنداب", en: "khandab" },
|
||||
{ fa: "کمیجان", en: "komeijan" },
|
||||
{ fa: "فراهان", en: "farahan" },
|
||||
{ fa: "تفرش", en: "tafresh" },
|
||||
{ fa: "آشتیان", en: "ashtian" },
|
||||
{ fa: "ساوه", en: "saveh" },
|
||||
{ fa: "زرندیه", en: "zarandieh" },
|
||||
];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
49
src/utils/getFaCityName.ts
Normal file
49
src/utils/getFaCityName.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
export function getFaCityName(enCityName: string): string {
|
||||
switch (enCityName) {
|
||||
case "hamedan":
|
||||
return "همدان";
|
||||
case "famenin":
|
||||
return "فامنین";
|
||||
case "razan":
|
||||
return "رزن";
|
||||
case "dargazin":
|
||||
return "درگزین";
|
||||
case "asadabad":
|
||||
return "اسدآباد";
|
||||
case "bahar":
|
||||
return "بهار";
|
||||
case "tuyserkan":
|
||||
return "تویسرکان";
|
||||
case "nehavand":
|
||||
return "نهاوند";
|
||||
case "malayer":
|
||||
return "ملایر";
|
||||
case "kabudar-ahang":
|
||||
return "کبودر آهنگ";
|
||||
case "arak":
|
||||
return "اراک";
|
||||
case "khomein":
|
||||
return "خمین";
|
||||
case "delijan":
|
||||
return "دلیجان";
|
||||
case "shazand":
|
||||
return "شازند";
|
||||
case "khandab":
|
||||
return "خنداب";
|
||||
case "komeijan":
|
||||
return "کمیجان";
|
||||
case "farahan":
|
||||
return "فراهان";
|
||||
case "tafresh":
|
||||
return "تفرش";
|
||||
case "ashtian":
|
||||
return "آشتیان";
|
||||
case "saveh":
|
||||
return "ساوه";
|
||||
case "zarandieh":
|
||||
return "زرندیه";
|
||||
default:
|
||||
return "نامشخص";
|
||||
}
|
||||
}
|
||||
|
||||
40
src/utils/getFaPermissions.ts
Normal file
40
src/utils/getFaPermissions.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
export function getFaPermissions(permission: string) {
|
||||
let faPermission = "";
|
||||
switch (permission) {
|
||||
case "users":
|
||||
faPermission = "کاربران";
|
||||
break;
|
||||
case "inspections":
|
||||
faPermission = "بازرسیها";
|
||||
break;
|
||||
case "statics":
|
||||
faPermission = "آمار";
|
||||
break;
|
||||
case "nationalinfo":
|
||||
faPermission = "اطلاعات افراد";
|
||||
break;
|
||||
case "ladinginfo":
|
||||
faPermission = "اطلاعات بارنامه";
|
||||
break;
|
||||
case "veterinarytransfer":
|
||||
faPermission = "اطلاعات گواهی حمل";
|
||||
break;
|
||||
case "main":
|
||||
faPermission = "صفحه اصلی";
|
||||
break;
|
||||
case "add":
|
||||
faPermission = "افزودن کاربر";
|
||||
break;
|
||||
case "submit":
|
||||
faPermission = "ثبت بازرسی";
|
||||
break;
|
||||
case "admin":
|
||||
faPermission = "مدیر";
|
||||
break;
|
||||
default:
|
||||
faPermission = permission;
|
||||
break;
|
||||
}
|
||||
|
||||
return faPermission;
|
||||
}
|
||||
13
src/utils/getFaProvince.ts
Normal file
13
src/utils/getFaProvince.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export function getFaProvince(province: string): string {
|
||||
switch (province) {
|
||||
case "hamedan":
|
||||
return "همدان";
|
||||
case "markazi":
|
||||
return "مركزی";
|
||||
case "lorestan":
|
||||
return "لرستان";
|
||||
default:
|
||||
return "نامشخص";
|
||||
}
|
||||
}
|
||||
|
||||
14
src/utils/getLocationByProvince.ts
Normal file
14
src/utils/getLocationByProvince.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
export function getLocationByProvince(province: string): [number, number] {
|
||||
switch (province) {
|
||||
case "hamedan":
|
||||
return [34.79759408342567, 48.51519584655762];
|
||||
case "markazi":
|
||||
return [34.089416725974985, 49.68841552734375];
|
||||
case "lorestan":
|
||||
return [33.48238560115483, 48.35046866139527];
|
||||
default:
|
||||
return [33.48238560115483, 48.35046866139527];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
10
src/utils/getPosSellStatus.ts
Normal file
10
src/utils/getPosSellStatus.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
export const getPosSellStatus = (item: any): number => {
|
||||
const realAllocated = parseInt(item?.pos?.products?.[0]?.real_allocated_weight || "0");
|
||||
const totalCarcasses = parseInt(item?.pos?.products?.[0]?.total_carcasses_weight || "0");
|
||||
|
||||
if (totalCarcasses === 0) return 0;
|
||||
|
||||
return Math.round((realAllocated / totalCarcasses) * 100);
|
||||
};
|
||||
|
||||
|
||||
9
src/utils/getProgress.ts
Normal file
9
src/utils/getProgress.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export const getProgress = (item: any): number => {
|
||||
const totalQuantity = item?.hatching?.[0]?.quantity || 0;
|
||||
const leftOver = item?.hatching?.[0]?.left_over || 0;
|
||||
const progress = totalQuantity ? (leftOver / totalQuantity) * 100 : 0;
|
||||
|
||||
return progress;
|
||||
};
|
||||
|
||||
|
||||
16
src/utils/getSystemBaseAddress.ts
Normal file
16
src/utils/getSystemBaseAddress.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
// Helper to get backend address for province
|
||||
|
||||
export const getSystemBaseAddress = (province: string): string => {
|
||||
let backendAddress;
|
||||
if (province === "markazi") {
|
||||
backendAddress = "https://mabackend.rasadyar.com/";
|
||||
} else if (province === "hamedan") {
|
||||
backendAddress = "https://habackend.rasadyar.com/";
|
||||
} else if (province === "bushehr") {
|
||||
backendAddress = "https://bubackend.rasadyar.com/";
|
||||
} else {
|
||||
backendAddress = "https://habackend.rasadyar.com/";
|
||||
}
|
||||
|
||||
return backendAddress;
|
||||
};
|
||||
65
src/utils/useApiRequest.ts
Normal file
65
src/utils/useApiRequest.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { useQuery, useMutation } from "@tanstack/react-query";
|
||||
import { useBackdropStore } from "../context/zustand-store/appStore";
|
||||
import api from "./axios";
|
||||
import { AxiosError } from "axios";
|
||||
|
||||
type RequestParams = {
|
||||
api: string;
|
||||
method?: "get" | "post" | "put" | "delete" | "patch";
|
||||
params?: any;
|
||||
queryKey?: any[];
|
||||
enabled?: boolean;
|
||||
disableBackdrop?: boolean;
|
||||
};
|
||||
|
||||
export function useApiRequest<TData = any>({
|
||||
api: url,
|
||||
params,
|
||||
queryKey = [url],
|
||||
enabled = true,
|
||||
disableBackdrop = false,
|
||||
}: RequestParams) {
|
||||
const { openBackdrop, closeBackdrop } = useBackdropStore();
|
||||
|
||||
return useQuery<TData>({
|
||||
queryKey,
|
||||
queryFn: async () => {
|
||||
if (!disableBackdrop && window.location.pathname !== "/") openBackdrop();
|
||||
|
||||
try {
|
||||
const response = await api.get(url, { params });
|
||||
return response.data;
|
||||
} finally {
|
||||
if (!disableBackdrop) closeBackdrop();
|
||||
}
|
||||
},
|
||||
enabled,
|
||||
retry: 3,
|
||||
});
|
||||
}
|
||||
|
||||
export function useApiMutation<TData = any>({
|
||||
api: url,
|
||||
method = "post",
|
||||
disableBackdrop = false,
|
||||
}: RequestParams) {
|
||||
const { openBackdrop, closeBackdrop } = useBackdropStore();
|
||||
|
||||
return useMutation<TData, AxiosError, any>({
|
||||
mutationFn: async (params) => {
|
||||
if (!disableBackdrop) openBackdrop();
|
||||
|
||||
try {
|
||||
const response = await api.request({
|
||||
url,
|
||||
method,
|
||||
data: ["post", "put", "patch"].includes(method) ? params : undefined,
|
||||
params: ["get", "delete"].includes(method) ? params : undefined,
|
||||
});
|
||||
return response.data;
|
||||
} finally {
|
||||
if (!disableBackdrop) closeBackdrop();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user