From a5577765ed5a0bb97cf405b2b2a2a6c902070850 Mon Sep 17 00:00:00 2001 From: Rahaf Date: Sun, 10 May 2026 16:21:32 +0300 Subject: [PATCH] Edit register for tenant --- app/register/tenant/page.js | 949 ++++++++++++++++++++++++++---------- 1 file changed, 687 insertions(+), 262 deletions(-) diff --git a/app/register/tenant/page.js b/app/register/tenant/page.js index a136068..81ead86 100644 --- a/app/register/tenant/page.js +++ b/app/register/tenant/page.js @@ -1,14 +1,632 @@ +// 'use client'; + +// import { useState, useRef, useMemo } from 'react'; +// import { motion, AnimatePresence } from 'framer-motion'; +// import { useRouter } from 'next/navigation'; +// import Link from 'next/link'; +// import Image from 'next/image'; +// import { +// User, Mail, Phone, Lock, Eye, EyeOff, +// CheckCircle, XCircle, ArrowLeft, Home, Loader2, +// Shield, KeyRound, Camera, X +// } from 'lucide-react'; +// import toast, { Toaster } from 'react-hot-toast'; +// import { addCustomer, loginWithEmail, sendEmailOTP, verifyEmail } from '../../utils/api'; +// import AuthService from '../../services/AuthService'; +// import { CustomerType, CustomerTypeLabels } from '../../enums'; + +// export default function TenantRegisterPage() { +// const router = useRouter(); +// const [step, setStep] = useState(1); // 1=form, 2=id images +// const [showOtpModal, setShowOtpModal] = useState(false); +// const [showPassword, setShowPassword] = useState(false); +// const [showConfirmPassword, setShowConfirmPassword] = useState(false); +// const [isLoading, setIsLoading] = useState(false); + +// const [formData, setFormData] = useState({ +// firstName: '', +// lastName: '', +// email: '', +// phone: '', +// whatsapp: '', +// phone2: '', +// nationalNumber: '', +// password: '', +// confirmPassword: '', +// customerType: CustomerType.PERSONAL, +// agreeTerms: false +// }); + +// const [idImages, setIdImages] = useState({ front: null, back: null }); +// const [idImagePreviews, setIdImagePreviews] = useState({ front: '', back: '' }); +// const [otpCode, setOtpCode] = useState(''); +// const [errors, setErrors] = useState({}); + +// const fileInputFrontRef = useRef(null); +// const fileInputBackRef = useRef(null); + +// const handleImageUpload = (side, file) => { +// if (!file) return; +// if (!file.type.startsWith('image/')) { +// toast.error('الرجاء اختيار صورة صالحة'); +// return; +// } +// if (file.size > 5 * 1024 * 1024) { +// toast.error('حجم الصورة يجب أن يكون أقل من 5 ميجابايت'); +// return; +// } +// const reader = new FileReader(); +// reader.onloadend = () => { +// setIdImagePreviews(prev => ({ ...prev, [side]: reader.result })); +// }; +// reader.readAsDataURL(file); +// setIdImages(prev => ({ ...prev, [side]: file })); +// console.log('[CustomerRegister] Image uploaded:', side); +// toast.success('تم رفع الصورة بنجاح', { style: { background: '#dcfce7', color: '#166534' } }); +// }; + +// const validateEmail = (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); +// const validatePhone = (phone) => /^(09|05)[0-9]{8}$/.test(phone); + +// const validateStep1 = () => { +// const newErrors = {}; +// if (!formData.firstName) newErrors.firstName = 'الاسم الأول مطلوب'; +// if (!formData.lastName) newErrors.lastName = 'اسم العائلة مطلوب'; + + +// if (!formData.email) newErrors.email = 'البريد الإلكتروني مطلوب'; +// else if (!validateEmail(formData.email)) newErrors.email = 'البريد الإلكتروني غير صالح'; + +// if (!formData.phone) newErrors.phone = 'رقم الهاتف مطلوب'; +// else if (!validatePhone(formData.phone)) newErrors.phone = 'رقم الهاتف غير صالح (يجب أن يبدأ 09 أو 05)'; + +// if (!formData.password) newErrors.password = 'كلمة المرور مطلوبة'; +// else if (formData.password.length < 6) newErrors.password = 'كلمة المرور يجب أن تكون 6 أحرف على الأقل'; + +// if (!formData.whatsapp) newErrors.whatsapp = 'رقم الواتساب مطلوب'; +// if (!formData.phone2 || formData.phone2.length !== 7) newErrors.phone2 = 'رقم الهاتف يجب أن يكون 7 أرقام'; +// if (!formData.nationalNumber) newErrors.nationalNumber = 'الرقم الوطني مطلوب'; +// if (formData.password !== formData.confirmPassword) newErrors.confirmPassword = 'كلمات المرور غير متطابقة'; + +// setErrors(newErrors); +// return Object.keys(newErrors).length === 0; +// }; + +// const validateStep2 = () => { +// const newErrors = {}; +// if (!idImages.front) newErrors.front = 'صورة الوجه الأمامي للهوية مطلوبة'; +// if (!idImages.back) newErrors.back = 'صورة الوجه الخلفي للهوية مطلوبة'; +// setErrors(newErrors); +// return Object.keys(newErrors).length === 0; +// }; + +// const handleNextStep = () => { +// if (validateStep1()) { +// console.log('[CustomerRegister] Step 1 valid, moving to step 2'); +// setStep(2); +// window.scrollTo({ top: 0, behavior: 'smooth' }); +// } else { +// toast.error('يرجى تصحيح الأخطاء في النموذج'); +// } +// }; + +// // ─── Main signup handler ─── +// const handleSubmit = async (e) => { +// e.preventDefault(); + +// if (!validateStep2()) { +// toast.error('يرجى إكمال جميع الصور المطلوبة'); +// return; +// } +// if (!formData.agreeTerms) { +// toast.error('يجب الموافقة على الشروط والأحكام'); +// return; +// } + +// setIsLoading(true); +// console.log('[CustomerRegister] Submitting customer registration...'); + +// const payload = { +// firstName: formData.firstName, +// lastName: formData.lastName, +// email: formData.email, +// phoneNumber: formData.phone, +// whatsAppNumber: formData.whatsapp, +// phone: formData.phone2, +// nationalNumber: formData.nationalNumber, +// password: formData.password, +// customerType: formData.customerType, +// }; + +// try { +// const res = await addCustomer(payload, idImages.front, idImages.back); +// console.log('[CustomerRegister] addCustomer response:', res); + +// if (res.status === 200 || res.ok) { +// const tempToken = res.data; +// if (tempToken) { +// AuthService.addToken(tempToken); +// console.log('[CustomerRegister] Temp token stored for OTP'); +// } + +// const apiMessage = res.message || res.data?.message; +// toast.success(apiMessage || 'تم إنشاء الحساب! يرجى التحقق من بريدك الإلكتروني', { duration: 4000 }); + +// // Auto-login to trigger OTP +// console.log('[CustomerRegister] Auto-login to send OTP...'); +// const loginRes = await loginWithEmail(formData.email, formData.password); +// console.log('[CustomerRegister] login response:', loginRes); + +// if (loginRes.status === 206) { +// const otpToken = loginRes.data; +// if (otpToken) AuthService.addToken(otpToken); +// const loginMsg = loginRes.message || loginRes.data?.message; +// toast(loginMsg || 'تم إرسال رمز التحقق إلى بريدك الإلكتروني', { icon: '📧' }); +// setShowOtpModal(true); +// } else if (loginRes.status === 200) { +// const loginToken = loginRes.data; +// if (loginToken) AuthService.addToken(loginToken); +// toast.success(loginRes.message || 'تم تسجيل الدخول بنجاح!'); +// router.push('/'); +// } +// } else { +// const errMsg = res.message || res.data?.message || 'فشل في إنشاء الحساب'; +// console.error('[CustomerRegister] Registration failed:', errMsg); +// toast.error(errMsg); +// } +// } catch (err) { +// console.error('[CustomerRegister] Error:', err); +// toast.error(err.message || 'حدث خطأ أثناء التسجيل'); +// } finally { +// setIsLoading(false); +// } +// }; + +// // ─── OTP verification handler ─── +// const handleVerifyOTP = async () => { +// if (!otpCode || otpCode.length < 4) { +// toast.error('يرجى إدخال رمز التحقق'); +// return; +// } + +// setIsLoading(true); +// console.log('[CustomerRegister] Verifying OTP:', otpCode); + +// try { +// const res = await verifyEmail(otpCode); +// console.log('[CustomerRegister] VerifyEmail response:', res); + +// if (res.status === 200) { +// AuthService.deleteToken(); +// console.log('[CustomerRegister] Temp token removed after verification'); +// toast.success(res.message || 'تم التحقق من البريد الإلكتروني بنجاح!', { duration: 3000 }); +// setShowOtpModal(false); +// setTimeout(() => router.push('/login'), 1500); +// } else { +// const errMsg = res.message || res.data?.message || 'رمز التحقق غير صحيح'; +// console.error('[CustomerRegister] Verification failed:', errMsg); +// toast.error(errMsg); +// } +// } catch (err) { +// console.error('[CustomerRegister] Verify error:', err); +// toast.error(err.message || 'حدث خطأ أثناء التحقق'); +// } finally { +// setIsLoading(false); +// } +// }; + +// const handleResendOTP = async () => { +// setIsLoading(true); +// console.log('[CustomerRegister] Resending email OTP...'); +// try { +// await sendEmailOTP(); +// toast.success('تم إرسال رمز تحقق جديد'); +// } catch (err) { +// console.error('[CustomerRegister] Resend OTP error:', err); +// toast.error('فشل في إرسال الرمز'); +// } finally { +// setIsLoading(false); +// } +// }; + +// const fadeInUp = { +// initial: { opacity: 0, y: 20 }, +// animate: { opacity: 1, y: 0 }, +// transition: { duration: 0.5 } +// }; + +// const staggerContainer = { +// animate: { transition: { staggerChildren: 0.1 } } +// }; + + +// const backgroundElements = useMemo(() => { +// const circles = [ +// { style: { top: '20%', right: '20%', width: '256px', height: '256px' }, className: 'bg-blue-500/10' }, +// { style: { bottom: '20%', left: '20%', width: '320px', height: '320px' }, className: 'bg-blue-500/10' }, +// { style: { top: '50%', left: '50%', width: '384px', height: '384px', transform: 'translate(-50%, -50%)' }, className: 'bg-blue-500/10' }, +// ]; + +// const dots = [ +// { left: '5%', top: '10%', size: '120px' }, +// { left: '15%', top: '70%', size: '80px' }, +// { left: '25%', top: '30%', size: '150px' }, +// { left: '35%', top: '85%', size: '100px' }, +// { left: '45%', top: '15%', size: '90px' }, +// { left: '55%', top: '60%', size: '130px' }, +// { left: '65%', top: '40%', size: '70px' }, +// { left: '75%', top: '80%', size: '110px' }, +// { left: '85%', top: '20%', size: '140px' }, +// { left: '95%', top: '50%', size: '85px' }, +// ]; + +// return ( +// <> +// {circles.map((circle, i) => ( +//
+// ))} +// {dots.map((dot, i) => ( +//
+// ))} +// +// ); +// }, []); +// return ( +//
+// + +// {/*
+// {[...Array(20)].map((_, i) => ( +// +// ))} +//
*/} +//
+// {backgroundElements} +//
+// +// {/* Back */} +// +// +// +// العودة +// +// + +// {/* Progress */} +//
+// {[1, 2].map((s) => ( +// = s ? 'bg-blue-500' : 'bg-gray-700'}`} animate={{ scaleX: step >= s ? 1 : 0.5 }} /> +// ))} +//
+ +//
+//
+// +// +// +// +// +//

