push rasad front on new repo

This commit is contained in:
2026-01-18 14:32:49 +03:30
commit 4fe6e70525
2139 changed files with 303150 additions and 0 deletions

29
src/utils/address.js Normal file
View File

@@ -0,0 +1,29 @@
export const extractProvinceFromAddress = (address, provinceData) => {
if (
!address ||
typeof address !== "string" ||
!provinceData ||
provinceData.length === 0
) {
return "";
}
const normalized = address
.replace(/\u200c/g, " ")
.replace(/\s+/g, " ")
.trim();
const words = normalized.split(/\s+/).slice(0, 2);
const firstTwoWords = words.join(" ");
const matchedProvince = provinceData.find((province) => {
const provinceName = province.name || "";
return (
provinceName.includes(firstTwoWords) ||
firstTwoWords.includes(provinceName) ||
normalized.includes(provinceName)
);
});
return matchedProvince ? matchedProvince.name : "";
};

View File

@@ -0,0 +1,7 @@
export const checkPathStartsWith = (str) => {
const path = window.location.pathname;
if (path.startsWith("/" + str)) {
return true;
}
return false;
};

View File

@@ -0,0 +1,84 @@
const STORAGE_KEY = "dashboard_custom_order";
export const getCustomOrders = () => {
try {
const orders = localStorage.getItem(STORAGE_KEY);
return orders ? JSON.parse(orders) : {};
} catch (error) {
console.error("Error reading custom orders:", error);
return {};
}
};
const saveCustomOrders = (orders) => {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(orders));
} catch (error) {
console.error("Error saving custom orders:", error);
}
};
export const getRoleCustomOrder = (role) => {
const orders = getCustomOrders();
return orders[role] || null;
};
export const saveRoleCustomOrder = (role, items) => {
const orders = getCustomOrders();
const routeOrder = items.map((item) => item.route);
orders[role] = routeOrder;
saveCustomOrders(orders);
};
export const applyCustomOrder = (items, role) => {
if (!items || !Array.isArray(items)) return items;
const customOrder = getRoleCustomOrder(role);
if (!customOrder || customOrder.length === 0) return items;
const orderedItems = [];
const remainingItems = [...items];
for (const route of customOrder) {
const index = remainingItems.findIndex((item) => item.route === route);
if (index !== -1) {
orderedItems.push(remainingItems[index]);
remainingItems.splice(index, 1);
}
}
orderedItems.push(...remainingItems);
return orderedItems;
};
export const clearRoleCustomOrder = (role) => {
const orders = getCustomOrders();
if (orders[role]) {
delete orders[role];
saveCustomOrders(orders);
}
};
export const clearAllCustomOrders = () => {
try {
localStorage.removeItem(STORAGE_KEY);
} catch (error) {
console.error("Error clearing custom orders:", error);
}
};
export const hasCustomOrder = (role) => {
const customOrder = getRoleCustomOrder(role);
return customOrder !== null && customOrder.length > 0;
};
export const reorderArray = (list, startIndex, endIndex) => {
const result = Array.from(list);
const [removed] = result.splice(startIndex, 1);
result.splice(endIndex, 0, removed);
return result;
};

135
src/utils/formatTime.js Normal file
View File

