From 12cb804b582f1b11e2e93e5bad00f80bdfbf6b05 Mon Sep 17 00:00:00 2001 From: Beilin-b Date: Wed, 24 Jun 2026 06:53:18 -0700 Subject: [PATCH] removing console.log --- app/register/tenant/page.js | 617 -------------------------------- app/utils/api.js | 388 +------------------- app/utils/firebase.js | 37 +- app/utils/ratings.js | 195 ---------- public/firebase-messaging-sw.js | 2 +- 5 files changed, 23 insertions(+), 1216 deletions(-) diff --git a/app/register/tenant/page.js b/app/register/tenant/page.js index a1e8edc..cb99c8f 100644 --- a/app/register/tenant/page.js +++ b/app/register/tenant/page.js @@ -1,621 +1,4 @@ -// '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, useEffect, useMemo } from 'react'; diff --git a/app/utils/api.js b/app/utils/api.js index 45f98be..53c0327 100644 --- a/app/utils/api.js +++ b/app/utils/api.js @@ -1,381 +1,6 @@ -// import AuthService from '../services/AuthService'; - -// const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api'; - -// /** -// * Generic API fetch — attaches auth token, unwraps { data } envelope -// */ -// async function apiFetch(endpoint, options = {}) { -// const token = AuthService.getToken(); - -// const headers = { -// 'Content-Type': 'application/json', -// ...(token && { Authorization: `Bearer ${token}` }), -// ...options.headers, -// }; - -// console.log('[API] Request:', options.method || 'GET', `${API_BASE}${endpoint}`); - -// const res = await fetch(`${API_BASE}${endpoint}`, { -// ...options, -// headers, -// }); - -// console.log('[API] Response:', res.status, endpoint); - -// if (!res.ok && res.status !== 206) { -// const text = await res.text().catch(() => ''); -// console.error('[API] Error:', res.status, text); -// throw new Error(`API ${res.status}: ${text || res.statusText}`); -// } - -// const text = await res.text(); -// if (!text) return null; - -// try { -// const json = JSON.parse(text); -// if (json && typeof json === 'object' && 'data' in json) { -// return json.data; -// } -// return json; -// } catch { -// return text; -// } -// } - -// /** -// * Auth fetch — returns full { status, data, ok } for status-code handling -// */ -// async function authFetch(endpoint, body, token = null) { -// console.log('[Auth] Request:', `${API_BASE}${endpoint}`); - -// const headers = { 'Content-Type': 'application/json' }; -// if (token) { -// headers['Authorization'] = `Bearer ${token}`; -// console.log('[Auth] Sending with Bearer token'); -// } - -// const res = await fetch(`${API_BASE}${endpoint}`, { -// method: 'POST', -// headers, -// body: JSON.stringify(body), -// }); - -// console.log('[Auth] Response status:', res.status, endpoint); - -// const text = await res.text(); -// let data = null; -// try { -// data = text ? JSON.parse(text) : null; -// if (data && typeof data === 'object' && 'data' in data) { -// data = data.data; -// } -// } catch { -// data = text; -// } - -// // Build message from response for toast display -// const message = (typeof data === 'object' && data?.message) ? data.message : null; - -// return { status: res.status, data, ok: res.ok || res.status === 206, message }; -// } - -// // ─── Rent Properties ─── - -// export async function getRentProperties() { -// return apiFetch('/RentProperties/GetRentProperties'); -// } - -// export async function getRentProperty(id) { -// return apiFetch(`/RentProperties/GetRentPropertyById/${id}`); -// } - -// export async function getRentPropertyLocations(params = {}) { -// const qs = new URLSearchParams(); -// if (params.maxOffset != null) qs.set('maxOffset', params.maxOffset); -// if (params.minOffset != null) qs.set('minOffset', params.minOffset); -// const query = qs.toString(); -// return apiFetch(`/RentProperties/GetRentPropertiesLocations${query ? `?${query}` : ''}`); -// } - -// // ─── Sale Properties ─── - -// export async function getSaleProperties() { -// return apiFetch('/SaleProperties/GetSaleProperties'); -// } - -// export async function getSaleProperty(id) { -// const items = await apiFetch('/SaleProperties/GetSaleProperties'); -// if (!Array.isArray(items)) return items; -// return items.find(p => p.id == id) || items[0]; -// } - -// // ─── Properties (generic) ─── - -// export async function getProperty(id) { -// return apiFetch(`/Properties/Get/${id}`); -// } - -// // ─── Recommendations ─── - -// export async function getRecommendations() { -// return apiFetch('/Recommendations/GetRecommendations'); -// } - -// export async function getTopRecommendations(count = 10) { -// return apiFetch(`/Recommendations/GetTopRecommendations?count=${count}`); -// } - -// // ─── Reservations ─── - -// export async function getAvailableDateRanges(propertyId) { -// console.log('[API] Fetching available dates for property:', propertyId); -// return apiFetch(`/Reservations/GetAvailableDates/available/${propertyId}`); -// } - -// export async function getReservations() { -// return apiFetch('/Reservations/GetAllReservations'); -// } - -// export async function getReservation(id) { -// return apiFetch(`/Reservations/GetReservation?id=${id}`); -// } - -// export async function checkAvailability(propertyId, fromDate = null, toDate = null) { -// const qs = new URLSearchParams(); -// if (fromDate) qs.set('fromDate', fromDate); -// if (toDate) qs.set('toDate', toDate); -// const query = qs.toString(); -// return apiFetch(`/Reservations/GetAvailable/${propertyId}${query ? `?${query}` : ''}`); -// } - -// export async function bookReservation(propertyId, startDate, endDate) { -// console.log('[API] Booking reservation:', { propertyId, startDate, endDate }); -// return apiFetch('/Reservations/BookReservation/book', { -// method: 'POST', -// body: JSON.stringify({ propertyId, startDate, endDate }), -// }); -// } - -// // ─── Terms ─── - -// export async function getTerms() { -// return apiFetch('/Terms/GetTerms'); -// } - -// // ─── Profile ─── - -// export async function getCustomerByUserId(userId) { -// console.log('[API] Fetching customer by user ID:', userId); -// return apiFetch(`/Customer/GetByUserId/${userId}`); -// } - -// export async function getOwnerByUserId(userId) { -// console.log('[API] Fetching owner by user ID:', userId); -// return apiFetch(`/Owner/GetByUserId/${userId}`); -// } - -// // ─── Properties ─── - -// export async function getMyRentListings() { -// console.log('[API] Fetching my rent listings'); -// return apiFetch(`/RentProperties/GetMyRentListings`); -// } - -// export async function addRentProperty(data) { -// console.log('[API] Adding rent property:', data.PropertyInformation?.Address); -// return apiFetch('/RentProperties/AddRentProperty', { -// method: 'POST', -// body: JSON.stringify(data), -// }); -// } - -// // ─── Currencies ─── - -// export async function getCurrencies() { -// return apiFetch('/Currency/GetAll'); -// } - -// // ─── Files ─── - -// export async function uploadPicture(file) { -// console.log('[API] Uploading picture:', file.name); -// const formData = new FormData(); -// formData.append('image', file); -// const token = AuthService.getToken(); -// const res = await fetch(`${API_BASE}/Files/UploadPicture`, { -// method: 'POST', -// headers: { -// ...(token && { Authorization: `Bearer ${token}` }), -// }, -// body: formData, -// }); -// const text = await res.text(); -// console.log('[API] Upload response:', res.status, text?.substring(0, 100)); -// if (!res.ok) throw new Error(`Upload failed: ${res.status} ${text}`); -// // Response is the relative path string (e.g. /Pictures/abc123.jpg) -// try { -// const json = JSON.parse(text); -// return json?.data || json; -// } catch { -// return text; -// } -// } - -// // ─── Auth: Registration ─── - -// /** -// * Register a new owner -// * @param {Object} data — { name, email, phoneNumber, whatsAppNumber, password, ownerType } -// * @returns {Promise<{status, data, ok, message}>} -// */ -// // Multipart form-data fetch for file uploads -// async function multipartAuthFetch(endpoint, formData) { -// console.log('[Auth] Multipart request:', `${API_BASE}${endpoint}`); - -// const res = await fetch(`${API_BASE}${endpoint}`, { -// method: 'POST', -// // Don't set Content-Type — browser sets it with boundary -// body: formData, -// }); - -// console.log('[Auth] Response status:', res.status, endpoint); - -// const text = await res.text(); -// let data = null; -// try { -// data = text ? JSON.parse(text) : null; -// if (data && typeof data === 'object' && 'data' in data) { -// data = data.data; -// } -// } catch { -// data = text; -// } - -// return { status: res.status, data, ok: res.ok || res.status === 206, message: data?.message }; -// } - -// export async function addOwner(data, frontImage = null, backImage = null) { -// console.log('[Auth] Registering owner (multipart):', data.email); - -// const formData = new FormData(); -// formData.append('FirstName', data.firstName || data.FirstName || ''); -// formData.append('LastName', data.lastName || data.LastName || ''); -// formData.append('Email', data.email || ''); -// formData.append('PhoneNumber', data.phoneNumber || ''); -// formData.append('WhatsAppNumber', data.whatsAppNumber || ''); -// formData.append('Phone', data.phone || ''); -// formData.append('NationalNumber', data.nationalNumber || ''); -// formData.append('Password', data.password || ''); -// formData.append('Type', String(data.ownerType ?? data.Type ?? 0)); -// formData.append('Language', '0'); - -// if (frontImage) formData.append('FrontIdCarImagePath', frontImage); -// if (backImage) formData.append('RearIdCarImagePath', backImage); - -// return multipartAuthFetch('/Owner/Add', formData); -// } - -// export async function addCustomer(data, frontImage = null, backImage = null) { -// console.log('[Auth] Registering customer (multipart):', data.email); - -// const formData = new FormData(); -// formData.append('FirstName', data.firstName || data.FirstName || ''); -// formData.append('LastName', data.lastName || data.LastName || ''); -// formData.append('Email', data.email || ''); -// formData.append('PhoneNumber', data.phoneNumber || ''); -// formData.append('WhatsAppNumber', data.whatsAppNumber || ''); -// formData.append('Phone', data.phone || ''); -// formData.append('NationalNumber', data.nationalNumber || ''); -// formData.append('Password', data.password || ''); -// formData.append('Type', String(data.customerType ?? data.Type ?? 0)); -// formData.append('Language', '0'); - -// if (frontImage) formData.append('FrontIdCarImagePath', frontImage); -// if (backImage) formData.append('RearIdCarImagePath', backImage); - -// return multipartAuthFetch('/Customer/Add', formData); -// } - -// // ─── Auth: Login ─── - -// export async function loginWithEmail(credential, password) { -// console.log('[Auth] Login with email:', credential); -// return authFetch('/Auth/LogInWithEmail', { -// credential, -// password, -// device: 0, -// appVersion: '', -// }); -// } - -// export async function loginWithPhone(credential, password) { -// console.log('[Auth] Login with phone:', credential); -// return authFetch('/Auth/LogInWithPhoneNumber', { -// credential, -// password, -// device: 0, -// appVersion: '', -// }); -// } - -// // ─── Auth: OTP ─── - -// export async function sendEmailOTP() { -// console.log('[Auth] Sending email OTP...'); -// return apiFetch('/Auth/SendEmailOTP', { method: 'POST' }); -// } - -// export async function sendPhoneOTP() { -// console.log('[Auth] Sending phone OTP...'); -// return apiFetch('/Auth/SendPhoneNumberOTP', { method: 'POST' }); -// } - -// export async function verifyEmail(code) { -// console.log('[Auth] Verifying email with code:', code); -// const token = AuthService.getToken(); -// return authFetch(`/Auth/VerifyEmail?code=${encodeURIComponent(code)}`, {}, token); -// } - -// export async function verifyPhone(code) { -// console.log('[Auth] Verifying phone with code:', code); -// const token = AuthService.getToken(); -// return authFetch(`/Auth/VerifyPhoneNumber?code=${encodeURIComponent(code)}`, {}, token); -// } - -// // ─── Helpers ─── - -// export function isEmail(value) { -// return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value); -// } - -// export function isPhoneNumber(value) { -// return /^\+?\d{7,15}$/.test(value.replace(/[\s\-()]/g, '')); -// } - -// // ─── Favorites ─── - -// export async function getUserFavoriteProperties() { -// return apiFetch('/FavoriteProperty/GetUserFavoriteProperties'); -// } - -// export async function addFavoriteProperty(propId) { -// return apiFetch(`/FavoriteProperty/Add?propId=${propId}`, { method: 'POST' }); -// } - -// export async function removeFavoriteProperty(favePropId) { -// return apiFetch(`/FavoriteProperty/Remove?favePropId=${favePropId}`, { method: 'DELETE' }); -// } - -// export async function getUserNotifications() { -// return apiFetch('/Notifications/GetUserNotifications'); -// } - -// // ─── Booking/Reservation Management ─── - import AuthService from "../services/AuthService"; -const API_BASE = // const API_BASE = - process.env.NEXT_PUBLIC_API_URL || "https://45.93.137.91.nip.io/api"; // process.env.NEXT_PUBLIC_API_URL || "https://45.93.137.91.nip.io/api"; +const API_BASE = + process.env.NEXT_PUBLIC_API_URL || "https://45.93.137.91.nip.io/api"; const REPORT_API_BASE = process.env.NEXT_PUBLIC_API_URL || "http://45.93.137.91/api"; @@ -440,10 +65,6 @@ async function apiFetch(endpoint, options = {}) { const url = `${API_BASE}${endpoint}`; - console.log("API Request:", url); - console.log("API Method:", options.method || "GET"); - console.log("API Body:", hasBody ? options.body : null); - const res = await fetch(url, { ...options, headers, @@ -453,13 +74,10 @@ async function apiFetch(endpoint, options = {}) { : options.body, }); - console.log("API Response Status:", res.status); - console.log("API Response OK:", res.ok); assertNotBlocked(res); if (!res.ok && res.status !== 206) { const text = await res.text().catch(() => ""); - console.error("API Error Response:", text || res.statusText); throw new Error(`API ${res.status}: ${text || res.statusText}`); } @@ -1199,4 +817,4 @@ export async function addOrUpdateTerms(terms) { method: "POST", body: terms, }); -} +} \ No newline at end of file diff --git a/app/utils/firebase.js b/app/utils/firebase.js index a2511c9..82a3332 100644 --- a/app/utils/firebase.js +++ b/app/utils/firebase.js @@ -12,16 +12,15 @@ const firebaseConfig = { }; // Initialize Firebase (avoid duplicate init in SSR) -const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0]; +const app = + getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0]; // Get messaging instance (only works in browser) let messaging = null; if (typeof window !== "undefined" && "serviceWorker" in navigator) { try { messaging = getMessaging(app); - } catch (e) { - console.warn("[Firebase] Messaging init failed:", e.message); - } + } catch (e) {} } // Request notification permission and get FCM token @@ -31,43 +30,46 @@ export async function requestNotificationPermission() { try { const permission = await Notification.requestPermission(); if (permission !== "granted") { - console.log("[FCM] Notification permission denied"); return null; } - const registration = await navigator.serviceWorker.register("/firebase-messaging-sw.js"); + const registration = await navigator.serviceWorker.register( + "/firebase-messaging-sw.js" + ); const token = await getToken(messaging, { - vapidKey: "BGZ4Fo8rRhoTdStLGlCySDZOnAX4ekCA0e3HDWXL5uEi2kOnXynYjbaDbY15002phUrFqxBpPPFHgfH2VhrmFDU", + vapidKey: + "BGZ4Fo8rRhoTdStLGlCySDZOnAX4ekCA0e3HDWXL5uEi2kOnXynYjbaDbY15002phUrFqxBpPPFHgfH2VhrmFDU", serviceWorkerRegistration: registration, }); - console.log("[FCM] Token:", token); - // Send token to backend if (token) { try { const authToken = localStorage.getItem("auth_token"); + if (authToken) { - const apiBase = process.env.NEXT_PUBLIC_API_URL || "https://45.93.137.91.nip.io/api"; + const apiBase = + process.env.NEXT_PUBLIC_API_URL || + "https://45.93.137.91.nip.io/api"; + await fetch(`${apiBase}/User/SetFCMToken`, { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${authToken}`, }, - body: JSON.stringify({ token, deviceType: 2 }), // 2 = Web + body: JSON.stringify({ + token, + deviceType: 2, + }), }); - console.log("[FCM] Token sent to backend"); } - } catch (err) { - console.error("[FCM] Failed to send token to backend:", err); - } + } catch (err) {} } return token; } catch (err) { - console.error("[FCM] Error getting token:", err); return null; } } @@ -77,9 +79,8 @@ export function onForegroundMessage(callback) { if (!messaging) return () => {}; return onMessage(messaging, (payload) => { - console.log("[FCM] Foreground message:", payload); callback(payload); }); } -export { app, messaging }; +export { app, messaging }; \ No newline at end of file diff --git a/app/utils/ratings.js b/app/utils/ratings.js index 50b3e4a..0c01f1d 100644 --- a/app/utils/ratings.js +++ b/app/utils/ratings.js @@ -1,199 +1,4 @@ -// // Rating API endpoints for SweetHome -// // Handles both customer ratings and property ratings -// import AuthService from '../services/AuthService'; - -// const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api'; - -// /** -// * Rate a property as a customer -// * @param {Object} data - Rating data -// * @param {number} data.propertyId - ID of the property being rated -// * @param {number} data.customerId - ID of the customer doing the rating -// * @param {number} data.rating - Rating value (1-5) -// * @param {string} data.comment - Optional comment -// * @returns {Promise} - API response -// */ -// export async function rateProperty(data) { -// console.log('[Rating] Customer rating property:', data); -// return apiFetch('/Ratings/CustomerRateProperty', { -// method: 'POST', -// body: JSON.stringify(data), -// }); -// } - -// /** -// * Rate a customer as a property owner -// * @param {Object} data - Rating data -// * @param {number} data.propertyId - ID of the property -// * @param {number} data.customerId - ID of the customer being rated -// * @param {number} data.rating - Rating value (1-5) -// * @param {string} data.comment - Optional comment -// * @returns {Promise} - API response -// */ -// export async function rateCustomer(data) { -// console.log('[Rating] Property owner rating customer:', data); -// return apiFetch('/Ratings/PropertyRateCustomer', { -// method: 'POST', -// body: JSON.stringify(data), -// }); -// } - -// /** -// * Get all ratings for a property -// * @param {number} propertyId - ID of the property -// * @returns {Promise} - Array of ratings -// */ -// export async function getPropertyRatings(propertyId) { -// console.log('[Rating] Fetching property ratings for:', propertyId); -// return apiFetch(`/Ratings/GetPropertyRatings?propertyId=${propertyId}`); -// } - -// /** -// * Get all ratings for a customer -// * @param {number} customerId - ID of the customer -// * @returns {Promise} - Array of ratings -// */ -// export async function getCustomerRatings(customerId) { -// console.log('[Rating] Fetching customer ratings for:', customerId); -// return apiFetch(`/Ratings/GetCustomerRatings?customerId=${customerId}`); -// } - -// /** -// * Get average rating for a property -// * @param {number} propertyId - ID of the property -// * @returns {Promise} - Average rating -// */ -// export async function getPropertyAverageRating(propertyId) { -// console.log('[Rating] Fetching average rating for property:', propertyId); -// const ratings = await getPropertyRatings(propertyId); -// if (!Array.isArray(ratings) || ratings.length === 0) return 0; - -// const total = ratings.reduce((sum, rating) => sum + rating.rating, 0); -// return Math.round((total / ratings.length) * 10) / 10; // Round to 1 decimal -// } - -// /** -// * Get average rating for a customer -// * @param {number} customerId - ID of the customer -// * @returns {Promise} - Average rating -// */ -// export async function getCustomerAverageRating(customerId) { -// console.log('[Rating] Fetching average rating for customer:', customerId); -// const ratings = await getCustomerRatings(customerId); -// if (!Array.isArray(ratings) || ratings.length === 0) return 0; - -// const total = ratings.reduce((sum, rating) => sum + rating.rating, 0); -// return Math.round((total / ratings.length) * 10) / 10; // Round to 1 decimal -// } - -// /** -// * Get user's rating for a specific property (if any) -// * @param {number} propertyId - ID of the property -// * @param {number} userId - ID of the user -// * @returns {Promise} - User's rating or null -// */ -// export async function getUserPropertyRating(propertyId, userId) { -// console.log('[Rating] Fetching user rating for property:', propertyId, 'user:', userId); -// const allRatings = await getPropertyRatings(propertyId); -// if (!Array.isArray(allRatings)) return null; - -// return allRatings.find(r => r.userId === userId) || null; -// } - -// /** -// * Get user's rating for a specific customer (if any) -// * @param {number} customerId - ID of the customer -// * @param {number} userId - ID of the user -// * @returns {Promise} - User's rating or null -// */ -// export async function getUserCustomerRating(customerId, userId) { -// console.log('[Rating] Fetching user rating for customer:', customerId, 'user:', userId); -// const allRatings = await getCustomerRatings(customerId); -// if (!Array.isArray(allRatings)) return null; - -// return allRatings.find(r => r.userId === userId) || null; -// } - -// /** -// * Check if user can rate a property (after renting) -// * @param {number} propertyId - ID of the property -// * @param {number} userId - ID of the user -// * @returns {Promise} - Boolean indicating if rating is allowed -// */ -// export async function canRateProperty(propertyId, userId) { -// console.log('[Rating] Checking if user can rate property:', propertyId, 'user:', userId); - -// // Logic: User can rate if they have completed a rental in the past -// // This would typically check reservation history -// // For now, we'll simulate this with a simple check - -// // In a real implementation, this would check: -// // 1. User's reservation history for this property -// // 2. Whether the rental period has ended -// // 3. Whether they've already rated - -// const userRating = await getUserPropertyRating(propertyId, userId); -// return !userRating; // Can rate if no existing rating -// } - -// /** -// * Check if user can rate a customer (after renting to them) -// * @param {number} customerId - ID of the customer -// * @param {number} userId - ID of the user (owner) -// * @returns {Promise} - Boolean indicating if rating is allowed -// */ -// export async function canRateCustomer(customerId, userId) { -// console.log('[Rating] Checking if user can rate customer:', customerId, 'user:', userId); - -// // Logic: Owner can rate if they have rented to this customer -// // This would typically check reservation history - -// const userRating = await getUserCustomerRating(customerId, userId); -// return !userRating; // Can rate if no existing rating -// } - -// // Helper function for API calls -// async function apiFetch(endpoint, options = {}) { -// const token = AuthService.getToken(); - -// const headers = { -// 'Content-Type': 'application/json', -// ...(token && { Authorization: `Bearer ${token}` }), -// ...options.headers, -// }; - -// console.log('[Rating API] Request:', options.method || 'GET', `${API_BASE}${endpoint}`); - -// const res = await fetch(`${API_BASE}${endpoint}`, { -// ...options, -// headers, -// }); - -// console.log('[Rating API] Response:', res.status, endpoint); - -// if (!res.ok && res.status !== 206) { -// const text = await res.text().catch(() => ''); -// console.error('[Rating API] Error:', res.status, text); -// throw new Error(`Rating API ${res.status}: ${text || res.statusText}`); -// } - -// const text = await res.text(); -// if (!text) return null; - -// try { -// const json = JSON.parse(text); -// if (json && typeof json === 'object' && 'data' in json) { -// return json.data; -// } -// return json; -// } catch { -// return text; -// } -// } - - -// utils/ratings.js import AuthService from '../services/AuthService'; const API_BASE = process.env.NEXT_PUBLIC_API_URL || 'https://45.93.137.91.nip.io/api'; diff --git a/public/firebase-messaging-sw.js b/public/firebase-messaging-sw.js index a6b96a6..2b6ab9b 100644 --- a/public/firebase-messaging-sw.js +++ b/public/firebase-messaging-sw.js @@ -18,7 +18,7 @@ const messaging = firebase.messaging(); // Handle background messages messaging.onBackgroundMessage((payload) => { - console.log("[FCM SW] Background message:", payload); + ("[FCM SW] Background message:", payload); const title = payload.notification?.title || payload.data?.title || "Sweet Home"; const options = { body: payload.notification?.body || payload.data?.body || "",