CoffeeJoo_Panel_kafeDar/services/api/base-api.js

131 lines
4.8 KiB
JavaScript

import axios from "axios";
import { store } from "../../redux/store";
import { showLoading, hideLoading } from "../../redux/slices/loadingSlice";
import { clearToken } from "../../redux/slices/authSlice";
import { clearProfile } from "../../redux/slices/profileSlice";
import { showToast } from "../../redux/slices/toastSlice";
import { toastIgnore } from "./toastIgnore";
const BASE_URL = 'https://cafeju.maksiran.ir/api';
const TIMEOUT = 600000;
axios.defaults.baseURL = BASE_URL;
axios.defaults.timeout = TIMEOUT;
// Helpers
const isMutatingMethod = (method) => ["post", "put", "delete", "patch"].includes(method?.toLowerCase());
const extractMessage = (obj) =>
obj?.response?.data?.data?.message ||
obj?.data?.data?.message ||
obj?.message ||
obj?.data?.message ||
obj?.response?.data?.message ||
obj?.response?.message ||
"خطایی رخ داده است!";
const getErrorMessageByStatus = (status, data) => {
switch (status) {
case 400: return data?.message || "درخواست نامعتبر است";
case 401: return data?.message || "نشست شما منقضی شده، مجدد وارد شوید";
case 403: return data?.message || "دسترسی شما محدود شده است";
case 404: return data?.message || "صفحه یا اطلاعات درخواستی یافت نشد";
case 422: return data?.message || "اطلاعات ارسالی نامعتبر است";
case 429: return data?.message || "تعداد درخواست‌ها زیاد است، کمی صبر کنید";
case 500: return data?.message || "خطای داخلی سرور، لطفاً بعداً تلاش کنید";
case 502:
case 503: return data?.message || "سرور در حال حاضر در دسترس نیست";
case 504: return data?.message || "سرور پاسخ نداد، دوباره تلاش کنید";
default: return data?.message || `خطای غیرمنتظره (کد: ${status})`;
}
};
// Request Interceptor
axios.interceptors.request.use(
(config) => {
const token = localStorage.getItem("token");
if (token) config.headers.Authorization = `Bearer ${token}`;
store.dispatch(showLoading());
return config;
},
(error) => {
store.dispatch(hideLoading());
return Promise.reject(error);
}
);
// Response Interceptor
axios.interceptors.response.use(
(response) => {
try {
const method = response.config.method;
const url = response.config.url;
if (!toastIgnore.some(u => url.includes(u)) && isMutatingMethod(method)) {
const message = extractMessage(response) || "عملیات با موفقیت انجام شد";
store.dispatch(showToast({ type: "success", message }));
}
} catch (e) {
console.error("toast response error:", e);
} finally {
store.dispatch(hideLoading());
}
return response;
},
(error) => {
store.dispatch(hideLoading());
if (!error.response) {
const networkMessage = error.message.includes("Network Error")
? "لطفا اتصال اینترنت خود را بررسی کنید"
: error.message.includes("timeout")
? "مهلت زمانی درخواست تمام شد، دوباره تلاش کنید"
: "خطا در برقراری ارتباط با سرور";
store.dispatch(showToast({ message: networkMessage, type: "error" }));
return Promise.reject(error);
}
const { status, data } = error.response;
const url = error.config?.url || "";
// برای خطاهای 401 و 403: فورا توکن پاک شود
if ([401, 403].includes(status)) {
store.dispatch(clearToken());
store.dispatch(clearProfile());
// redirect به login اگر در protected route هستیم
if (typeof window !== "undefined") {
const currentPath = window.location.pathname;
const publicRoutes = ["/login", "/register", "/"];
const isPublicRoute = publicRoutes.some(route => currentPath.startsWith(route));
if (!isPublicRoute) {
window.location.href = "/login";
}
}
}
if (!toastIgnore.some(u => url.includes(u))) {
const message = getErrorMessageByStatus(status, data);
store.dispatch(showToast({ type: "error", message }));
}
return Promise.reject(error);
}
);
// Request Wrappers
const requests = {
get: (url) => axios.get(url),
getByParams: (url, params) => axios.get(url, { params }),
post: (url, body) => axios.post(url, body),
put: (url, body) => axios.put(url, body),
patch: (url, body) => axios.patch(url, body),
delete: (url) => axios.delete(url),
postFormData: (url, formData) =>
axios.post(url, formData, { headers: { "Content-Type": "multipart/form-data" } }),
putMedia: (url, body) =>
axios.put(url, body, { headers: { "Content-Type": "application/x-www-form-urlencoded" } }),
};
export default requests;