Add image upload to property form via FilesController
All checks were successful
Build frontend / build (push) Successful in 52s
All checks were successful
Build frontend / build (push) Successful in 52s
- Added uploadPicture() API function for POST /Files/UploadPicture - Images uploaded immediately on selection, paths stored - PropertyInformation.images sent with server-side paths - Remove image also removes from uploaded paths
This commit is contained in:
@ -175,7 +175,7 @@ export default function AddPropertyPage() {
|
|||||||
{ id: 'daily', label: 'إيجار يومي', icon: Clock },
|
{ id: 'daily', label: 'إيجار يومي', icon: Clock },
|
||||||
{ id: 'monthly', label: 'إيجار شهري', icon: Calendar },
|
{ id: 'monthly', label: 'إيجار شهري', icon: Calendar },
|
||||||
{ id: 'both', label: 'إيجار يومي وشهري', icon: Calendar },
|
{ id: 'both', label: 'إيجار يومي وشهري', icon: Calendar },
|
||||||
];
|
].filter(Boolean);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
@ -376,22 +376,25 @@ const handleMapClick = async (coords) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const toggleService = (serviceId) => {
|
const toggleService = (serviceId) => {
|
||||||
setFormData({
|
setFormData(prev => {
|
||||||
...formData,
|
const services = { ...prev.services };
|
||||||
services: {
|
services[serviceId] = !services[serviceId];
|
||||||
...formData.services,
|
return { ...prev, services };
|
||||||
[serviceId]: !formData.services[serviceId]
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateServiceDetail = (serviceId, value) => {
|
||||||
|
setFormData(prev => ({
|
||||||
|
...prev,
|
||||||
|
serviceDetails: { ...prev.serviceDetails, [serviceId]: value }
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
const toggleTerm = (termId) => {
|
const toggleTerm = (termId) => {
|
||||||
setFormData({
|
setFormData(prev => {
|
||||||
...formData,
|
const terms = { ...prev.terms };
|
||||||
terms: {
|
terms[termId] = !terms[termId];
|
||||||
...formData.terms,
|
return { ...prev, terms };
|
||||||
[termId]: !formData.terms[termId]
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -565,6 +568,7 @@ const handleMapClick = async (coords) => {
|
|||||||
buildingType: buildingTypeMap[formData.propertyType] ?? BuildingType.APARTMENT,
|
buildingType: buildingTypeMap[formData.propertyType] ?? BuildingType.APARTMENT,
|
||||||
status: 0,
|
status: 0,
|
||||||
propertyType: formData.furnished ? RentPropertyCondition.WITH_FURNITURE : RentPropertyCondition.WITHOUT_FURNITURE,
|
propertyType: formData.furnished ? RentPropertyCondition.WITH_FURNITURE : RentPropertyCondition.WITHOUT_FURNITURE,
|
||||||
|
images: uploadedImagePaths,
|
||||||
},
|
},
|
||||||
deposit: parseFloat(formData.deposit) || 0,
|
deposit: parseFloat(formData.deposit) || 0,
|
||||||
monthlyRent: parseFloat(formData.monthlyPrice) || 0,
|
monthlyRent: parseFloat(formData.monthlyPrice) || 0,
|
||||||
|
|||||||
@ -196,6 +196,32 @@ export async function getCurrencies() {
|
|||||||
return apiFetch('/Currency/GetAll');
|
return apiFetch('/Currency/GetAll');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Files ───
|
||||||
|
|
||||||
|
export async function uploadPicture(file) {
|
||||||
|
console.log('[API] Uploading picture:', file.name);
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', file);
|
||||||
|
const token = AuthService.getToken();
|
||||||
|
const res = await fetch(`${API_BASE}/Files/UploadPicture`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
...(token && { Authorization: `Bearer ${token}` }),
|
||||||
|
},
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
const text = await res.text();
|
||||||
|
console.log('[API] Upload response:', res.status, text?.substring(0, 100));
|
||||||
|
if (!res.ok) throw new Error(`Upload failed: ${res.status} ${text}`);
|
||||||
|
// Response is the relative path string (possibly in envelope)
|
||||||
|
try {
|
||||||
|
const json = JSON.parse(text);
|
||||||
|
return json?.data || json;
|
||||||
|
} catch {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Auth: Registration ───
|
// ─── Auth: Registration ───
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user