fixing agent api
All checks were successful
Build frontend / build (push) Successful in 57s

This commit is contained in:
Beilin-b
2026-06-06 03:55:53 -07:00
parent 53a83494b7
commit 471332b59f
2 changed files with 828 additions and 251 deletions

File diff suppressed because it is too large Load Diff

View File

@ -453,6 +453,10 @@ import AuthService from '../services/AuthService';
const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api';
function isFormData(value) {
return typeof FormData !== 'undefined' && value instanceof FormData;
}
/**
* Generic API fetch — attaches auth token, unwraps { data } envelope
*/
@ -460,14 +464,24 @@ async function apiFetch(endpoint, options = {}) {
const token = AuthService.getToken();
const headers = {
'Content-Type': 'application/json',
...(token && { Authorization: `Bearer ${token}` }),
...options.headers,
...(options.headers || {}),
};
const hasBody = options.body != null;
const bodyIsFormData = isFormData(options.body);
if (hasBody && !bodyIsFormData && !headers['Content-Type'] && !headers['content-type']) {
headers['Content-Type'] = 'application/json';
}
const res = await fetch(`${API_BASE}${endpoint}`, {
...options,
headers,
body:
hasBody && !bodyIsFormData && typeof options.body !== 'string'
? JSON.stringify(options.body)
: options.body,
});
if (!res.ok && res.status !== 206) {
@ -493,7 +507,13 @@ async function apiFetch(endpoint, options = {}) {
* Auth fetch — returns full { status, data, ok } for status-code handling
*/
async function authFetch(endpoint, body, token = null) {
const headers = { 'Content-Type': 'application/json' };
const headers = {};
const bodyIsFormData = isFormData(body);
if (!bodyIsFormData) {
headers['Content-Type'] = 'application/json';
}
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
@ -501,11 +521,12 @@ async function authFetch(endpoint, body, token = null) {
const res = await fetch(`${API_BASE}${endpoint}`, {
method: 'POST',
headers,
body: JSON.stringify(body),
body: bodyIsFormData ? body : JSON.stringify(body),
});
const text = await res.text();
let data = null;
try {
data = text ? JSON.parse(text) : null;
if (data && typeof data === 'object' && 'data' in data) {
@ -515,7 +536,7 @@ async function authFetch(endpoint, body, token = null) {
data = text;
}
const message = (typeof data === 'object' && data?.message) ? data.message : null;
const message = typeof data === 'object' && data?.message ? data.message : null;
return { status: res.status, data, ok: res.ok || res.status === 206, message };
}
@ -547,7 +568,7 @@ export async function getSaleProperties() {
export async function getSaleProperty(id) {
const items = await apiFetch('/SaleProperties/GetSaleProperties');
if (!Array.isArray(items)) return items;
return items.find(p => p.id == id) || items[0];
return items.find((p) => p.id == id) || items[0];
}
// ─── Properties (generic) ───
@ -596,15 +617,13 @@ export async function checkAvailability(propertyId, fromDate = null, toDate = nu
}
export async function bookReservation(propertyInfoId, startDate, endDate) {
const payload = {
propertyInfoId,
startDate,
endDate,
};
return apiFetch('/Reservations/BookReservation/book', {
method: 'POST',
body: JSON.stringify(payload),
body: {
propertyInfoId,
startDate,
endDate,
},
});
}
@ -627,34 +646,34 @@ export async function getOwnerByUserId(userId) {
// ─── Properties ───
export async function getMyRentListings() {
return apiFetch(`/RentProperties/GetMyRentListings`);
return apiFetch('/RentProperties/GetMyRentListings');
}
export async function addRentProperty(data) {
return apiFetch('/RentProperties/AddRentProperty', {
method: 'POST',
body: JSON.stringify(data),
body: data,
});
}
export async function editRentProperty(id, data) {
return apiFetch(`/RentProperties/EditRentProperty/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
body: data,
});
}
export async function editSaleProperty(id, data) {
return apiFetch(`/SaleProperties/EditSaleProperty/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
body: data,
});
}
export async function addSaleProperty(data) {
return apiFetch('/SaleProperties/AddSaleProperty', {
method: 'POST',
body: JSON.stringify(data),
body: data,
});
}
@ -677,6 +696,7 @@ export async function getCurrencies() {
export async function uploadPicture(file) {
const formData = new FormData();
formData.append('image', file);
const token = AuthService.getToken();
const res = await fetch(`${API_BASE}/Files/UploadPicture`, {
@ -702,8 +722,13 @@ export async function uploadPicture(file) {
// ─── Auth: Registration ───
async function multipartAuthFetch(endpoint, formData) {
const token = AuthService.getToken();
const res = await fetch(`${API_BASE}${endpoint}`, {
method: 'POST',
headers: {
...(token && { Authorization: `Bearer ${token}` }),
},
body: formData,
});
@ -729,8 +754,7 @@ export async function addOwner(data, frontImage = null, backImage = null, licens
formData.append('LastName', data.lastName || data.LastName || '');
formData.append('Email', data.email || data.Email || '');
const phoneValue =
data.phone || data.phoneNumber || data.Phone || data.PhoneNumber || '';
const phoneValue = data.phone || data.phoneNumber || data.Phone || data.PhoneNumber || '';
const whatsappValue =
data.whatsAppNumber || data.whatsapp || data.WhatsAppNumber || data.WhatsApp || '';
@ -842,7 +866,7 @@ export async function getUserNotifications() {
export async function confirmDepositPayment(bookingId) {
return apiFetch('/Reservations/ConfirmDepositPayment', {
method: 'POST',
body: JSON.stringify({ bookingId }),
body: { bookingId },
});
}
@ -890,7 +914,7 @@ export async function adminConfirmDeposit(reservationId, adminId, comment = null
export async function updateBookingStatus(bookingId, status) {
return apiFetch('/Reservations/UpdateStatus', {
method: 'PUT',
body: JSON.stringify({ bookingId, status }),
body: { bookingId, status },
});
}
@ -903,7 +927,7 @@ export async function getOwnerReservationRequests() {
export async function getOwnerReservationsByStatuses(filterStatuses) {
return apiFetch('/Reservations/GetAllReservationsByStateForOwner', {
method: 'POST',
body: JSON.stringify({ filterStatuses }),
body: { filterStatuses },
});
}
@ -922,14 +946,16 @@ export async function ownerConfirmReservation(id) {
export async function payDeposit(data) {
return apiFetch('/Reservations/PayDeposit/pay-deposit', {
method: 'POST',
body: JSON.stringify(data),
body: data,
});
}
// ─── Owner Contact & Stats ───
export async function getOwnerContactInformation(propertyInformationId) {
return apiFetch(`/Owner/GetOwnerContactInformation?propertyInformationId=${propertyInformationId}`);
return apiFetch(
`/Owner/GetOwnerContactInformation?propertyInformationId=${propertyInformationId}`
);
}
export async function getOwnerStatistics() {
@ -940,28 +966,42 @@ export async function getOwnerStatistics() {
export async function registerRealEstateAgent(formData) {
const token = AuthService.getToken();
const res = await fetch(`${API_BASE}/RealEstateAgent/Add`, {
method: 'POST',
headers: { ...(token && { Authorization: `Bearer ${token}` }) },
headers: {
...(token && { Authorization: `Bearer ${token}` }),
},
body: formData,
});
const text = await res.text();
let data = null;
try {
data = text ? JSON.parse(text) : null;
if (data && typeof data === 'object' && 'data' in data) data = data.data;
} catch {
data = text;
}
return { status: res.status, data, ok: res.ok || res.status === 206, message: data?.message };
return {
status: res.status,
data,
ok: res.ok || res.status === 206,
message: data?.message || (typeof data === 'string' ? data : null),
};
}
// ─── Change Password ───
export async function changePassword(oldPassword, newPassword) {
return apiFetch(`/User/ChangePassword?oldPassword=${encodeURIComponent(oldPassword)}&newPassword=${encodeURIComponent(newPassword)}`, {
method: 'PUT',
});
return apiFetch(
`/User/ChangePassword?oldPassword=${encodeURIComponent(oldPassword)}&newPassword=${encodeURIComponent(newPassword)}`,
{
method: 'PUT',
}
);
}
// ─── Forget Password (OTP flow) ───
@ -971,9 +1011,12 @@ export async function requestForgetPasswordOtp(email) {
}
export async function verifyForgetPasswordOtp(email, code, newPassword) {
return apiFetch(`/User/VerifyForgetPasswordOTP?email=${encodeURIComponent(email)}&code=${encodeURIComponent(code)}&newPassword=${encodeURIComponent(newPassword)}`, {
method: 'POST',
});
return apiFetch(
`/User/VerifyForgetPasswordOTP?email=${encodeURIComponent(email)}&code=${encodeURIComponent(code)}&newPassword=${encodeURIComponent(newPassword)}`,
{
method: 'POST',
}
);
}
// ─── Reset Password (token flow) ───
@ -995,7 +1038,7 @@ export async function deleteMyAccount(password) {
export async function setFCMToken(token, deviceType = 2) {
return apiFetch('/User/SetFCMToken', {
method: 'POST',
body: JSON.stringify({ token, deviceType }),
body: { token, deviceType },
});
}
@ -1003,7 +1046,9 @@ export async function setFCMToken(token, deviceType = 2) {
export async function filterRentProperties(params = {}) {
const qs = new URLSearchParams();
Object.entries(params).forEach(([k, v]) => { if (v != null && v !== '') qs.set(k, v); });
Object.entries(params).forEach(([k, v]) => {
if (v != null && v !== '') qs.set(k, v);
});
const query = qs.toString();
return apiFetch(`/RentProperties/FilterRentProperties${query ? `?${query}` : ''}`);
}
@ -1013,35 +1058,35 @@ export async function filterRentProperties(params = {}) {
export async function submitReport(subject, body) {
return apiFetch('/Reports', {
method: 'POST',
body: JSON.stringify({ subject, body }),
body: { subject, body },
});
}
export async function submitReservationReport(data) {
return apiFetch('/ReservationReports', {
method: 'POST',
body: JSON.stringify(data),
body: data,
});
}
export async function updateReservationReport(id, data) {
return apiFetch(`/ReservationReports/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
body: data,
});
}
export async function submitSaleReport(data) {
return apiFetch('/SaleReports', {
method: 'POST',
body: JSON.stringify(data),
body: data,
});
}
export async function updateSaleReport(id, data) {
return apiFetch(`/SaleReports/${id}`, {
method: 'PUT',
body: JSON.stringify(data),
body: data,
});
}
@ -1050,6 +1095,6 @@ export async function updateSaleReport(id, data) {
export async function addTerm(name, description) {
return apiFetch('/Terms', {
method: 'POST',
body: JSON.stringify({ name, description }),
body: { name, description },
});
}
}