+// {step === 1 ? 'إنشاء حساب مستأجر' : 'الوثائق الرسمية'} +//

+//

+// {step === 1 ? 'انضم إلينا وابحث عن منزل أحلامك' : 'يرجى رفع صور الهوية للتحقق'} +//

+//
+//
+ +//
+// { e.preventDefault(); handleNextStep(); } : handleSubmit} +// className="space-y-6"> + +// {/* ─── STEP 1: Form ─── */} +// {step === 1 && ( +// <> +// +//
+// +//
+//
+// +//
+// { 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.firstName ? 'border-red-500' : 'border-gray-700'}`} +// placeholder="الاسم الأول" /> +//
+// {errors.firstName &&

{errors.firstName}

} +//
+//
+// +// { 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 &&

{errors.lastName}

} +//
+//
+ +// +// +//
+//
+// +//
+// { setFormData({...formData, email: e.target.value}); setErrors({...errors, email: 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.email ? 'border-red-500' : 'border-gray-700'}`} +// placeholder="أدخل بريدك الإلكتروني" /> +//
+// {errors.email &&

{errors.email}

} +//
+ +// +// +//
+//
+// +//
+// { setFormData({...formData, phone: e.target.value}); setErrors({...errors, phone: 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.phone ? 'border-red-500' : 'border-gray-700'}`} +// placeholder="أدخل رقم هاتفك" /> +//
+// {errors.phone &&

