forked from amer2004/SweetHome
Added city and document type
This commit is contained in:
@ -64,6 +64,11 @@ import {
|
||||
PropertyTerm,
|
||||
PropertyTermLabels,
|
||||
PropertyTermsList,
|
||||
DocumentType,
|
||||
DocumentTypeList,
|
||||
Governorate,
|
||||
GovernorateLabels,
|
||||
GovernorateList,
|
||||
Currency,
|
||||
CurrencyLabels
|
||||
} from '../../../enums';
|
||||
@ -84,6 +89,7 @@ export default function AddPropertyPage() {
|
||||
propertyType: 'apartment',
|
||||
|
||||
furnished: false,
|
||||
documentType: DocumentType.PASSPORT,
|
||||
|
||||
bedrooms: 1,
|
||||
bathrooms: 1,
|
||||
@ -118,7 +124,7 @@ export default function AddPropertyPage() {
|
||||
deposit: '',
|
||||
allowedPaymentPeriod: '',
|
||||
|
||||
city: '',
|
||||
city: Governorate.DAMASCUS,
|
||||
district: '',
|
||||
address: '',
|
||||
lat: null,
|
||||
@ -206,6 +212,19 @@ export default function AddPropertyPage() {
|
||||
{ id: 'both', label: t('addProperty.dailyAndMonthly'), icon: Calendar },
|
||||
].filter(Boolean);
|
||||
|
||||
const getDocumentTypeLabel = (type) => {
|
||||
switch (type) {
|
||||
case DocumentType.PASSPORT:
|
||||
return t('documentType.passport');
|
||||
case DocumentType.IDCARD:
|
||||
return t('documentType.idCard');
|
||||
case DocumentType.BOTH:
|
||||
return t('documentType.both');
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// Fetch available currencies
|
||||
getCurrencies().then((data) => {
|
||||
@ -662,6 +681,8 @@ const handleMarkerDragEnd = async (lat, lng) => {
|
||||
buildingType: buildingTypeMap[formData.propertyType] ?? BuildingType.APARTMENT,
|
||||
status: 0,
|
||||
propertyType: formData.furnished ? RentPropertyCondition.WITH_FURNITURE : RentPropertyCondition.WITHOUT_FURNITURE,
|
||||
documentType: formData.documentType,
|
||||
governorate: formData.city,
|
||||
};
|
||||
|
||||
try {
|
||||
@ -822,6 +843,23 @@ const handleMarkerDragEnd = async (lat, lng) => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
{t('addProperty.documentTypeLabel')} <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
value={formData.documentType}
|
||||
onChange={(e) => setFormData({...formData, documentType: 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"
|
||||
>
|
||||
{DocumentTypeList.map((type) => (
|
||||
<option key={type} value={type}>
|
||||
{getDocumentTypeLabel(type)}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
{t('addProperty.additionalDescription')}
|
||||
@ -1519,38 +1557,72 @@ const handleMarkerDragEnd = async (lat, lng) => {
|
||||
<p className="text-gray-600">{t('addProperty.locationAndImagesSubtitle')}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-bold text-gray-900 mb-4">{t('addProperty.selectLocationTitle')}</h3>
|
||||
|
||||
<div className="flex gap-2 mb-4">
|
||||
<div className="flex-1 relative">
|
||||
<input
|
||||
type="text"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
onKeyPress={(e) => e.key === 'Enter' && handleSearch()}
|
||||
placeholder={t('addProperty.searchAddress')}
|
||||
className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500 pr-12"
|
||||
/>
|
||||
<Search className="absolute left-4 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
|
||||
<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="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">
|
||||
<Navigation className="w-4 h-4" />
|
||||
{t('addProperty.selectLocationTitle')}
|
||||
</div>
|
||||
<p className="text-sm text-gray-600">{t('addProperty.clickMapHint')}</p>
|
||||
</div>
|
||||
<div className="inline-flex items-center gap-2 rounded-full border border-amber-200 bg-white px-3 py-1.5 text-sm font-medium text-amber-700 shadow-sm">
|
||||
<MapPin className="w-4 h-4" />
|
||||
{t('addProperty.cityLabel')}
|
||||
</div>
|
||||
<button
|
||||
onClick={handleSearch}
|
||||
className="px-6 py-3 bg-amber-500 text-white rounded-xl hover:bg-amber-600 transition-colors"
|
||||
>
|
||||
{t('addProperty.searchButton')}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="bg-amber-50 border border-amber-200 rounded-xl p-4 mb-4 text-sm text-amber-800 leading-relaxed">
|
||||
<Search className="w-4 h-4 inline ml-1" />
|
||||
{t('addProperty.searchHint')}
|
||||
<br />
|
||||
<MapPin className="w-4 h-4 inline ml-1" />
|
||||
{t('addProperty.clickMapHint')}
|
||||
<div className="grid grid-cols-1 xl:grid-cols-[minmax(220px,260px)_1fr] gap-4 mb-5">
|
||||
<div className="rounded-2xl border border-white/80 bg-white/90 p-4 shadow-sm">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
{t('addProperty.cityLabel')} <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<select
|
||||
value={formData.city}
|
||||
onChange={(e) => setFormData({...formData, city: 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 bg-white"
|
||||
>
|
||||
{GovernorateList.map((city) => (
|
||||
<option key={city} value={city}>
|
||||
{GovernorateLabels[city] || city}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<p className="text-xs text-gray-500 mt-2">{t('addProperty.searchHint')}</p>
|
||||
</div>
|
||||
|
||||
<div className="rounded-2xl border border-white/80 bg-white/90 p-4 shadow-sm">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
{t('addProperty.searchAddress')}
|
||||
</label>
|
||||
<div className="flex flex-col sm:flex-row gap-2">
|
||||
<div className="relative flex-1">
|
||||
<input
|
||||
type="text"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
onKeyPress={(e) => e.key === 'Enter' && handleSearch()}
|
||||
placeholder={t('addProperty.searchAddress')}
|
||||
className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500 pr-10"
|
||||
/>
|
||||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
|
||||
</div>
|
||||
<button
|
||||
onClick={handleSearch}
|
||||
className="px-5 py-3 bg-amber-500 text-white rounded-xl hover:bg-amber-600 transition-colors font-medium flex items-center justify-center gap-2"
|
||||
>
|
||||
<Search className="w-4 h-4" />
|
||||
{t('addProperty.searchButton')}
|
||||
</button>
|
||||
</div>
|
||||
<div className="mt-3 flex items-start gap-2 text-sm text-amber-700">
|
||||
<Info className="w-4 h-4 mt-0.5 shrink-0" />
|
||||
<span>{t('addProperty.clickMapHint')}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative w-full h-96 rounded-xl overflow-hidden border-2 border-gray-200 mb-4">
|
||||
<div className="relative w-full h-96 rounded-2xl overflow-hidden border border-gray-200 shadow-inner">
|
||||
<AddPropertyMap
|
||||
mapCenter={mapCenter}
|
||||
mapZoom={mapZoom}
|
||||
@ -1559,29 +1631,36 @@ const handleMarkerDragEnd = async (lat, lng) => {
|
||||
onMarkerDragEnd={handleMarkerDragEnd}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{selectedLocation && !formData.lat && (
|
||||
<button
|
||||
onClick={confirmLocation}
|
||||
className="w-full mb-4 bg-green-500 text-white py-3 rounded-xl font-medium hover:bg-green-600 transition-colors flex items-center justify-center gap-2"
|
||||
>
|
||||
<CheckCircle className="w-5 h-5" />
|
||||
{t('addProperty.confirmLocation')}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{formData.lat && (
|
||||
<div className="bg-green-50 border border-green-200 rounded-xl p-4 mb-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<CheckCircle className="w-5 h-5 text-green-600" />
|
||||
<span className="text-green-800 font-medium">{t('addProperty.locationConfirmed')}:</span>
|
||||
<div className="mt-4 flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
|
||||
{selectedLocation && !formData.lat ? (
|
||||
<button
|
||||
onClick={confirmLocation}
|
||||
className="w-full md:w-auto bg-green-600 text-white py-3 px-5 rounded-xl font-medium hover:bg-green-700 transition-colors flex items-center justify-center gap-2 shadow-sm"
|
||||
>
|
||||
<CheckCircle className="w-5 h-5" />
|
||||
{t('addProperty.confirmLocation')}
|
||||
</button>
|
||||
) : (
|
||||
<div className="rounded-2xl border border-amber-100 bg-amber-50 px-4 py-3 text-sm text-amber-800 flex items-start gap-2">
|
||||
<Info className="w-4 h-4 mt-0.5 shrink-0" />
|
||||
<span>{t('addProperty.clickMapHint')}</span>
|
||||
</div>
|
||||
<p className="text-green-700 text-sm mt-2 line-clamp-2">{formData.address}</p>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
|
||||
{formData.lat && (
|
||||
<div className="flex-1 rounded-2xl border border-green-200 bg-green-50 p-4">
|
||||
<div className="flex items-center gap-2">
|
||||
<CheckCircle className="w-5 h-5 text-green-600" />
|
||||
<span className="text-green-800 font-medium">{t('addProperty.locationConfirmed')}:</span>
|
||||
</div>
|
||||
<p className="text-green-700 text-sm mt-2 line-clamp-2">{formData.address}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{errors.location && (
|
||||
<p className="text-red-500 text-sm text-center mb-4">{errors.location}</p>
|
||||
<p className="text-red-500 text-sm text-center mt-4">{errors.location}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user