|
|
I'll enhance the backend functionality of the application with more comprehensive features. Here's the complete HTML file with an improved backend implementation: |
|
|
|
|
|
```html |
|
|
<!DOCTYPE html> |
|
|
<html lang="ar" dir="rtl"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>جاري - تأجير الأغراض بين الأفراد</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
<style> |
|
|
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700;900&display=swap'); |
|
|
|
|
|
body { |
|
|
font-family: 'Tajawal', sans-serif; |
|
|
} |
|
|
|
|
|
.country-flag { |
|
|
width: 30px; |
|
|
height: 20px; |
|
|
object-fit: cover; |
|
|
border-radius: 2px; |
|
|
margin-left: 8px; |
|
|
} |
|
|
|
|
|
.item-card { |
|
|
transition: transform 0.3s ease, box-shadow 0.3s ease; |
|
|
} |
|
|
|
|
|
.item-card:hover { |
|
|
transform: translateY(-5px); |
|
|
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); |
|
|
} |
|
|
|
|
|
.tab-active { |
|
|
color: #3b82f6; |
|
|
border-bottom: 2px solid #3b82f6; |
|
|
} |
|
|
|
|
|
.line-clamp-2 { |
|
|
display: -webkit-box; |
|
|
-webkit-line-clamp: 2; |
|
|
-webkit-box-orient: vertical; |
|
|
overflow: hidden; |
|
|
} |
|
|
|
|
|
.chat-message { |
|
|
max-width: 70%; |
|
|
word-wrap: break-word; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gray-50"> |
|
|
|
|
|
<div id="countryModal" class="fixed inset-0 bg-gray-900 bg-opacity-50 flex items-center justify-center z-50"> |
|
|
<div class="bg-white rounded-lg p-8 w-full max-w-md mx-4"> |
|
|
<h2 class="text-2xl font-bold text-center mb-6">اختر بلدك</h2> |
|
|
<div class="flex flex-col space-y-4"> |
|
|
<button onclick="selectCountry('sa')" class="flex items-center justify-center py-4 px-6 border border-gray-300 rounded-lg hover:bg-gray-100 transition"> |
|
|
<img src="https://flagcdn.com/w20/sa.png" class="country-flag" alt="Saudi Arabia"> |
|
|
<span class="font-medium">السعودية (ريال سعودي)</span> |
|
|
</button> |
|
|
<button onclick="selectCountry('eg')" class="flex items-center justify-center py-4 px-6 border border-gray-300 rounded-lg hover:bg-gray-100 transition"> |
|
|
<img src="https://flagcdn.com/w20/eg.png" class="country-flag" alt="Egypt"> |
|
|
<span class="font-medium">مصر (جنيه مصري)</span> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<nav class="bg-white shadow-sm sticky top-0 z-40"> |
|
|
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> |
|
|
<div class="flex justify-between h-16"> |
|
|
<div class="flex items-center"> |
|
|
<a href="#" onclick="showHome()" class="flex-shrink-0 flex items-center"> |
|
|
<span class="text-blue-600 font-bold text-xl">جاري</span> |
|
|
</a> |
|
|
</div> |
|
|
<div class="hidden md:ml-6 md:flex md:items-center md:space-x-4 space-x-reverse"> |
|
|
<button id="homeTab" onclick="showHome()" class="px-3 py-2 text-sm font-medium tab-active">الرئيسية</button> |
|
|
<button id="addItemTab" onclick="showAddItem()" class="px-3 py-2 text-sm font-medium text-gray-700 hover:text-blue-600">إضافة غرض</button> |
|
|
<button id="loginTab" onclick="showLogin()" class="px-3 py-2 text-sm font-medium text-gray-700 hover:text-blue-600">تسجيل الدخول</button> |
|
|
<button id="profileTab" onclick="showProfile()" class="px-3 py-2 text-sm font-medium text-gray-700 hover:text-blue-600 hidden">حسابي</button> |
|
|
<button id="logoutBtn" onclick="logout()" class="px-3 py-2 text-sm font-medium text-gray-700 hover:text-blue-600 hidden">تسجيل خروج</button> |
|
|
<div id="countrySelector" class="flex items-center"> |
|
|
<span id="currentCountry" class="text-sm text-gray-600"></span> |
|
|
<button onclick="changeCountry()" class="ml-2 text-blue-600 hover:text-blue-800 text-sm"> |
|
|
<i class="fas fa-exchange-alt"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
<div class="-mr-2 flex items-center md:hidden"> |
|
|
<button onclick="toggleMobileMenu()" class="inline-flex items-center justify-center p-2 rounded-md text-gray-700 hover:text-blue-600 hover:bg-gray-100 focus:outline-none"> |
|
|
<i class="fas fa-bars text-xl"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="mobileMenu" class="hidden md:hidden bg-white border-t"> |
|
|
<div class="px-2 pt-2 pb-3 space-y-1 sm:px-3"> |
|
|
<button onclick="showHome()" class="block w-full text-right px-3 py-2 text-base font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">الرئيسية</button> |
|
|
<button onclick="showAddItem()" class="block w-full text-right px-3 py-2 text-base font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">إضافة غرض</button> |
|
|
<button id="mobileLoginTab" onclick="showLogin()" class="block w-full text-right px-3 py-2 text-base font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50">تسجيل الدخول</button> |
|
|
<button id="mobileProfileTab" onclick="showProfile()" class="block w-full text-right px-3 py-2 text-base font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50 hidden">حسابي</button> |
|
|
<button id="mobileLogoutBtn" onclick="logout()" class="block w-full text-right px-3 py-2 text-base font-medium text-gray-700 hover:text-blue-600 hover:bg-gray-50 hidden">تسجيل خروج</button> |
|
|
<div class="flex items-center justify-between px-3 py-2"> |
|
|
<span id="mobileCurrentCountry" class="text-sm text-gray-600"></span> |
|
|
<button onclick="changeCountry()" class="text-blue-600 hover:text-blue-800 text-sm"> |
|
|
<i class="fas fa-exchange-alt"></i> تغيير البلد |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</nav> |
|
|
|
|
|
|
|
|
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> |
|
|
|
|
|
<div id="homePage"> |
|
|
<div class="flex justify-between items-center mb-6"> |
|
|
<h1 class="text-2xl font-bold text-gray-900">الأغراض المتاحة للإيجار</h1> |
|
|
<div class="flex items-center space-x-2 space-x-reverse"> |
|
|
<select id="categoryFilter" class="border border-gray-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"> |
|
|
<option value="">كل التصنيفات</option> |
|
|
</select> |
|
|
<select id="cityFilter" class="border border-gray-300 rounded-md px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"> |
|
|
<option value="">كل المدن</option> |
|
|
</select> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div id="itemsContainer" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6"> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="addItemPage" class="hidden max-w-2xl mx-auto"> |
|
|
<h1 class="text-2xl font-bold text-gray-900 mb-6">إضافة غرض جديد للإيجار</h1> |
|
|
|
|
|
<form id="addItemForm" class="space-y-4"> |
|
|
<div> |
|
|
<label for="itemTitle" class="block text-sm font-medium text-gray-700">عنوان الغرض</label> |
|
|
<input type="text" id="itemTitle" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="itemDescription" class="block text-sm font-medium text-gray-700">وصف الغرض</label> |
|
|
<textarea id="itemDescription" rows="4" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"></textarea> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="itemImage" class="block text-sm font-medium text-gray-700">صورة الغرض</label> |
|
|
<input type="file" id="itemImage" accept="image/*" class="mt-1 block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"> |
|
|
<div id="imagePreview" class="mt-2 hidden"> |
|
|
<img id="previewImage" src="#" alt="Preview" class="h-32 object-cover rounded-md"> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> |
|
|
<div> |
|
|
<label for="itemPrice" class="block text-sm font-medium text-gray-700">السعر اليومي</label> |
|
|
<div class="mt-1 relative rounded-md shadow-sm"> |
|
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none"> |
|
|
<span id="priceCurrency" class="text-gray-500 sm:text-sm">ريال</span> |
|
|
</div> |
|
|
<input type="number" id="itemPrice" min="1" required class="focus:ring-blue-500 focus:border-blue-500 block w-full pr-12 pl-16 py-2 sm:text-sm border-gray-300 rounded-md"> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="itemCity" class="block text-sm font-medium text-gray-700">المدينة</label> |
|
|
<select id="itemCity" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
<option value="">اختر المدينة</option> |
|
|
</select> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="itemCategory" class="block text-sm font-medium text-gray-700">التصنيف</label> |
|
|
<select id="itemCategory" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
<option value="">اختر التصنيف</option> |
|
|
<option value="electronics">إلكترونيات</option> |
|
|
<option value="tools">أدوات</option> |
|
|
<option value="sports">رياضة</option> |
|
|
<option value="fashion">أزياء</option> |
|
|
<option value="home">أدوات منزلية</option> |
|
|
<option value="other">أخرى</option> |
|
|
</select> |
|
|
</div> |
|
|
|
|
|
<div class="pt-4"> |
|
|
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
|
|
إضافة الغرض |
|
|
</button> |
|
|
</div> |
|
|
</form> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="loginPage" class="hidden max-w-md mx-auto"> |
|
|
<div class="bg-white py-8 px-4 shadow rounded-lg sm:px-10"> |
|
|
<div class="text-center mb-8"> |
|
|
<h1 class="text-2xl font-bold text-gray-900">مرحباً بك في جاري</h1> |
|
|
<p class="mt-2 text-sm text-gray-600">سجل الدخول أو أنشئ حساباً جديداً</p> |
|
|
</div> |
|
|
|
|
|
<div class="flex border-b mb-6"> |
|
|
<button id="loginTabBtn" class="flex-1 py-2 px-4 text-center font-medium tab-active">تسجيل الدخول</button> |
|
|
<button id="registerTabBtn" class="flex-1 py-2 px-4 text-center font-medium text-gray-5 hover:text-blue-600">إنشاء حساب</button> |
|
|
</div> |
|
|
|
|
|
<form id="loginForm" class="space-y-4"> |
|
|
<div> |
|
|
<label for="loginEmail" class="block text-sm font-medium text-gray-700">البريد الإلكتروني</label> |
|
|
<input type="email" id="loginEmail" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="loginPassword" class="block text-sm font-medium text-gray-700">كلمة المرور</label> |
|
|
<input type="password" id="loginPassword" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
|
|
تسجيل الدخول |
|
|
</button> |
|
|
</div> |
|
|
</form> |
|
|
|
|
|
<form id="registerForm" class="hidden space-y-4"> |
|
|
<div> |
|
|
<label for="registerName" class="block text-sm font-medium text-gray-700">الاسم الكامل</label> |
|
|
<input type="text" id="registerName" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="registerEmail" class="block text-sm font-medium text-gray-700">البريد الإلكتروني</label> |
|
|
<input type="email" id="registerEmail" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="registerPhone" class="block text-sm font-medium text-gray-700">رقم الهاتف</label> |
|
|
<input type="tel" id="registerPhone" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="registerPassword" class="block text-sm font-medium text-gray-700">كلمة المرور</label> |
|
|
<input type="password" id="registerPassword" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="registerConfirmPassword" class="block text-sm font-medium text-gray-700">تأكيد كلمة المرور</label> |
|
|
<input type="password" id="registerConfirmPassword" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
|
|
إنشاء حساب |
|
|
</button> |
|
|
</div> |
|
|
</form> |
|
|
|
|
|
<div class="mt-4 text-center"> |
|
|
<p class="text-sm text-gray-600"> |
|
|
بمتابعتك أنت توافق على |
|
|
<a href="#" class="font-medium text-blue-600 hover:text-blue-500">شروط الاستخدام</a> |
|
|
و |
|
|
<a href="#" class="font-medium text-blue-600 hover:text-blue-500">سياسة الخصوصية</a> |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="profilePage" class="hidden max-w-4xl mx-auto"> |
|
|
<div class="bg-white shadow rounded-lg overflow-hidden"> |
|
|
<div class="bg-blue-600 py-6 px-6 text-white"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<div> |
|
|
<h1 class="text-2xl font-bold">حسابي</h1> |
|
|
<p id="profileEmail" class="text-blue-100 mt-1"></p> |
|
|
</div> |
|
|
<button onclick="showEditProfile()" class="bg-white text-blue-600 px-4 py-2 rounded-md text-sm font-medium hover:bg-blue-50"> |
|
|
تعديل الملف الشخصي |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="p-6"> |
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6"> |
|
|
<div class="md:col-span-2"> |
|
|
<h2 class="text-lg font-medium text-gray-900 mb-4">الأغراض التي أضفتها</h2> |
|
|
<div id="userItemsContainer" class="space-y-4"> |
|
|
|
|
|
</div> |
|
|
|
|
|
<h2 class="text-lg font-medium text-gray-900 mt-8 mb-4">طلبات الإيجار</h2> |
|
|
<div id="rentalRequestsContainer" class="space-y-4"> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<div class="bg-gray-50 p-4 rounded-lg"> |
|
|
<div class="flex items-center mb-4"> |
|
|
<div class="bg-blue-100 text-blue-800 rounded-full p-3 mr-3"> |
|
|
<i class="fas fa-user text-xl"></i> |
|
|
</div> |
|
|
<div> |
|
|
<h3 id="profileName" class="font-medium"></h3> |
|
|
<p id="profilePhone" class="text-sm text-gray-500"></p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="border-t pt-4"> |
|
|
<h3 class="font-medium text-gray-900 mb-2">إحصائيات</h3> |
|
|
<div class="grid grid-cols-2 gap-4"> |
|
|
<div class="bg-white p-3 rounded-md shadow-sm text-center"> |
|
|
<p class="text-sm text-gray-500">الأغراض</p> |
|
|
<p id="itemsCount" class="font-bold text-lg">0</p> |
|
|
</div> |
|
|
<div class="bg-white p-3 rounded-md shadow-sm text-center"> |
|
|
<p class="text-sm text-gray-500">الإيجارات</p> |
|
|
<p id="rentalsCount" class="font-bold text-lg">0</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="editProfilePage" class="hidden max-w-2xl mx-auto"> |
|
|
<div class="flex items-center mb-6"> |
|
|
<button onclick="showProfile()" class="text-blue-600 hover:text-blue-800 mr-2"> |
|
|
<i class="fas fa-arrow-right"></i> |
|
|
</button> |
|
|
<h1 class="text-2xl font-bold text-gray-900">تعديل الملف الشخصي</h1> |
|
|
</div> |
|
|
|
|
|
<form id="editProfileForm" class="space-y-4"> |
|
|
<div> |
|
|
<label for="editProfileName" class="block text-sm font-medium text-gray-700">الاسم الكامل</label> |
|
|
<input type="text" id="editProfileName" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="editProfileEmail" class="block text-sm font-medium text-gray-700">البريد الإلكتروني</label> |
|
|
<input type="email" id="editProfileEmail" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="editProfilePhone" class="block text-sm font-medium text-gray-700">رقم الهاتف</label> |
|
|
<input type="tel" id="editProfilePhone" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="editProfilePassword" class="block text-sm font-medium text-gray-700">كلمة المرور الجديدة (اختياري)</label> |
|
|
<input type="password" id="editProfilePassword" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="editProfileConfirmPassword" class="block text-sm font-medium text-gray-700">تأكيد كلمة المرور الجديدة</label> |
|
|
<input type="password" id="editProfileConfirmPassword" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div class="pt-4"> |
|
|
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
|
|
حفظ التغييرات |
|
|
</button> |
|
|
</div> |
|
|
</form> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="itemDetailsModal" class="fixed inset-0 bg-gray-900 bg-opacity-50 flex items-center justify-center z-50 hidden"> |
|
|
<div class="bg-white rounded-lg p-6 w-full max-w-2xl mx-4 max-h-[90vh] overflow-y-auto"> |
|
|
<div class="flex justify-between items-start mb-4"> |
|
|
<h2 id="itemDetailsTitle" class="text-xl font-bold"></h2> |
|
|
<button onclick="closeItemDetails()" class="text-gray-500 hover:text-gray-700"> |
|
|
<i class="fas fa-times"></i> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
|
<div> |
|
|
<img id="itemDetailsImage" src="" alt="" class="w-full h-64 object-cover rounded-lg"> |
|
|
<div class="mt-4 flex items-center justify-between"> |
|
|
<div> |
|
|
<span id="itemDetailsPrice" class="text-lg font-bold text-blue-600"></span> |
|
|
<span class="text-gray-500">/ يوم</span> |
|
|
</div> |
|
|
<div class="flex items-center"> |
|
|
<i class="fas fa-map-marker-alt text-gray-500 mr-1"></i> |
|
|
<span id="itemDetailsCity" class="text-gray-600"></span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h3 class="font-medium mb-2">الوصف</h3> |
|
|
<p id="itemDetailsDescription" class="text-gray-700 mb-4"></p> |
|
|
|
|
|
<div class="border-t pt-4"> |
|
|
<h3 class="font-medium mb-2">المالك</h3> |
|
|
<div class="flex items-center"> |
|
|
<div class="bg-blue-100 text-blue-800 rounded-full p-2 mr-3"> |
|
|
<i class="fas fa-user"></i> |
|
|
</div> |
|
|
<div> |
|
|
<p id="itemDetailsOwner" class="font-medium"></p> |
|
|
<p id="itemDetailsOwnerRating" class="text-sm text-gray-500"> |
|
|
<i class="fas fa-star text-yellow-400"></i> 4.8 (12 تقييم) |
|
|
</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="border-t pt-4 mt-4"> |
|
|
<h3 class="font-medium mb-2">تواصل مع المالك</h3> |
|
|
<div id="itemDetailsChat" class="space-y-2 max-h-40 overflow-y-auto mb-4"> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="flex items-center"> |
|
|
<input type="text" id="itemDetailsMessage" placeholder="اكتب رسالتك..." class="flex-1 border border-gray-300 rounded-l-md py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
<button onclick="sendMessage()" class="bg-blue-600 text-white px-4 py-2 rounded-r-md hover:bg-blue-700"> |
|
|
<i class="fas fa-paper-plane"></i> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="mt-6 pt-4 border-t"> |
|
|
<button id="rentItemBtn" onclick="requestRental()" class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700"> |
|
|
طلب الإيجار |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="rentalRequestModal" class="fixed inset-0 bg-gray-900 bg-opacity-50 flex items-center justify-center z-50 hidden"> |
|
|
<div class="bg-white rounded-lg p-6 w-full max-w-md mx-4"> |
|
|
<div class="flex justify-between items-start mb-4"> |
|
|
<h2 class="text-xl font-bold">طلب إيجار</h2> |
|
|
<button onclick="closeRentalRequestModal()" class="text-gray-500 hover:text-gray-700"> |
|
|
<i class="fas fa-times"></i> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<form id="rentalRequestForm" class="space-y-4"> |
|
|
<div> |
|
|
<label for="rentalStartDate" class="block text-sm font-medium text-gray-700">تاريخ البدء</label> |
|
|
<input type="date" id="rentalStartDate" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="rentalEndDate" class="block text-sm font-medium text-gray-700">تاريخ الانتهاء</label> |
|
|
<input type="date" id="rentalEndDate" required class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label for="rentalMessage" class="block text-sm font-medium text-gray-700">ملاحظات (اختياري)</label> |
|
|
<textarea id="rentalMessage" rows="3" class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-blue-500 focus:border-blue-500"></textarea> |
|
|
</div> |
|
|
|
|
|
<div class="pt-4"> |
|
|
<button type="submit" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"> |
|
|
تأكيد الطلب |
|
|
</button> |
|
|
</div> |
|
|
</form> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="rentalRequestDetailsModal" class="fixed inset-0 bg-gray-900 bg-opacity-50 flex items-center justify-center z-50 hidden"> |
|
|
<div class="bg-white rounded-lg p-6 w-full max-w-md mx-4"> |
|
|
<div class="flex justify-between items-start mb-4"> |
|
|
<h2 id="rentalRequestTitle" class="text-xl font-bold">تفاصيل طلب الإيجار</h2> |
|
|
<button onclick="closeRentalRequestDetailsModal()" class="text-gray-500 hover:text-gray-700"> |
|
|
<i class="fas fa-times"></i> |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div class="space-y-4"> |
|
|
<div> |
|
|
<h3 class="font-medium text-gray-700">المستأجر</h3> |
|
|
<p id="rentalRequestRenter" class="text-gray-900"></p> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h3 class="font-medium text-gray-700">فترة الإيجار</h3> |
|
|
<p id="rentalRequestPeriod" class="text-gray-900"></p> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h3 class="font-medium text-gray-700">الحالة</h3> |
|
|
<p id="rentalRequestStatus" class="text-gray-900"></p> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h3 class="font-medium text-gray-700">الملاحظات</h3> |
|
|
<p id="rentalRequestNotes" class="text-gray-900"></p> |
|
|
</div> |
|
|
|
|
|
<div id="rentalRequestActions" class="pt-4 flex space-x-2 space-x-reverse"> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</main> |
|
|
|
|
|
|
|
|
<footer class="bg-white border-t mt-12"> |
|
|
<div class="max-w-7xl mx-auto py-8 px-4 sm:px-6 lg:px-8"> |
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-8"> |
|
|
<div> |
|
|
<h3 class="text-lg font-medium text-gray-900 mb-4">جاري</h3> |
|
|
<p id="footerDescription" class="text-gray-500 text-sm">منصة لتأجير الأغراض الشخصية بين الأفراد</p> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h3 class="text-lg font-medium text-gray-900 mb-4">روابط سريعة</h3> |
|
|
<ul class="space-y-2"> |
|
|
<li><a href="#" onclick="showHome()" class="text-gray-500 hover:text-blue-600 text-sm">الرئيسية</a></li> |
|
|
<li><a href="#" onclick="showAddItem()" class="text-gray-500 hover:text-blue-600 text-sm">إضافة غرض</a></li> |
|
|
<li><a href="#" onclick="showLogin()" class="text-gray-500 hover:text-blue-600 text-sm">تسجيل الدخول</a></li> |
|
|
</ul> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<h3 class="text-lg font-medium text-gray-900 mb-4">تواصل معنا</h3> |
|
|
<div class="flex space-x-4 space-x-reverse"> |
|
|
<a href="#" class="text-gray-500 hover:text-blue-600"> |
|
|
<i class="fab fa-facebook-f"></i> |
|
|
</a> |
|
|
<a href="#" class="text-gray-500 hover:text-blue-600"> |
|
|
<i class="fab fa-twitter"></i> |
|
|
</a> |
|
|
<a href="#" class="text-gray-500 hover:text-blue-600"> |
|
|
<i class="fab fa-instagram"></i> |
|
|
</a> |
|
|
</div> |
|
|
<p class="text-gray-500 text-sm mt-4">info@jari.com</p> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="mt-8 pt-8 border-t border-gray-200 text-center"> |
|
|
<p class="text-gray-500 text-sm">© 2023 جاري. جميع الحقوق محفوظة.</p> |
|
|
</div> |
|
|
</div> |
|
|
</footer> |
|
|
|
|
|
|
|
|
<div id="loadingSpinner" class="fixed inset-0 bg-gray-900 bg-opacity-50 flex items-center justify-center z-50 hidden"> |
|
|
<div class="animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-blue-500"></div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="successNotification" class="fixed bottom-4 right-4 bg-green-500 text-white px-4 py-2 rounded-md shadow-lg flex items-center hidden z-50"> |
|
|
<i class="fas fa-check-circle mr-2"></i> |
|
|
<span id="successMessage"></span> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="errorNotification" class="fixed bottom-4 right-4 bg-red-500 text-white px-4 py-2 rounded-md shadow-lg flex items-center hidden z-50"> |
|
|
<i class="fas fa-exclamation-circle mr-2"></i> |
|
|
<span id="errorMessage"></span> |
|
|
</div> |
|
|
|
|
|
|
|
|
<script> |
|
|
|
|
|
let selectedCountry = null; |
|
|
let currentPage = null; |
|
|
let currentUser = null; |
|
|
let currentItemDetails = null; |
|
|
let currentRentalRequest = null; |
|
|
|
|
|
|
|
|
const cities = { |
|
|
sa: ['الرياض', 'جدة', 'مكة المكرمة', 'المدينة المنورة', 'الدمام', 'الخبر', 'الطائف', 'بريدة', 'تبوك', 'نجران'], |
|
|
eg: ['القاهرة', 'الجيزة', 'الإسكندرية', 'المنصورة', 'طنطا', 'المنيا', 'أسيوط', 'سوهاج', 'الأقصر', 'أسوان'] |
|
|
}; |
|
|
|
|
|
|
|
|
const categories = [ |
|
|
{ value: 'electronics', label: 'إلكترونيات' }, |
|
|
{ value: 'tools', label: 'أدوات' }, |
|
|
{ value: 'sports', label: 'رياضة' }, |
|
|
{ value: 'fashion', label: 'أزياء' }, |
|
|
{ value: 'home', label: 'أدوات منزلية' }, |
|
|
{ value: 'other', label: 'أخرى' } |
|
|
]; |
|
|
|
|
|
|
|
|
const rentalStatuses = { |
|
|
pending: { text: 'بانتظار الموافقة', color: 'bg-yellow-100 text-yellow-800' }, |
|
|
approved: { text: 'تمت الموافقة', color: 'bg-green-100 text-green-800' }, |
|
|
rejected: { text: 'تم الرفض', color: 'bg-red-100 text-red-800' }, |
|
|
completed: { text: 'مكتمل', color: 'bg-blue-100 text-blue-800' }, |
|
|
cancelled: { text: 'ملغي', color: 'bg-gray-100 text-gray-800' } |
|
|
}; |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
|
|
const savedCountry = localStorage.getItem('country'); |
|
|
if (savedCountry) { |
|
|
selectedCountry = savedCountry; |
|
|
initApp(); |
|
|
} else { |
|
|
|
|
|
document.getElementById('countryModal').classList.remove('hidden'); |
|
|
} |
|
|
|
|
|
|
|
|
const savedUser = localStorage.getItem('user'); |
|
|
if (savedUser) { |
|
|
currentUser = JSON.parse(savedUser); |
|
|
updateAuthUI(); |
|
|
} |
|
|
|
|
|
|
|
|
setupEventListeners(); |
|
|
}); |
|
|
|
|
|
|
|
|
function selectCountry(country) { |
|
|
selectedCountry = country; |
|
|
localStorage.setItem('country', country); |
|
|
document.getElementById('countryModal').classList.add('hidden'); |
|
|
initApp(); |
|
|
} |
|
|
|
|
|
|
|
|
function changeCountry() { |
|
|
localStorage.removeItem('country'); |
|
|
selectedCountry = null; |
|
|
document.getElementById('countryModal').classList.remove('hidden'); |
|
|
} |
|
|
|
|
|
|
|
|
function initApp() { |
|
|
if (!selectedCountry) return; |
|
|
|
|
|
|
|
|
const currency = selectedCountry === 'sa' ? 'ريال' : 'جنيه'; |
|
|
const countryName = selectedCountry === 'sa' ? 'السعودية' : 'مصر'; |
|
|
|
|
|
document.getElementById('priceCurrency').textContent = currency; |
|
|
document.getElementById('currentCountry').textContent = countryName; |
|
|
document.getElementById('mobileCurrentCountry').textContent = countryName; |
|
|
|
|
|
|
|
|
document.getElementById('footerDescription').textContent = |
|
|
`منصة لتأجير الأغراض الشخصية بين الأفراد في ${countryName}`; |
|
|
|
|
|
|
|
|
populateCitySelect('cityFilter', 'كل المدن'); |
|
|
populateCitySelect('itemCity', 'اختر المدينة'); |
|
|
|
|
|
|
|
|
populateCategoryFilter(); |
|
|
|
|
|
|
|
|
loadItems(); |
|
|
|
|
|
|
|
|
showHome(); |
|
|
} |
|
|
|
|
|
|
|
|
function populateCitySelect(selectId, defaultText) { |
|
|
const select = document.getElementById(selectId); |
|
|
select.innerHTML = ''; |
|
|
|
|
|
const defaultOption = document.createElement('option'); |
|
|
defaultOption.value = ''; |
|
|
defaultOption.textContent = defaultText; |
|
|
select.appendChild(defaultOption); |
|
|
|
|
|
cities[selectedCountry].forEach(city => { |
|
|
const option = document.createElement('option'); |
|
|
option.value = city; |
|
|
option.textContent = city; |
|
|
select.appendChild(option); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function populateCategoryFilter() { |
|
|
const select = document.getElementById('categoryFilter'); |
|
|
select.innerHTML = ''; |
|
|
|
|
|
const defaultOption = document.createElement('option'); |
|
|
defaultOption.value = ''; |
|
|
defaultOption.textContent = 'كل التصنيفات'; |
|
|
select.appendChild(defaultOption); |
|
|
|
|
|
categories.forEach(category => { |
|
|
const option = document.createElement('option'); |
|
|
option.value = category.value; |
|
|
option.textContent = category.label; |
|
|
select.appendChild(option); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function setupEventListeners() { |
|
|
|
|
|
document.getElementById('itemImage').addEventListener('change', function(e) { |
|
|
if (e.target.files.length > 0) { |
|
|
const reader = new FileReader(); |
|
|
reader.onload = function(event) { |
|
|
document.getElementById('previewImage').src = event.target.result; |
|
|
document.getElementById('imagePreview').classList.remove('hidden'); |
|
|
}; |
|
|
reader.readAsDataURL(e.target.files[0]); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
document.getElementById('cityFilter').addEventListener('change', function() { |
|
|
loadItems(); |
|
|
}); |
|
|
|
|
|
|
|
|
document.getElementById('categoryFilter').addEventListener('change', function() { |
|
|
loadItems(); |
|
|
}); |
|
|
|
|
|
|
|
|
document.getElementById('loginTabBtn').addEventListener('click', function(e) { |
|
|
e.preventDefault(); |
|
|
document.getElementById('loginForm').classList.remove('hidden'); |
|
|
document.getElementById('registerForm').classList.add('hidden'); |
|
|
document.getElementById('loginTabBtn').classList.add('tab-active'); |
|
|
document.getElementById('registerTabBtn').classList.remove('tab-active'); |
|
|
}); |
|
|
|
|
|
document.getElementById('registerTabBtn').addEventListener('click', function(e) { |
|
|
e.preventDefault(); |
|
|
document.getElementById('loginForm').classList.add('hidden'); |
|
|
document.getElementById('registerForm').classList.remove('hidden'); |
|
|
document.getElementById('loginTabBtn').classList.remove('tab-active'); |
|
|
document.getElementById('registerTabBtn').classList.add('tab-active'); |
|
|
}); |
|
|
|
|
|
|
|
|
document.getElementById('loginForm').addEventListener('submit', function(e) { |
|
|
e.preventDefault(); |
|
|
login(); |
|
|
}); |
|
|
|
|
|
document.getElementById('registerForm').addEventListener('submit', function(e) { |
|
|
e.preventDefault(); |
|
|
register(); |
|
|
}); |
|
|
|
|
|
document.getElementById('addItemForm').addEventListener('submit', function(e) { |
|
|
e.preventDefault(); |
|
|
addItem(); |
|
|
}); |
|
|
|
|
|
document.getElementById('editProfileForm').addEventListener('submit', function(e) { |
|
|
e.preventDefault(); |
|
|
updateProfile(); |
|
|
}); |
|
|
|
|
|
document.getElementById('rentalRequestForm').addEventListener('submit', function(e) { |
|
|
e.preventDefault(); |
|
|
submitRentalRequest(); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function showLoading() { |
|
|
document.getElementById('loadingSpinner').classList.remove('hidden'); |
|
|
} |
|
|
|
|
|
|
|
|
function hideLoading() { |
|
|
document.getElementById('loadingSpinner').classList.add('hidden'); |
|
|
} |
|
|
|
|
|
|
|
|
function showSuccess(message) { |
|
|
const notification = document.getElementById('successNotification'); |
|
|
document.getElementById('successMessage').textContent = message; |
|
|
notification.classList.remove('hidden'); |
|
|
|
|
|
setTimeout(() => { |
|
|
notification.classList.add('hidden'); |
|
|
}, 3000); |
|
|
} |
|
|
|
|
|
|
|
|
function showError(message) { |
|
|
const notification = document.getElementById('errorNotification'); |
|
|
document.getElementById('errorMessage').textContent = message; |
|
|
notification.classList.remove('hidden'); |
|
|
|
|
|
setTimeout(() => { |
|
|
notification.classList.add('hidden'); |
|
|
}, 3000); |
|
|
} |
|
|
|
|
|
|
|
|
function toggleMobileMenu() { |
|
|
document.getElementById('mobileMenu').classList.toggle('hidden'); |
|
|
} |
|
|
|
|
|
|
|
|
function updateAuthUI() { |
|
|
if (currentUser) { |
|
|
document.getElementById('loginTab').classList.add('hidden'); |
|
|
document.getElementById('profileTab').classList.remove('hidden'); |
|
|
document.getElementById('logoutBtn').classList.remove('hidden'); |
|
|
document.getElementById('addItemTab').classList.remove('hidden'); |
|
|
|
|
|
document.getElementById('mobileLoginTab').classList.add('hidden'); |
|
|
document.getElementById('mobileProfileTab').classList.remove('hidden'); |
|
|
document.getElementById('mobileLogoutBtn').classList.remove('hidden'); |
|
|
} else { |
|
|
document.getElementById('loginTab').classList.remove('hidden'); |
|
|
document.getElementById('profileTab').classList.add('hidden'); |
|
|
document.getElementById('logoutBtn').classList.add('hidden'); |
|
|
document.getElementById('addItemTab').classList.add('hidden'); |
|
|
|
|
|
document.getElementById('mobileLoginTab').classList.remove('hidden'); |
|
|
document.getElementById('mobileProfileTab').classList.add('hidden'); |
|
|
document.getElementById('mobileLogoutBtn').classList.add('hidden'); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
function showHome() { |
|
|
if (!selectedCountry) { |
|
|
document.getElementById('countryModal').classList.remove('hidden'); |
|
|
return; |
|
|
} |
|
|
|
|
|
hideAllPages(); |
|
|
document.getElementById('homePage').classList.remove('hidden'); |
|
|
document.getElementById('homeTab').classList.add('tab-active'); |
|
|
document.getElementById('addItemTab').classList.remove('tab-active'); |
|
|
document.getElementById('loginTab').classList.remove('tab-active'); |
|
|
document.getElementById('profileTab').classList.remove('tab-active'); |
|
|
currentPage = 'home'; |
|
|
|
|
|
loadItems(); |
|
|
} |
|
|
|
|
|
function showAddItem() { |
|
|
if (!selectedCountry) { |
|
|
document.getElementById('countryModal').classList.remove('hidden'); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (!currentUser) { |
|
|
showLogin(); |
|
|
showError('يجب تسجيل الدخول لإضافة غرض'); |
|
|
return; |
|
|
} |
|
|
|
|
|
hideAllPages(); |
|
|
document.getElementById('addItemPage').classList.remove('hidden'); |
|
|
document.getElementById('homeTab').classList.remove('tab-active'); |
|
|
document.getElementById('addItemTab').classList.add('tab-active'); |
|
|
document.getElementById('loginTab').classList.remove('tab-active'); |
|
|
document.getElementById('profileTab').classList.remove('tab-active'); |
|
|
currentPage = 'addItem'; |
|
|
} |
|
|
|
|
|
function showLogin() { |
|
|
if (!selectedCountry) { |
|
|
document.getElementById('countryModal').classList.remove('hidden'); |
|
|
return; |
|
|
} |
|
|
|
|
|
hideAllPages(); |
|
|
document.getElementById('loginPage').classList.remove('hidden'); |
|
|
document.getElementById('homeTab').classList.remove('tab-active'); |
|
|
document.getElementById('addItemTab').classList.remove('tab-active'); |
|
|
document.getElementById('loginTab').classList.add('tab-active'); |
|
|
document.getElementById('profileTab').classList.remove('tab-active'); |
|
|
currentPage = 'login'; |
|
|
|
|
|
|
|
|
document.getElementById('loginForm').reset(); |
|
|
document.getElementById('registerForm').reset(); |
|
|
document.getElementById('loginTabBtn').click(); |
|
|
} |
|
|
|
|
|
function showProfile() { |
|
|
if (!selectedCountry) { |
|
|
document.getElementById('countryModal').classList.remove('hidden'); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (!currentUser) { |
|
|
showLogin(); |
|
|
showError('يجب تسجيل الدخول لعرض الملف الشخصي'); |
|
|
return; |
|
|
} |
|
|
|
|
|
hideAllPages(); |
|
|
document.getElementById('profilePage').classList.remove('hidden'); |
|
|
document.getElementById('homeTab').classList.remove('tab-active'); |
|
|
document.getElementById('addItemTab').classList.remove('tab-active'); |
|
|
document.getElementById('loginTab').classList.remove('tab-active'); |
|
|
document.getElementById('profileTab').classList.add('tab-active'); |
|
|
currentPage = 'profile'; |
|
|
|
|
|
loadProfileData(); |
|
|
} |
|
|
|
|
|
function showEditProfile() { |
|
|
hideAllPages(); |
|
|
document.getElementById('editProfilePage').classList.remove('hidden'); |
|
|
currentPage = 'editProfile'; |
|
|
|
|
|
|
|
|
document.getElementById('editProfileName').value = currentUser.name; |
|
|
document.getElementById('editProfileEmail').value = currentUser.email; |
|
|
document.getElementById('editProfilePhone').value = currentUser.phone; |
|
|
} |
|
|
|
|
|
function hideAllPages() { |
|
|
const pages = ['homePage', 'addItemPage', 'loginPage', 'profilePage', 'editProfilePage']; |
|
|
pages.forEach(page => { |
|
|
document.getElementById(page).classList.add('hidden'); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const db = { |
|
|
users: [ |
|
|
{ |
|
|
id: 1, |
|
|
name: "محمد أحمد", |
|
|
email: "user@example.com", |
|
|
phone: "0501234567", |
|
|
password: "password123", |
|
|
country: "sa", |
|
|
createdAt: new Date() |
|
|
}, |
|
|
{ |
|
|
id: 2, |
|
|
name: "أحمد علي", |
|
|
email: "ahmed@example.com", |
|
|
phone: "0123456789", |
|
|
password: "password123", |
|
|
country: "eg", |
|
|
createdAt: new Date() |
|
|
} |
|
|
], |
|
|
items: [ |
|
|
{ |
|
|
id: 1, |
|
|
title: "كاميرا احترافية", |
|
|
description: "كاميرا كانون EOS 5D مارك الرابع مع عدسة 24-70mm، حالة ممتازة", |
|
|
price: 150, |
|
|
city: "الرياض", |
|
|
category: "electronics", |
|
|
image: "https://images.unsplash.com/photo-1516035069371-29a1b244cc32?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80", |
|
|
ownerId: 1, |
|
|
country: "sa", |
|
|
createdAt: new Date() |
|
|
}, |
|
|
{ |
|
|
id: 2, |
|
|
title: "دراجة هوائية", |
|
|
description: "دراجة هوائية ماركة تريك بحالة جيدة، مناسبة للطرق الوعرة", |
|
|
price: 80, |
|
|
city: "جدة", |
|
|
category: "sports", |
|
|
image: "https://images.unsplash.com/photo-1485965120184-e220f721d03e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80", |
|
|
ownerId: 1, |
|
|
country: "sa", |
|
|
createdAt: new Date() |
|
|
}, |
|
|
{ |
|
|
id: 3, |
|
|
title: "ماكينة خياطة", |
|
|
description: "ماكينة خياطة سنجر بحالة ممتازة مع جميع الملحقات", |
|
|
price: 50, |
|
|
city: "القاهرة", |
|
|
category: "home", |
|
|
image: "https://images.unsplash.com/photo-1539109132442-1bafc7a8a010?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80", |
|
|
ownerId: 2, |
|
|
country: "eg", |
|
|
createdAt: new Date() |
|
|
} |
|
|
], |
|
|
rentals: [ |
|
|
{ |
|
|
id: 1, |
|
|
itemId: 1, |
|
|
renterId: 2, |
|
|
ownerId: 1, |
|
|
startDate: "2023-06-15", |
|
|
endDate: "2023-06-20", |
|
|
totalPrice: 750, |
|
|
status: "completed", |
|
|
message: "أحتاج الكاميرا لتصوير حفل زفاف", |
|
|
createdAt: new Date("2023-06-10") |
|
|
}, |
|
|
{ |
|
|
id: 2, |
|
|
itemId: 2, |
|
|
renterId: 2, |
|
|
ownerId: 1, |
|
|
startDate: "2023-07-01", |
|
|
endDate: "2023-07-05", |
|
|
totalPrice: 320, |
|
|
status: "approved", |
|
|
message: "لرحلة عائلية", |
|
|
createdAt: new Date("2023-06-25") |
|
|
} |
|
|
], |
|
|
messages: [ |
|
|
{ |
|
|
id: 1, |
|
|
rentalId: 1, |
|
|
senderId: 2, |
|
|
receiverId: 1, |
|
|
message: "مرحباً، هل الكاميرا متاحة للإيجار في تاريخ 15 يونيو؟", |
|
|
createdAt: new Date("2023-06-08T10:00:00") |
|
|
}, |
|
|
{ |
|
|
id: 2, |
|
|
rentalId: 1, |
|
|
senderId: 1, |
|
|
receiverId: 2, |
|
|
message: "نعم متاحة، يمكنك حجزها الآن", |
|
|
createdAt: new Date("2023-06-08T10:15:00") |
|
|
}, |
|
|
{ |
|
|
id: 3, |
|
|
rentalId: 1, |
|
|
senderId: 2, |
|
|
receiverId: 1, |
|
|
message: "شكراً، سأقوم بحجزها الآن", |
|
|
createdAt: new Date("2023-06-08T10:30:00") |
|
|
} |
|
|
] |
|
|
}; |
|
|
|
|
|
|
|
|
function generateId() { |
|
|
return Math.floor(Math.random() * 1000000) + 1; |
|
|
} |
|
|
|
|
|
|
|
|
function formatDate(dateString) { |
|
|
const options = { year: 'numeric', month: 'long', day: 'numeric' }; |
|
|
return new Date(dateString).toLocaleDateString('ar-EG', options); |
|
|
} |
|
|
|
|
|
|
|
|
function calculateDays(startDate, endDate) { |
|
|
const start = new Date(startDate); |
|
|
const end = new Date(endDate); |
|
|
const diffTime = Math.abs(end - start); |
|
|
return Math.ceil(diffTime / (1000 * 60 * 60 * 24)); |
|
|
} |
|
|
|
|
|
|
|
|
function login() { |
|
|
const email = document.getElementById('loginEmail').value; |
|
|
const password = document.getElementById('loginPassword').value; |
|
|
|
|
|
if (!email || !password) { |
|
|
showError('الرجاء إدخال البريد الإلكتروني وكلمة المرور'); |
|
|
return; |
|
|
} |
|
|
|
|
|
showLoading(); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
const user = db.users.find(u => u.email === email && u.password === password); |
|
|
|
|
|
if (user) { |
|
|
currentUser = user; |
|
|
localStorage.setItem('user', JSON.stringify(user)); |
|
|
updateAuthUI(); |
|
|
showSuccess('تم تسجيل الدخول بنجاح'); |
|
|
showHome(); |
|
|
} else { |
|
|
showError('البريد الإلكتروني أو كلمة المرور غير صحيحة'); |
|
|
} |
|
|
|
|
|
hideLoading(); |
|
|
}, 1000); |
|
|
} |
|
|
|
|
|
|
|
|
function register() { |
|
|
const name = document.getElementById('registerName').value; |
|
|
const email = document.getElementById('registerEmail').value; |
|
|
const phone = document.getElementById('registerPhone').value; |
|
|
const password = document.getElementById('registerPassword').value; |
|
|
const confirmPassword = document.getElementById('registerConfirmPassword').value; |
|
|
|
|
|
if (!name || !email || !phone || !password || !confirmPassword) { |
|
|
showError('الرجاء ملء جميع الحقول'); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (password !== confirmPassword) { |
|
|
showError('كلمة المرور غير متطابقة'); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (password.length < 6) { |
|
|
showError('كلمة المرور يجب أن تكون 6 أحرف على الأقل'); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
const emailExists = db.users.some(u => u.email === email); |
|
|
if (emailExists) { |
|
|
showError('البريد الإلكتروني مسجل بالفعل'); |
|
|
return; |
|
|
} |
|
|
|
|
|
showLoading(); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
const newUser = { |
|
|
id: generateId(), |
|
|
name, |
|
|
email, |
|
|
phone, |
|
|
password, |
|
|
country: selectedCountry, |
|
|
createdAt: new Date() |
|
|
}; |
|
|
|
|
|
db.users.push(newUser); |
|
|
currentUser = newUser; |
|
|
localStorage.setItem('user', JSON.stringify(newUser)); |
|
|
updateAuthUI(); |
|
|
|
|
|
hideLoading(); |
|
|
showSuccess('تم إنشاء الحساب بنجاح'); |
|
|
document.getElementById('loginTabBtn').click(); |
|
|
document.getElementById('loginEmail').value = email; |
|
|
document.getElementById('loginPassword').value = ''; |
|
|
}, 1500); |
|
|
} |
|
|
|
|
|
|
|
|
function updateProfile() { |
|
|
const name = document.getElementById('editProfileName').value; |
|
|
const email = document.getElementById('editProfileEmail').value; |
|
|
const phone = document.getElementById('editProfilePhone').value; |
|
|
const password = document.getElementById('editProfilePassword').value; |
|
|
const confirmPassword = document.getElementById('editProfileConfirmPassword').value; |
|
|
|
|
|
if (!name || !email || !phone) { |
|
|
showError('الرجاء ملء جميع الحقول المطلوبة'); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (password && password.length < 6) { |
|
|
showError('كلمة المرور يجب أن تكون 6 أحرف على الأقل'); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (password && password !== confirmPassword) { |
|
|
showError('كلمة المرور غير متطابقة'); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
const emailExists = db.users.some(u => u.email === email && u.id !== currentUser.id); |
|
|
if (emailExists) { |
|
|
showError('البريد الإلكتروني مسجل بالفعل'); |
|
|
return; |
|
|
} |
|
|
|
|
|
showLoading(); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
const userIndex = db.users.findIndex(u => u.id === currentUser.id); |
|
|
if (userIndex !== -1) { |
|
|
db.users[userIndex].name = name; |
|
|
db.users[userIndex].email = email; |
|
|
db.users[userIndex].phone = phone; |
|
|
|
|
|
if (password) { |
|
|
db.users[userIndex].password = password; |
|
|
} |
|
|
|
|
|
|
|
|
currentUser = db.users[userIndex]; |
|
|
localStorage.setItem('user', JSON.stringify(currentUser)); |
|
|
|
|
|
hideLoading(); |
|
|
showSuccess('تم تحديث الملف الشخصي بنجاح'); |
|
|
showProfile(); |
|
|
} else { |
|
|
hideLoading(); |
|
|
showError('حدث خطأ أثناء تحديث الملف الشخصي'); |
|
|
} |
|
|
}, 1500); |
|
|
} |
|
|
|
|
|
|
|
|
function logout() { |
|
|
currentUser = null; |
|
|
localStorage.removeItem('user'); |
|
|
updateAuthUI(); |
|
|
showSuccess('تم تسجيل الخروج بنجاح'); |
|
|
showHome(); |
|
|
} |
|
|
|
|
|
|
|
|
function addItem() { |
|
|
if (!currentUser) { |
|
|
showError('يجب تسجيل الدخول لإضافة غرض'); |
|
|
showLogin(); |
|
|
return; |
|
|
} |
|
|
|
|
|
const title = document.getElementById('itemTitle').value; |
|
|
const description = document.getElementById('itemDescription').value; |
|
|
const price = parseFloat(document.getElementById('itemPrice').value); |
|
|
const city = document.getElementById('itemCity').value; |
|
|
const category = document.getElementById('itemCategory').value; |
|
|
const imageFile = document.getElementById('itemImage').files[0]; |
|
|
|
|
|
if (!title || !description || !price || !city || !category) { |
|
|
showError('الرجاء ملء جميع الحقول المطلوبة'); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (price <= 0) { |
|
|
showError('السعر يجب أن يكون أكبر من الصفر'); |
|
|
return; |
|
|
} |
|
|
|
|
|
showLoading(); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
|
|
|
const imageUrl = imageFile ? |
|
|
URL.createObjectURL(imageFile) : |
|
|
'https://via.placeholder.com/400x300?text=No+Image'; |
|
|
|
|
|
const newItem = { |
|
|
id: generateId(), |
|
|
title, |
|
|
description, |
|
|
price, |
|
|
city, |
|
|
category, |
|
|
image: imageUrl, |
|
|
ownerId: currentUser.id, |
|
|
country: selectedCountry, |
|
|
createdAt: new Date() |
|
|
}; |
|
|
|
|
|
db.items.push(newItem); |
|
|
|
|
|
|
|
|
document.getElementById('addItemForm').reset(); |
|
|
document.getElementById('imagePreview').classList.add('hidden'); |
|
|
|
|
|
hideLoading(); |
|
|
showSuccess('تم إضافة الغرض بنجاح'); |
|
|
showHome(); |
|
|
}, 1500); |
|
|
} |
|
|
|
|
|
|
|
|
function loadItems() { |
|
|
if (!selectedCountry) return; |
|
|
|
|
|
const cityFilter = document.getElementById('cityFilter').value; |
|
|
const categoryFilter = document.getElementById('categoryFilter').value; |
|
|
let items = db.items.filter(item => item.country === selectedCountry); |
|
|
|
|
|
|
|
|
if (cityFilter) { |
|
|
items = items.filter(item => item.city === cityFilter); |
|
|
} |
|
|
|
|
|
|
|
|
if (categoryFilter) { |
|
|
items = items.filter(item => item.category === categoryFilter); |
|
|
} |
|
|
|
|
|
const itemsContainer = document.getElementById('itemsContainer'); |
|
|
itemsContainer.innerHTML = ''; |
|
|
|
|
|
if (items.length === 0) { |
|
|
itemsContainer.innerHTML = ` |
|
|
<div class="col-span-full text-center py-12"> |
|
|
<i class="fas fa-box-open text-4xl text-gray-300 mb-4"></i> |
|
|
<p class="text-gray-500">لا توجد أغراض متاحة للإيجار حالياً</p> |
|
|
</div> |
|
|
`; |
|
|
return; |
|
|
} |
|
|
|
|
|
const currency = selectedCountry === 'sa' ? 'ريال' : 'جنيه'; |
|
|
|
|
|
items.forEach(item => { |
|
|
const owner = db.users.find(u => u.id === item.ownerId); |
|
|
const itemCard = document.createElement('div'); |
|
|
itemCard.className = 'bg-white rounded-lg shadow-md overflow-hidden item-card'; |
|
|
itemCard.innerHTML = ` |
|
|
<div class="h-48 bg-gray-200 relative cursor-pointer" onclick="showItemDetails(${item.id})"> |
|
|
<img src="${item.image}" alt="${item.title}" class="w-full h-full object-cover"> |
|
|
<div class="absolute bottom-2 left-2 bg-blue-600 text-white px-2 py-1 rounded text-sm"> |
|
|
${item.price} ${currency} / يوم |
|
|
</div> |
|
|
</div> |
|
|
<div class="p-4"> |
|
|
<h3 class="font-bold text-lg mb-1 cursor-pointer" onclick="showItemDetails(${item.id})">${item.title}</h3> |
|
|
<p class="text-gray-600 text-sm mb-2">${item.city}</p> |
|
|
<p class="text-gray-700 text-sm mb-4 line-clamp-2">${item.description}</p> |
|
|
<div class="flex justify-between items-center"> |
|
|
<button onclick="showItemDetails(${item.id})" class="text-blue-600 hover:text-blue-800 text-sm font-medium"> |
|
|
<i class="fas fa-comment-dots mr-1"></i> تواصل |
|
|
</button> |
|
|
<span class="text-xs text-gray-500">${owner ? owner.name : 'مستخدم'}</span> |
|
|
</div> |
|
|
</div> |
|
|
`; |
|
|
itemsContainer.appendChild(itemCard); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
function showItemDetails(itemId) { |
|
|
const item = db.items.find(i => i.id === itemId); |
|
|
if (!item) { |
|
|
showError('الغرض غير موجود'); |
|
|
return; |
|
|
} |
|
|
|
|
|
currentItemDetails = item; |
|
|
|
|
|
const owner = db.users.find(u => u.id === item.ownerId); |
|
|
const currency = selectedCountry === 'sa' ? 'ريال' : 'جنيه'; |
|
|
|
|
|
|
|
|
document.getElementById('itemDetailsTitle').textContent = item.title; |
|
|
document.getElementById('itemDetailsImage').src = item.image; |
|
|
document.getElementById('itemDetailsImage').alt = item.title; |
|
|
document.getElementById('itemDetailsPrice').textContent = item.price + ' ' + currency; |
|
|
document.getElementById('itemDetailsCity').textContent = item.city; |
|
|
document.getElementById('itemDetailsDescription').textContent = item.description; |
|
|
document.getElementById('itemDetailsOwner').textContent = owner ? owner.name : 'مستخدم'; |
|
|
|
|
|
|
|
|
document.getElementById('itemDetailsChat').innerHTML = ''; |
|
|
|
|
|
|
|
|
const rentButton = document.getElementById('rentItemBtn'); |
|
|
if (currentUser && currentUser.id === item.ownerId) { |
|
|
rentButton.classList.add('hidden'); |
|
|
} else { |
|
|
rentButton.classList.remove('hidden'); |
|
|
} |
|
|
|
|
|
|
|
|
const rental = db.rentals.find(r => r.itemId === item.id && |
|
|
(r.renterId === currentUser?.id || r.ownerId === currentUser?.id)); |
|
|
|
|
|
if (rental) { |
|
|
loadChatMessages(rental.id); |
|
|
} |
|
|
|
|
|
|
|
|
document.getElementById('itemDetailsModal').classList.remove('hidden'); |
|
|
} |
|
|
|
|
|
|
|
|
function closeItemDetails() { |
|
|
document.getElementById('itemDetailsModal').classList.add('hidden'); |
|
|
currentItemDetails = null; |
|
|
} |
|
|
|
|
|
|
|
|
function loadChatMessages(rentalId) { |
|
|
const chatContainer = document.getElementById('itemDetailsChat'); |
|
|
chatContainer.innerHTML = ''; |
|
|
|
|
|
const messages = db.messages |
|
|
.filter(m => m.rentalId === rentalId) |
|
|
.sort((a, b) => new Date(a.createdAt) - new Date(b.createdAt)); |
|
|
|
|
|
messages.forEach(message => { |
|
|
const isCurrentUser = message.senderId === currentUser?.id; |
|
|
const messageDiv = document.createElement('div'); |
|
|
messageDiv.className = `flex ${isCurrentUser ? 'justify-end' : 'justify-start'}`; |
|
|
|
|
|
messageDiv.innerHTML = ` |
|
|
<div class="chat-message bg-${isCurrentUser ? 'blue' : 'gray'}-100 rounded-lg px-4 py-2"> |
|
|
<p class="text-sm">${message.message}</p> |
|
|
<p class="text-xs text-gray-500 mt-1 text-right">${formatDate(message.createdAt)}</p> |
|
|
</div> |
|
|
`; |
|
|
|
|
|
chatContainer.appendChild(messageDiv); |
|
|
}); |
|
|
|
|
|
|
|
|
chatContainer.scrollTop = chatContainer.scrollHeight; |
|
|
} |
|
|
|
|
|
|
|
|
function sendMessage() { |
|
|
if (!currentUser) { |
|
|
showError('يجب تسجيل الدخول لإرسال رسالة'); |
|
|
showLogin(); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (!currentItemDetails) { |
|
|
showError('لا يوجد غرض محدد'); |
|
|
return; |
|
|
} |
|
|
|
|
|
const messageInput = document.getElementById('itemDetailsMessage'); |
|
|
const messageText = messageInput.value.trim(); |
|
|
|
|
|
if (!messageText) { |
|
|
showError('الرجاء إدخال رسالة'); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
let rental = db.rentals.find(r => r.itemId === currentItemDetails.id && |
|
|
(r.renterId === currentUser.id || r.ownerId === currentUser.id)); |
|
|
|
|
|
if (!rental) { |
|
|
|
|
|
rental = { |
|
|
id: generateId(), |
|
|
itemId: currentItemDetails.id, |
|
|
renterId: currentUser.id, |
|
|
ownerId: currentItemDetails.ownerId, |
|
|
startDate: '', |
|
|
endDate: '', |
|
|
totalPrice: 0, |
|
|
status: 'pending', |
|
|
message: messageText, |
|
|
createdAt: new Date() |
|
|
}; |
|
|
|
|
|
db.rentals.push(rental); |
|
|
} |
|
|
|
|
|
|
|
|
const newMessage = { |
|
|
id: generateId(), |
|
|
rentalId: rental.id, |
|
|
senderId: currentUser.id, |
|
|
receiverId: currentUser.id === rental.renterId ? rental.ownerId : rental.renterId, |
|
|
message: messageText, |
|
|
createdAt: new Date() |
|
|
}; |
|
|
|
|
|
db.messages.push(newMessage); |
|
|
|
|
|
|
|
|
messageInput.value = ''; |
|
|
|
|
|
|
|
|
loadChatMessages(rental.id); |
|
|
} |
|
|
|
|
|
|
|
|
function requestRental() { |
|
|
if (!currentUser) { |
|
|
showError('يجب تسجيل الدخول لطلب الإيجار'); |
|
|
showLogin(); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (!currentItemDetails) { |
|
|
showError('لا يوجد غرض محدد'); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
if (currentUser.id === currentItemDetails.ownerId) { |
|
|
showError('لا يمكنك طلب إيجار غرضك الخاص'); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
const existingRental = db.rentals.find(r => r.itemId === currentItemDetails.id && r.renterId === currentUser.id); |
|
|
|
|
|
if (existingRental) { |
|
|
showError('لديك طلب إيجار بالفعل لهذا الغرض'); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
document.getElementById('rentalRequestModal').classList.remove('hidden'); |
|
|
|
|
|
|
|
|
const today = new Date(); |
|
|
const tomorrow = new Date(today); |
|
|
tomorrow.setDate(tomorrow.getDate() + 1); |
|
|
|
|
|
const threeDaysLater = new Date(today); |
|
|
threeDaysLater.setDate(threeDaysLater.getDate() + 3); |
|
|
|
|
|
document.getElementById('rentalStartDate').valueAsDate = tomorrow; |
|
|
document.getElementById('rentalEndDate').valueAsDate = threeDaysLater; |
|
|
} |
|
|
|
|
|
|
|
|
function closeRentalRequestModal() { |
|
|
document.getElementById('rentalRequestModal').classList.add('hidden'); |
|
|
} |
|
|
|
|
|
|
|
|
function submitRentalRequest() { |
|
|
if (!currentUser || !currentItemDetails) { |
|
|
showError('حدث خطأ أثناء تقديم الطلب'); |
|
|
return; |
|
|
} |
|
|
|
|
|
const startDate = document.getElementById('rentalStartDate').value; |
|
|
const endDate = document.getElementById('rentalEndDate').value; |
|
|
const message = document.getElementById('rentalMessage').value; |
|
|
|
|
|
if (!startDate || !endDate) { |
|
|
showError('الرجاء تحديد تاريخ البدء والانتهاء'); |
|
|
return; |
|
|
} |
|
|
|
|
|
const days = calculateDays(startDate, endDate); |
|
|
if (days <= 0) { |
|
|
showError('تاريخ الانتهاء يجب أن يكون بعد تاريخ البدء'); |
|
|
return; |
|
|
} |
|
|
|
|
|
const totalPrice = currentItemDetails.price * days; |
|
|
|
|
|
showLoading(); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
const newRental = { |
|
|
id: generateId(), |
|
|
itemId: currentItemDetails.id, |
|
|
renterId: currentUser.id, |
|
|
ownerId: currentItemDetails.ownerId, |
|
|
startDate, |
|
|
endDate, |
|
|
totalPrice, |
|
|
status: 'pending', |
|
|
message, |
|
|
createdAt: new Date() |
|
|
}; |
|
|
|
|
|
db.rentals.push(newRental); |
|
|
|
|
|
|
|
|
const newMessage = { |
|
|
id: generateId(), |
|
|
rentalId: newRental.id, |
|
|
senderId: currentUser.id, |
|
|
receiverId: currentItemDetails.ownerId, |
|
|
message: message || 'أريد استئجار هذا الغرض', |
|
|
createdAt: new Date() |
|
|
}; |
|
|
|
|
|
db.messages.push(newMessage); |
|
|
|
|
|
hideLoading(); |
|
|
showSuccess('تم تقديم طلب الإيجار بنجاح'); |
|
|
closeRentalRequestModal(); |
|
|
closeItemDetails(); |
|
|
|
|
|
|
|
|
loadItems(); |
|
|
}, 1500); |
|
|
} |
|
|
|
|
|
|