{errors.phone}

} +//
+ +// +// +//
+//
+// +//
+// { setFormData({...formData, whatsapp: e.target.value}); setErrors({...errors, whatsapp: 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.whatsapp ? 'border-red-500' : 'border-gray-700'}`} +// placeholder="أدخل رقم الواتساب" /> +//
+// {errors.whatsapp &&

{errors.whatsapp}

} +//
+ +// +// +//
+//
+// +//
+// { setFormData({...formData, phone2: e.target.value}); setErrors({...errors, phone2: 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.phone2 ? 'border-red-500' : 'border-gray-700'}`} +// placeholder="أدخل رقم الهاتف" maxLength={7} /> +//
+// {errors.phone2 &&

{errors.phone2}

} +//
+ +// +// +//
+//
+// +//
+// { setFormData({...formData, nationalNumber: e.target.value}); setErrors({...errors, nationalNumber: 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.nationalNumber ? 'border-red-500' : 'border-gray-700'}`} +// placeholder="أدخل الرقم الوطني" /> +//
+// {errors.nationalNumber &&

{errors.nationalNumber}

} +//
+ +// +// +// +// + +// +// +//
+//
+// +//
+// { setFormData({...formData, password: e.target.value}); setErrors({...errors, password: null}); }} +// className={`w-full pr-12 pl-12 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.password ? 'border-red-500' : 'border-gray-700'}`} +// placeholder="أدخل كلمة المرور" /> +// +//
+// {errors.password &&

