diff --git a/app/page.js b/app/page.js index ee2148f..dc91195 100644 --- a/app/page.js +++ b/app/page.js @@ -31,46 +31,47 @@ import Image from 'next/image'; import { getRentProperties, getSaleProperties } from './utils/api'; // Map API property data to the format the UI expects +// API returns { propInfoId, deposit, monthlyRent, dailyRent, rating, ... } +// If propertyInformation is nested, use it; otherwise use flat response with defaults function mapApiProperty(item, index) { - const info = item.propertyInformation || item; - const isRent = item.monthlyRent !== undefined || item.dailyRent !== undefined; + const info = item.propertyInformation || {}; + const hasNestedInfo = !!item.propertyInformation; - // Determine price display const dailyPrice = item.dailyRent ?? item.monthlyRent ?? item.price ?? 0; const monthlyPrice = item.monthlyRent ?? 0; - // Map building type integer to string + // BuildingType: 0=Apartment, 1=Villa, 2=House const buildingTypeMap = { 0: 'apartment', 1: 'villa', 2: 'house' }; - const propType = buildingTypeMap[info.buildingType] || 'apartment'; + const propType = buildingTypeMap[info.buildingType] ?? buildingTypeMap[item.type] ?? 'apartment'; - // Map property status integer to string + // Status: 0=Available, 1=Booked, 2=Maintenance const statusMap = { 0: 'available', 1: 'booked', 2: 'maintenance' }; - const status = statusMap[info.status] || 'available'; + const status = statusMap[info.status] ?? statusMap[item.status] ?? 'available'; - // Extract features as string array const features = []; if (item.isSmokeAllow) features.push('يسمح بالتدخين'); if (item.isVisitorAllow) features.push('يسمح بالزوار'); if (item.specializedFor) features.push('متخصص'); - if (info.numberOfRooms) features.push(`${info.numberOfRooms} غرف`); + if (info.numberOfBedRooms) features.push(`${info.numberOfBedRooms} غرف نوم`); if (info.numberOfBathRooms) features.push(`${info.numberOfBathRooms} حمامات`); return { id: item.id ?? index + 1, - title: info.address || info.description?.substring(0, 40) || 'عقار', + propInfoId: item.propInfoId, + title: info.address || `عقار #${item.id || index + 1}`, description: info.description || '', type: propType, price: dailyPrice, priceUSD: dailyPrice, priceUnit: 'daily', location: { - city: extractCity(info.address), + city: extractCity(info.address) || 'دمشق', district: info.address || '', address: info.address || '', lat: parseFloat(info.cordsX) || 0, lng: parseFloat(info.cordsY) || 0, }, - bedrooms: info.numberOfBedRooms || info.numberOfRooms || 0, + bedrooms: info.numberOfBedRooms || 0, bathrooms: info.numberOfBathRooms || 0, area: info.space || 0, features, @@ -94,7 +95,7 @@ function extractCity(address) { for (const city of cities) { if (address.includes(city)) return city; } - return address.split(' ').pop() || ''; + return ''; } // Fallback dummy data diff --git a/app/properties/page.js b/app/properties/page.js index dd1a362..bfee996 100644 --- a/app/properties/page.js +++ b/app/properties/page.js @@ -35,35 +35,37 @@ import { getRentProperties, getSaleProperties } from '../utils/api'; // Map API data to UI format function mapApiProperty(item, index) { - const info = item.propertyInformation || item; + const info = item.propertyInformation || {}; + const hasNestedInfo = !!item.propertyInformation; const dailyPrice = item.dailyRent ?? item.monthlyRent ?? item.price ?? 0; const monthlyPrice = item.monthlyRent ?? 0; const buildingTypeMap = { 0: 'apartment', 1: 'villa', 2: 'house' }; - const propType = buildingTypeMap[info.buildingType] || 'apartment'; + const propType = buildingTypeMap[info.buildingType] ?? buildingTypeMap[item.type] ?? 'apartment'; const statusMap = { 0: 'available', 1: 'booked', 2: 'maintenance' }; - const status = statusMap[info.status] || 'available'; + const status = statusMap[info.status] ?? statusMap[item.status] ?? 'available'; const features = []; if (item.isSmokeAllow) features.push('يسمح بالتدخين'); if (item.isVisitorAllow) features.push('يسمح بالزوار'); - if (info.numberOfRooms) features.push(`${info.numberOfRooms} غرف`); + if (item.specializedFor) features.push('متخصص'); + if (info.numberOfBedRooms) features.push(`${info.numberOfBedRooms} غرف نوم`); if (info.numberOfBathRooms) features.push(`${info.numberOfBathRooms} حمامات`); return { id: item.id ?? index + 1, - title: info.address || info.description?.substring(0, 40) || 'عقار', + title: info.address || `عقار #${item.id || index + 1}`, description: info.description || '', type: propType, price: dailyPrice, priceUnit: 'daily', location: { - city: extractCity(info.address), + city: extractCity(info.address) || 'دمشق', district: info.address || '', }, - bedrooms: info.numberOfBedRooms || info.numberOfRooms || 0, + bedrooms: info.numberOfBedRooms || 0, bathrooms: info.numberOfBathRooms || 0, area: info.space || 0, features, diff --git a/app/property/[id]/page.js b/app/property/[id]/page.js index a01e3c5..5d477c4 100644 --- a/app/property/[id]/page.js +++ b/app/property/[id]/page.js @@ -48,47 +48,47 @@ import { getRentProperty, getSaleProperty, bookReservation, checkAvailability } function mapApiDetail(item) { if (!item) return null; - const info = item.propertyInformation || item; - const isRent = item.monthlyRent !== undefined || item.dailyRent !== undefined; + const info = item.propertyInformation || {}; + const hasNestedInfo = !!item.propertyInformation; const dailyPrice = item.dailyRent ?? item.monthlyRent ?? item.price ?? 0; const monthlyPrice = item.monthlyRent ?? 0; const buildingTypeMap = { 0: 'apartment', 1: 'villa', 2: 'house' }; - const propType = buildingTypeMap[info.buildingType] || 'apartment'; + const propType = buildingTypeMap[info.buildingType] ?? buildingTypeMap[item.type] ?? 'apartment'; const statusMap = { 0: 'available', 1: 'booked', 2: 'maintenance' }; - const status = statusMap[info.status] || 'available'; + const status = statusMap[info.status] ?? statusMap[item.status] ?? 'available'; - // Build features array const features = []; if (item.isSmokeAllow) features.push({ name: 'يسمح بالتدخين', available: true, description: '' }); if (item.isVisitorAllow) features.push({ name: 'يسمح بالزوار', available: true, description: '' }); if (item.specializedFor) features.push({ name: 'متخصص', available: true, description: '' }); + if (info.numberOfBedRooms) features.push({ name: 'غرف النوم', available: true, description: `${info.numberOfBedRooms} غرف` }); + if (info.numberOfBathRooms) features.push({ name: 'الحمامات', available: true, description: `${info.numberOfBathRooms} حمامات` }); + if (info.space) features.push({ name: 'المساحة', available: true, description: `${info.space} م²` }); const typeLabels = { 0: 'شقة', 1: 'فيلا', 2: 'بيت' }; return { id: item.id, - title: info.address || info.description?.substring(0, 50) || `عقار #${item.id}`, - description: info.description || '', + title: info.address || `عقار #${item.id}`, + description: info.description || 'عقار سكني مميز في موقع استراتيجي.', type: propType, price: dailyPrice, - priceUnit: isRent ? 'daily' : 'sale', + priceUnit: 'daily', location: { - city: extractCity(info.address), + city: extractCity(info.address) || 'دمشق', district: info.address || '', address: info.address || '', lat: parseFloat(info.cordsX) || 0, lng: parseFloat(info.cordsY) || 0, }, - bedrooms: info.numberOfBedRooms || info.numberOfRooms || 0, + bedrooms: info.numberOfBedRooms || 0, bathrooms: info.numberOfBathRooms || 0, area: info.space || 0, features: features.length > 0 ? features : [ - { name: 'غرف نوم', available: true, description: `${info.numberOfBedRooms || 0} غرف` }, - { name: 'حمامات', available: true, description: `${info.numberOfBathRooms || 0} حمامات` }, - { name: 'المساحة', available: true, description: `${info.space || 0} م²` }, + { name: 'متاح للإيجار', available: true, description: '' }, ], images: ['/property-placeholder.jpg', '/villa1.jpg', '/villa2.jpg'], status, diff --git a/app/utils/api.js b/app/utils/api.js index e4d1d12..2ff3a7c 100644 --- a/app/utils/api.js +++ b/app/utils/api.js @@ -37,11 +37,39 @@ async function apiFetch(endpoint, options = {}) { // ─── Rent Properties ─── export async function getRentProperties() { - return apiFetch('/RentProperties/GetRentProperties'); + const rentList = await apiFetch('/RentProperties/GetRentProperties'); + if (!Array.isArray(rentList) || rentList.length === 0) return rentList; + + // Fetch property info for each rent property's propInfoId + const enriched = await Promise.all( + rentList.map(async (item) => { + try { + const propInfo = await apiFetch(`/Properties/Get/${item.propInfoId}`); + return { ...item, propertyInformation: propInfo }; + } catch { + return item; + } + }) + ); + return enriched; } export async function getRentProperty(id) { - return apiFetch(`/RentProperties/GetRentProperties?id=${id}`); + const item = await apiFetch(`/RentProperties/GetRentProperties?id=${id}`); + if (!item) return item; + + // If it's an array (all results), pick the matching one + const property = Array.isArray(item) ? item.find(p => p.id == id) || item[0] : item; + + if (property?.propInfoId) { + try { + const propInfo = await apiFetch(`/Properties/Get/${property.propInfoId}`); + return { ...property, propertyInformation: propInfo }; + } catch { + // ignore + } + } + return property; } export async function getRentPropertyLocations(params = {}) { @@ -55,11 +83,35 @@ export async function getRentPropertyLocations(params = {}) { // ─── Sale Properties ─── export async function getSaleProperties() { - return apiFetch('/SaleProperties/GetSaleProperties'); + const saleList = await apiFetch('/SaleProperties/GetSaleProperties'); + if (!Array.isArray(saleList) || saleList.length === 0) return saleList; + + const enriched = await Promise.all( + saleList.map(async (item) => { + try { + const propInfo = await apiFetch(`/Properties/Get/${item.propInfoId}`); + return { ...item, propertyInformation: propInfo }; + } catch { + return item; + } + }) + ); + return enriched; } export async function getSaleProperty(id) { - return apiFetch(`/SaleProperties/GetSaleProperties?id=${id}`); + const item = await apiFetch(`/SaleProperties/GetSaleProperties?id=${id}`); + const property = Array.isArray(item) ? item.find(p => p.id == id) || item[0] : item; + + if (property?.propInfoId) { + try { + const propInfo = await apiFetch(`/Properties/Get/${property.propInfoId}`); + return { ...property, propertyInformation: propInfo }; + } catch { + // ignore + } + } + return property; } // ─── Properties (generic) ───