first commit
This commit is contained in:
57
src/utils/axios.ts
Normal file
57
src/utils/axios.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
import axios from "axios";
|
||||
import { useUserStore } from "../context/zustand-store/userStore";
|
||||
import { toast } from "react-toastify";
|
||||
import { checkIsMobile } from "./checkIsMobile";
|
||||
|
||||
let hasShownUnauthorizedToast = false;
|
||||
const getBaseURL = () => {
|
||||
const hostname =
|
||||
typeof window !== "undefined" ? window.location.hostname : "";
|
||||
return hostname === "dam.rasadyar.com"
|
||||
? "https://api.dam.rasadyar.com"
|
||||
: "https://api.tdam.rasadyar.com";
|
||||
};
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: getBaseURL(),
|
||||
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 = `Bearer ${token}`;
|
||||
}
|
||||
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;
|
||||
24
src/utils/checkAccess.ts
Normal file
24
src/utils/checkAccess.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { useUserProfileStore } from "../context/zustand-store/userStore";
|
||||
|
||||
type CheckAccessParams = {
|
||||
page: string;
|
||||
access: string;
|
||||
};
|
||||
|
||||
export const checkAccess = ({ page, access }: CheckAccessParams): boolean => {
|
||||
const profile = useUserProfileStore.getState()?.profile;
|
||||
|
||||
if (!access || !page) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const finded = profile?.permissions?.find(
|
||||
(item: any) => item.page_name === page
|
||||
);
|
||||
|
||||
if (finded && finded.page_access.includes(access)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
7
src/utils/checkIsMobile.ts
Normal file
7
src/utils/checkIsMobile.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
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);
|
||||
}
|
||||
147
src/utils/convertNumberToPersian.ts
Normal file
147
src/utils/convertNumberToPersian.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Converts a number to Persian words
|
||||
* @param num - The number to convert
|
||||
* @returns Persian words representation of the number
|
||||
*/
|
||||
export const convertNumberToPersian = (num: number | null | undefined): string => {
|
||||
if (num === null || num === undefined || isNaN(num)) {
|
||||
return "صفر";
|
||||
}
|
||||
|
||||
if (num === 0) {
|
||||
return "صفر";
|
||||
}
|
||||
|
||||
const ones = [
|
||||
"",
|
||||
"یک",
|
||||
"دو",
|
||||
"سه",
|
||||
"چهار",
|
||||
"پنج",
|
||||
"شش",
|
||||
"هفت",
|
||||
"هشت",
|
||||
"نه",
|
||||
"ده",
|
||||
"یازده",
|
||||
"دوازده",
|
||||
"سیزده",
|
||||
"چهارده",
|
||||
"پانزده",
|
||||
"شانزده",
|
||||
"هفده",
|
||||
"هجده",
|
||||
"نوزده",
|
||||
];
|
||||
|
||||
const tens = [
|
||||
"",
|
||||
"",
|
||||
"بیست",
|
||||
"سی",
|
||||
"چهل",
|
||||
"پنجاه",
|
||||
"شصت",
|
||||
"هفتاد",
|
||||
"هشتاد",
|
||||
"نود",
|
||||
];
|
||||
|
||||
const hundreds = [
|
||||
"",
|
||||
"صد",
|
||||
"دویست",
|
||||
"سیصد",
|
||||
"چهارصد",
|
||||
"پانصد",
|
||||
"ششصد",
|
||||
"هفتصد",
|
||||
"هشتصد",
|
||||
"نهصد",
|
||||
];
|
||||
|
||||
const convertHundreds = (n: number): string => {
|
||||
if (n === 0) return "";
|
||||
if (n < 20) return ones[n];
|
||||
if (n < 100) {
|
||||
const ten = Math.floor(n / 10);
|
||||
const one = n % 10;
|
||||
if (one === 0) {
|
||||
return tens[ten];
|
||||
}
|
||||
return `${tens[ten]} و ${ones[one]}`;
|
||||
}
|
||||
if (n < 1000) {
|
||||
const hundred = Math.floor(n / 100);
|
||||
const remainder = n % 100;
|
||||
if (remainder === 0) {
|
||||
return hundreds[hundred];
|
||||
}
|
||||
return `${hundreds[hundred]} و ${convertHundreds(remainder)}`;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
const convertThousands = (n: number): string => {
|
||||
if (n < 1000) {
|
||||
return convertHundreds(n);
|
||||
}
|
||||
if (n < 1000000) {
|
||||
const thousand = Math.floor(n / 1000);
|
||||
const remainder = n % 1000;
|
||||
let result = "";
|
||||
|
||||
if (thousand === 1) {
|
||||
result = "هزار";
|
||||
} else if (thousand < 1000) {
|
||||
result = `${convertHundreds(thousand)} هزار`;
|
||||
}
|
||||
|
||||
if (remainder > 0) {
|
||||
result = result ? `${result} و ${convertHundreds(remainder)}` : convertHundreds(remainder);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (n < 1000000000) {
|
||||
const million = Math.floor(n / 1000000);
|
||||
const remainder = n % 1000000;
|
||||
let result = "";
|
||||
|
||||
if (million === 1) {
|
||||
result = "یک میلیون";
|
||||
} else if (million < 1000) {
|
||||
result = `${convertHundreds(million)} میلیون`;
|
||||
} else {
|
||||
result = `${convertThousands(million)} میلیون`;
|
||||
}
|
||||
|
||||
if (remainder > 0) {
|
||||
result = `${result} و ${convertThousands(remainder)}`;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (n < 1000000000000) {
|
||||
const billion = Math.floor(n / 1000000000);
|
||||
const remainder = n % 1000000000;
|
||||
let result = "";
|
||||
|
||||
if (billion === 1) {
|
||||
result = "یک میلیارد";
|
||||
} else if (billion < 1000) {
|
||||
result = `${convertHundreds(billion)} میلیارد`;
|
||||
} else {
|
||||
result = `${convertThousands(billion)} میلیارد`;
|
||||
}
|
||||
|
||||
if (remainder > 0) {
|
||||
result = `${result} و ${convertThousands(remainder)}`;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
return convertThousands(Math.floor(num));
|
||||
};
|
||||
|
||||
18
src/utils/filterByAccess.ts
Normal file
18
src/utils/filterByAccess.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
type SubItems = {
|
||||
name: string;
|
||||
path: string;
|
||||
component: () => React.ComponentType | any;
|
||||
};
|
||||
|
||||
type Item = {
|
||||
page_name: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export function filterByAccess(
|
||||
permissions: Item[] = [],
|
||||
items: SubItems[]
|
||||
): Item[] {
|
||||
const nameSet = new Set(items.map((item) => item.name));
|
||||
return permissions.filter((obj) => nameSet.has(obj.page_name));
|
||||
}
|
||||
106
src/utils/formatTime.ts
Normal file
106
src/utils/formatTime.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
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) {
|
||||
try {
|
||||
let normalizedTime = time;
|
||||
if (typeof time === "string") {
|
||||
const timezoneWithSecondsRegex = /([+-])(\d{2}):(\d{2}):(\d{2})$/;
|
||||
const match = time.match(timezoneWithSecondsRegex);
|
||||
if (match) {
|
||||
normalizedTime = time.replace(timezoneWithSecondsRegex, `$1$2:$3`);
|
||||
}
|
||||
}
|
||||
const date = new Date(normalizedTime);
|
||||
if (isNaN(date.getTime())) {
|
||||
console.warn(`Invalid date format: ${time}`);
|
||||
return null;
|
||||
}
|
||||
return format(date, "yyyy/MM/dd");
|
||||
} catch (error) {
|
||||
console.warn(`Error formatting date: ${time}`, error);
|
||||
return null;
|
||||
}
|
||||
} 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 const formatJustDateGregorian = (time: any) => {
|
||||
// var timePortion = time.getTime() % (3600 * 1000 * 24);
|
||||
// return new Date(time - timePortion);
|
||||
// };
|
||||
19
src/utils/getAbleToSee.ts
Normal file
19
src/utils/getAbleToSee.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { useUserProfileStore } from "../context/zustand-store/userStore";
|
||||
|
||||
export const getAbleToSee = (page: string, access: string) => {
|
||||
let isAble;
|
||||
if (!access || !page) {
|
||||
isAble = "hidden";
|
||||
} else {
|
||||
const finded = useUserProfileStore
|
||||
.getState()
|
||||
?.profile?.permissions?.find((item: any) => item.page_name === page);
|
||||
if (finded && finded.page_access.includes(access)) {
|
||||
isAble = "";
|
||||
} else {
|
||||
isAble = "hidden";
|
||||
}
|
||||
}
|
||||
|
||||
return isAble;
|
||||
};
|
||||
6
src/utils/getBase64ImageSrc.ts
Normal file
6
src/utils/getBase64ImageSrc.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export function getBase64ImageSrc(
|
||||
base64: string,
|
||||
mimeType = "image/png"
|
||||
): string {
|
||||
return `data:${mimeType};base64,${base64}`;
|
||||
}
|
||||
205
src/utils/getCategoryParameters.ts
Normal file
205
src/utils/getCategoryParameters.ts
Normal file
@@ -0,0 +1,205 @@
|
||||
import Management from "../Pages/Management";
|
||||
import * as R from "../routes/paths";
|
||||
import Users from "../Pages/Users";
|
||||
import Organizations from "../Pages/Organizations";
|
||||
import Roles from "../Pages/Roles";
|
||||
import Products from "../Pages/Products";
|
||||
import { ProductsCategories } from "../Pages/ProductsCategories";
|
||||
import Pricing from "../Pages/Pricing";
|
||||
import IncentivePlans from "../Pages/IncentivePlans";
|
||||
import Quota from "../Pages/Quota";
|
||||
import Inventory from "../Pages/Inventory";
|
||||
import Reporting from "../Pages/Reporting";
|
||||
import LiveStockFarmers from "../Pages/LiveStockFarmers";
|
||||
import LiveStocks from "../Pages/LiveStocks";
|
||||
import Herds from "../Pages/Herds";
|
||||
import Pos from "../Pages/Pos";
|
||||
import PosCompanies from "../Pages/PosCompanies";
|
||||
import PosAccounts from "../Pages/PosAccounts";
|
||||
import RancherPlans from "../Pages/RancherPlans";
|
||||
import Transactions from "../Pages/Transactions";
|
||||
import Unions from "../Pages/Unions";
|
||||
import Cooperatives from "../Pages/Cooperatives";
|
||||
import CooperativeRanchers from "../Pages/CooperativeRanchers";
|
||||
import SettingsOfUnits from "../Pages/SettingsOfUnits";
|
||||
import Tagging from "../Pages/Tagging";
|
||||
|
||||
export const managementCategoryItems = [
|
||||
{
|
||||
name: "permission_control",
|
||||
path: R.PERMISSION_ACCESS,
|
||||
component: Management,
|
||||
},
|
||||
{
|
||||
name: "users",
|
||||
path: R.USERS,
|
||||
component: Users,
|
||||
},
|
||||
{
|
||||
name: "organizations",
|
||||
path: R.ORGANIZATIONS,
|
||||
component: Organizations,
|
||||
},
|
||||
{
|
||||
name: "roles_management",
|
||||
path: R.ROLES,
|
||||
component: Roles,
|
||||
},
|
||||
];
|
||||
|
||||
export const unitCategoryItems = [
|
||||
{
|
||||
name: "unions",
|
||||
path: R.UNION_LIST,
|
||||
component: Unions,
|
||||
},
|
||||
{
|
||||
name: "cooperatives",
|
||||
path: R.COOPERATIVE_LIST,
|
||||
component: Cooperatives,
|
||||
},
|
||||
{
|
||||
name: "union_cooperatives",
|
||||
path: R.UNION_COOPERATIVE_LIST,
|
||||
component: Cooperatives,
|
||||
},
|
||||
{
|
||||
name: "cooperative_ranchers",
|
||||
path: R.COOPERATIVE_RANCHERS_LIST,
|
||||
component: CooperativeRanchers,
|
||||
},
|
||||
{
|
||||
name: "units_settings",
|
||||
path: R.UNITS_SETTINGS,
|
||||
component: SettingsOfUnits,
|
||||
},
|
||||
];
|
||||
|
||||
export const feedInputCategoryItems = [
|
||||
{
|
||||
name: "feed_input_products",
|
||||
path: R.FEED_INPUT_PRODUCTS,
|
||||
component: Products,
|
||||
},
|
||||
{
|
||||
name: "product_categories",
|
||||
path: R.PRODUCT_CATEGORIES,
|
||||
component: ProductsCategories,
|
||||
},
|
||||
{
|
||||
name: "pricing",
|
||||
path: R.PRODUCT_PRICING,
|
||||
component: Pricing,
|
||||
},
|
||||
];
|
||||
|
||||
export const quotaCategoryItems = [
|
||||
{
|
||||
name: "quota",
|
||||
path: R.QUOTAS,
|
||||
component: Quota,
|
||||
},
|
||||
{
|
||||
name: "quota_distributions",
|
||||
path: R.QUOTA_DISTRIBUTION,
|
||||
component: Quota,
|
||||
},
|
||||
{
|
||||
name: "inventory",
|
||||
path: R.INVENTORY,
|
||||
component: Inventory,
|
||||
},
|
||||
{
|
||||
name: "inventory_entries",
|
||||
path: R.INVENTORY_ENTRIES,
|
||||
component: Inventory,
|
||||
},
|
||||
{
|
||||
name: "reporting",
|
||||
path: R.REPORTING,
|
||||
component: Reporting,
|
||||
},
|
||||
{
|
||||
name: "reporting_details",
|
||||
path: R.REPORTING_DETAIL,
|
||||
component: Reporting,
|
||||
},
|
||||
|
||||
{
|
||||
name: "incentive_plans",
|
||||
path: R.QUOTA_INCENTIVE_PLANS,
|
||||
component: IncentivePlans,
|
||||
},
|
||||
];
|
||||
|
||||
export const livestockCategoryItems = [
|
||||
{
|
||||
name: "livestock_farmers",
|
||||
path: R.LIVESTOCK_FARMERS,
|
||||
component: LiveStockFarmers,
|
||||
},
|
||||
{
|
||||
name: "herds",
|
||||
path: R.HERDS,
|
||||
component: Herds,
|
||||
},
|
||||
{
|
||||
name: "farmer_details",
|
||||
path: R.LIVESTOCK_FARMER_DETAIL,
|
||||
component: Herds,
|
||||
},
|
||||
{
|
||||
name: "farmer_plans",
|
||||
path: R.LIVESTOCK_FARMERS_INCENTIVE_PLANS,
|
||||
component: RancherPlans,
|
||||
},
|
||||
{
|
||||
name: "livestocks",
|
||||
path: R.LIVESTOCKS,
|
||||
component: LiveStocks,
|
||||
},
|
||||
{
|
||||
name: "livestocks",
|
||||
path: R.LIVESTOCKS_HERDS_DETAIL,
|
||||
component: LiveStocks,
|
||||
},
|
||||
];
|
||||
|
||||
export const taggingCategoryItems = [
|
||||
{
|
||||
name: "tagging",
|
||||
path: R.TAGGING,
|
||||
component: Tagging,
|
||||
},
|
||||
];
|
||||
|
||||
export const posCategoryItems = [
|
||||
{
|
||||
name: "pos_companies",
|
||||
path: R.POS_COMPANIES,
|
||||
component: PosCompanies,
|
||||
},
|
||||
{
|
||||
name: "pos_company_detail",
|
||||
path: R.POS_COMPANY_DETAIL,
|
||||
component: Pos,
|
||||
},
|
||||
{
|
||||
name: "pos",
|
||||
path: R.POS_POS_LIST,
|
||||
component: Pos,
|
||||
},
|
||||
{
|
||||
name: "pos_accounts",
|
||||
path: R.POS_COMPANY_ACCOUNTS,
|
||||
component: PosAccounts,
|
||||
},
|
||||
];
|
||||
|
||||
export const transactionCategoryItems = [
|
||||
{
|
||||
name: "transactions",
|
||||
path: R.TRANSACTIONS,
|
||||
component: Transactions,
|
||||
},
|
||||
];
|
||||
105
src/utils/getFaPermissions.ts
Normal file
105
src/utils/getFaPermissions.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
export function getFaPermissions(permission: string) {
|
||||
let faPermission = "";
|
||||
switch (permission) {
|
||||
case "permission_control":
|
||||
faPermission = "مدیریت دسترسی";
|
||||
break;
|
||||
case "users":
|
||||
faPermission = "کاربران";
|
||||
break;
|
||||
case "organizations":
|
||||
faPermission = "سازمان ها";
|
||||
break;
|
||||
case "roles_management":
|
||||
faPermission = "مدیریت نقش";
|
||||
break;
|
||||
case "feed_input_products":
|
||||
faPermission = "محصولات";
|
||||
break;
|
||||
case "product_categories":
|
||||
faPermission = "دسته بندی محصولات";
|
||||
break;
|
||||
case "pricing":
|
||||
faPermission = "قیمت گذاری";
|
||||
break;
|
||||
case "incentive_plans":
|
||||
faPermission = "طرح های تشویقی";
|
||||
break;
|
||||
case "quota":
|
||||
faPermission = "سهمیه ها (طرح فروش)";
|
||||
break;
|
||||
case "quota_distributions":
|
||||
faPermission = "نمایش توزیع سهمیه";
|
||||
break;
|
||||
case "inventory":
|
||||
faPermission = "انبار";
|
||||
break;
|
||||
case "reporting":
|
||||
faPermission = "گزارش گیری";
|
||||
break;
|
||||
case "reporting_details":
|
||||
faPermission = "جزئیات گزارش گیری";
|
||||
break;
|
||||
case "livestock_farmers":
|
||||
faPermission = "دامداران";
|
||||
break;
|
||||
case "herds":
|
||||
faPermission = "گله ها";
|
||||
break;
|
||||
case "livestocks":
|
||||
faPermission = "دام ها";
|
||||
break;
|
||||
case "reporting_distribution_details":
|
||||
faPermission = "گزارش توزیع سهمیه";
|
||||
break;
|
||||
case "farmer_details":
|
||||
faPermission = "گله های دامدار";
|
||||
break;
|
||||
case "farmer_plans":
|
||||
faPermission = "طرح های تشویقی دامدار";
|
||||
break;
|
||||
case "herd_livestocks":
|
||||
faPermission = "دام های گله";
|
||||
break;
|
||||
case "pos_companies":
|
||||
faPermission = "شرکت های پرداخت";
|
||||
break;
|
||||
case "pos_company_detail":
|
||||
faPermission = "کارتخوان های شرکت پرداخت";
|
||||
break;
|
||||
case "pos":
|
||||
faPermission = "لیست دستگاه";
|
||||
break;
|
||||
case "pos_accounts":
|
||||
faPermission = "حساب های پوز";
|
||||
break;
|
||||
case "transactions":
|
||||
faPermission = "تراکنش ها";
|
||||
break;
|
||||
case "inventory_entries":
|
||||
faPermission = "لیست ورودی به انبار";
|
||||
break;
|
||||
case "unions":
|
||||
faPermission = "اتحادیه ها";
|
||||
break;
|
||||
case "cooperatives":
|
||||
faPermission = "تعاونی ها";
|
||||
break;
|
||||
case "union_cooperatives":
|
||||
faPermission = "تعاونی های اتحادیه";
|
||||
break;
|
||||
case "cooperative_ranchers":
|
||||
faPermission = "دامداران تعاونی";
|
||||
break;
|
||||
case "units_settings":
|
||||
faPermission = "تنظیمات واحدها";
|
||||
break;
|
||||
case "tagging":
|
||||
faPermission = "پلاک کوبی";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return faPermission;
|
||||
}
|
||||
41
src/utils/getNestedValue.ts
Normal file
41
src/utils/getNestedValue.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
type GetNestedValueOptions = {
|
||||
disableLocaleString?: boolean;
|
||||
};
|
||||
|
||||
export function getNestedValue(
|
||||
obj: any,
|
||||
keys: string[],
|
||||
options?: GetNestedValueOptions
|
||||
) {
|
||||
const value = keys?.reduce((acc, key) => acc?.[key], obj);
|
||||
|
||||
if (options?.disableLocaleString) {
|
||||
if (typeof value === "string" && !isNaN(Number(value))) {
|
||||
return Number(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
if (typeof value === "number") {
|
||||
if (Number.isInteger(value)) {
|
||||
return value.toLocaleString("en-US", { maximumFractionDigits: 0 });
|
||||
}
|
||||
return value.toLocaleString("en-US", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof value === "string" && !isNaN(Number(value))) {
|
||||
const numValue = Number(value);
|
||||
if (Number.isInteger(numValue)) {
|
||||
return numValue.toLocaleString("en-US", { maximumFractionDigits: 0 });
|
||||
}
|
||||
return numValue.toLocaleString("en-US", {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
34
src/utils/getObjectId.ts
Normal file
34
src/utils/getObjectId.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
interface Identifiable {
|
||||
id?: string | number;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export function getObjectId(
|
||||
savedList: Identifiable[] = [],
|
||||
newList: Identifiable[] = [],
|
||||
key: string
|
||||
): Identifiable[] {
|
||||
if (!newList.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!savedList.length) {
|
||||
return newList;
|
||||
}
|
||||
|
||||
const savedItemsMap = new Map();
|
||||
savedList.forEach((item) => {
|
||||
if (item[key] !== undefined) {
|
||||
savedItemsMap.set(item[key], item.id);
|
||||
}
|
||||
});
|
||||
|
||||
return newList.map((item) => {
|
||||
const id =
|
||||
item[key] !== undefined ? savedItemsMap.get(item[key]) : undefined;
|
||||
return {
|
||||
...item,
|
||||
...(id !== undefined ? { id } : {}),
|
||||
};
|
||||
});
|
||||
}
|
||||
24
src/utils/getPersianMonths.ts
Normal file
24
src/utils/getPersianMonths.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
export function getPersianMonths(monthNumbers?: number[] | null): string[] {
|
||||
const persianMonths: { [key: number]: string } = {
|
||||
1: "فروردین",
|
||||
2: "اردیبهشت",
|
||||
3: "خرداد",
|
||||
4: "تیر",
|
||||
5: "مرداد",
|
||||
6: "شهریور",
|
||||
7: "مهر",
|
||||
8: "آبان",
|
||||
9: "آذر",
|
||||
10: "دی",
|
||||
11: "بهمن",
|
||||
12: "اسفند",
|
||||
};
|
||||
|
||||
if (!monthNumbers) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return monthNumbers?.map((num) => {
|
||||
return persianMonths[num];
|
||||
});
|
||||
}
|
||||
125
src/utils/getUserAvalableItems.ts
Normal file
125
src/utils/getUserAvalableItems.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
import { ItemWithSubItems } from "../types/userPermissions";
|
||||
import { filterByAccess } from "./filterByAccess";
|
||||
import {
|
||||
feedInputCategoryItems,
|
||||
livestockCategoryItems,
|
||||
managementCategoryItems,
|
||||
posCategoryItems,
|
||||
quotaCategoryItems,
|
||||
taggingCategoryItems,
|
||||
transactionCategoryItems,
|
||||
unitCategoryItems,
|
||||
} from "./getCategoryParameters";
|
||||
import { getUserAvalablePaths } from "./getUserAvalablePaths";
|
||||
import LogoManagement from "../assets/images/svg/management.svg?react";
|
||||
import LogoFeedInput from "../assets/images/svg/feed-input.svg?react";
|
||||
import LogoWage from "../assets/images/svg/wage.svg?react";
|
||||
import LogoLivestock from "../assets/images/svg/livestock.svg?react";
|
||||
import LogoPos from "../assets/images/svg/pos.svg?react";
|
||||
import LogoTransactions from "../assets/images/svg/transactions.svg?react";
|
||||
import LogoUnits from "../assets/images/svg/units.svg?react";
|
||||
import LogoTagging from "../assets/images/svg/tagging.svg?react";
|
||||
|
||||
type Item = {
|
||||
page_name: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export function getUserPermissions(
|
||||
permissions: Item[] = []
|
||||
): ItemWithSubItems[] {
|
||||
if (!permissions || !permissions.length) {
|
||||
return [];
|
||||
}
|
||||
const managementItems = filterByAccess(permissions, managementCategoryItems);
|
||||
|
||||
const feedInputItems = filterByAccess(permissions, feedInputCategoryItems);
|
||||
|
||||
const wageItems = filterByAccess(permissions, quotaCategoryItems);
|
||||
|
||||
const livestockItems = filterByAccess(permissions, livestockCategoryItems);
|
||||
|
||||
const posItems = filterByAccess(permissions, posCategoryItems);
|
||||
|
||||
const unitItems = filterByAccess(permissions, unitCategoryItems);
|
||||
|
||||
const taggingItems = filterByAccess(permissions, taggingCategoryItems);
|
||||
|
||||
const transactionItems = filterByAccess(
|
||||
permissions,
|
||||
transactionCategoryItems
|
||||
);
|
||||
|
||||
const items: ItemWithSubItems[] = [];
|
||||
|
||||
if (managementItems.length) {
|
||||
items.push({
|
||||
en: "management",
|
||||
fa: "مدیریت",
|
||||
icon: LogoManagement,
|
||||
subItems: getUserAvalablePaths("management", permissions),
|
||||
});
|
||||
}
|
||||
|
||||
if (unitItems.length) {
|
||||
items.push({
|
||||
en: "unit",
|
||||
fa: "مدیریت واحد ها",
|
||||
icon: LogoUnits,
|
||||
subItems: getUserAvalablePaths("unit", permissions),
|
||||
});
|
||||
}
|
||||
|
||||
if (feedInputItems.length) {
|
||||
items.push({
|
||||
en: "feed-input",
|
||||
fa: "نهاده",
|
||||
icon: LogoFeedInput,
|
||||
subItems: getUserAvalablePaths("feed-input", permissions),
|
||||
});
|
||||
}
|
||||
if (wageItems.length) {
|
||||
items.push({
|
||||
en: "quota",
|
||||
fa: "سهمیه",
|
||||
icon: LogoWage,
|
||||
subItems: getUserAvalablePaths("quota", permissions),
|
||||
});
|
||||
}
|
||||
|
||||
if (livestockItems.length) {
|
||||
items.push({
|
||||
en: "livestock",
|
||||
fa: "امور دام",
|
||||
icon: LogoLivestock,
|
||||
subItems: getUserAvalablePaths("livestock", permissions),
|
||||
});
|
||||
}
|
||||
|
||||
if (taggingItems.length) {
|
||||
items.push({
|
||||
en: "livestock",
|
||||
fa: "پلاک کوبی",
|
||||
icon: LogoTagging,
|
||||
subItems: getUserAvalablePaths("tagging", permissions),
|
||||
});
|
||||
}
|
||||
if (transactionItems.length) {
|
||||
items.push({
|
||||
en: "transactions",
|
||||
fa: "تراکنش ها",
|
||||
icon: LogoTransactions,
|
||||
subItems: getUserAvalablePaths("transactions", permissions),
|
||||
});
|
||||
}
|
||||
if (posItems.length) {
|
||||
items.push({
|
||||
en: "pos",
|
||||
fa: "شرکت پرداخت",
|
||||
icon: LogoPos,
|
||||
subItems: getUserAvalablePaths("pos", permissions),
|
||||
});
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
73
src/utils/getUserAvalablePaths.ts
Normal file
73
src/utils/getUserAvalablePaths.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
import {
|
||||
feedInputCategoryItems,
|
||||
livestockCategoryItems,
|
||||
managementCategoryItems,
|
||||
posCategoryItems,
|
||||
quotaCategoryItems,
|
||||
taggingCategoryItems,
|
||||
transactionCategoryItems,
|
||||
unitCategoryItems,
|
||||
} from "./getCategoryParameters";
|
||||
|
||||
type SubItems = {
|
||||
name: string;
|
||||
path: string;
|
||||
component: () => React.ComponentType | any;
|
||||
};
|
||||
|
||||
type Item = {
|
||||
page_name: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
export function getUserAvalablePaths(
|
||||
category: string,
|
||||
permissions: any[] = []
|
||||
): SubItems[] {
|
||||
if (!Array.isArray(permissions)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const filterByAccess = (items: SubItems[]): SubItems[] => {
|
||||
if (!permissions?.length) return [];
|
||||
|
||||
const nameSet = new Set(
|
||||
permissions.map((item: Item) => item?.page_name).filter(Boolean)
|
||||
);
|
||||
|
||||
return items?.filter((item) => item?.name && nameSet.has(item.name)) || [];
|
||||
};
|
||||
|
||||
let list: SubItems[] = [];
|
||||
|
||||
switch (category) {
|
||||
case "management":
|
||||
list = filterByAccess(managementCategoryItems);
|
||||
break;
|
||||
case "feed-input":
|
||||
list = filterByAccess(feedInputCategoryItems);
|
||||
break;
|
||||
case "quota":
|
||||
list = filterByAccess(quotaCategoryItems);
|
||||
break;
|
||||
case "livestock":
|
||||
list = filterByAccess(livestockCategoryItems);
|
||||
break;
|
||||
case "transactions":
|
||||
list = filterByAccess(transactionCategoryItems);
|
||||
break;
|
||||
case "pos":
|
||||
list = filterByAccess(posCategoryItems);
|
||||
break;
|
||||
case "unit":
|
||||
list = filterByAccess(unitCategoryItems);
|
||||
break;
|
||||
case "tagging":
|
||||
list = filterByAccess(taggingCategoryItems);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return list || [];
|
||||
}
|
||||
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