{errors.password}

} +//
+ +// +// +//
+//
+// +//
+// { setFormData({...formData, confirmPassword: e.target.value}); setErrors({...errors, confirmPassword: null}); }} +// className={`w-full pr-12 pl-12 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.confirmPassword ? 'border-red-500' : 'border-gray-700'}`} +// placeholder="أعد إدخال كلمة المرور" /> +// +// {formData.confirmPassword && ( +//
+// {formData.password === formData.confirmPassword ? : } +//
+// )} +//
+// {errors.confirmPassword &&

{errors.confirmPassword}

} +//
+// +// )} + +// {/* ─── STEP 2: ID Images ─── */} +// {step === 2 && ( +// <> +// +// +//
fileInputFrontRef.current?.click()} +// className={`relative border-2 border-dashed rounded-xl p-6 text-center cursor-pointer transition-all ${idImagePreviews.front ? 'border-green-500 bg-green-500/10' : errors.front ? 'border-red-500 bg-red-500/10' : 'border-gray-700 hover:border-blue-500 hover:bg-white/5'}`}> +// handleImageUpload('front', e.target.files?.[0])} className="hidden" /> +// {idImagePreviews.front ? ( +//
+// Front ID +// +//
+// ) : (<>

اضغط لرفع الصورة

JPEG, PNG, JPG • حتى 5MB

)} +//
+// {errors.front &&

{errors.front}

} +//
+ +// +// +//
fileInputBackRef.current?.click()} +// className={`relative border-2 border-dashed rounded-xl p-6 text-center cursor-pointer transition-all ${idImagePreviews.back ? 'border-green-500 bg-green-500/10' : errors.back ? 'border-red-500 bg-red-500/10' : 'border-gray-700 hover:border-blue-500 hover:bg-white/5'}`}> +// handleImageUpload('back', e.target.files?.[0])} className="hidden" /> +// {idImagePreviews.back ? ( +//
+// Back ID +// +//
+// ) : (<>

اضغط لرفع الصورة

JPEG, PNG, JPG • حتى 5MB

)} +//
+// {errors.back &&

{errors.back}

} +//
+ +// +// setFormData({...formData, agreeTerms: e.target.checked})} +// className="w-4 h-4 rounded border-gray-600 bg-white/5 text-blue-500 focus:ring-blue-500" required /> +// +// +// +// )} + +// {/* ─── Buttons ─── */} +// +// {step === 1 ? ( +// <> +// +// +// +// ) : ( +// <> +// +// +// +// )} +// + +// {step === 1 && ( +// +// لديك حساب بالفعل؟{' '} +// تسجيل الدخول +// +// )} +//
+//
+//
+//
+ +// {/* ─── OTP Modal ─── */} +// +// {showOtpModal && ( +// +// +//
+//
+// +//
+//

التحقق من البريد

+//

تم إرسال رمز التحقق إلى

+//

{formData.email}

