This commit is contained in:
@ -174,6 +174,7 @@ export default function AddPropertyPage() {
|
||||
const [errors, setErrors] = useState({});
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isUploadingImages, setIsUploadingImages] = useState(false);
|
||||
const [agreeToTerms, setAgreeToTerms] = useState(false);
|
||||
|
||||
const fileInputRef = useRef(null);
|
||||
@ -602,11 +603,51 @@ const handleMarkerDragEnd = async (lat, lng) => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
};
|
||||
|
||||
const ensureImagesUploaded = async () => {
|
||||
if (formData.images.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
setIsUploadingImages(true);
|
||||
const finalPaths = [];
|
||||
|
||||
for (let index = 0; index < formData.images.length; index += 1) {
|
||||
const file = formData.images[index];
|
||||
const existingPath = uploadedImagePaths[index];
|
||||
|
||||
if (existingPath) {
|
||||
finalPaths.push(existingPath);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const path = await uploadPicture(file);
|
||||
finalPaths.push(path);
|
||||
} catch (err) {
|
||||
console.error('[AddProperty] Image upload failed:', err);
|
||||
toast.error(`${t('toast.imageUploadFailed')}: ${file.name}`);
|
||||
setIsUploadingImages(false);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
setUploadedImagePaths(finalPaths);
|
||||
setIsUploadingImages(false);
|
||||
return finalPaths;
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!validateStep()) return;
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
const finalImagePaths = await ensureImagesUploaded();
|
||||
if (finalImagePaths.length < 2) {
|
||||
toast.error(t('addProperty.minImagesRequired'));
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Map UI property type to API BuildingType enum
|
||||
const buildingTypeMap = { apartment: BuildingType.APARTMENT, villa: BuildingType.VILLA, sweet: BuildingType.SWEET, suite: BuildingType.SWEET, room: BuildingType.ROOM, studio: BuildingType.STUDIO, office: BuildingType.OFFICE, farms: BuildingType.FARMS, shop: BuildingType.SHOP, warehouse: BuildingType.WAREHOUSE };
|
||||
|
||||
@ -670,14 +711,14 @@ const handleMarkerDragEnd = async (lat, lng) => {
|
||||
const propInfo = {
|
||||
cordsX: formData.lat ? String(formData.lat) : '',
|
||||
cordsY: formData.lng ? String(formData.lng) : '',
|
||||
images: uploadedImagePaths,
|
||||
images: finalImagePaths,
|
||||
address: `${formData.city} - ${formData.district} - ${formData.address}`.trim(),
|
||||
description: formData.description || '',
|
||||
numberOfBathRooms: formData.bathrooms || 0,
|
||||
numberOfRooms: formData.bedrooms || 0,
|
||||
numberOfBedRooms: formData.bedrooms || 0,
|
||||
space: parseFloat(formData.space) || 0,
|
||||
detailsJSON,
|
||||
detailsJSON: detailsJSON || '{}',
|
||||
buildingType: buildingTypeMap[formData.propertyType] ?? BuildingType.APARTMENT,
|
||||
status: 0,
|
||||
propertyType: formData.furnished ? RentPropertyCondition.WITH_FURNITURE : RentPropertyCondition.WITHOUT_FURNITURE,
|
||||
@ -738,6 +779,12 @@ const handleMarkerDragEnd = async (lat, lng) => {
|
||||
<Toaster position="top-center" reverseOrder={false} />
|
||||
|
||||
<div className="container mx-auto px-4 max-w-4xl">
|
||||
{isUploadingImages && (
|
||||
<div className="mb-4 rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800 flex items-center justify-center gap-2">
|
||||
<Loader2 className="w-4 h-4 animate-spin" />
|
||||
<span>{t('addProperty.uploadingImagesMessage') || 'جاري رفع الصور... يرجى الانتظار'}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="mb-8">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<Link
|
||||
@ -1561,7 +1608,7 @@ const handleMarkerDragEnd = async (lat, lng) => {
|
||||
<p className="text-gray-600">{t('addProperty.locationAndImagesSubtitle')}</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-3xl border border-amber-100 bg-gradient-to-br from-amber-50 via-white to-orange-50 p-4 sm:p-5 md:p-6 shadow-sm">
|
||||
<div className="rounded-3xl border border-amber-100 bg-linear-to-br from-amber-50 via-white to-orange-50 p-4 sm:p-5 md:p-6 shadow-sm">
|
||||
<div className="flex flex-col gap-3 md:flex-row md:items-start md:justify-between mb-5">
|
||||
<div>
|
||||
<div className="flex items-center gap-2 text-amber-700 font-semibold mb-1">
|
||||
@ -1782,7 +1829,7 @@ const handleMarkerDragEnd = async (lat, lng) => {
|
||||
<button
|
||||
onClick={handleSubmit}
|
||||
disabled={isLoading || !agreeToTerms}
|
||||
className="flex-1 py-3 px-4 bg-gradient-to-r from-amber-500 to-amber-600 text-white rounded-xl font-medium hover:from-amber-600 hover:to-amber-700 transition-all disabled:opacity-50 flex items-center justify-center gap-2"
|
||||
className="flex-1 py-3 px-4 bg-linear-to-r from-amber-500 to-amber-600 text-white rounded-xl font-medium hover:from-amber-600 hover:to-amber-700 transition-all disabled:opacity-50 flex items-center justify-center gap-2"
|
||||
>
|
||||
{isLoading ? (
|
||||
<>
|
||||
|
||||
Reference in New Issue
Block a user