Edit AddProperty
This commit is contained in:
@ -297,6 +297,7 @@ export default function AddPropertyForm({ onClose, onSuccess }) {
|
||||
<option value="house">بيت</option>
|
||||
<option value="villa">فيلا</option>
|
||||
<option value="studio">استوديو</option>
|
||||
<option value="office">مكتب</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
@ -1,12 +1,19 @@
|
||||
/**
|
||||
* BuildingType Enum
|
||||
* Backend values are numeric (0, 1, 2)
|
||||
* Backend values are numeric
|
||||
* Used in: PropertyInformation.buildingType
|
||||
*/
|
||||
const BuildingType = Object.freeze({
|
||||
APARTMENT: 0,
|
||||
VILLA: 1,
|
||||
HOUSE: 2,
|
||||
SWEET: 3,
|
||||
ROOM: 4,
|
||||
STUDIO: 5,
|
||||
OFFICE: 6,
|
||||
FARMS: 7,
|
||||
SHOP: 8,
|
||||
WAREHOUSE: 9,
|
||||
});
|
||||
|
||||
// Map numeric value → Arabic label
|
||||
@ -14,6 +21,13 @@ const BuildingTypeLabels = Object.freeze({
|
||||
[BuildingType.APARTMENT]: 'شقة',
|
||||
[BuildingType.VILLA]: 'فيلا',
|
||||
[BuildingType.HOUSE]: 'بيت',
|
||||
[BuildingType.SWEET]: 'سويت',
|
||||
[BuildingType.ROOM]: 'غرفة',
|
||||
[BuildingType.STUDIO]: 'استوديو',
|
||||
[BuildingType.OFFICE]: 'مكتب',
|
||||
[BuildingType.FARMS]: 'مزرعة',
|
||||
[BuildingType.SHOP]: 'محل',
|
||||
[BuildingType.WAREHOUSE]: 'مستودع',
|
||||
});
|
||||
|
||||
// Map numeric value → English key (for UI filters)
|
||||
@ -21,6 +35,13 @@ const BuildingTypeKeys = Object.freeze({
|
||||
[BuildingType.APARTMENT]: 'apartment',
|
||||
[BuildingType.VILLA]: 'villa',
|
||||
[BuildingType.HOUSE]: 'house',
|
||||
[BuildingType.SWEET]: 'sweet',
|
||||
[BuildingType.ROOM]: 'room',
|
||||
[BuildingType.STUDIO]: 'studio',
|
||||
[BuildingType.OFFICE]: 'office',
|
||||
[BuildingType.FARMS]: 'farms',
|
||||
[BuildingType.SHOP]: 'shop',
|
||||
[BuildingType.WAREHOUSE]: 'warehouse',
|
||||
});
|
||||
|
||||
// Reverse map: English key → numeric value
|
||||
@ -28,6 +49,14 @@ const BuildingTypeByKey = Object.freeze({
|
||||
apartment: BuildingType.APARTMENT,
|
||||
villa: BuildingType.VILLA,
|
||||
house: BuildingType.HOUSE,
|
||||
sweet: BuildingType.SWEET,
|
||||
suite: BuildingType.SWEET,
|
||||
room: BuildingType.ROOM,
|
||||
studio: BuildingType.STUDIO,
|
||||
office: BuildingType.OFFICE,
|
||||
farms: BuildingType.FARMS,
|
||||
shop: BuildingType.SHOP,
|
||||
warehouse: BuildingType.WAREHOUSE,
|
||||
});
|
||||
|
||||
export { BuildingType, BuildingTypeLabels, BuildingTypeKeys, BuildingTypeByKey };
|
||||
|
||||
@ -90,13 +90,15 @@ export default function AddPropertyPage() {
|
||||
const totalSteps = 4;
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
propertyType: 'apartment', // apartment, villa, suite, room
|
||||
propertyType: 'apartment', // apartment, villa, suite, room, studio, office
|
||||
|
||||
furnished: false,
|
||||
|
||||
bedrooms: 1,
|
||||
bedrooms: 0,
|
||||
bathrooms: 1,
|
||||
livingRooms: 1,
|
||||
livingRooms: 0,
|
||||
balconies: 0,
|
||||
floor: '',
|
||||
|
||||
services: {
|
||||
[PropertyService.ELECTRICITY]: false,
|
||||
@ -153,7 +155,9 @@ export default function AddPropertyPage() {
|
||||
{ id: 'apartment', label: 'شقة', icon: Building },
|
||||
{ id: 'villa', label: 'فيلا', icon: Home },
|
||||
{ id: 'suite', label: 'سويت', icon: Sofa },
|
||||
{ id: 'room', label: 'غرفة ضمن شقة', icon: DoorOpen }
|
||||
{ id: 'room', label: 'غرفة ضمن شقة', icon: DoorOpen },
|
||||
{ id: 'studio', label: 'استوديو', icon: Layers },
|
||||
{ id: 'office', label: 'مكتب', icon: Building },
|
||||
];
|
||||
|
||||
const serviceList = [
|
||||
@ -430,7 +434,7 @@ const handleMapClick = async (coords) => {
|
||||
};
|
||||
|
||||
const decrementBedrooms = () => {
|
||||
if (formData.bedrooms > 1) {
|
||||
if (formData.bedrooms > 0) {
|
||||
setFormData({
|
||||
...formData,
|
||||
bedrooms: formData.bedrooms - 1
|
||||
@ -462,7 +466,7 @@ const handleMapClick = async (coords) => {
|
||||
};
|
||||
|
||||
const decrementLivingRooms = () => {
|
||||
if (formData.livingRooms > 1) {
|
||||
if (formData.livingRooms > 0) {
|
||||
setFormData({
|
||||
...formData,
|
||||
livingRooms: formData.livingRooms - 1
|
||||
@ -470,6 +474,22 @@ const handleMapClick = async (coords) => {
|
||||
}
|
||||
};
|
||||
|
||||
const incrementBalconies = () => {
|
||||
setFormData({
|
||||
...formData,
|
||||
balconies: formData.balconies + 1
|
||||
});
|
||||
};
|
||||
|
||||
const decrementBalconies = () => {
|
||||
if (formData.balconies > 0) {
|
||||
setFormData({
|
||||
...formData,
|
||||
balconies: formData.balconies - 1
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const validateStep = () => {
|
||||
const newErrors = {};
|
||||
|
||||
@ -481,15 +501,12 @@ const handleMapClick = async (coords) => {
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (!formData.bedrooms) {
|
||||
newErrors.bedrooms = 'عدد الغرف مطلوب';
|
||||
if (!formData.floor && formData.floor !== 0) {
|
||||
newErrors.floor = 'رقم الطابق مطلوب';
|
||||
}
|
||||
if (!formData.bathrooms) {
|
||||
newErrors.bathrooms = 'عدد الحمامات مطلوب';
|
||||
}
|
||||
if (!formData.livingRooms) {
|
||||
newErrors.livingRooms = 'عدد الصالونات مطلوب';
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
@ -538,7 +555,18 @@ const handleMapClick = async (coords) => {
|
||||
console.log('[AddProperty] Building RentPropertyDto payload...');
|
||||
|
||||
// Map UI property type to API BuildingType enum
|
||||
const buildingTypeMap = { apartment: BuildingType.APARTMENT, villa: BuildingType.VILLA, suite: BuildingType.APARTMENT, room: BuildingType.APARTMENT };
|
||||
const buildingTypeMap = {
|
||||
apartment: BuildingType.APARTMENT,
|
||||
villa: BuildingType.VILLA,
|
||||
suite: BuildingType.SWEET,
|
||||
sweet: BuildingType.SWEET,
|
||||
room: BuildingType.ROOM,
|
||||
studio: BuildingType.STUDIO,
|
||||
office: BuildingType.OFFICE,
|
||||
farms: BuildingType.FARMS,
|
||||
shop: BuildingType.SHOP,
|
||||
warehouse: BuildingType.WAREHOUSE,
|
||||
};
|
||||
|
||||
// Map offer type to RentType enum: 0=Monthly, 1=Daily
|
||||
const rentTypeMap = { daily: RentType.DAILY, monthly: RentType.MONTHLY, both: RentType.MONTHLY };
|
||||
@ -561,6 +589,7 @@ const handleMapClick = async (coords) => {
|
||||
displayType: formData.offerType === 'both' ? 'Both' : formData.offerType === 'daily' ? 'Daily' : 'Monthly',
|
||||
propertyCondition: formData.furnished ? 'Furnished' : 'Unfurnished',
|
||||
photos: imagePreviews.map((_, i) => `photo_${i}.jpg`),
|
||||
floor: parseInt(formData.floor, 10) || 0,
|
||||
room: {
|
||||
areaType: formData.propertyType === 'room' ? 'Shared room' : 'Private room',
|
||||
peopleAllowed: String(formData.bedrooms),
|
||||
@ -575,7 +604,9 @@ const handleMapClick = async (coords) => {
|
||||
visitorsAllowed: true,
|
||||
quietTimesEnabled: false,
|
||||
quietTimes: '',
|
||||
}
|
||||
},
|
||||
balconies: formData.balconies || 0,
|
||||
isOffice: formData.propertyType === 'office',
|
||||
});
|
||||
|
||||
const payload = {
|
||||
@ -768,10 +799,10 @@ const handleMapClick = async (coords) => {
|
||||
<p className="text-gray-600">أدخل التفاصيل والخدمات المتاحة</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-6">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
عدد الغرف <span className="text-red-500">*</span>
|
||||
عدد الغرف <span className="text-gray-400 text-xs">(اختياري)</span>
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
@ -827,7 +858,7 @@ const handleMapClick = async (coords) => {
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
عدد الصالونات <span className="text-red-500">*</span>
|
||||
عدد الصالونات <span className="text-gray-400 text-xs">(اختياري)</span>
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
@ -852,6 +883,50 @@ const handleMapClick = async (coords) => {
|
||||
<p className="text-red-500 text-sm mt-1">{errors.livingRooms}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
رقم الطابق <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
value={formData.floor}
|
||||
onChange={(e) => setFormData({...formData, floor: e.target.value})}
|
||||
className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||
placeholder="أدخل رقم الطابق"
|
||||
/>
|
||||
{errors.floor && (
|
||||
<p className="text-red-500 text-sm mt-1">{errors.floor}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{formData.propertyType === 'office' && (
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
عدد البلكونات (اختياري)
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={decrementBalconies}
|
||||
className="w-10 h-10 bg-gray-100 rounded-lg flex items-center justify-center hover:bg-gray-200"
|
||||
>
|
||||
<Minus className="w-4 h-4" />
|
||||
</button>
|
||||
<div className="flex-1 text-center font-bold text-xl">
|
||||
{formData.balconies}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={incrementBalconies}
|
||||
className="w-10 h-10 bg-gray-100 rounded-lg flex items-center justify-center hover:bg-gray-200"
|
||||
>
|
||||
<Plus className="w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
Reference in New Issue
Block a user