Software: Apache. PHP/8.1.30 uname -a: Linux server1.tuhinhossain.com 5.15.0-163-generic #173-Ubuntu SMP Tue Oct 14 17:51:00 UTC uid=1002(picotech) gid=1003(picotech) groups=1003(picotech),0(root) Safe-mode: OFF (not secure) /home/picotech/domains/rentals.picotech.app/public_html/src/services/ drwxr-xr-x | |
| Viewing file: Select action/file-type: import axios from 'axios';
const API_BASE_URL = '/api';
// CSRF Token management
let csrfToken = null;
// Fetch CSRF token
const fetchCsrfToken = async () => {
try {
const response = await axios.get(`${API_BASE_URL}/csrf-token`, {
withCredentials: true
});
csrfToken = response.data.csrfToken;
return csrfToken;
} catch (error) {
console.error('Failed to fetch CSRF token:', error);
return null;
}
};
// Initialize CSRF token
fetchCsrfToken();
// Create axios instance
const api = axios.create({
baseURL: API_BASE_URL,
headers: {
'Content-Type': 'application/json',
},
withCredentials: true, // Important for CSRF cookies
});
// Add auth token and CSRF token to requests
api.interceptors.request.use(
async (config) => {
// Add auth token
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
// Add CSRF token for state-changing methods
const methodsNeedingCsrf = ['post', 'put', 'delete', 'patch'];
if (methodsNeedingCsrf.includes(config.method.toLowerCase())) {
// Get CSRF token (fetch if not available)
if (!csrfToken) {
await fetchCsrfToken();
}
if (csrfToken) {
config.headers['X-CSRF-Token'] = csrfToken;
}
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// Handle auth errors and CSRF errors
api.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
// Handle 403 CSRF errors - refetch token and retry
if (error.response?.status === 403 && error.response?.data?.message === 'Invalid CSRF token') {
if (!originalRequest._retry) {
originalRequest._retry = true;
// Refetch CSRF token
await fetchCsrfToken();
// Retry the request with new token
if (csrfToken) {
originalRequest.headers['X-CSRF-Token'] = csrfToken;
return api(originalRequest);
}
}
}
// Handle 401 auth errors
if (error.response?.status === 401) {
localStorage.removeItem('token');
localStorage.removeItem('user');
// window.location.href = '/login';
}
return Promise.reject(error);
}
);
// Auth API
export const authAPI = {
login: (credentials) => api.post('/auth/login', credentials),
getMe: () => api.get('/auth/me'),
changePassword: (data) => api.put('/auth/change-password', data),
request: () => api.get('/request'),
};
// Users API
export const usersAPI = {
getAll: () => api.get('/users'),
create: (data) => api.post('/users', data),
// update: (id, data) => api.put(`/users/${id}`, data),
update: (id, data) =>
api.put(`/users/${id}`, data, {
headers: {
'Content-Type': 'multipart/form-data',
},
}),
delete: (id) => api.delete(`/users/${id}`),
toggleStatus: (id) => api.patch(`/users/${id}/toggle-status`),
getAllActivity: () => api.get('/users/activity'),
};
// Buildings API
export const buildingsAPI = {
getAll: () => api.get('/buildings'),
getById: (id) => api.get(`/buildings/${id}`),
// create: (data) => api.post('/buildings', data),
// update: (id, data) => api.put(`/buildings/${id}`, data),
create: (data) =>
api.post('/buildings', data, {
headers: {
'Content-Type': 'multipart/form-data',
},
}),
update: (id, data) =>
api.put(`/buildings/${id}`, data, {
headers: {
'Content-Type': 'multipart/form-data',
},
}),
delete: (id) => api.delete(`/buildings/${id}`),
};
// Floor API
export const floorsAPI = {
getAll: () => api.get('/floors'),
getById: (id) => api.get(`/floors/${id}`),
create: (data) => api.post('/floors', data),
update: (id, data) => api.put(`/floors/${id}`, data),
delete: (id) => api.delete(`/floors/${id}`),
getBybuildId: (building_id) => api.get(`/floors`, { params: { building_id } })
};
// Room API
export const roomsAPI = {
getAll: () => api.get('/rooms'),
getById: (id) => api.get(`/rooms/${id}`),
create: (data) => api.post('/rooms', data),
update: (id, data) => api.put(`/rooms/${id}`, data),
delete: (id) => api.delete(`/rooms/${id}`),
};
// Bed API
export const bedsAPI = {
getAll: () => api.get('/beds'),
getById: (id) => api.get(`/beds/${id}`),
create: (data) => api.post('/beds', data),
update: (id, data) => api.put(`/beds/${id}`, data),
delete: (id) => api.delete(`/beds/${id}`),
};
// Renter API
export const rentersAPI = {
getAll: () => api.get('/renters'),
getById: (id) => api.get(`/renters/${id}`),
// create: (data) => api.post('/renters', data),
create: async (data) => {
const formData = new FormData();
// Append all simple fields (non-object/non-array)
Object.entries(data).forEach(([key, value]) => {
if (
value !== null &&
value !== undefined &&
typeof value !== 'object' // skip objects and arrays here (we handle later)
) {
formData.append(key, value);
}
});
// Append nested objects that need special handling, e.g.:
// preferences object -> stringify it
if (data.preferences) {
formData.append('preferences', JSON.stringify(data.preferences));
}
// Append files from documents array (assuming documents have file objects)
await appendDocumentsToFormData(formData, data.documents || []);
// If you want to send the entire documents array as JSON (no files),
// you could do formData.append('documents', JSON.stringify(data.documents));
return api.post('/renters', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
},
update: (id, data) => api.put(`/renters/${id}`, data),
delete: (id) => api.delete(`/renters/${id}`),
};
// Renter API
export const rentPaymentsAPI = {
getAll: () => api.get('/rents'),
getById: (id) => api.get(`/rents/${id}`),
create: (data) => api.post('/rents', data),
update: (id, data) => api.put(`/rents/${id}`, data),
delete: (id) => api.delete(`/rents/${id}`),
};
// Renter API
export const maintenanceAPI = {
getAll: () => api.get('/maintenance'),
getById: (id) => api.get(`/maintenance/${id}`),
create: (data) => api.post('/maintenance', data),
update: (id, data) => api.put(`/maintenance/${id}`, data),
delete: (id) => api.delete(`/maintenance/${id}`),
};
// Expenses API
export const expensesAPI = {
getAll: () => api.get('/expense'),
getById: (id) => api.get(`/expense/${id}`),
create: (data) => api.post('/expense', data, {
headers: {
'Content-Type': 'multipart/form-data',
},
}),
update: (id, data) => api.put(`/expense/${id}`, data, {
headers: {
'Content-Type': 'multipart/form-data',
},
}),
delete: (id) => api.delete(`/expense/${id}`),
};
// Expenses API
export const noticeAPI = {
getAll: () => api.get('/notices'),
getById: (id) => api.get(`/notices/${id}`),
create: (data) => api.post('/notices', data),
update: (id, data) => api.put(`/notices/${id}`, data),
delete: (id) => api.delete(`/notices/${id}`),
};
// Expenses API
export const visitorsAPI = {
getAll: () => api.get('/visitors'),
getById: (id) => api.get(`/visitors/${id}`),
create: (data) => api.post('/visitors', data),
update: (id, data) => api.put(`/visitors/${id}`, data),
delete: (id) => api.delete(`/visitors/${id}`),
checkout: (id) => api.post(`/visitors/checkout/${id}`),
};
// Settings API
export const settingsAPI = {
getAll: () => api.get('/settings'),
update: (data) =>
api.post('/settings', data, {
headers: {
'Content-Type': 'multipart/form-data',
},
}),
};
// Upload API
export const uploadAPI = {
uploadRenterDocument: (renterId, type, file, description) => {
console.log(file);
const formData = new FormData();
formData.append('file', file);
formData.append('description', description);
return api.post(`/upload/renter/${renterId}/${type}`, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
},
deleteDocument: (id) => api.delete(`/upload/document/${id}`),
};
// Renter API
export const categoryAPI = {
getAll: () => api.get('/category'),
getById: (id) => api.get(`/category/${id}`),
create: (data) => api.post('/category', data),
update: (id, data) => api.put(`/category/${id}`, data),
delete: (id) => api.delete(`/category/${id}`),
};
export const downloadAPI = {
download: () => api.get('/request/download/apk'),
};
// async function appendDocumentsToFormData(formData, documents) {
// for (let i = 0; i < documents.length; i++) {
// const doc = documents[i];
// if (doc.file_url && doc.file_name) {
// // Fetch the blob from the blob URL
// const response = await fetch(doc.file_url);
// const blob = await response.blob();
// // Append the file blob with filename
// formData.append(`documents[${i}][file]`, blob, doc.file_name);
// // Append other metadata
// formData.append(`documents[${i}][description]`, doc.description || '');
// formData.append(`documents[${i}][type]`, doc.type || '');
// }
// }
// }
async function appendDocumentsToFormData(formData, documents) {
for (let i = 0; i < documents.length; i++) {
const doc = documents[i];
if (doc.file_url && doc.file_name) {
const response = await fetch(doc.file_url);
const blob = await response.blob();
// All files are under the same field name: 'documents'
formData.append('documents', blob, doc.file_name);
// Also send metadata in JSON array
// Optional: you can collect all metadata first
}
}
// Optional: append metadata separately if needed
const metadata = documents.map(({ description, type, file_name }) => ({
description,
type,
file_name,
}));
formData.append('documentsMeta', JSON.stringify(metadata));
}
export default api; |
:: Command execute :: | |
--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0038 ]-- |