Add image upload to property form via FilesController
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:
Claw AI
2026-03-30 00:57:52 +00:00
parent 1a96e457ca
commit 4299968764
2 changed files with 43 additions and 13 deletions

View File

@ -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,

View File

@ -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 ───
/** /**