+//
+ +//
+// +//
+//
+// +//
+// setOtpCode(e.target.value)} +// className="w-full pr-12 pl-4 py-3 bg-white/5 border border-gray-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-white text-center tracking-[0.5em] text-xl" +// placeholder="------" /> +//
+//
+ +//
+// +//
+ +// +//
+//
+// )} +//
+//
+// ); +// } + + + +// app/register/tenant/page.js + 'use client'; -import { useState, useRef, useMemo } from 'react'; +import { useState, useMemo } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; -import Image from 'next/image'; import { User, Mail, Phone, Lock, Eye, EyeOff, CheckCircle, XCircle, ArrowLeft, Home, Loader2, - Shield, KeyRound, Camera, X + Shield, KeyRound } from 'lucide-react'; import toast, { Toaster } from 'react-hot-toast'; import { addCustomer, loginWithEmail, sendEmailOTP, verifyEmail } from '../../utils/api'; @@ -17,7 +635,7 @@ import { CustomerType, CustomerTypeLabels } from '../../enums'; export default function TenantRegisterPage() { const router = useRouter(); - const [step, setStep] = useState(1); // 1=form, 2=id images + const [step, setStep] = useState(1); // 1=form, 2=agree terms (no images) const [showOtpModal, setShowOtpModal] = useState(false); const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); @@ -37,34 +655,9 @@ export default function TenantRegisterPage() { agreeTerms: false }); - const [idImages, setIdImages] = useState({ front: null, back: null }); - const [idImagePreviews, setIdImagePreviews] = useState({ front: '', back: '' }); const [otpCode, setOtpCode] = useState(''); const [errors, setErrors] = useState({}); - const fileInputFrontRef = useRef(null); - const fileInputBackRef = useRef(null); - - const handleImageUpload = (side, file) => { - if (!file) return; - if (!file.type.startsWith('image/')) { - toast.error('الرجاء اختيار صورة صالحة'); - return; - } - if (file.size > 5 * 1024 * 1024) { - toast.error('حجم الصورة يجب أن يكون أقل من 5 ميجابايت'); - return; - } - const reader = new FileReader(); - reader.onloadend = () => { - setIdImagePreviews(prev => ({ ...prev, [side]: reader.result })); - }; - reader.readAsDataURL(file); - setIdImages(prev => ({ ...prev, [side]: file })); - console.log('[CustomerRegister] Image uploaded:', side); - toast.success('تم رفع الصورة بنجاح', { style: { background: '#dcfce7', color: '#166534' } }); - }; - const validateEmail = (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); const validatePhone = (phone) => /^(09|05)[0-9]{8}$/.test(phone); @@ -72,37 +665,22 @@ export default function TenantRegisterPage() { const newErrors = {}; if (!formData.firstName) newErrors.firstName = 'الاسم الأول مطلوب'; if (!formData.lastName) newErrors.lastName = 'اسم العائلة مطلوب'; - - if (!formData.email) newErrors.email = 'البريد الإلكتروني مطلوب'; else if (!validateEmail(formData.email)) newErrors.email = 'البريد الإلكتروني غير صالح'; - if (!formData.phone) newErrors.phone = 'رقم الهاتف مطلوب'; else if (!validatePhone(formData.phone)) newErrors.phone = 'رقم الهاتف غير صالح (يجب أن يبدأ 09 أو 05)'; - if (!formData.password) newErrors.password = 'كلمة المرور مطلوبة'; else if (formData.password.length < 6) newErrors.password = 'كلمة المرور يجب أن تكون 6 أحرف على الأقل'; - if (!formData.whatsapp) newErrors.whatsapp = 'رقم الواتساب مطلوب'; if (!formData.phone2 || formData.phone2.length !== 7) newErrors.phone2 = 'رقم الهاتف يجب أن يكون 7 أرقام'; if (!formData.nationalNumber) newErrors.nationalNumber = 'الرقم الوطني مطلوب'; if (formData.password !== formData.confirmPassword) newErrors.confirmPassword = 'كلمات المرور غير متطابقة'; - - setErrors(newErrors); - return Object.keys(newErrors).length === 0; - }; - - const validateStep2 = () => { - const newErrors = {}; - if (!idImages.front) newErrors.front = 'صورة الوجه الأمامي للهوية مطلوبة'; - if (!idImages.back) newErrors.back = 'صورة الوجه الخلفي للهوية مطلوبة'; setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const handleNextStep = () => { if (validateStep1()) { - console.log('[CustomerRegister] Step 1 valid, moving to step 2'); setStep(2); window.scrollTo({ top: 0, behavior: 'smooth' }); } else { @@ -110,14 +688,9 @@ export default function TenantRegisterPage() { } }; - // ─── Main signup handler ─── const handleSubmit = async (e) => { e.preventDefault(); - if (!validateStep2()) { - toast.error('يرجى إكمال جميع الصور المطلوبة'); - return; - } if (!formData.agreeTerms) { toast.error('يجب الموافقة على الشروط والأحكام'); return; @@ -139,29 +712,24 @@ export default function TenantRegisterPage() { }; try { - const res = await addCustomer(payload, idImages.front, idImages.back); + // لا توجد صور للمستأجر + const res = await addCustomer(payload, null, null); console.log('[CustomerRegister] addCustomer response:', res); if (res.status === 200 || res.ok) { const tempToken = res.data; if (tempToken) { AuthService.addToken(tempToken); - console.log('[CustomerRegister] Temp token stored for OTP'); } const apiMessage = res.message || res.data?.message; toast.success(apiMessage || 'تم إنشاء الحساب! يرجى التحقق من بريدك الإلكتروني', { duration: 4000 }); - // Auto-login to trigger OTP - console.log('[CustomerRegister] Auto-login to send OTP...'); const loginRes = await loginWithEmail(formData.email, formData.password); - console.log('[CustomerRegister] login response:', loginRes); - if (loginRes.status === 206) { const otpToken = loginRes.data; if (otpToken) AuthService.addToken(otpToken); - const loginMsg = loginRes.message || loginRes.data?.message; - toast(loginMsg || 'تم إرسال رمز التحقق إلى بريدك الإلكتروني', { icon: '📧' }); + toast(loginRes.message || 'تم إرسال رمز التحقق إلى بريدك الإلكتروني', { icon: '📧' }); setShowOtpModal(true); } else if (loginRes.status === 200) { const loginToken = loginRes.data; @@ -171,44 +739,32 @@ export default function TenantRegisterPage() { } } else { const errMsg = res.message || res.data?.message || 'فشل في إنشاء الحساب'; - console.error('[CustomerRegister] Registration failed:', errMsg); toast.error(errMsg); } } catch (err) { - console.error('[CustomerRegister] Error:', err); toast.error(err.message || 'حدث خطأ أثناء التسجيل'); } finally { setIsLoading(false); } }; - // ─── OTP verification handler ─── const handleVerifyOTP = async () => { if (!otpCode || otpCode.length < 4) { toast.error('يرجى إدخال رمز التحقق'); return; } - setIsLoading(true); - console.log('[CustomerRegister] Verifying OTP:', otpCode); - try { const res = await verifyEmail(otpCode); - console.log('[CustomerRegister] VerifyEmail response:', res); - if (res.status === 200) { AuthService.deleteToken(); - console.log('[CustomerRegister] Temp token removed after verification'); - toast.success(res.message || 'تم التحقق من البريد الإلكتروني بنجاح!', { duration: 3000 }); + toast.success(res.message || 'تم التحقق من البريد الإلكتروني بنجاح!'); setShowOtpModal(false); setTimeout(() => router.push('/login'), 1500); } else { - const errMsg = res.message || res.data?.message || 'رمز التحقق غير صحيح'; - console.error('[CustomerRegister] Verification failed:', errMsg); - toast.error(errMsg); + toast.error(res.message || res.data?.message || 'رمز التحقق غير صحيح'); } } catch (err) { - console.error('[CustomerRegister] Verify error:', err); toast.error(err.message || 'حدث خطأ أثناء التحقق'); } finally { setIsLoading(false); @@ -217,12 +773,10 @@ export default function TenantRegisterPage() { const handleResendOTP = async () => { setIsLoading(true); - console.log('[CustomerRegister] Resending email OTP...'); try { await sendEmailOTP(); toast.success('تم إرسال رمز تحقق جديد'); } catch (err) { - console.error('[CustomerRegister] Resend OTP error:', err); toast.error('فشل في إرسال الرمز'); } finally { setIsLoading(false); @@ -239,64 +793,42 @@ export default function TenantRegisterPage() { animate: { transition: { staggerChildren: 0.1 } } }; - const backgroundElements = useMemo(() => { - const circles = [ - { style: { top: '20%', right: '20%', width: '256px', height: '256px' }, className: 'bg-blue-500/10' }, - { style: { bottom: '20%', left: '20%', width: '320px', height: '320px' }, className: 'bg-blue-500/10' }, - { style: { top: '50%', left: '50%', width: '384px', height: '384px', transform: 'translate(-50%, -50%)' }, className: 'bg-blue-500/10' }, - ]; + const circles = [ + { style: { top: '20%', right: '20%', width: '256px', height: '256px' }, className: 'bg-blue-500/10' }, + { style: { bottom: '20%', left: '20%', width: '320px', height: '320px' }, className: 'bg-blue-500/10' }, + { style: { top: '50%', left: '50%', width: '384px', height: '384px', transform: 'translate(-50%, -50%)' }, className: 'bg-blue-500/10' }, + ]; + const dots = [ + { left: '5%', top: '10%', size: '120px' }, + { left: '15%', top: '70%', size: '80px' }, + { left: '25%', top: '30%', size: '150px' }, + { left: '35%', top: '85%', size: '100px' }, + { left: '45%', top: '15%', size: '90px' }, + { left: '55%', top: '60%', size: '130px' }, + { left: '65%', top: '40%', size: '70px' }, + { left: '75%', top: '80%', size: '110px' }, + { left: '85%', top: '20%', size: '140px' }, + { left: '95%', top: '50%', size: '85px' }, + ]; + return ( + <> + {circles.map((circle, i) => ( +
+ ))} + {dots.map((dot, i) => ( +
+ ))} + + ); + }, []); - const dots = [ - { left: '5%', top: '10%', size: '120px' }, - { left: '15%', top: '70%', size: '80px' }, - { left: '25%', top: '30%', size: '150px' }, - { left: '35%', top: '85%', size: '100px' }, - { left: '45%', top: '15%', size: '90px' }, - { left: '55%', top: '60%', size: '130px' }, - { left: '65%', top: '40%', size: '70px' }, - { left: '75%', top: '80%', size: '110px' }, - { left: '85%', top: '20%', size: '140px' }, - { left: '95%', top: '50%', size: '85px' }, - ]; - - return ( - <> - {circles.map((circle, i) => ( -
- ))} - {dots.map((dot, i) => ( -
- ))} - - ); -}, []); return (
+
{backgroundElements}
- {/*
- {[...Array(20)].map((_, i) => ( - - ))} -
*/} -
- {backgroundElements} -
- - {/* Back */} + @@ -304,7 +836,6 @@ export default function TenantRegisterPage() { - {/* Progress */}
{[1, 2].map((s) => ( = s ? 'bg-blue-500' : 'bg-gray-700'}`} animate={{ scaleX: step >= s ? 1 : 0.5 }} /> @@ -313,28 +844,18 @@ export default function TenantRegisterPage() {
- + - + -

- {step === 1 ? 'إنشاء حساب مستأجر' : 'الوثائق الرسمية'} -

-

- {step === 1 ? 'انضم إلينا وابحث عن منزل أحلامك' : 'يرجى رفع صور الهوية للتحقق'} -

+

{step === 1 ? 'إنشاء حساب مستأجر' : 'الموافقة على الشروط'}

+

{step === 1 ? 'انضم إلينا وابحث عن منزل أحلامك' : 'يرجى الموافقة على الشروط لإكمال التسجيل'}

- { e.preventDefault(); handleNextStep(); } : handleSubmit} - className="space-y-6"> - - {/* ─── STEP 1: Form ─── */} + { e.preventDefault(); handleNextStep(); } : handleSubmit} className="space-y-6"> {step === 1 && ( <> @@ -344,19 +865,13 @@ export default function TenantRegisterPage() {
- { 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.firstName ? 'border-red-500' : 'border-gray-700'}`} - placeholder="الاسم الأول" /> + { 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.firstName ? 'border-red-500' : 'border-gray-700'}`} placeholder="الاسم الأول" />
{errors.firstName &&

{errors.firstName}

}
- { 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="اسم العائلة" /> + { 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 &&

{errors.lastName}

}
@@ -367,10 +882,7 @@ export default function TenantRegisterPage() {
- { setFormData({...formData, email: e.target.value}); setErrors({...errors, email: 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.email ? 'border-red-500' : 'border-gray-700'}`} - placeholder="أدخل بريدك الإلكتروني" /> + { setFormData({...formData, email: e.target.value}); setErrors({...errors, email: 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.email ? 'border-red-500' : 'border-gray-700'}`} placeholder="أدخل بريدك الإلكتروني" />
{errors.email &&

{errors.email}

}
@@ -381,10 +893,7 @@ export default function TenantRegisterPage() {
- { setFormData({...formData, phone: e.target.value}); setErrors({...errors, phone: 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.phone ? 'border-red-500' : 'border-gray-700'}`} - placeholder="أدخل رقم هاتفك" /> + { setFormData({...formData, phone: e.target.value}); setErrors({...errors, phone: 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.phone ? 'border-red-500' : 'border-gray-700'}`} placeholder="أدخل رقم هاتفك" />
{errors.phone &&

{errors.phone}

} @@ -395,10 +904,7 @@ export default function TenantRegisterPage() {
- { setFormData({...formData, whatsapp: e.target.value}); setErrors({...errors, whatsapp: 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.whatsapp ? 'border-red-500' : 'border-gray-700'}`} - placeholder="أدخل رقم الواتساب" /> + { setFormData({...formData, whatsapp: e.target.value}); setErrors({...errors, whatsapp: 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.whatsapp ? 'border-red-500' : 'border-gray-700'}`} placeholder="أدخل رقم الواتساب" />
{errors.whatsapp &&

{errors.whatsapp}

} @@ -409,10 +915,7 @@ export default function TenantRegisterPage() {
- { setFormData({...formData, phone2: e.target.value}); setErrors({...errors, phone2: 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.phone2 ? 'border-red-500' : 'border-gray-700'}`} - placeholder="أدخل رقم الهاتف" maxLength={7} /> + { setFormData({...formData, phone2: e.target.value}); setErrors({...errors, phone2: 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.phone2 ? 'border-red-500' : 'border-gray-700'}`} placeholder="أدخل رقم الهاتف" maxLength={7} />
{errors.phone2 &&

{errors.phone2}

} @@ -423,22 +926,15 @@ export default function TenantRegisterPage() {
- { setFormData({...formData, nationalNumber: e.target.value}); setErrors({...errors, nationalNumber: 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.nationalNumber ? 'border-red-500' : 'border-gray-700'}`} - placeholder="أدخل الرقم الوطني" /> + { setFormData({...formData, nationalNumber: e.target.value}); setErrors({...errors, nationalNumber: 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.nationalNumber ? 'border-red-500' : 'border-gray-700'}`} placeholder="أدخل الرقم الوطني" />
{errors.nationalNumber &&

{errors.nationalNumber}

} - setFormData({...formData, customerType: e.target.value})} className="w-full py-3 px-4 bg-white/5 border border-gray-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent text-white appearance-none cursor-pointer"> + {Object.entries(CustomerTypeLabels).map(([value, label]) => ())} @@ -448,10 +944,7 @@ export default function TenantRegisterPage() {
- { setFormData({...formData, password: e.target.value}); setErrors({...errors, password: null}); }} - className={`w-full pr-12 pl-12 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.password ? 'border-red-500' : 'border-gray-700'}`} - placeholder="أدخل كلمة المرور" /> + { setFormData({...formData, password: e.target.value}); setErrors({...errors, password: null}); }} className={`w-full pr-12 pl-12 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.password ? 'border-red-500' : 'border-gray-700'}`} placeholder="أدخل كلمة المرور" /> @@ -465,67 +958,21 @@ export default function TenantRegisterPage() {
- { setFormData({...formData, confirmPassword: e.target.value}); setErrors({...errors, confirmPassword: null}); }} - className={`w-full pr-12 pl-12 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.confirmPassword ? 'border-red-500' : 'border-gray-700'}`} - placeholder="أعد إدخال كلمة المرور" /> + { setFormData({...formData, confirmPassword: e.target.value}); setErrors({...errors, confirmPassword: null}); }} className={`w-full pr-12 pl-12 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.confirmPassword ? 'border-red-500' : 'border-gray-700'}`} placeholder="أعد إدخال كلمة المرور" /> - {formData.confirmPassword && ( -
- {formData.password === formData.confirmPassword ? : } -
- )} + {formData.confirmPassword && (
{formData.password === formData.confirmPassword ? : }
)}
{errors.confirmPassword &&

{errors.confirmPassword}

} )} - {/* ─── STEP 2: ID Images ─── */} {step === 2 && ( <> - - -
fileInputFrontRef.current?.click()} - className={`relative border-2 border-dashed rounded-xl p-6 text-center cursor-pointer transition-all ${idImagePreviews.front ? 'border-green-500 bg-green-500/10' : errors.front ? 'border-red-500 bg-red-500/10' : 'border-gray-700 hover:border-blue-500 hover:bg-white/5'}`}> - handleImageUpload('front', e.target.files?.[0])} className="hidden" /> - {idImagePreviews.front ? ( -
- Front ID - -
- ) : (<>

اضغط لرفع الصورة

JPEG, PNG, JPG • حتى 5MB

)} -
- {errors.front &&

{errors.front}

} -
- - - -
fileInputBackRef.current?.click()} - className={`relative border-2 border-dashed rounded-xl p-6 text-center cursor-pointer transition-all ${idImagePreviews.back ? 'border-green-500 bg-green-500/10' : errors.back ? 'border-red-500 bg-red-500/10' : 'border-gray-700 hover:border-blue-500 hover:bg-white/5'}`}> - handleImageUpload('back', e.target.files?.[0])} className="hidden" /> - {idImagePreviews.back ? ( -
- Back ID - -
- ) : (<>

اضغط لرفع الصورة

JPEG, PNG, JPG • حتى 5MB

)} -
- {errors.back &&

{errors.back}

} -
- - setFormData({...formData, agreeTerms: e.target.checked})} - className="w-4 h-4 rounded border-gray-600 bg-white/5 text-blue-500 focus:ring-blue-500" required /> + setFormData({...formData, agreeTerms: e.target.checked})} className="w-4 h-4 rounded border-gray-600 bg-white/5 text-blue-500 focus:ring-blue-500" required /> @@ -533,21 +980,16 @@ export default function TenantRegisterPage() { )} - {/* ─── Buttons ─── */} {step === 1 ? ( <> - - + + ) : ( <> - - + @@ -565,50 +1007,33 @@ export default function TenantRegisterPage() {
- {/* ─── OTP Modal ─── */} {showOtpModal && ( - - + +
-
- -
+

التحقق من البريد

تم إرسال رمز التحقق إلى

{formData.email}

-
-
- -
- setOtpCode(e.target.value)} - className="w-full pr-12 pl-4 py-3 bg-white/5 border border-gray-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-white text-center tracking-[0.5em] text-xl" - placeholder="------" /> +
+ setOtpCode(e.target.value)} className="w-full pr-12 pl-4 py-3 bg-white/5 border border-gray-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500 text-white text-center tracking-[0.5em] text-xl" placeholder="------" />
-
-
- - +
)}
); -} +} \ No newline at end of file