655 lines
17 KiB
JavaScript
655 lines
17 KiB
JavaScript
import { toast } from "react-toastify";
|
||
import Cookies from "js-cookie";
|
||
import moment from "moment-jalaali";
|
||
|
||
// Data
|
||
import specialties from "@/data/specialties.json";
|
||
import states from "@/data/state.json";
|
||
import cities from "@/data/city.json";
|
||
|
||
export const numberToArStyle = (num) => num?.toLocaleString("ar-AE") || "";
|
||
|
||
export const isActiveURL = (link, name) => link === name;
|
||
|
||
export const convertToJalali = (date) => {
|
||
const currentDate = date;
|
||
|
||
const jalaliDate = moment(currentDate).format("jYYYY/jM/jD");
|
||
const jalaliYear = moment(jalaliDate, "jYYYY/jM/jD").jYear();
|
||
const jalaliMonth = moment(jalaliDate, "jYYYY/jM/jD").jMonth() + 1;
|
||
const jalaliDay = moment(jalaliDate, "jYYYY/jM/jD").jDate();
|
||
|
||
return `${jalaliYear}/${jalaliMonth}/${jalaliDay}`;
|
||
};
|
||
|
||
export const handleTwoLength = (value) =>
|
||
String(value).length === 1 ? `0${value}` : value;
|
||
|
||
export const checkAllValues = (data) => {
|
||
for (let key in data) {
|
||
const item = data[key];
|
||
|
||
if (typeof item === "object" && item !== null) {
|
||
if ("value" in item) {
|
||
if (!item.value) {
|
||
return false;
|
||
}
|
||
} else {
|
||
if (!checkAllValues(item)) {
|
||
return false;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
export const checkTimes = (arr) => {
|
||
return arr.map((day) => {
|
||
const hasMorningTime = day.morning_time.some((time) => time !== "");
|
||
const hasEveningTime = day.evening_time.some((time) => time !== "");
|
||
return hasMorningTime && hasEveningTime;
|
||
});
|
||
};
|
||
|
||
export const uploadImage = async (event) => {
|
||
let obj = {
|
||
file: "",
|
||
blob: "",
|
||
};
|
||
|
||
const file = event.target.files[0];
|
||
if (file) {
|
||
obj.file = file;
|
||
const readFileAsDataURL = (file) => {
|
||
return new Promise((resolve, reject) => {
|
||
const reader = new FileReader();
|
||
|
||
reader.onload = () => resolve(reader.result);
|
||
|
||
reader.onerror = (error) => reject(error);
|
||
|
||
reader.readAsDataURL(file);
|
||
});
|
||
};
|
||
try {
|
||
obj.blob = await readFileAsDataURL(file);
|
||
return obj;
|
||
} catch (error) {
|
||
console.error("Error reading file: ", error);
|
||
throw error;
|
||
}
|
||
} else {
|
||
throw new Error("No file selected");
|
||
}
|
||
};
|
||
|
||
export const alert = (type, text, prop) => {
|
||
toast[type](
|
||
<div className="h-full w-full flex flex-col items-start justify-center gap-[13px]">
|
||
<p className="text-[14px] font-medium">
|
||
پیغام{" "}
|
||
{type === "error"
|
||
? "خطا"
|
||
: type === "warning"
|
||
? "هشدار"
|
||
: type === "info"
|
||
? "اعلام"
|
||
: "موفقیت"}
|
||
</p>
|
||
<p className="text-[14px] font-normal">{text}</p>
|
||
</div>,
|
||
{ prop }
|
||
);
|
||
};
|
||
|
||
export const formatPhoneNumber = (input) => {
|
||
if (typeof input !== "string") input = String(input);
|
||
|
||
const normalized = input
|
||
.replace(/[\u06F0-\u06F9]/g, (d) => String(d.charCodeAt(0) - 0x06f0))
|
||
.replace(/[\u0660-\u0669]/g, (d) => String(d.charCodeAt(0) - 0x0660));
|
||
|
||
const digits = normalized.replace(/\D/g, "");
|
||
|
||
const trimmed = digits.substring(0, 9);
|
||
|
||
const match = trimmed.match(/^(\d{0,2})(\d{0,3})(\d{0,4})$/);
|
||
if (!match) return trimmed;
|
||
|
||
return [match[1], match[2], match[3]].filter(Boolean).join(" ");
|
||
};
|
||
|
||
export function validatePhoneNumber(input) {
|
||
if (!input) {
|
||
return { valid: false, text: "شماره موبایل نمیتواند خالی باشد." };
|
||
}
|
||
|
||
if (input.length !== 11) {
|
||
return { valid: false, text: "شماره موبایل باید دقیقا 11 رقم باشد." };
|
||
}
|
||
|
||
const isValid = /^09\d{9}$/.test(input);
|
||
if (!isValid) {
|
||
return { valid: false, text: "شماره موبایل نامعتبر است." };
|
||
}
|
||
|
||
return { valid: true, text: null };
|
||
}
|
||
|
||
export const searchOnList = (list, value, name) => {
|
||
let newList = list;
|
||
newList = list.filter((item) => item[name]?.toLowerCase()?.includes(value));
|
||
return newList;
|
||
};
|
||
|
||
export function clearFilterParams(router, listRemove) {
|
||
const currentParams = new URLSearchParams(window.location.search);
|
||
const keysToRemove = listRemove;
|
||
keysToRemove.forEach((key) => currentParams.delete(key));
|
||
const queryString = currentParams.toString();
|
||
const newUrl = queryString ? `/doctors?${queryString}` : "/doctors";
|
||
|
||
router.push(newUrl);
|
||
}
|
||
export function clearDoctorClinicParams(router,slug){
|
||
|
||
const clinicslug=slug;
|
||
const newUrl = `/clinic/${clinicslug}`;
|
||
router.push(newUrl)
|
||
}
|
||
export const filterList = (data) => {
|
||
const parentList = specialties.filter((item) => !item.parent);
|
||
const childrenList = specialties.filter((item) => item.parent);
|
||
|
||
const filteredChildrenList =
|
||
data && data.category
|
||
? childrenList.filter((item) => item.parent === data.category.id)
|
||
: [];
|
||
|
||
return {
|
||
parentList: parentList,
|
||
childrenList: filteredChildrenList,
|
||
};
|
||
};
|
||
|
||
export function getCleanNumberValue(value, defaultValue = 0) {
|
||
if (typeof value !== "string") value = String(value);
|
||
|
||
const persianArabicToEnglish = value
|
||
.replace(/[\u06F0-\u06F9]/g, (d) => String(d.charCodeAt(0) - 0x06f0))
|
||
.replace(/[\u0660-\u0669]/g, (d) => String(d.charCodeAt(0) - 0x0660));
|
||
|
||
const cleaned = persianArabicToEnglish.replace(/[^0-9.]/g, "");
|
||
|
||
const number = parseFloat(cleaned);
|
||
return isNaN(number) ? defaultValue : number;
|
||
}
|
||
|
||
export function hasDataChanged(previousData, newData) {
|
||
const oldDataString = JSON.stringify(
|
||
previousData,
|
||
Object.keys(previousData).sort()
|
||
);
|
||
const newDataString = JSON.stringify(newData, Object.keys(newData).sort());
|
||
return oldDataString !== newDataString;
|
||
}
|
||
|
||
export const getParsedUserInfo = () => {
|
||
const user = Cookies.get("userInfo");
|
||
const parsedUserInfo = user && JSON.parse(user);
|
||
return parsedUserInfo;
|
||
};
|
||
|
||
export const handleTimeExpiresToken = (expires_in) => {
|
||
const accessTokenExpires = new Date();
|
||
accessTokenExpires.setSeconds(accessTokenExpires.getSeconds() + expires_in);
|
||
const refreshTokenExpires = new Date();
|
||
refreshTokenExpires.setDate(refreshTokenExpires.getDate() + 30);
|
||
|
||
return {
|
||
accessTokenExpires,
|
||
refreshTokenExpires,
|
||
};
|
||
};
|
||
|
||
export const removeAdditionalKeysDashboard = (information) => {
|
||
const {
|
||
national_code,
|
||
changed,
|
||
created,
|
||
id,
|
||
status,
|
||
prev_data,
|
||
uuid,
|
||
...usedKays
|
||
} = information;
|
||
|
||
return usedKays;
|
||
};
|
||
|
||
export const changeDateType = (data, toTimeStamp) => {
|
||
const newData = { ...data };
|
||
const birthday = newData.birthday;
|
||
|
||
if (toTimeStamp) {
|
||
const m = moment(birthday, "jYYYY/jMM/jDD");
|
||
newData.birthday = m.unix();
|
||
} else {
|
||
newData.birthday = moment.unix(birthday).format("jYYYY/jMM/jDD");
|
||
}
|
||
return newData;
|
||
};
|
||
|
||
export const removeTokenHead = {
|
||
headers: {
|
||
Authorization: "",
|
||
},
|
||
};
|
||
|
||
export const dateToTimestamp = (date) => {
|
||
const gregorianMoment = date.clone().locale("fa");
|
||
|
||
// Get the Unix timestamp in milliseconds
|
||
const unixTimestamp = gregorianMoment.valueOf();
|
||
|
||
const inSeconde = unixTimestamp / 1000;
|
||
|
||
return inSeconde;
|
||
};
|
||
|
||
export const degreeVal = [
|
||
{ name: "پزشک عمومی", val: "general" },
|
||
{ name: "پزشک متخصص", val: "specialist" },
|
||
{ name: "پزشک فوق تخصص", val: "subspecialistplus" },
|
||
];
|
||
|
||
export const addLabelToList = (list) =>
|
||
list.map((item) => {
|
||
return {
|
||
...item,
|
||
label: item.name,
|
||
};
|
||
});
|
||
|
||
export const QueryForDoctorsFilter = (newFilter) => {
|
||
const query = {};
|
||
|
||
// 🔹 active => only when value === 1
|
||
if (newFilter.active === 1) {
|
||
query.active = 1;
|
||
}
|
||
|
||
// 🔹 specialty or category
|
||
|
||
if (newFilter.specialty) {
|
||
query.specialty = newFilter.specialty.name;
|
||
} else if (newFilter.category) {
|
||
query.specialty = newFilter.category.name;
|
||
}
|
||
|
||
// 🔹 city
|
||
if (newFilter.city) {
|
||
query.city = newFilter.city.name;
|
||
}
|
||
|
||
// 🔹 state
|
||
if (newFilter.state) {
|
||
query.state = newFilter.state.name;
|
||
}
|
||
|
||
// 🔹 degree (only if not "همه موارد")
|
||
if (newFilter.degree && newFilter.degree !== "همه موارد") {
|
||
query.degree = newFilter.degree;
|
||
}
|
||
|
||
// 🔹 gender (only if not "هر دو")
|
||
if (newFilter.gender && newFilter.gender !== "هر دو") {
|
||
query.gender = newFilter.gender;
|
||
}
|
||
|
||
// 🔹 name (only if has value)
|
||
if (newFilter.name && newFilter.name.trim() !== "") {
|
||
query.name = newFilter.name;
|
||
}
|
||
|
||
// 🔹 sort => only if value is 3,4,5
|
||
if ([3, 4, 5].includes(Number(newFilter.sort))) {
|
||
// query.sort = newFilter.sort === 3 ? "ASC" : "DESC";
|
||
query.sort = newFilter.sort;
|
||
}
|
||
|
||
return query;
|
||
};
|
||
export const QueryForClinicDoctorFilter=(newFilter)=>{
|
||
const query = {};
|
||
|
||
// 🔹 active => only when value === 1
|
||
if (newFilter.active === 1) {
|
||
query.active = 1;
|
||
}
|
||
|
||
// 🔹 specialty or category
|
||
|
||
if (newFilter.specialty) {
|
||
query.specialty = newFilter.specialty.name;
|
||
} else if (newFilter.category) {
|
||
query.specialty = newFilter.category.name;
|
||
}
|
||
|
||
// 🔹 degree (only if not "همه موارد")
|
||
if (newFilter.degree && newFilter.degree !== "همه موارد") {
|
||
query.degree = newFilter.degree;
|
||
}
|
||
|
||
// 🔹 gender (only if not "هر دو")
|
||
if (newFilter.gender && newFilter.gender !== "هر دو") {
|
||
query.gender = newFilter.gender;
|
||
}
|
||
|
||
// 🔹 name (only if has value)
|
||
if (newFilter.name && newFilter.name.trim() !== "") {
|
||
query.name = newFilter.name;
|
||
}
|
||
|
||
// 🔹 sort => only if value is 3,4,5
|
||
if ([3, 4, 5].includes(Number(newFilter.sort))) {
|
||
// query.sort = newFilter.sort === 3 ? "ASC" : "DESC";
|
||
query.sort = newFilter.sort;
|
||
}
|
||
|
||
return query;
|
||
}
|
||
export const QueryForDoctorsReq = (newFilter) => {
|
||
const params = {};
|
||
|
||
if (newFilter.active === 1) params.active = 1;
|
||
|
||
if (newFilter.specialty?.id) {
|
||
params.specialty = newFilter.specialty.id;
|
||
} else if (newFilter.category?.id) {
|
||
params.specialty = newFilter.category.id;
|
||
}
|
||
|
||
if (newFilter.city?.id) params.city = newFilter.city.id;
|
||
if (newFilter.state?.id) params.state = newFilter.state.id;
|
||
|
||
if (newFilter.degree && newFilter.degree !== "همه موارد")
|
||
switch (newFilter.degree) {
|
||
case "کارشناس":
|
||
params.degree = "expert";
|
||
break;
|
||
case "پزشک عمومی":
|
||
params.degree = "general";
|
||
break;
|
||
case "پزشک متخصص":
|
||
params.degree = "specialist";
|
||
break;
|
||
case "پزشک فوق تخصص":
|
||
params.degree = "subspecialistplus";
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (newFilter.gender && newFilter.gender !== "هر دو")
|
||
params.gender = newFilter.gender === "مرد" ? "man" : "woman";
|
||
|
||
if (newFilter.name) params.name = newFilter.name;
|
||
|
||
if (newFilter.sort) {
|
||
if (newFilter.sort === 3) params.sort = "ASC";
|
||
else if (newFilter.sort === 4 || newFilter.sort === 5) params.sort = "DESC";
|
||
}
|
||
|
||
return params;
|
||
};
|
||
export const QueryForDoctorsClinicReq=(newFilter)=>{
|
||
const params = {};
|
||
|
||
if (newFilter.active === 1) params.active = 1;
|
||
|
||
if (newFilter.specialty?.id) {
|
||
params.specialty = newFilter.specialty.id;
|
||
} else if (newFilter.category?.id) {
|
||
params.specialty = newFilter.category.id;
|
||
}
|
||
|
||
if (newFilter.degree && newFilter.degree !== "همه موارد")
|
||
switch (newFilter.degree) {
|
||
case "کارشناس":
|
||
params.degree = "expert";
|
||
break;
|
||
case "پزشک عمومی":
|
||
params.degree = "general";
|
||
break;
|
||
case "پزشک متخصص":
|
||
params.degree = "specialist";
|
||
break;
|
||
case "پزشک فوق تخصص":
|
||
params.degree = "subspecialistplus";
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
if (newFilter.gender && newFilter.gender !== "هر دو")
|
||
params.gender = newFilter.gender === "مرد" ? "man" : "woman";
|
||
|
||
if (newFilter.name) params.name = newFilter.name;
|
||
|
||
if (newFilter.sort) {
|
||
if (newFilter.sort === 3) params.sort = "ASC";
|
||
else if (newFilter.sort === 4 || newFilter.sort === 5) params.sort = "DESC";
|
||
}
|
||
|
||
return params;
|
||
}
|
||
export const buildDoctorParams = (searchParams) => {
|
||
const params = {};
|
||
|
||
// 🔹 active
|
||
if (searchParams.active && Number(searchParams.active) === 1) {
|
||
params.active = 1;
|
||
}
|
||
|
||
// 🔹 specialty (find by name in specialties.json)
|
||
if (searchParams.specialty) {
|
||
const spec = specialties.find((s) => s.name === searchParams.specialty);
|
||
if (spec) {
|
||
params.specialty = spec.id;
|
||
}
|
||
}
|
||
|
||
// 🔹 city (find by name in city.json)
|
||
if (searchParams.city) {
|
||
const cityObj = cities.find((c) => c.name === searchParams.city);
|
||
if (cityObj) {
|
||
params.city = cityObj.id;
|
||
}
|
||
}
|
||
|
||
// 🔹 state (find by name in state.json)
|
||
if (searchParams.state) {
|
||
const stateObj = states.find((s) => s.name === searchParams.state);
|
||
if (stateObj) {
|
||
params.state = stateObj.id;
|
||
}
|
||
}
|
||
|
||
// 🔹 degree → convert fa → en
|
||
if (searchParams.degree) {
|
||
switch (searchParams.degree) {
|
||
case "کارشناس":
|
||
params.degree = "expert";
|
||
break;
|
||
case "پزشک عمومی":
|
||
params.degree = "general";
|
||
break;
|
||
case "پزشک متخصص":
|
||
params.degree = "specialist";
|
||
break;
|
||
case "پزشک فوق تخصص":
|
||
params.degree = "subspecialistplus";
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 🔹 gender
|
||
if (searchParams.gender) {
|
||
if (searchParams.gender === "مرد") params.gender = "man";
|
||
if (searchParams.gender === "زن") params.gender = "woman";
|
||
}
|
||
|
||
// 🔹 name
|
||
if (searchParams.name) {
|
||
params.name = searchParams.name;
|
||
}
|
||
|
||
// 🔹 sort (3 = ASC, 4|5 = DESC)
|
||
if (searchParams.sort) {
|
||
const sortNum = Number(searchParams.sort);
|
||
if (sortNum === 3) params.sort = "ASC";
|
||
else if ([4, 5].includes(sortNum)) params.sort = "DESC";
|
||
}
|
||
|
||
// 🔹 page
|
||
params.page = searchParams.page || 1;
|
||
|
||
// 🔹 limit
|
||
params.limit = 12;
|
||
|
||
return params;
|
||
};
|
||
|
||
export const QueryForClinicsFilter = (searchParams) => {
|
||
const params = {};
|
||
|
||
// 🔹 specialty (find by name in specialties.json)
|
||
if (searchParams.specialty) {
|
||
const spec = specialties.find((s) => s.name === searchParams.specialty);
|
||
if (spec) {
|
||
params.specialty = spec.id;
|
||
}
|
||
}
|
||
|
||
// 🔹 city (find by name in city.json)
|
||
if (searchParams.city) {
|
||
const cityObj = cities.find((c) => c.name === searchParams.city.name);
|
||
if (cityObj) {
|
||
params.city = cityObj.id;
|
||
}
|
||
}
|
||
|
||
// 🔹 state (find by name in state.json)
|
||
if (searchParams.province) {
|
||
const stateObj = states.find((s) => s.name === searchParams.province.name);
|
||
if (stateObj) {
|
||
params.state = stateObj.id;
|
||
}
|
||
}
|
||
|
||
// 🔹 page
|
||
params.page = searchParams.page || 1;
|
||
|
||
// 🔹 limit
|
||
params.limit = 12;
|
||
|
||
return params;
|
||
};
|
||
|
||
export const buildClinicParams = (searchParams) => {
|
||
const params = {};
|
||
|
||
// 🔹 city (find by name in city.json)
|
||
if (searchParams.city) {
|
||
const cityObj = cities.find((c) => c.name === searchParams.city);
|
||
if (cityObj) {
|
||
params.city = cityObj.id;
|
||
}
|
||
}
|
||
|
||
// 🔹 state (find by name in state.json)
|
||
if (searchParams.state) {
|
||
const stateObj = states.find((s) => s.name === searchParams.state);
|
||
if (stateObj) {
|
||
params.state = stateObj.id;
|
||
}
|
||
}
|
||
|
||
// 🔹 specialty (find by name in specialties.json)
|
||
if (searchParams.specialty) {
|
||
const spec = specialties.find((s) => s.name === searchParams.specialty);
|
||
if (spec) {
|
||
params.specialty = spec.id;
|
||
}
|
||
}
|
||
|
||
// 🔹 page
|
||
params.page = searchParams.page || 1;
|
||
|
||
// 🔹 limit
|
||
params.limit = 12;
|
||
|
||
return params;
|
||
};
|
||
|
||
export function timeAgo(timestamp) {
|
||
const now = moment();
|
||
const then = moment.unix(timestamp);
|
||
const diffSeconds = now.diff(then, "seconds");
|
||
|
||
if (diffSeconds < 60) {
|
||
return diffSeconds === 0 ? "همین الان" : `${diffSeconds} ثانیه پیش`;
|
||
} else if (diffSeconds < 3600) {
|
||
const minutes = Math.floor(diffSeconds / 60);
|
||
return `${minutes} دقیقه پیش`;
|
||
} else if (diffSeconds < 86400) {
|
||
const hours = Math.floor(diffSeconds / 3600);
|
||
return `${hours} ساعت پیش`;
|
||
} else if (diffSeconds < 2592000) {
|
||
const days = Math.floor(diffSeconds / 86400);
|
||
return `${days} روز پیش`;
|
||
} else if (diffSeconds < 31104000) {
|
||
const months = Math.floor(diffSeconds / 2592000);
|
||
return `${months} ماه پیش`;
|
||
} else {
|
||
const years = Math.floor(diffSeconds / 31104000);
|
||
return `${years} سال پیش`;
|
||
}
|
||
}
|
||
|
||
export function isUserLoggedIn() {
|
||
const userInfo = Cookies.get("access_token");
|
||
return !!userInfo;
|
||
}
|
||
|
||
export function convertTimestampToPersianDateSimple(timestamp) {
|
||
const date = new Date(timestamp * 1000);
|
||
|
||
const options = {
|
||
timeZone: "Asia/Tehran",
|
||
calendar: "persian",
|
||
year: "numeric",
|
||
month: "2-digit",
|
||
day: "2-digit",
|
||
weekday: "long",
|
||
hour: "2-digit",
|
||
minute: "2-digit",
|
||
second: "2-digit",
|
||
hour12: true,
|
||
};
|
||
|
||
return date.toLocaleString("fa-IR", options);
|
||
}
|
||
export function changeNumToDefault(str) {
|
||
if (!str) return "";
|
||
return str
|
||
.toString()
|
||
.replace(/[۰-۹]/g, d => "۰۱۲۳۴۵۶۷۸۹".indexOf(d))
|
||
.replace(/[٠-٩]/g, d => "٠١٢٣٤٥٦٧٨٩".indexOf(d));
|
||
}
|