Add currency dropdown and deposit field to add property form
All checks were successful
Build frontend / build (push) Successful in 53s
All checks were successful
Build frontend / build (push) Successful in 53s
- Added getCurrencies() API function for /Currency/GetAll - Currency dropdown fetched on mount, populated with available currencies - Added deposit input field (مبلغ الضمان) - CurrencyId sent in RentPropertyDto instead of hardcoded 1
This commit is contained in:
@ -51,7 +51,7 @@ import {
|
|||||||
Move
|
Move
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import toast, { Toaster } from 'react-hot-toast';
|
import toast, { Toaster } from 'react-hot-toast';
|
||||||
import { addRentProperty } from '../../../utils/api';
|
import { addRentProperty, getCurrencies } from '../../../utils/api';
|
||||||
|
|
||||||
const MapContainer = dynamic(() => import('react-leaflet').then(mod => mod.MapContainer), { ssr: false });
|
const MapContainer = dynamic(() => import('react-leaflet').then(mod => mod.MapContainer), { ssr: false });
|
||||||
const TileLayer = dynamic(() => import('react-leaflet').then(mod => mod.TileLayer), { ssr: false });
|
const TileLayer = dynamic(() => import('react-leaflet').then(mod => mod.TileLayer), { ssr: false });
|
||||||
@ -127,6 +127,8 @@ export default function AddPropertyPage() {
|
|||||||
const [mapZoom, setMapZoom] = useState(13);
|
const [mapZoom, setMapZoom] = useState(13);
|
||||||
const [searchQuery, setSearchQuery] = useState('');
|
const [searchQuery, setSearchQuery] = useState('');
|
||||||
const [mapLoaded, setMapLoaded] = useState(false);
|
const [mapLoaded, setMapLoaded] = useState(false);
|
||||||
|
const [currencies, setCurrencies] = useState([]);
|
||||||
|
const [selectedCurrencyId, setSelectedCurrencyId] = useState(1);
|
||||||
|
|
||||||
const [errors, setErrors] = useState({});
|
const [errors, setErrors] = useState({});
|
||||||
|
|
||||||
@ -178,6 +180,17 @@ export default function AddPropertyPage() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setMapLoaded(true);
|
setMapLoaded(true);
|
||||||
|
|
||||||
|
// Fetch available currencies
|
||||||
|
getCurrencies().then((data) => {
|
||||||
|
if (Array.isArray(data) && data.length > 0) {
|
||||||
|
setCurrencies(data);
|
||||||
|
setSelectedCurrencyId(data[0].id);
|
||||||
|
console.log('[AddProperty] Currencies loaded:', data);
|
||||||
|
}
|
||||||
|
}).catch((err) => {
|
||||||
|
console.warn('[AddProperty] Failed to load currencies:', err);
|
||||||
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleSearch = async () => {
|
const handleSearch = async () => {
|
||||||
@ -537,7 +550,7 @@ const handleMapClick = async (coords) => {
|
|||||||
MonthlyRent: parseFloat(formData.monthlyPrice) || 0,
|
MonthlyRent: parseFloat(formData.monthlyPrice) || 0,
|
||||||
DailyRent: parseFloat(formData.dailyPrice) || 0,
|
DailyRent: parseFloat(formData.dailyPrice) || 0,
|
||||||
Rating: 0,
|
Rating: 0,
|
||||||
CurrencyId: 1,
|
CurrencyId: selectedCurrencyId,
|
||||||
RentType: rentTypeMap[formData.offerType] ?? 0,
|
RentType: rentTypeMap[formData.offerType] ?? 0,
|
||||||
IsSmokeAllow: !formData.terms?.noSmoking,
|
IsSmokeAllow: !formData.terms?.noSmoking,
|
||||||
SpecializedFor: false,
|
SpecializedFor: false,
|
||||||
@ -908,6 +921,43 @@ function MapClickHandler({ onMapClick }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Currency dropdown */}
|
||||||
|
{currencies.length > 0 && (
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
العملة <span className="text-red-500">*</span>
|
||||||
|
</label>
|
||||||
|
<select
|
||||||
|
value={selectedCurrencyId}
|
||||||
|
onChange={(e) => setSelectedCurrencyId(parseInt(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"
|
||||||
|
>
|
||||||
|
{currencies.map((c) => (
|
||||||
|
<option key={c.id} value={c.id}>
|
||||||
|
{c.name || c.sign || `Currency ${c.id}`}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Deposit field */}
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||||
|
مبلغ الضمان (العربون)
|
||||||
|
</label>
|
||||||
|
<div className="relative">
|
||||||
|
<DollarSign className="absolute right-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
value={formData.deposit || ''}
|
||||||
|
onChange={(e) => setFormData({...formData, deposit: e.target.value})}
|
||||||
|
className="w-full pr-12 pl-4 py-3 border border-gray-300 rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500"
|
||||||
|
placeholder="مثال: 500000"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<AnimatePresence mode="wait">
|
<AnimatePresence mode="wait">
|
||||||
{(formData.offerType === 'daily' || formData.offerType === 'both') && (
|
{(formData.offerType === 'daily' || formData.offerType === 'both') && (
|
||||||
<motion.div
|
<motion.div
|
||||||
|
|||||||
@ -179,6 +179,12 @@ export async function addRentProperty(data) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Currencies ───
|
||||||
|
|
||||||
|
export async function getCurrencies() {
|
||||||
|
return apiFetch('/Currency/GetAll');
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Auth: Registration ───
|
// ─── Auth: Registration ───
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user