@@ -0,0 +1,135 @@
import { format } from "date-fns-jalali";
import { enUS } from "date-fns/locale";
import PersianDate from "persian-date";
const persianLocale = {
...enUS,
localize: {
...enUS.localize,
month: (n) =>
[
"فروردین",
"اردیبهشت",
"خرداد",
"تیر",
"مرداد",
"شهریور",
"مهر",
"آبان",
"آذر",
"دی",
"بهمن",
"اسفند",
][n],
},
formatLong: {
...enUS.formatLong,
date: () => "d MMMM yyyy",
},
};
export const formatTime = (time) => {
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 formatTimeFull = (time) => {
const date = new Date(time);
const hours = date.getHours().toString().padStart(2, "0");
const minutes = date.getMinutes().toString().padStart(2, "0");
const seconds = date.getSeconds().toString().padStart(2, "0");
return (
format(new Date(time), "yyyy/MM/dd ") + `(${hours}:${minutes}:${seconds})`
);
};
export const formatJustDate = (time) => {
if (time) {
return format(new Date(time), "yyyy/MM/dd");
} else {
return null;
}
};
export const formatJustTime = (time) => {
return format(new Date(time), "HH:MM");
};
export const formatJustDateGregorian = (time) => {
const timePortion = time.getTime() % (3600 * 1000 * 24);
return new Date(time - timePortion);
};
export function formatTimeStampDate(timestamp) {
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 convertToIranianTime(dateString) {
const gregorianDate = new Date(dateString);
const iranianDate = new PersianDate(gregorianDate);
const iranianDateString = iranianDate.format("YYYY/MM/DD");
const asciiIranianDateString = iranianDateString.replace(
/[۰-۹]/g,
function (digit) {
return String.fromCharCode(digit.charCodeAt(0) - 1728);
}
);
return asciiIranianDateString;
}
export function getPersianMonth(dateString) {
const date = new Date(dateString);
const persianMonth = format(date, "MMMM", { locale: persianLocale });
return persianMonth + " " + format(new Date(date), "yyyy");
}
export function convertDaysToYMD(days) {
const daysInYear = 365;
const daysInMonth = 30;
const years = Math.floor(days / daysInYear);
days = days % daysInYear;
const months = Math.floor(days / daysInMonth);
days = days % daysInMonth;
const remainingDays = days;
const result = [];
if (years > 0) result.push(`${years} سال`);
if (months > 0) result.push(`${months} ماه`);
if (remainingDays > 0) result.push(`${remainingDays} روز`);
return result.join(" و ");
}
export function convertPersianToEnglishNumerals(text) {
if (!text || typeof text !== "string") {
return text;
}
const persianToEnglish = {
"۰": "0",
"۱": "1",
"۲": "2",
"۳": "3",
"۴": "4",
"۵": "5",
"۶": "6",
"۷": "7",
"۸": "8",
"۹": "9",
};
return text.replace(/[۰-۹]/g, (char) => persianToEnglish[char] || char);
}

View File

@@ -0,0 +1,15 @@
export const getAllocationType = (item) => {
if (!item?.allocationType) return "-";
const types = {
killhouse_steward: "کشتارگاه به مباشر",
killhouse_guild: "کشتارگاه به صنف",
killhouse_coldhouse: "کشتارگاه به سردخانه",
steward_steward: "مباشر به مباشر",
steward_guild: "مباشر به صنف",
ColdHouse: "کشتارگاه به سردخانه",
guild_killhouse: "صنف به کشتارگاه",
};
return types[item.allocationType] || "-";
};

View File

@@ -0,0 +1,40 @@
import React from "react";
import * as ROUTES from "../routes/routes";
import CorporateFareIcon from "@mui/icons-material/CorporateFare";
import ApartmentIcon from "@mui/icons-material/Apartment";
import PeopleIcon from "@mui/icons-material/People";
import CompareArrowsIcon from "@mui/icons-material/CompareArrows";
export const getBarSquareItems = (role) => {
switch (role) {
case "BarSquareProvinceJahad":
return [
{
text: "دسترسی ها",
icon: <CorporateFareIcon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_UNIONS,
disabled: true,
},
{
text: "بنک دارها",
icon: <ApartmentIcon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_COOPERATIVES,
disabled: true,
},
{
text: "تراکنش ها",
icon: <CompareArrowsIcon />,
route: ROUTES.ROUTE_BAR_SQUARE_TRANSACTIONS,
},
{
text: "صنوف",
icon: <PeopleIcon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_USERS,
disabled: true,
},
];
default:
return [];
}
};

View File

@@ -0,0 +1,26 @@
import { useSelector } from "react-redux";
export const useCeoAddress = () => {
const userPath = useSelector((state) => state.userSlice.userPath);
if (
userPath === "https://check.rasadyaar.ir" ||
userPath.includes("localhost")
) {
return "خرم آباد، مطهری، شرکت آرتامهر آرتان";
} else if (userPath === "https://mabackend.rasadyar.com/") {
return "مرودشت، رو به روی شبکه دامپزشکی شهرستان اراک، اتحادیه مرغداران استان مرکزی";
} else if (userPath === "https://arbackend.rasadyar.com/") {
return "آدرس : اردبیل، شهرک کارشناسان ،جنب ساختمان نظام مهندسی، ساختمان فرهنگ، طبقه دوم تلفن : 33749254 تلفاکس : 33749253 ";
} else if (userPath === "https://habackend.rasadyar.com/") {
return "همدان، بلوار آیت اله مدنی، کوچه امامزاده یحیی یک تلفن: 081 32523689 ";
} else if (userPath === "https://shabackend.rasadyar.com/") {
return "تبریز خیابان راه آهن نبش کوی اشکان ساختمان ۱۴ طبقه دوم تلفن: 041 34502363";
} else if (userPath === "https://ghabackend.rasadyar.com/") {
return "آدرس استان آذربایجان غربی";
} else if (userPath === "https://bubackend.rasadyar.com/") {
return "بوشهر، خيابان امام خمينی، جنب مديريت برق، ساختمان رضايي، طبقه 3";
} else {
return "آدرس تست";
}
};

26
src/utils/getCeoName.js Normal file
View File

@@ -0,0 +1,26 @@
import { useSelector } from "react-redux";
export const useCeoName = () => {
const userPath = useSelector((state) => state.userSlice.userPath);
if (
userPath === "https://check.rasadyaar.ir" ||
userPath.includes("localhost")
) {
return "محمد میرانی";
} else if (userPath === "https://mabackend.rasadyar.com/") {
return "علی حیدری";
} else if (userPath === "https://arbackend.rasadyar.com/") {
return "علیرضا سقایی";
} else if (userPath === "https://habackend.rasadyar.com/") {
return "داوود شعبانلو";
} else if (userPath === "https://shabackend.rasadyar.com/") {
return "جواد سلطانی مجد";
} else if (userPath === "https://ghabackend.rasadyar.com/") {
return "آقای/خانم";
} else if (userPath === "https://bubackend.rasadyar.com/") {
return "حسین تمجیدی پور";
} else {
return "محمد میرانی";
}
};

22
src/utils/getDayOfWeek.js Normal file
View File

@@ -0,0 +1,22 @@
export const getDayOfWeek = (inputdate) => {
let x = new Date(inputdate);
let dayofweek = x.getDay();
switch (dayofweek) {
case 1:
return "دوشنبه";
case 2:
return "سه شنبه";
case 3:
return "چهارشنبه";
case 4:
return "پنج شنبه";
case 5:
return "جمعه";
case 6:
return "شنبه";
case 7:
return "یکشنبه";
default:
return "نامشخص";
}
};

View File

@@ -0,0 +1,35 @@
export function getEnRoleFromFa(name) {
let itemVal;
switch (name) {
case "شهرستان":
itemVal = "CityOperator";
break;
case "مرغدار":
itemVal = "Poultry";
break;
case "دامپزشک":
itemVal = "VetFarm";
break;
case "راننده":
itemVal = "Driver";
break;
case "کشتارگاه":
itemVal = "KillHouse";
break;
case "پشتیبانی امور دام":
itemVal = "LiveStockSupport";
break;
case "مالی":
itemVal = "ProvinceFinancial";
break;
case "ادمین کل":
itemVal = "SuperAdmin";
break;
case "پخش کننده":
itemVal = "Dispenser";
break;
default:
break;
}
return itemVal;
}

View File

@@ -0,0 +1,88 @@
export function getFaUserRole(role) {
switch (role) {
case "Admin":
return "ادمین استان";
case "CityOperator":
return "تعاونی";
case "Poultry":
return "مرغدار";
case "ProvinceOperator":
return "مدیر اجرایی";
case "ProvinceFinancial":
return "مالی اتحادیه";
case "KillHouse":
return "کشتارگاه";
case "KillHouseVet":
return "دامپزشک کشتارگاه";
case "VetFarm":
return "دامپزشک فارم";
case "Driver":
return "راننده";
case "ProvinceInspector":
return "بازرس اتحادیه ";
case "VetSupervisor":
return "دامپزشک کل";
case "Jahad":
return "جهاد کشاورزی استان";
case "CityJahad":
return "جهاد کشاورزی شهرستان";
case "ProvincialGovernment":
return "استانداری";
case "Guilds":
return "صنف";
case "Steward":
return "مباشر";
case "Commerce":
return "معاونت بازرگانی استان";
case "CityCommerce":
return "بازرگانی شهرستان";
case "UnitWindow":
return "پنجره واحد";
case "CityVet":
return "دامپزشک شهرستان";
case "Observatory":
return "رصدخانه";
case "ProvinceSupervisor":
return "ناظر استان";
case "GuildRoom":
return "اتاق اصناف";
case "PosCompany":
return "شرکت psp";
case "LiveStockSupport":
return "پشتیبانی امور دام";
case "SuperAdmin":
return "ادمین کل";
case "ChainCompany":
return "شرکت زنجیره";
case "AdminX":
return "ادمین ایکس";
case "Supporter":
return "پشتیبان سامانه";
case "Dispenser":
return "پخش کننده";
case "CityPoultry":
return "طیور شهرستان";
case "ParentCompany":
return "شرکت مادر";
case "ColdHouseSteward":
return "مباشر سردخانه";
case "CityGuild":
return "اتحادیه پروتئینی";
case "LiveStockProvinceJahad":
return "جهاد استان";
case "Union":
return "اتحادیه دامداران";
case "Cooperative":
return "تعاونی دامداران";
case "Rancher":
return "دامدار";
case "BarSquareProvinceJahad":
return "جهاد میدان بار";
case "PoultryScience":
return "کارشناس علوم دامی";
case "ProteinGuild":
return "گویهای پروتئین";
default:
return "";
}
}

View File

@@ -0,0 +1,24 @@
export const getListOfProvinces = () => {
return [
{
name: "همدان",
link: "https://habackend.rasadyar.com/",
},
{
name: "مرکزی",
link: "https://mabackend.rasadyar.com/",
},
{
name: "بوشهر",
link: "https://bubackend.rasadyar.com/",
},
// {
// name: "آذربایجان شرقی",
// link: "https://shabackend.rasadyar.com/",
// },
// {
// name: "اردبیل",
// link: "https://arbackend.rasadyar.com/",
// },
];
};

121
src/utils/getLivestock.js Normal file
View File

@@ -0,0 +1,121 @@
import React from "react";
import * as ROUTES from "../routes/routes";
import CorporateFareIcon from "@mui/icons-material/CorporateFare";
import ApartmentIcon from "@mui/icons-material/Apartment";
import ListAltIcon from "@mui/icons-material/ListAlt";
import PeopleIcon from "@mui/icons-material/People";
import Face5Icon from "@mui/icons-material/Face5";
import BlurOnIcon from "@mui/icons-material/BlurOn";
import CompareArrowsIcon from "@mui/icons-material/CompareArrows";
export const getLiveStockItems = (role) => {
switch (role) {
case "LiveStockProvinceJahad":
return [
{
text: "اتحادیه ها",
icon: <CorporateFareIcon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_UNIONS,
},
{
text: "تعاونی ها",
icon: <ApartmentIcon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_COOPERATIVES,
},
{
text: "دامداران",
icon: <Face5Icon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_RANCHERS,
},
{
text: "گله ها",
icon: <ListAltIcon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_HERDS,
},
{
text: "محصولات",
icon: <BlurOnIcon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_PRODUCT_DISTRIBUTION,
},
{
text: "تراکنش ها",
icon: <CompareArrowsIcon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_PRODUCT_TRANSACTIONS,
},
{
text: "کاربران",
icon: <PeopleIcon />,
route: ROUTES.ROUTE_PROVINCE_JAHAD_USERS,
},
];
case "Union":
return [
{
text: "تعاونی ها",
icon: <ApartmentIcon />,
route: ROUTES.ROUTE_UNION_COOPERATIVES,
},
{
text: "دامداران",
icon: <Face5Icon />,
route: ROUTES.ROUTE_UNION_RANCHERS,
},
{
text: "گله ها",
icon: <ListAltIcon />,
route: ROUTES.ROUTE_UNION_HERDS,
},
{
text: "محصولات",
icon: <BlurOnIcon />,
route: ROUTES.ROUTE_UNION_PRODUCT_DISTRIBUTION,
},
{
text: "تراکنش ها",
icon: <CompareArrowsIcon />,
route: ROUTES.ROUTE_UNION_PRODUCT_TRANSACTIONS,
},
{
text: "کاربران",
icon: <PeopleIcon />,
route: ROUTES.ROUTE_UNION_USERS,
disabled: true,
},
];
case "Cooperative":
return [
{
text: "دامداران",
icon: <Face5Icon />,
route: ROUTES.ROUTE_COOPERATIVE_RANCHERS,
disabled: true,
disabledText: "شما مجوز دسترسی به این بخش را ندارید!",
},
{
text: "گله ها",
icon: <ListAltIcon />,
route: ROUTES.ROUTE_COOPERATIVE_HERDS,
disabled: true,
disabledText: "شما مجوز دسترسی به این بخش را ندارید!",
},
{
text: "محصولات",
icon: <BlurOnIcon />,
route: ROUTES.ROUTE_COOPERATIVE_PRODUCT_DISTRIBUTION,
},
{
text: "تراکنش ها",
icon: <CompareArrowsIcon />,
route: ROUTES.ROUTE_COOPERATIVE_PRODUCT_TRANSACTIONS,
},
{
text: "کاربران",
icon: <PeopleIcon />,
route: ROUTES.ROUTE_COOPERATIVE_USERS,
disabled: true,
},
];
default:
return [];
}
};

View File

@@ -0,0 +1,18 @@
export const getPosProviderName = (provider) => {
switch (provider) {
case "SEP":
return "سامان کیش";
case "asanpardakht":
return "آسان پرداخت";
case "irkish":
return "ایران کیش";
case "sepehr":
return "سپهر";
case "mellat":
return "ملت";
case "pec":
return "پارسیان";
default:
return "نامشخص";
}
};

View File

@@ -0,0 +1,57 @@
import React from "react";
import RiceBowlIcon from "@mui/icons-material/RiceBowl";
import AcUnitIcon from "@mui/icons-material/AcUnit";
import LocalDiningIcon from "@mui/icons-material/LocalDining";
import IcecreamIcon from "@mui/icons-material/Icecream";
import FastfoodIcon from "@mui/icons-material/Fastfood";
import KitchenIcon from "@mui/icons-material/Kitchen";
import SetMealIcon from "@mui/icons-material/SetMeal";
import RestaurantIcon from "@mui/icons-material/Restaurant";
import LocalGroceryStoreIcon from "@mui/icons-material/LocalGroceryStore";
const getEssentialGoodsMenuItems = () => {
return [
{
text: "برنج",
icon: <RiceBowlIcon />,
},
{
text: "شکر",
icon: <AcUnitIcon />,
},
{
text: "قند",
icon: <LocalDiningIcon />,
},
{
text: "گوشت قرمز (منجمد)",
icon: <IcecreamIcon />,
},
{
text: "گوشت قرمز (گرم)",
icon: <FastfoodIcon />,
},
{
text: "روغن خوراکی",
icon: <KitchenIcon />,
},
{
text: "حبوبات",
icon: <SetMealIcon />,
},
{
text: "مرغ (منجمد)",
icon: <RestaurantIcon />,
},
{
text: "مرغ (گرم)",
icon: <RestaurantIcon />,
},
{
text: "ماهی",
icon: <LocalGroceryStoreIcon />,
},
];
};
export default getEssentialGoodsMenuItems;

View File

@@ -0,0 +1,22 @@
import { useSelector } from "react-redux";
export const useProvinceName = () => {
const userPath = useSelector((state) => state.userSlice.userPath);
let province;
if (userPath === "https://testbackend.rasadyar.com/") {
province = "test";
} else if (userPath === "https://mabackend.rasadyar.com/") {
province = "markazi";
} else if (userPath === "https://arbackend.rasadyar.com/") {
province = "ardabil";
} else if (userPath === "https://habackend.rasadyar.com/") {
province = "hamedan";
} else if (userPath === "https://bubackend.rasadyar.com/") {
province = "bushehr";
} else {
province = "hamedan";
}
return province;
};

View File

@@ -0,0 +1,9 @@
import moment from "moment";
export const getRemainedSeconds = (item) => {
const finishDate = moment(new Date(item));
const currentDate = moment();
const diff = finishDate.diff(currentDate);
let remainedSeconds = moment.duration(diff).asSeconds();
return remainedSeconds;
};

View File

@@ -0,0 +1,98 @@
export const getRoleFromUrl = () => {
switch (window.location.pathname.split("/")[1]) {
case "city":
return "CityOperator";
case "aviculture":
return "Poultry";
case "province":
return "ProvinceOperator";
case "slaughter":
return "KillHouse";
case "slaughter-house-vet":
return "KillHouseVet";
case "vetfarm":
return "VetFarm";
case "financial":
return "ProvinceFinancial";
case "inspector":
return "ProvinceInspector";
case "vet-supervisor":
return "VetSupervisor";
case "commerce":
return "Commerce";
case "city-commerce":
return "CityCommerce";
case "city-vet":
return "CityVet";
case "city-jahad":
return "CityJahad";
case "observatory":
return "Observatory";
case "province-supervisor":
return "ProvinceSupervisor";
case "guild":
return "Guilds";
case "senf":
return "Guilds";
case "steward":
return "Steward";
case "guild-room":
return "GuildRoom";
case "livestock":
return "LiveStockSupport";
case "superadmin":
return "SuperAdmin";
case "chaincompany":
return "ChainCompany";
case "adminx":
return "AdminX";
case "supporter":
return "Supporter";
case "dispenser":
return "Dispenser";
case "citypoultry":
return "CityPoultry";
case "driver":
return "Driver";
case "parent-company":
return "ParentCompany";
case "cold-house-steward":
return "ColdHouseSteward";
case "city-guild":
return "CityGuild";
case "province-jahad":
return "LiveStockProvinceJahad";
case "union":
return "Union";
case "cooperative":
return "Cooperative";
case "rancher":
return "Rancher";
case "psp-company":
return "PosCompany";
case "poultry-science":
return "PoultryScience";
default:
return null;
}
};
export const getActualRoleFromRole = (role) => {
switch (role) {
case "city":
return "CityOperator";
case "aviculture":
return "Poultry";
case "province":
return "ProvinceOperator";
case "slaughter":
return "KillHouse";
case "slaughter-house-vet":
case "vetfarm":
return "Vet";
case "financial":
return "ProvinceFinancial";
default:
return null;
}
};

114
src/utils/getRoleIcon.js Normal file
View File

@@ -0,0 +1,114 @@
import ReduceCapacityIcon from "@mui/icons-material/ReduceCapacity";
import EggIcon from "@mui/icons-material/Egg";
import FactoryIcon from "@mui/icons-material/Factory";
import HdrStrongIcon from "@mui/icons-material/HdrStrong";
import VaccinesIcon from "@mui/icons-material/Vaccines";
import StoreIcon from "@mui/icons-material/Store";
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
import SupportIcon from "@mui/icons-material/Support";
import WindowIcon from "@mui/icons-material/Window";
import PaymentIcon from "@mui/icons-material/Payment";
import AnimationIcon from "@mui/icons-material/Animation";
import CoPresentIcon from "@mui/icons-material/CoPresent";
import Diversity3Icon from "@mui/icons-material/Diversity3";
import BrightnessLowIcon from "@mui/icons-material/BrightnessLow";
import MedicalInformationIcon from "@mui/icons-material/MedicalInformation";
import MonetizationOnIcon from "@mui/icons-material/MonetizationOn";
import PolicyIcon from "@mui/icons-material/Policy";
import LocalTaxiIcon from "@mui/icons-material/LocalTaxi";
import AdminPanelSettingsIcon from "@mui/icons-material/AdminPanelSettings";
import AgricultureIcon from "@mui/icons-material/Agriculture";
import StorefrontIcon from "@mui/icons-material/Storefront";
import CurrencyExchangeIcon from "@mui/icons-material/CurrencyExchange";
import LocalAtmIcon from "@mui/icons-material/LocalAtm";
import PreviewIcon from "@mui/icons-material/Preview";
import DomainIcon from "@mui/icons-material/Domain";
import AcUnitIcon from "@mui/icons-material/AcUnit";
import FoodBankIcon from "@mui/icons-material/FoodBank";
import { CorporateFare } from "@mui/icons-material";
import HowToRegIcon from "@mui/icons-material/HowToReg";
export function getIconUserRole(role) {
switch (role) {
case "Admin":
return <AdminPanelSettingsIcon />;
case "CityOperator":
return <BrightnessLowIcon />;
case "Poultry":
return <EggIcon />;
case "ProvinceOperator":
return <Diversity3Icon />;
case "ProvinceFinancial":
return <MonetizationOnIcon />;
case "KillHouse":
return <FactoryIcon />;
case "KillHouseVet":
return <VaccinesIcon />;
case "VetFarm":
return <MedicalInformationIcon />;
case "Driver":
return <LocalTaxiIcon />;
case "ProvinceInspector":
return <PolicyIcon />;
case "VetSupervisor":
return <MedicalInformationIcon />;
case "Jahad":
return <AgricultureIcon />;
case "CityJahad":
return <AgricultureIcon />;
case "ProvincialGovernment":
return <ReduceCapacityIcon />;
case "Guilds":
return <StorefrontIcon />;
case "Steward":
return <StoreIcon />;
case "Commerce":
return <CurrencyExchangeIcon />;
case "CityCommerce":
return <LocalAtmIcon />;
case "UnitWindow":
return <WindowIcon />;
case "CityVet":
return <MedicalInformationIcon />;
case "Observatory":
return <PreviewIcon />;
case "ProvinceSupervisor":
return <RemoveRedEyeIcon />;
case "GuildRoom":
return <StorefrontIcon />;
case "PosCompany":
return <PaymentIcon />;
case "LiveStockSupport":
return <SupportIcon />;
case "SuperAdmin":
return <AdminPanelSettingsIcon />;
case "AdminX":
return <AdminPanelSettingsIcon />;
case "ChainCompany":
return <AnimationIcon />;
case "Supporter":
return <SupportIcon />;
case "Dispenser":
return <CoPresentIcon />;
case "CityPoultry":
return <AgricultureIcon />;
case "ParentCompany":
return <DomainIcon />;
case "ColdHouseSteward":
return <AcUnitIcon />;
case "CityGuild":
return <FoodBankIcon />;
case "LiveStockProvinceJahad":
return <CorporateFare />;
case "Union":
return <BrightnessLowIcon />;
case "Cooperative":
return <BrightnessLowIcon />;
case "ranRanchercher":
return <AgricultureIcon />;
case "PoultryScience":
return <HowToRegIcon />;
default:
return <HdrStrongIcon />;
}
}

42
src/utils/getRoleList.js Normal file
View File

@@ -0,0 +1,42 @@
import { getFaUserRole } from "./getFaUserRole";
export const getRoleList = () => {
const roles = [
"CityOperator",
"Poultry",
"ProvinceOperator",
"KillHouse",
"KillHouseVet",
"VetFarm",
"ProvinceFinancial",
"ProvinceInspector",
"VetSupervisor",
"Commerce",
"CityCommerce",
"CityVet",
"CityJahad",
"Observatory",
"ProvinceSupervisor",
"Guilds",
"GuildRoom",
"LiveStockSupport",
"SuperAdmin",
"ChainCompany",
"AdminX",
"Supporter",
"Dispenser",
"CityPoultry",
"ParentCompany",
"ColdHouseSteward",
"CityGuild",
"LiveStockProvinceJahad",
"Union",
"Cooperative",
"Rancher",
];
return roles.map((role) => ({
role,
translation: getFaUserRole(role),
}));
};

1675
src/utils/getRolesItems.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
export const getSamasatProvinces = () => {
return [
{
name: "آذربایجان شرقی",
id: "65521",
},
{
name: "آذربایجان غربی",
id: "65522",
},
{
name: "اردبیل",
id: "65523",
},
{
name: "اصفهان",
id: "65524",
},
{
name: "البرز",
id: "65525",
},
{
name: "ایلام",
id: "65526",
},
{
name: "بوشهر",
id: "65527",
},
{
name: "تهران",
id: "65528",
},
{
name: "چهارمحال و بختیاری",
id: "65529",
},
{
name: "خراسان جنوبی",
id: "65530",
},
{
name: "خراسان رضوی",
id: "65531",
},
{
name: "خراسان شمالی",
id: "65532",
},
{
name: "خوزستان",
id: "65533",
},
{
name: "زنجان",
id: "65534",
},
{
name: "سمنان",
id: "65535",
},
{
name: "سیستان و بلوچستان",
id: "65536",
},
{
name: "فارس",
id: "65537",
},
{
name: "قزوین",
id: "65538",
},
{
name: "قم",
id: "65539",
},
{
name: "کردستان",
id: "65540",
},
{
name: "کرمان",
id: "65541",
},
{
name: "کرمانشاه",
id: "65542",
},
{
name: "کهکیلویه و بویراحمد",
id: "65543",
},
{
name: "گلستان",
id: "65544",
},
{
name: "گیلان",
id: "65545",
},
{
name: "لرستان",
id: "65546",
},
{
name: "مازندران",
id: "65547",
},
{
name: "مرکزی",
id: "65548",
},
{
name: "هرمزگان",
id: "65549",
},
{
name: "همدان",
id: "65550",
},
{
name: "یزد",
id: "65551",
},
];
};

View File

@@ -0,0 +1,11 @@
/**
* Helper function to get the selected sub user key from Redux state
* @param {Object} state - Redux state
* @returns {string|null} - The sub user key or null if not available
*/
export const getSelectedSubUserKey = (state) => {
const selectedSubUser = state?.userSlice?.selectedSubUser;
return selectedSubUser?.key || null;
};
export default getSelectedSubUserKey;

View File

@@ -0,0 +1,18 @@
export const getSystemBaseAddress = (userPath) => {
let province;
if (userPath === "https://testbackend.rasadyar.com/") {
province = "test";
} else if (userPath === "https://mabackend.rasadyar.com/") {
province = "ma";
} else if (userPath === "https://arbackend.rasadyar.com/") {
province = "ar";
} else if (userPath === "https://habackend.rasadyar.com/") {
province = "ha";
} else if (userPath === "https://bubackend.rasadyar.com/") {
province = "bu";
} else {
province = "ha";
}
return province;
};

View File

@@ -0,0 +1,18 @@
import { useSelector } from "react-redux";
export const useSystemName = () => {
const userPath = useSelector((state) => state.userSlice.userPath);
if (userPath === "https://testbackend.rasadyar.com/") {
return "تست";
} else if (userPath === "https://mabackend.rasadyar.com/") {
return "استان مرکزی";
} else if (userPath === "https://bubackend.rasadyar.com/") {
return "استان بوشهر";
} else if (userPath === "https://habackend.rasadyar.com/") {
return "استان همدان";
} else if (userPath === "https://kubackend.rasadyar.com/") {
return "استان کردستان";
} else {
return "تست";
}
};

View File

@@ -0,0 +1,104 @@
export function getUserTypeOfActivity(userRoles) {
const poultryRoles = [
"CityOperator",
"Poultry",
"ProvinceOperator",
"KillHouse",
"KillHouseVet",
"VetFarm",
"ProvinceFinancial",
"ProvinceInspector",
"VetSupervisor",
"Commerce",
"CityCommerce",
"CityVet",
"CityJahad",
"Observatory",
"ProvinceSupervisor",
"Guilds",
"GuildRoom",
"LiveStockSupport",
"SuperAdmin",
"ChainCompany",
"AdminX",
"Supporter",
"Dispenser",
"CityPoultry",
"ParentCompany",
"ColdHouseSteward",
"PosCompany",
];
const liveStockRoles = [
"LiveStockProvinceJahad",
"Union",
"Cooperative",
"Rancher",
];
const isPoultry = userRoles?.some((role) => poultryRoles?.includes(role));
const isLiveStock = userRoles?.some((role) => liveStockRoles?.includes(role));
if (isPoultry && isLiveStock) {
return "Both";
} else if (isPoultry) {
return "Poultry";
} else if (isLiveStock) {
return "LiveStock";
} else {
return "";
}
}
export function getLiveStockRoles(userRoles) {
const liveStockRoles = [
"LiveStockProvinceJahad",
"Union",
"Cooperative",
"Rancher",
];
return userRoles.filter((role) => liveStockRoles.includes(role));
}
export function getBarSquareRoles(userRoles) {
const liveStockRoles = ["BarSquareProvinceJahad"];
return userRoles.filter((role) => liveStockRoles.includes(role));
}
export function getPoultryRoles(userRoles) {
const poultryRoles = [
"CityOperator",
"Poultry",
"ProvinceOperator",
"KillHouse",
"KillHouseVet",
"VetFarm",
"ProvinceFinancial",
"ProvinceInspector",
"VetSupervisor",
"Commerce",
"CityCommerce",
"CityVet",
"CityJahad",
"Observatory",
"ProvinceSupervisor",
"Guilds",
"GuildRoom",
"LiveStockSupport",
"SuperAdmin",
"ChainCompany",
"AdminX",
"Supporter",
"Dispenser",
"CityPoultry",
"ParentCompany",
"ColdHouseSteward",
"PosCompany",
"Steward",
];
return userRoles.filter((role) => poultryRoles.includes(role));
}

8
src/utils/groupBy.js Normal file
View File

@@ -0,0 +1,8 @@
export function groupBy(array, key) {
return array.reduce((hash, obj) => {
if (obj[key] === undefined) return hash;
return Object.assign(hash, {
[obj[key]]: (hash[obj[key]] || []).concat(obj),
});
}, {});
}

View File

@@ -0,0 +1,14 @@
export function isDateOlderThanToday(date) {
// Create a Date object for today's date
var today = new Date();
today.toLocaleString("fa-IR", { timeZone: "Asia/Tehran" });
// Create a Date object for the input date
// Compare the input date with today's date
if (date < today) {
return true; // The input date is older than today
} else {
return false; // The input date is today or a future date
}
}

View File

@@ -0,0 +1,16 @@
export const isValidIndexWeight = (weightRange, age, weight) => {
if (
!Array.isArray(weightRange) ||
typeof age !== "number" ||
typeof weight !== "number"
) {
return false;
}
const range = weightRange.find((r) => age >= r.fromAge && age <= r.toAge);
if (!range) return false;
const maxAllowedWeight = range.toWeight * 1.2;
return weight >= range.fromWeight && weight <= maxAllowedWeight;
};

View File

@@ -0,0 +1,14 @@
export const isValidNationalId = (id) => {
let s = 0;
if (id.toString().length === 10) {
for (let i = 0; i < 10; i++) s = s + String(id).substr(i, 1) * (10 - i);
if (s % 11 === 0) {
return true;
} else {
return false;
}
} else {
return false;
}
};

21
src/utils/jalali.js Normal file
View File

@@ -0,0 +1,21 @@
import { toJalali as toJalaali, toGregorian } from "date-fns-jalali/_jalali";
export const toJalali = (date) => {
const gregorianDate = date instanceof Date ? date : new Date(date);
const jalali = toJalaali(
gregorianDate.getFullYear(),
gregorianDate.getMonth() + 1,
gregorianDate.getDate()
);
return {
jy: jalali.jy,
jm: jalali.jm - 1,
jd: jalali.jd,
};
};
export const fromJalali = (jy, jm, jd) => {
const month = jm >= 1 && jm <= 12 ? jm : jm + 1;
const gregorian = toGregorian(jy, month, jd);
return new Date(gregorian.gy, gregorian.gm - 1, gregorian.gd);
};

19
src/utils/lazyRetry.js Normal file
View File

@@ -0,0 +1,19 @@
export const lazyRetry = function (componentImport) {
return new Promise((resolve, reject) => {
const hasRefreshed = JSON.parse(
window.sessionStorage.getItem("retry-lazy-refreshed") || "false"
);
componentImport()
.then((component) => {
window.sessionStorage.setItem("retry-lazy-refreshed", "false");
resolve(component);
})
.catch((error) => {
if (!hasRefreshed) {
window.sessionStorage.setItem("retry-lazy-refreshed", "true");
return window.location.reload();
}
reject(error);
});
});
};

View File

@@ -0,0 +1,10 @@
export const numberDigitSeperator = (inputNumber) => {
let formetedNumber = Number(inputNumber)
.toFixed(2)
.replace(/\d(?=(\d{3})+\.)/g, "$&,");
let splitArray = formetedNumber.split(".");
if (splitArray.length > 1) {
formetedNumber = splitArray[0];
}
return formetedNumber;
};

38
src/utils/resizeImage.js Normal file
View File

@@ -0,0 +1,38 @@
export const resizeImage = (file, callback) => {
const img = new Image();
img.src = URL.createObjectURL(file);
let width = 1500;
let height = 1500;
img.onload = () => {
// if (width > height) {
// if (width > 3000) {
// height = Math.round(height / 2);
// width = 3000;
// }
// } else {
// if (height > 3000) {
// width = Math.round(width / 2);
// height = 3000;
// }
// }
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob(
(blob) => {
const reader = new FileReader();
reader.onloadend = () => {
callback(reader.result);
};
reader.readAsDataURL(blob);
},
file.type,
0.8
);
};
};

View File

@@ -0,0 +1,7 @@
export const reverseNumbers = (item) => {
const reversedText = item.replace(/\d+/g, (match) => {
return match.split("").reverse().join("");
});
return reversedText;
};

30
src/utils/reverseToRtl.js Normal file
View File

@@ -0,0 +1,30 @@
export function reverseToRtl(text) {
const regex = /(\d+(\.\d+)?)/g;
var reversedDecimal = "";
reversedDecimal = text.replace(regex, (match) => {
if (match.includes(".")) {
const [integerPart, decimalPart] = match.split(".");
return (
decimalPart.split("").reverse().join("") +
"." +
integerPart.split("").reverse().join("")
);
} else {
return match.split("").reverse().join("");
}
});
const datePattern = /\d{4}\/\d{2}\/\d{2}/g;
const finaltext = reversedDecimal.replace(datePattern, (match) => {
const parts = match.split("/");
if (parts.length === 3) {
const [year, month, day] = parts;
return `${day}/${month}/${year}`;
} else {
return match;
}
});
return finaltext;
}

27
src/utils/showSnackbar.js Normal file
View File

@@ -0,0 +1,27 @@
import React from "react";
import ReactDOM from "react-dom";
import Snackbar from "@mui/material/Snackbar";
import MuiAlert from "@mui/material/Alert";
export function showSnackbar(message, severity = "warning") {
const snackbarDiv = document.createElement("div");
document.body.appendChild(snackbarDiv);
const handleClose = () => {
ReactDOM.unmountComponentAtNode(snackbarDiv);
document.body.removeChild(snackbarDiv);
};
ReactDOM.render(
<Snackbar open autoHideDuration={6000} onClose={handleClose}>
<MuiAlert
onClose={handleClose}
severity={severity}
sx={{ width: "100%" }}
>
{message}
</MuiAlert>
</Snackbar>,
snackbarDiv
);
}

35
src/utils/sortRoles.js Normal file
View File

@@ -0,0 +1,35 @@
export const sortRoles = (roles) => {
if (roles) {
const priorityRoles = [
"AdminX",
"SuperAdmin",
"ProvinceOperator",
"LiveStockProvinceJahad",
"Union",
"Cooperative",
"Rancher",
"KillHouse",
"KillHouseVet",
"VetFarm",
"VetSupervisor",
"CityVet",
"ParentCompany",
"Steward",
"Guilds",
"ProvinceSupervisor",
"Commerce",
"PoultryScience",
];
return [...roles].sort((a, b) => {
const aIndex = priorityRoles.indexOf(a);
const bIndex = priorityRoles.indexOf(b);
if (aIndex !== -1 && bIndex !== -1) {
return aIndex - bIndex;
}
if (aIndex !== -1) return -1;
if (bIndex !== -1) return 1;
return a.localeCompare(b);
});
}
return [];
};

View File

@@ -0,0 +1,20 @@
export function stringToColor(string) {
let hash = 0;
let i;
if (string) {
/* eslint-disable no-bitwise */
for (i = 0; i < string.length; i += 1) {
hash = string.charCodeAt(i) + ((hash << 5) - hash);
}
let color = "#";
for (i = 0; i < 3; i += 1) {
const value = (hash >> (i * 8)) & 0xff;
color += `00${value.toString(16)}`.slice(-2);
}
/* eslint-enable no-bitwise */
return color;
}
return "red";
}

31
src/utils/toBase64.js Normal file
View File

@@ -0,0 +1,31 @@
export const toBase64 = async (file) => {
const d = new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
return await d;
};
export const fixBase64 = (base64) => {
return base64.split(",").slice(1)[0];
};
export const urlToBase64 = async (url) => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error("Failed to fetch image: " + response.status);
}
const blob = await response.blob();
const reader = new FileReader();
reader.readAsDataURL(blob);
return new Promise((resolve) => {
reader.onloadend = () => resolve(reader.result);
});
} catch (error) {
console.error("Error converting URL to base64:", error);
throw error; // Rethrow the error to propagate it further
}
};

