أنشأت لك الملف كاملاً يعمل مباشرة في المتصفح بدون أي إعدادات:
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Voyago - منصة السياحة</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700;800&display=swap" rel="stylesheet">
<style>
* { font-family: 'Tajawal', sans-serif; }
.gradient-bg { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
.card-hover { transition: all 0.3s ease; }
.card-hover:hover { transform: translateY(-5px); box-shadow: 0 20px 40px rgba(0,0,0,0.3); }
.sidebar-item { transition: all 0.2s ease; }
.sidebar-item:hover { background: rgba(255,255,255,0.1); }
.sidebar-item.active { background: rgba(255,255,255,0.15); border-right: 3px solid #fff; }
.animate-fade { animation: fadeIn 0.3s ease; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.stat-card { background: linear-gradient(135deg, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0.05) 100%); backdrop-filter: blur(10px); }
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: #1f2937; }
::-webkit-scrollbar-thumb { background: #4b5563; border-radius: 4px; }
</style>
</head>
<body class="bg-gray-900 text-white min-h-screen">
<div id="app"></div>
<script>
// ============ DATA STORE ============
const Store = {
init() {
if (!localStorage.getItem('voyago_init')) {
localStorage.setItem('voyago_users', JSON.stringify([
{ id: 1, name: 'مدير النظام', email: 'admin@voyago.com', password: 'Admin@123', role: 'admin', entity_id: 1 },
{ id: 2, name: 'مكتب الرياض', email: 'office@riyadh.com', password: 'Office@123', role: 'office', entity_id: 2 },
{ id: 3, name: 'شركة النجم', email: 'company@nojoum.com', password: 'Company@123', role: 'company', entity_id: 3 }
]));
localStorage.setItem('voyago_entities', JSON.stringify([
{ id: 1, name: 'Voyago Admin', type: 'admin', city: 'الرياض', status: 'active' },
{ id: 2, name: 'مكتب الرياض للسياحة', type: 'office', city: 'الرياض', status: 'active', wallet_balance: 25000 },
{ id: 3, name: 'شركة النجم للسياحة', type: 'company', city: 'جدة', status: 'active', wallet_balance: 50000 }
]));
localStorage.setItem('voyago_services', JSON.stringify([
{ id: 1, entity_id: 3, name: 'رحلة دبي - 3 أيام', description: 'رحلة مميزة إلى دبي تشمل برج خليفة ونافورة دبي', price: 500, duration_days: 3, status: 'active' },
{ id: 2, entity_id: 3, name: 'رحلة تركيا - 5 أيام', description: 'جولة في اسطنبول ويزيتكا وكابادوكيا', price: 750, duration_days: 5, status: 'active' },
{ id: 3, entity_id: 3, name: 'رحلة ماليزيا - 7 أيام', description: 'استكشاف ماليزيا وسنغافورة', price: 1200, duration_days: 7, status: 'active' }
]));
localStorage.setItem('voyago_bookings', JSON.stringify([
{ id: 1, booking_number: 'VYG100001', service_id: 1, entity_id: 2, passenger_name: 'أحمد محمد', passenger_phone: '0501234567', amount: 500, commission: 50, total_amount: 500, status: 'confirmed', created_at: new Date().toISOString() },
{ id: 2, booking_number: 'VYG100002', service_id: 2, entity_id: 2, passenger_name: 'سارة علي', passenger_phone: '0559876543', amount: 750, commission: 75, total_amount: 750, status: 'pending', created_at: new Date().toISOString() }
]));
localStorage.setItem('voyago_topups', JSON.stringify([
{ id: 1, entity_id: 2, amount: 10000, payment_method: 'bank_transfer', status: 'pending', created_at: new Date().toISOString() }
]));
localStorage.setItem('voyago_refunds', JSON.stringify([]));
localStorage.setItem('voyago_init', 'true');
}
},
get(key) { return JSON.parse(localStorage.getItem('voyago_' + key) || '[]'); },
set(key, data) { localStorage.setItem('voyago_' + key, JSON.stringify(data)); },
getUser() { return JSON.parse(sessionStorage.getItem('voyago_current_user')); },
setUser(user) { sessionStorage.setItem('voyago_current_user', JSON.stringify(user)); },
logout() { sessionStorage.removeItem('voyago_current_user'); }
};
// ============ APP STATE ============
let currentPage = 'login';
let currentUser = null;
let currentFilter = '';
// ============ HELPER FUNCTIONS ============
function formatNumber(num) {
return num ? num.toLocaleString('ar-SA') : '0';
}
function formatDate(date) {
return new Date(date).toLocaleDateString('ar-SA');
}
function getStatusBadge(status) {
const badges = {
'pending': '<span class="px-2 py-1 rounded-full text-xs bg-yellow-500/20 text-yellow-400">قيد الانتظار</span>',
'confirmed': '<span class="px-2 py-1 rounded-full text-xs bg-green-500/20 text-green-400">مؤكد</span>',
'cancelled': '<span class="px-2 py-1 rounded-full text-xs bg-red-500/20 text-red-400">ملغي</span>',
'completed': '<span class="px-2 py-1 rounded-full text-xs bg-blue-500/20 text-blue-400">مكتمل</span>',
'active': '<span class="px-2 py-1 rounded-full text-xs bg-green-500/20 text-green-400">نشط</span>',
'inactive': '<span class="px-2 py-1 rounded-full text-xs bg-gray-500/20 text-gray-400">غير نشط</span>',
'approved': '<span class="px-2 py-1 rounded-full text-xs bg-green-500/20 text-green-400">مقبول</span>',
'rejected': '<span class="px-2 py-1 rounded-full text-xs bg-red-500/20 text-red-400">مرفوض</span>'
};
return badges[status] || '<span class="px-2 py-1 rounded-full text-xs bg-gray-500/20 text-gray-400">' + status + '</span>';
}
// ============ RENDER FUNCTIONS ============
function render() {
const app = document.getElementById('app');
if (!currentUser) {
app.innerHTML = renderLogin();
} else {
app.innerHTML = renderLayout();
}
attachEvents();
}
function renderLogin() {
return `
<div class="min-h-screen flex items-center justify-center p-4 gradient-bg">
<div class="w-full max-w-md animate-fade">
<div class="text-center mb-8">
<div class="inline-flex items-center justify-center w-20 h-20 bg-white/20 rounded-2xl mb-4 backdrop-blur">
<span class="text-4xl">✈️</span>
</div>
<h1 class="text-3xl font-bold">Voyago</h1>
<p class="text-white/70 mt-2">منصة السياحة والسفر</p>
</div>
<div class="bg-white/10 backdrop-blur-lg rounded-2xl p-8 border border-white/20">
<form id="loginForm" class="space-y-6">
<div>
<label class="block text-sm font-medium mb-2">البريد الإلكتروني</label>
<input type="email" id="loginEmail" required
class="w-full px-4 py-3 bg-white/10 border border-white/20 rounded-xl text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-white/30"
placeholder="example@email.com">
</div>
<div>
<label class="block text-sm font-medium mb-2">كلمة المرور</label>
<input type="password" id="loginPassword" required
class="w-full px-4 py-3 bg-white/10 border border-white/20 rounded-xl text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-white/30"
placeholder="••••••••">
</div>
<button type="submit"
class="w-full py-3 bg-white text-purple-600 rounded-xl font-bold hover:bg-white/90 transition-all">
تسجيل الدخول
</button>
</form>
<div id="loginError" class="hidden mt-4 p-3 bg-red-500/20 border border-red-500/30 rounded-xl text-red-300 text-center"></div>
</div>
<div class="mt-6 p-4 bg-white/10 backdrop-blur rounded-xl border border-white/20">
<p class="text-sm text-white/70 text-center mb-3">حسابات تجريبية</p>
<div class="grid grid-cols-3 gap-2 text-xs">
<div class="bg-white/10 p-2 rounded-lg text-center cursor-pointer hover:bg-white/20" onclick="quickLogin('admin@voyago.com','Admin@123')">
<p class="font-medium">👑 Admin</p>
<p class="text-white/50">Admin@123</p>
</div>
<div class="bg-white/10 p-2 rounded-lg text-center cursor-pointer hover:bg-white/20" onclick="quickLogin('office@riyadh.com','Office@123')">
<p class="font-medium">🏢 Office</p>
<p class="text-white/50">Office@123</p>
</div>
<div class="bg-white/10 p-2 rounded-lg text-center cursor-pointer hover:bg-white/20" onclick="quickLogin('company@nojoum.com','Company@123')">
<p class="font-medium">🏛️ Company</p>
<p class="text-white/50">Company@123</p>
</div>
</div>
</div>
</div>
</div>
`;
}
function renderLayout() {
const isAdmin = currentUser.role === 'admin';
const isOffice = currentUser.role === 'office';
const isCompany = currentUser.role === 'company';
return `
<div class="flex min-h-screen">
<!-- Sidebar -->
<aside class="w-64 bg-gray-800 border-l border-gray-700 flex flex-col">
<div class="p-6 border-b border-gray-700">
<div class="flex items-center gap-3">
<div class="w-10 h-10 gradient-bg rounded-xl flex items-center justify-center">
<span class="text-xl">✈️</span>
</div>
<div>
<h1 class="font-bold">Voyago</h1>
<p class="text-xs text-gray-400">${currentUser.name}</p>
</div>
</div>
</div>
<nav class="flex-1 p-4 space-y-2">
${isAdmin ? `
<button onclick="navigate('dashboard')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'dashboard' ? 'active' : ''}">
<span>📊</span> لوحة التحكم
</button>
<button onclick="navigate('entities')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'entities' ? 'active' : ''}">
<span>🏢</span> الكيانات
</button>
<button onclick="navigate('bookings')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'bookings' ? 'active' : ''}">
<span>📅</span> الحجوزات
</button>
<button onclick="navigate('topups')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'topups' ? 'active' : ''}">
<span>💳</span> طلبات الشحن
</button>
<button onclick="navigate('refunds')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'refunds' ? 'active' : ''}">
<span>↩️</span> طلبات الاسترجاع
</button>
<button onclick="navigate('wallets')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'wallets' ? 'active' : ''}">
<span>💰</span> المحافظ
</button>
` : ''}
${isOffice ? `
<button onclick="navigate('dashboard')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'dashboard' ? 'active' : ''}">
<span>📊</span> لوحة التحكم
</button>
<button onclick="navigate('wallet')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'wallet' ? 'active' : ''}">
<span>💰</span> المحفظة
</button>
<button onclick="navigate('bookings')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'bookings' ? 'active' : ''}">
<span>📅</span> الحجوزات
</button>
<button onclick="navigate('create_booking')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'create_booking' ? 'active' : ''}">
<span>➕</span> إنشاء حجز
</button>
<button onclick="navigate('topups')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'topups' ? 'active' : ''}">
<span>💳</span> طلبات الشحن
</button>
<button onclick="navigate('create_topup')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'create_topup' ? 'active' : ''}">
<span>💵</span> طلب شحن جديد
</button>
` : ''}
${isCompany ? `
<button onclick="navigate('dashboard')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'dashboard' ? 'active' : ''}">
<span>📊</span> لوحة التحكم
</button>
<button onclick="navigate('services')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'services' ? 'active' : ''}">
<span>🎯</span> خدماتي
</button>
<button onclick="navigate('bookings')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'bookings' ? 'active' : ''}">
<span>📅</span> الحجوزات
</button>
<button onclick="navigate('wallet')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'wallet' ? 'active' : ''}">
<span>💰</span> المحفظة
</button>
<button onclick="navigate('documents')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'documents' ? 'active' : ''}">
<span>📄</span> الوثائق
</button>
<button onclick="navigate('settlements')" class="sidebar-item w-full flex items-center gap-3 px-4 py-3 rounded-xl ${currentPage === 'settlements' ? 'active' : ''}">
<span>💵</span> التسويات
</button>
` : ''}
</nav>
<div class="p-4 border-t border-gray-700">
<button onclick="logout()" class="w-full flex items-center justify-center gap-2 px-4 py-3 bg-red-500/20 text-red-400 rounded-xl hover:bg-red-500/30 transition-colors">
<span>🚪</span> تسجيل الخروج
</button>
</div>
</aside>
<!-- Main Content -->
<main class="flex-1 overflow-auto">
<div class="p-6 animate-fade">
${renderPage()}
</div>
</main>
</div>
`;
}
function renderPage() {
switch(currentPage) {
case 'dashboard': return renderDashboard();
case 'entities': return renderEntities();
case 'bookings': return renderBookings();
case 'topups': return renderTopups();
case 'refunds': return renderRefunds();
case 'wallets': return renderWallets();
case 'wallet': return renderWallet();
case 'create_booking': return renderCreateBooking();
case 'create_topup': return renderCreateTopup();
case 'services': return renderServices();
case 'documents': return renderDocuments();
case 'settlements': return renderSettlements();
default: return renderDashboard();
}
}
function renderDashboard() {
const entities = Store.get('entities');
const bookings = Store.get('bookings');
const topups = Store.get('topups');
const services = Store.get('services');
const userEntity = entities.find(e => e.id === currentUser.entity_id);
const isAdmin = currentUser.role === 'admin';
const isOffice = currentUser.role === 'office';
const isCompany = currentUser.role === 'company';
let stats = [];
if (isAdmin) {
stats = [
{ title: 'إجمالي المستخدمين', value: Store.get('users').length, icon: '👥', color: 'from-purple-500 to-purple-600' },
{ title: 'الك