Update registration to match new API schema
All checks were successful
Build frontend / build (push) Successful in 37s

- FullName split into FirstName + LastName in both forms and API
- File fields renamed: FrontIdCarImage -> FrontIdCarImagePath, RearIdCarImage -> RearIdCarImagePath
- Added Language field to form data
- getRentProperty now uses /RentProperties/GetRentPropertyById/{id}
This commit is contained in:
Claw AI
2026-03-28 15:29:06 +00:00
parent bb15a7934e
commit d698305d79
3 changed files with 69 additions and 39 deletions

View File

@ -24,7 +24,8 @@ export default function OwnerRegisterPage() {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
name: '', firstName: '',
lastName: '',
email: '', email: '',
phone: '', phone: '',
whatsapp: '', whatsapp: '',
@ -67,8 +68,9 @@ export default function OwnerRegisterPage() {
const validateStep1 = () => { const validateStep1 = () => {
const newErrors = {}; const newErrors = {};
if (!formData.name) newErrors.name = 'الاسم الكامل مطلوب'; if (!formData.firstName) newErrors.firstName = 'الاسم الأول مطلوب';
else if (formData.name.length < 3) newErrors.name = 'الاسم يجب أن يكون 3 أحرف على الأقل'; if (!formData.lastName) newErrors.lastName = 'اسم العائلة مطلوب';
if (!formData.email) newErrors.email = 'البريد الإلكتروني مطلوب'; if (!formData.email) newErrors.email = 'البريد الإلكتروني مطلوب';
else if (!validateEmail(formData.email)) newErrors.email = 'البريد الإلكتروني غير صالح'; else if (!validateEmail(formData.email)) newErrors.email = 'البريد الإلكتروني غير صالح';
@ -122,8 +124,8 @@ export default function OwnerRegisterPage() {
console.log('[OwnerRegister] Submitting owner registration...'); console.log('[OwnerRegister] Submitting owner registration...');
const payload = { const payload = {
FullName: formData.name, firstName: formData.firstName,
name: formData.name, lastName: formData.lastName,
email: formData.email, email: formData.email,
phoneNumber: formData.phone || '', phoneNumber: formData.phone || '',
whatsAppNumber: formData.whatsapp, whatsAppNumber: formData.whatsapp,
@ -290,18 +292,28 @@ export default function OwnerRegisterPage() {
{/* ─── STEP 1: Form ─── */} {/* ─── STEP 1: Form ─── */}
{step === 1 && ( {step === 1 && (
<> <>
<motion.div variants={fadeInUp}> <motion.div variants={fadeInUp} className="grid grid-cols-2 gap-3">
<label className="block text-sm font-medium text-gray-300 mb-2">الاسم الكامل <span className="text-red-500">*</span></label> <div>
<label className="block text-sm font-medium text-gray-300 mb-2">الاسم الأول <span className="text-red-500">*</span></label>
<div className="relative group"> <div className="relative group">
<div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none"> <div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
<User className={`w-5 h-5 ${errors.name ? 'text-red-500' : 'text-gray-400 group-focus-within:text-amber-500'}`} /> <User className={`w-5 h-5 ${errors.firstName ? 'text-red-500' : 'text-gray-400 group-focus-within:text-amber-500'}`} />
</div> </div>
<input type="text" value={formData.name} <input type="text" value={formData.firstName}
onChange={(e) => { setFormData({...formData, name: e.target.value}); setErrors({...errors, name: null}); }} onChange={(e) => { setFormData({...formData, firstName: e.target.value}); setErrors({...errors, firstName: null}); }}
className={`w-full pr-12 pl-4 py-3 bg-white/5 border rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-transparent text-white placeholder-gray-500 transition-all ${errors.name ? 'border-red-500' : 'border-gray-700'}`} className={`w-full pr-12 pl-4 py-3 bg-white/5 border rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-transparent text-white placeholder-gray-500 transition-all ${errors.firstName ? 'border-red-500' : 'border-gray-700'}`}
placeholder="أدخل اسمك الكامل" /> placeholder="الاسم الأول" />
</div>
{errors.firstName && <p className="text-red-500 text-sm mt-1">{errors.firstName}</p>}
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">اسم العائلة <span className="text-red-500">*</span></label>
<input type="text" value={formData.lastName}
onChange={(e) => { setFormData({...formData, lastName: e.target.value}); setErrors({...errors, lastName: null}); }}
className={`w-full px-4 py-3 bg-white/5 border rounded-xl focus:outline-none focus:ring-2 focus:ring-amber-500 focus:border-transparent text-white placeholder-gray-500 transition-all ${errors.lastName ? 'border-red-500' : 'border-gray-700'}`}
placeholder="اسم العائلة" />
{errors.lastName && <p className="text-red-500 text-sm mt-1">{errors.lastName}</p>}
</div> </div>
{errors.name && <p className="text-red-500 text-sm mt-1">{errors.name}</p>}
</motion.div> </motion.div>
<motion.div variants={fadeInUp}> <motion.div variants={fadeInUp}>

View File

@ -24,9 +24,11 @@ export default function TenantRegisterPage() {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
name: '', firstName: '',
lastName: '',
email: '', email: '',
phone: '', phone: '',
whatsapp: '',
password: '', password: '',
confirmPassword: '', confirmPassword: '',
customerType: CustomerType.PERSONAL, customerType: CustomerType.PERSONAL,
@ -66,8 +68,9 @@ export default function TenantRegisterPage() {
const validateStep1 = () => { const validateStep1 = () => {
const newErrors = {}; const newErrors = {};
if (!formData.name) newErrors.name = 'الاسم الكامل مطلوب'; if (!formData.firstName) newErrors.firstName = 'الاسم الأول مطلوب';
else if (formData.name.length < 3) newErrors.name = 'الاسم يجب أن يكون 3 أحرف على الأقل'; if (!formData.lastName) newErrors.lastName = 'اسم العائلة مطلوب';
if (!formData.email) newErrors.email = 'البريد الإلكتروني مطلوب'; if (!formData.email) newErrors.email = 'البريد الإلكتروني مطلوب';
else if (!validateEmail(formData.email)) newErrors.email = 'البريد الإلكتروني غير صالح'; else if (!validateEmail(formData.email)) newErrors.email = 'البريد الإلكتروني غير صالح';
@ -119,8 +122,8 @@ export default function TenantRegisterPage() {
console.log('[CustomerRegister] Submitting customer registration...'); console.log('[CustomerRegister] Submitting customer registration...');
const payload = { const payload = {
FullName: formData.name, firstName: formData.firstName,
name: formData.name, lastName: formData.lastName,
email: formData.email, email: formData.email,
phoneNumber: formData.phone, phoneNumber: formData.phone,
password: formData.password, password: formData.password,
@ -284,18 +287,28 @@ export default function TenantRegisterPage() {
{/* ─── STEP 1: Form ─── */} {/* ─── STEP 1: Form ─── */}
{step === 1 && ( {step === 1 && (
<> <>
<motion.div variants={fadeInUp}> <motion.div variants={fadeInUp} className="grid grid-cols-2 gap-3">
<label className="block text-sm font-medium text-gray-300 mb-2">الاسم الكامل <span className="text-red-500">*</span></label> <div>
<label className="block text-sm font-medium text-gray-300 mb-2">الاسم الأول <span className="text-red-500">*</span></label>
<div className="relative group"> <div className="relative group">
<div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none"> <div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
<User className={`w-5 h-5 ${errors.name ? 'text-red-500' : 'text-gray-400 group-focus-within:text-blue-500'}`} /> <User className={`w-5 h-5 ${errors.firstName ? 'text-red-500' : 'text-gray-400 group-focus-within:text-blue-500'}`} />
</div> </div>
<input type="text" value={formData.name} <input type="text" value={formData.firstName}
onChange={(e) => { setFormData({...formData, name: e.target.value}); setErrors({...errors, name: null}); }} onChange={(e) => { setFormData({...formData, firstName: e.target.value}); setErrors({...errors, firstName: null}); }}
className={`w-full pr-12 pl-4 py-3 bg-white/5 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-white placeholder-gray-500 transition-all ${errors.name ? 'border-red-500' : 'border-gray-700'}`} className={`w-full pr-12 pl-4 py-3 bg-white/5 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-white placeholder-gray-500 transition-all ${errors.firstName ? 'border-red-500' : 'border-gray-700'}`}
placeholder="أدخل اسمك الكامل" /> placeholder="الاسم الأول" />
</div>
{errors.firstName && <p className="text-red-500 text-sm mt-1">{errors.firstName}</p>}
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">اسم العائلة <span className="text-red-500">*</span></label>
<input type="text" value={formData.lastName}
onChange={(e) => { setFormData({...formData, lastName: e.target.value}); setErrors({...errors, lastName: null}); }}
className={`w-full px-4 py-3 bg-white/5 border rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-white placeholder-gray-500 transition-all ${errors.lastName ? 'border-red-500' : 'border-gray-700'}`}
placeholder="اسم العائلة" />
{errors.lastName && <p className="text-red-500 text-sm mt-1">{errors.lastName}</p>}
</div> </div>
{errors.name && <p className="text-red-500 text-sm mt-1">{errors.name}</p>}
</motion.div> </motion.div>
<motion.div variants={fadeInUp}> <motion.div variants={fadeInUp}>

View File

@ -81,9 +81,7 @@ export async function getRentProperties() {
} }
export async function getRentProperty(id) { export async function getRentProperty(id) {
const items = await apiFetch('/RentProperties/GetRentProperties'); return apiFetch(`/RentProperties/GetRentPropertyById/${id}`);
if (!Array.isArray(items)) return items;
return items.find(p => p.id == id) || items[0];
} }
export async function getRentPropertyLocations(params = {}) { export async function getRentPropertyLocations(params = {}) {
@ -190,15 +188,18 @@ export async function addOwner(data, frontImage = null, backImage = null) {
console.log('[Auth] Registering owner (multipart):', data.email); console.log('[Auth] Registering owner (multipart):', data.email);
const formData = new FormData(); const formData = new FormData();
formData.append('FullName', data.name || data.FullName || ''); formData.append('FirstName', data.firstName || data.FirstName || '');
formData.append('LastName', data.lastName || data.LastName || '');
formData.append('Email', data.email || ''); formData.append('Email', data.email || '');
formData.append('PhoneNumber', data.phoneNumber || ''); formData.append('PhoneNumber', data.phoneNumber || '');
formData.append('WhatsAppNumber', data.whatsAppNumber || ''); formData.append('WhatsAppNumber', data.whatsAppNumber || '');
formData.append('NationalNumber', data.nationalNumber || '');
formData.append('Password', data.password || ''); formData.append('Password', data.password || '');
formData.append('Type', String(data.ownerType ?? data.Type ?? 0)); formData.append('Type', String(data.ownerType ?? data.Type ?? 0));
formData.append('Language', '0');
if (frontImage) formData.append('FrontIdCarImage', frontImage); if (frontImage) formData.append('FrontIdCarImagePath', frontImage);
if (backImage) formData.append('RearIdCarImage', backImage); if (backImage) formData.append('RearIdCarImagePath', backImage);
return multipartAuthFetch('/Owner/Add', formData); return multipartAuthFetch('/Owner/Add', formData);
} }
@ -207,14 +208,18 @@ export async function addCustomer(data, frontImage = null, backImage = null) {
console.log('[Auth] Registering customer (multipart):', data.email); console.log('[Auth] Registering customer (multipart):', data.email);
const formData = new FormData(); const formData = new FormData();
formData.append('FullName', data.name || data.FullName || ''); formData.append('FirstName', data.firstName || data.FirstName || '');
formData.append('LastName', data.lastName || data.LastName || '');
formData.append('Email', data.email || ''); formData.append('Email', data.email || '');
formData.append('PhoneNumber', data.phoneNumber || ''); formData.append('PhoneNumber', data.phoneNumber || '');
formData.append('WhatsAppNumber', data.whatsAppNumber || '');
formData.append('NationalNumber', data.nationalNumber || '');
formData.append('Password', data.password || ''); formData.append('Password', data.password || '');
formData.append('Type', String(data.customerType ?? data.Type ?? 0)); formData.append('Type', String(data.customerType ?? data.Type ?? 0));
formData.append('Language', '0');
if (frontImage) formData.append('FrontIdCarImage', frontImage); if (frontImage) formData.append('FrontIdCarImagePath', frontImage);
if (backImage) formData.append('RearIdCarImage', backImage); if (backImage) formData.append('RearIdCarImagePath', backImage);
return multipartAuthFetch('/Customer/Add', formData); return multipartAuthFetch('/Customer/Add', formData);
} }