11
src/utils/toCamelCase.js Normal file
View File

@@ -0,0 +1,11 @@
export function toCamelCase(str) {
return str.replace(/_([a-z])/g, function (match, letter) {
return letter.toUpperCase();
});
}
export function toUnderscore(str) {
return str.replace(/[A-Z]/g, function (match) {
return "_" + match.toLowerCase();
});
}

18
src/utils/toDDHHMMSS.js Normal file
View File

@@ -0,0 +1,18 @@
export const toDDHHMMSS = (secs) => {
const seconds = Number(secs);
var d = Math.floor(seconds / (3600 * 24));
var h = Math.floor((seconds % (3600 * 24)) / 3600);
var m = Math.floor((seconds % 3600) / 60);
// var s = Math.floor(seconds % 60);
// var dDisplay = d > 0 ? d + (d === 1 ? " day, " : " days, ") : "";
// var hDisplay = h > 0 ? h + (h === 1 ? " hour, " : " hours, ") : "";
// var mDisplay = m > 0 ? m + (m === 1 ? " minute, " : " minutes, ") : "";
// var sDisplay = s > 0 ? s + (s === 1 ? " second" : " seconds") : "";
var dDisplay = d > 0 ? d + (d === 1 ? " روز " : " روز ") : "";
var hDisplay = h > 0 ? h + (h === 1 ? " ساعت " : " ساعت ") : "";
var mDisplay = m > 0 ? m + (m === 1 ? " دقیقه " : " دقیقه ") : "";
// var sDisplay = s > 0 ? s + (s === 1 ? " ثانیه " : " ثانیه ") : "";
// return dDisplay + hDisplay + mDisplay + sDisplay;
return dDisplay + hDisplay + mDisplay;
};

