email plus return item statuses
This commit is contained in:
@@ -52,18 +52,6 @@ export const resetCSRFToken = () => {
|
||||
csrfToken = null;
|
||||
};
|
||||
|
||||
// Check if authentication cookie exists
|
||||
export const hasAuthCookie = (): boolean => {
|
||||
return document.cookie
|
||||
.split("; ")
|
||||
.some((cookie) => cookie.startsWith("accessToken="));
|
||||
};
|
||||
|
||||
// Check if user has any auth indicators
|
||||
export const hasAuthIndicators = (): boolean => {
|
||||
return hasAuthCookie();
|
||||
};
|
||||
|
||||
api.interceptors.request.use(async (config) => {
|
||||
// Add CSRF token to headers for state-changing requests
|
||||
const method = config.method?.toUpperCase() || "";
|
||||
@@ -119,14 +107,14 @@ api.interceptors.response.use(
|
||||
if (error.response?.status === 401) {
|
||||
const errorData = error.response?.data as any;
|
||||
|
||||
// Don't redirect for NO_TOKEN on public endpoints
|
||||
if (errorData?.code === "NO_TOKEN") {
|
||||
// Let the app handle this - user simply isn't logged in
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
// If token is expired, try to refresh
|
||||
if (errorData?.code === "TOKEN_EXPIRED" && !originalRequest._retry) {
|
||||
// Try to refresh for token errors
|
||||
// Note: We can't check refresh token from JS (httpOnly cookies)
|
||||
// The backend will determine if refresh is possible
|
||||
if (
|
||||
(errorData?.code === "TOKEN_EXPIRED" ||
|
||||
errorData?.code === "NO_TOKEN") &&
|
||||
!originalRequest._retry
|
||||
) {
|
||||
if (isRefreshing) {
|
||||
// If already refreshing, queue the request
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -152,18 +140,10 @@ api.interceptors.response.use(
|
||||
isRefreshing = false;
|
||||
processQueue(refreshError as AxiosError);
|
||||
|
||||
// Refresh failed, redirect to login
|
||||
window.location.href = "/login";
|
||||
// Refresh failed - let React Router handle redirects via PrivateRoute
|
||||
return Promise.reject(refreshError);
|
||||
}
|
||||
}
|
||||
|
||||
// For other 401 errors, check if we should redirect
|
||||
// Only redirect if this is not a login/register request
|
||||
const isAuthEndpoint = originalRequest.url?.includes("/auth/");
|
||||
if (!isAuthEndpoint && errorData?.error !== "Access token required") {
|
||||
window.location.href = "/login";
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
@@ -223,8 +203,19 @@ export const rentalAPI = {
|
||||
reviewItem: (id: string, data: any) =>
|
||||
api.post(`/rentals/${id}/review-item`, data),
|
||||
getRefundPreview: (id: string) => api.get(`/rentals/${id}/refund-preview`),
|
||||
getLateFeePreview: (id: string, actualReturnDateTime: string) =>
|
||||
api.get(`/rentals/${id}/late-fee-preview`, {
|
||||
params: { actualReturnDateTime },
|
||||
}),
|
||||
cancelRental: (id: string, reason?: string) =>
|
||||
api.post(`/rentals/${id}/cancel`, { reason }),
|
||||
// Return status marking
|
||||
markReturn: (
|
||||
id: string,
|
||||
data: { status: string; actualReturnDateTime?: string; notes?: string }
|
||||
) => api.post(`/rentals/${id}/mark-return`, data),
|
||||
reportDamage: (id: string, data: any) =>
|
||||
api.post(`/rentals/${id}/report-damage`, data),
|
||||
};
|
||||
|
||||
export const messageAPI = {
|
||||
@@ -277,4 +268,35 @@ export const mapsAPI = {
|
||||
getHealth: () => api.get("/maps/health"),
|
||||
};
|
||||
|
||||
export const conditionCheckAPI = {
|
||||
submitConditionCheck: (rentalId: string, formData: FormData) =>
|
||||
api.post(`/condition-checks/${rentalId}`, formData, {
|
||||
headers: { "Content-Type": "multipart/form-data" },
|
||||
}),
|
||||
getConditionChecks: (rentalId: string) =>
|
||||
api.get(`/condition-checks/${rentalId}`),
|
||||
getConditionCheckTimeline: (rentalId: string) =>
|
||||
api.get(`/condition-checks/${rentalId}/timeline`),
|
||||
getAvailableChecks: () => api.get("/condition-checks"),
|
||||
};
|
||||
|
||||
export const notificationAPI = {
|
||||
getNotifications: (params?: { limit?: number; page?: number }) =>
|
||||
api.get("/notifications", { params }),
|
||||
getUnreadCount: () => api.get("/notifications/unread-count"),
|
||||
markAsRead: (notificationId: string) =>
|
||||
api.patch(`/notifications/${notificationId}/read`),
|
||||
markAllAsRead: () => api.patch("/notifications/mark-all-read"),
|
||||
// Development endpoints
|
||||
createTestNotification: (data: {
|
||||
type?: string;
|
||||
title: string;
|
||||
message: string;
|
||||
metadata?: any;
|
||||
}) => api.post("/notifications/test", data),
|
||||
triggerConditionReminders: () =>
|
||||
api.post("/notifications/test/condition-reminders"),
|
||||
cleanupExpired: () => api.post("/notifications/test/cleanup-expired"),
|
||||
};
|
||||
|
||||
export default api;
|
||||
|
||||
Reference in New Issue
Block a user