11
src/utils/toHHMMSS.js Normal file
View File

@@ -0,0 +1,11 @@
export const toHHMMSS = (secs) => {
var sec_num = parseInt(secs, 10);
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor(sec_num / 60) % 60;
var seconds = sec_num % 60;
return [hours, minutes, seconds]
.map((v) => (v < 10 ? "0" + v : v))
.filter((v, i) => v !== "00" || i > 0)
.join(":");
};

159
src/utils/usageTracker.js Normal file
View File

@@ -0,0 +1,159 @@
/**
* Usage Tracker Utility
* Tracks user clicks on dashboard items and sorts them by usage frequency
*/
const STORAGE_KEY = "dashboard_usage_stats";
/**
* Get all usage statistics from localStorage
* @returns {Object} Usage statistics object
*/
export const getUsageStats = () => {
try {
const stats = localStorage.getItem(STORAGE_KEY);
return stats ? JSON.parse(stats) : {};
} catch (error) {
console.error("Error reading usage stats:", error);
return {};
}
};
/**
* Save usage statistics to localStorage
* @param {Object} stats - Usage statistics object
*/
const saveUsageStats = (stats) => {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(stats));
} catch (error) {
console.error("Error saving usage stats:", error);
}
};
/**
* Get click count for a specific item in a role
* @param {string} role - User role (e.g., 'admix', 'Province')
* @param {string} itemKey - Unique identifier for the item (route or text)
* @returns {number} Click count
*/
export const getItemClickCount = (role, itemKey) => {
const stats = getUsageStats();
return stats[role]?.[itemKey] || 0;
};
/**
* Increment click count for a specific item
* @param {string} role - User role (e.g., 'admix', 'Province')
* @param {string} itemKey - Unique identifier for the item (route or text)
*/
export const trackItemClick = (role, itemKey) => {
const stats = getUsageStats();
// Initialize role object if it doesn't exist
if (!stats[role]) {
stats[role] = {};
}
// Increment click count
stats[role][itemKey] = (stats[role][itemKey] || 0) + 1;
saveUsageStats(stats);
};
/**
* Sort items array by their usage (click count)
* @param {Array} items - Array of items with route or text property
* @param {string} role - User role
* @param {string} keyField - Field to use as key (default: 'route')
* @returns {Array} Sorted items array (most used first)
*/
export const sortItemsByUsage = (items, role, keyField = "route") => {
if (!items || !Array.isArray(items)) return items;
const stats = getUsageStats();
const roleStats = stats[role] || {};
return [...items].sort((a, b) => {
const keyA = a[keyField] || a.text || "";
const keyB = b[keyField] || b.text || "";
const countA = roleStats[keyA] || 0;
const countB = roleStats[keyB] || 0;
// Sort descending (most clicked first)
return countB - countA;
});
};
/**
* Get usage statistics for a specific role
* @param {string} role - User role
* @returns {Object} Usage statistics for the role
*/
export const getRoleUsageStats = (role) => {
const stats = getUsageStats();
return stats[role] || {};
};
/**
* Clear all usage statistics
*/
export const clearUsageStats = () => {
try {
localStorage.removeItem(STORAGE_KEY);
} catch (error) {
console.error("Error clearing usage stats:", error);
}
};
/**
* Clear usage statistics for a specific role
* @param {string} role - User role
*/
export const clearRoleUsageStats = (role) => {
const stats = getUsageStats();
if (stats[role]) {
delete stats[role];
saveUsageStats(stats);
}
};
/**
* Get top N most used items for a role
* @param {string} role - User role
* @param {number} limit - Number of top items to return
* @returns {Array} Array of {itemKey, count} objects
*/
export const getTopUsedItems = (role, limit = 5) => {
const roleStats = getRoleUsageStats(role);
return Object.entries(roleStats)
.map(([itemKey, count]) => ({ itemKey, count }))
.sort((a, b) => b.count - a.count)
.slice(0, limit);
};
/**
* Export usage statistics (for backup or analysis)
* @returns {string} JSON string of all statistics
*/
export const exportUsageStats = () => {
const stats = getUsageStats();
return JSON.stringify(stats, null, 2);
};
/**
* Import usage statistics (from backup)
* @param {string} jsonString - JSON string of statistics
*/
export const importUsageStats = (jsonString) => {
try {
const stats = JSON.parse(jsonString);
saveUsageStats(stats);
return true;
} catch (error) {
console.error("Error importing usage stats:", error);
return false;
}
};