<!DOCTYPE html>
<html dir="rtl" lang="ar">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>لوحة التحكم – مزايا منسوبي UPM</title>
<link href="https://fonts.googleapis.com/css2?family=Cairo:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.23.0/firebase-firestore-compat.js"></script>
<script>
const FIREBASE_CONFIG = {
apiKey: "AIzaSyCBvuJ907YcP5ybsGn41G_zwnb83N-sbkk",
authDomain: "upm-mazaya.firebaseapp.com",
projectId: "upm-mazaya",
storageBucket: "upm-mazaya.firebasestorage.app",
messagingSenderId: "271717030243",
appId: "1:271717030243:web:e9964b0d6e8d24bba5db56"
};
firebase.initializeApp(FIREBASE_CONFIG);
const db = firebase.firestore();
db.settings({ experimentalForceLongPolling: true, merge: true });
</script>
</head>
<body style="background-color:#f0f2f5;font-family:'Cairo',Tahoma,sans-serif;margin:0;padding:0;">
<!-- HEADER -->
<div style="background-color:#0a3d62;background-image:linear-gradient(135deg,#0a3d62 0%,#16213e 100%);padding:0 40px;">
<div style="align-items:center;display:flex;height:64px;justify-content:space-between;max-width:1400px;margin:0 auto;">
<div style="align-items:center;display:flex;gap:14px;">
<div style="align-items:center;background-color:rgba(201,168,76,0.2);border-radius:10px;display:flex;height:38px;justify-content:center;width:38px;font-size:18px;">⚙️</div>
<div>
<div style="color:#ffffff;font-size:16px;font-weight:700;">لوحة التحكم</div>
<div style="color:rgba(255,255,255,0.5);font-size:11px;">برنامج مزايا منسوبي UPM</div>
</div>
</div>
<div style="align-items:center;display:flex;gap:20px;">
<div id="statsBar" style="align-items:center;display:flex;gap:20px;"></div>
<a href="mazaya-complete.html" target="_blank" style="background-color:rgba(201,168,76,0.15);border-radius:8px;border:1px solid rgba(201,168,76,0.3);color:#f0d080;font-size:12px;font-weight:600;padding:7px 14px;text-decoration:none;">← الصفحة الرئيسية</a>
</div>
</div>
</div>
<!-- TABS -->
<div style="background-color:#ffffff;border-bottom:1px solid #e8e8e0;padding:0 40px;">
<div style="display:flex;gap:0;max-width:1400px;margin:0 auto;">
<button id="tab-pending" onclick="switchTab('pending')" style="background:none;border:none;border-bottom:3px solid #0a3d62;color:#0a3d62;cursor:pointer;font-family:'Cairo',sans-serif;font-size:14px;font-weight:700;padding:16px 24px;">
⏳ بانتظار المراجعة <span id="count-pending" style="background-color:#e74c3c;border-radius:20px;color:#fff;font-size:11px;margin-right:6px;padding:2px 8px;">0</span>
</button>
<button id="tab-approved" onclick="switchTab('approved')" style="background:none;border:none;border-bottom:3px solid transparent;color:#7f8c8d;cursor:pointer;font-family:'Cairo',sans-serif;font-size:14px;font-weight:600;padding:16px 24px;">
✅ معتمدة <span id="count-approved" style="background-color:#e8e8e0;border-radius:20px;color:#555;font-size:11px;margin-right:6px;padding:2px 8px;">0</span>
</button>
<button id="tab-rejected" onclick="switchTab('rejected')" style="background:none;border:none;border-bottom:3px solid transparent;color:#7f8c8d;cursor:pointer;font-family:'Cairo',sans-serif;font-size:14px;font-weight:600;padding:16px 24px;">
❌ مرفوضة <span id="count-rejected" style="background-color:#e8e8e0;border-radius:20px;color:#555;font-size:11px;margin-right:6px;padding:2px 8px;">0</span>
</button>
</div>
</div>
<!-- CONTENT -->
<div style="max-width:1400px;margin:0 auto;padding:32px 40px;">
<!-- FILTER BAR -->
<div style="align-items:center;display:flex;gap:12px;margin-bottom:24px;">
<input id="searchInput" type="text" placeholder="🔍 بحث باسم المنشأة أو رقم السجل..." oninput="filterCards()" style="background-color:#fff;border-radius:10px;border:1px solid #e8e8e0;color:#0a3d62;flex:1;font-family:'Cairo',sans-serif;font-size:14px;outline:none;padding:11px 16px;" />
<select id="categoryFilter" onchange="filterCards()" style="background-color:#fff;border-radius:10px;border:1px solid #e8e8e0;color:#0a3d62;font-family:'Cairo',sans-serif;font-size:13px;outline:none;padding:11px 16px;">
<option value="">كل التصنيفات</option>
<option>رعاية صحية</option>
<option>سفر وضيافة</option>
<option>عناية ولياقة</option>
<option>مقاهٍ ومطاعم</option>
<option>التسوق والخدمات</option>
<option>التدريب والتطوير</option>
<option>أخرى</option>
</select>
</div>
<!-- CARDS GRID -->
<div id="cardsGrid" style="display:grid;gap:20px;grid-template-columns:repeat(auto-fill,minmax(380px,1fr));"></div>
<!-- EMPTY STATE -->
<div id="emptyState" style="display:none;padding:80px 0;text-align:center;">
<div style="font-size:48px;margin-bottom:16px;">📭</div>
<div style="color:#0a3d62;font-size:18px;font-weight:700;margin-bottom:8px;">لا توجد طلبات</div>
<div style="color:#7f8c8d;font-size:14px;">ستظهر طلبات الشراكة هنا بمجرد إرسالها</div>
</div>
<!-- LOADING -->
<div id="loadingState" style="padding:80px 0;text-align:center;">
<div style="color:#0a3d62;font-size:16px;">⏳ جارٍ تحميل الطلبات...</div>
</div>
</div>
<!-- MODAL تفاصيل الطلب -->
<div id="detailModal" onclick="if(event.target===this)closeModal()" style="align-items:flex-start;background-color:rgba(10,61,98,0.6);bottom:0;display:none;justify-content:center;left:0;overflow-y:auto;padding:40px 20px;position:fixed;right:0;top:0;z-index:9999;">
<div style="background-color:#fafaf8;border-radius:20px;max-width:680px;padding:40px 44px;position:relative;width:100%;">
<button onclick="closeModal()" style="background:rgba(0,0,0,0.08);border:none;border-radius:50%;color:#0a3d62;cursor:pointer;font-size:18px;height:36px;left:16px;position:absolute;top:16px;width:36px;">✕</button>
<div id="modalContent"></div>
</div>
</div>
<script>
const CATEGORY_ICONS = {
"رعاية صحية":"🏥","سفر وضيافة":"🏨","عناية ولياقة":"🏃",
"مقاهٍ ومطاعم":"🍽️","التسوق والخدمات":"🛍️","التدريب والتطوير":"🎓","أخرى":"✨"
};
let allRequests = [];
let currentTab = 'pending';
// ── Load all requests ──
async function loadRequests() {
try {
const snap = await db.collection('partner_requests').orderBy('submittedAt','desc').get();
allRequests = snap.docs.map(d => ({id: d.id, ...d.data()}));
updateCounts();
renderCards();
document.getElementById('loadingState').style.display = 'none';
} catch(e) {
console.error(e);
document.getElementById('loadingState').innerHTML = '<div style="color:#e74c3c;font-size:14px;">❌ خطأ في تحميل البيانات — تحقق من اتصال Firebase</div>';
}
}
function updateCounts() {
const pending = allRequests.filter(r => r.status === 'pending').length;
const approved = allRequests.filter(r => r.status === 'approved').length;
const rejected = allRequests.filter(r => r.status === 'rejected').length;
document.getElementById('count-pending').textContent = pending;
document.getElementById('count-approved').textContent = approved;
document.getElementById('count-rejected').textContent = rejected;
// Stats bar
document.getElementById('statsBar').innerHTML = `
<div style="color:rgba(255,255,255,0.7);font-size:12px;">إجمالي الطلبات: <strong style="color:#f0d080;">${allRequests.length}</strong></div>
<div style="background-color:rgba(255,255,255,0.2);height:20px;width:1px;"></div>
<div style="color:rgba(255,255,255,0.7);font-size:12px;">معتمدة: <strong style="color:#2ecc71;">${approved}</strong></div>
`;
}
function switchTab(tab) {
currentTab = tab;
['pending','approved','rejected'].forEach(t => {
const btn = document.getElementById('tab-'+t);
btn.style.borderBottomColor = t === tab ? '#0a3d62' : 'transparent';
btn.style.color = t === tab ? '#0a3d62' : '#7f8c8d';
btn.style.fontWeight = t === tab ? '700' : '600';
});
renderCards();
}
function filterCards() { renderCards(); }
function renderCards() {
const search = document.getElementById('searchInput').value.toLowerCase();
const cat = document.getElementById('categoryFilter').value;
const filtered = allRequests.filter(r => {
if (r.status !== currentTab) return false;
if (cat && r.offer?.category !== cat) return false;
if (search) {
const name = (r.businessInfo?.name || r.cr || '').toLowerCase();
const cr = (r.cr || '').toLowerCase();
if (!name.includes(search) && !cr.includes(search)) return false;
}
return true;
});
const grid = document.getElementById('cardsGrid');
const empty = document.getElementById('emptyState');
if (filtered.length === 0) {
grid.innerHTML = '';
empty.style.display = 'block';
return;
}
empty.style.display = 'none';
grid.innerHTML = filtered.map(r => {
const icon = CATEGORY_ICONS[r.offer?.category] || '✦';
const name = r.businessInfo?.name || 'منشأة غير معرّفة';
const cat = r.offer?.category || '—';
const contact = r.contact?.name || '—';
const role = r.contact?.role || '';
const phone = r.contact?.phone || '—';
const email = r.contact?.email || '—';
const cr = r.cr || '—';
const date = r.submittedAt?.toDate ? r.submittedAt.toDate().toLocaleDateString('ar-SA') : '—';
const desc = r.offer?.description || '—';
const start = r.offer?.startDate || '—';
const statusColors = {
pending: { bg:'#fff8e6', border:'#f0b429', label:'بانتظار المراجعة', dot:'#f0b429' },
approved: { bg:'#f0fff4', border:'#2ecc71', label:'معتمد', dot:'#2ecc71' },
rejected: { bg:'#fff0f0', border:'#e74c3c', label:'مرفوض', dot:'#e74c3c' },
};
const sc = statusColors[r.status] || statusColors.pending;
return `
<div style="background-color:#ffffff;border-radius:16px;border:1px solid #e8e8e0;overflow:hidden;transition:box-shadow 0.2s;" onmouseover="this.style.boxShadow='0 4px 20px rgba(10,61,98,0.1)'" onmouseout="this.style.boxShadow='none'">
<!-- Card Header -->
<div style="background-color:#f8f9fc;border-bottom:1px solid #e8e8e0;padding:18px 22px;">
<div style="align-items:center;display:flex;gap:12px;justify-content:space-between;">
<div style="align-items:center;display:flex;gap:12px;">
<div style="align-items:center;background-color:#f0f4ff;border-radius:12px;display:flex;font-size:24px;height:46px;justify-content:center;width:46px;">${icon}</div>
<div>
<div style="color:#0a3d62;font-size:15px;font-weight:700;">${name}</div>
<div style="color:#7f8c8d;font-size:12px;margin-top:2px;">${cat} · سجل: ${cr}</div>
</div>
</div>
<div style="align-items:center;background-color:${sc.bg};border-radius:20px;border:1px solid ${sc.border};display:flex;gap:5px;padding:4px 10px;">
<div style="background-color:${sc.dot};border-radius:50%;height:7px;width:7px;"></div>
<span style="color:${sc.dot};font-size:11px;font-weight:700;">${sc.label}</span>
</div>
</div>
</div>
<!-- Card Body -->
<div style="padding:18px 22px;">
<div style="display:grid;gap:10px;grid-template-columns:1fr 1fr;margin-bottom:14px;">
<div><div style="color:#aaa;font-size:10px;margin-bottom:2px;">المسؤول</div><div style="color:#0a3d62;font-size:13px;font-weight:600;">${contact}</div><div style="color:#7f8c8d;font-size:11px;">${role}</div></div>
<div><div style="color:#aaa;font-size:10px;margin-bottom:2px;">الجوال</div><div style="color:#0a3d62;font-size:13px;font-weight:600;direction:ltr;text-align:right;">${phone}</div></div>
<div><div style="color:#aaa;font-size:10px;margin-bottom:2px;">تاريخ الطلب</div><div style="color:#0a3d62;font-size:13px;font-weight:600;">${date}</div></div>
<div><div style="color:#aaa;font-size:10px;margin-bottom:2px;">بدء العرض</div><div style="color:#0a3d62;font-size:13px;font-weight:600;">${start}</div></div>
</div>
<div style="background-color:#f8f9fc;border-radius:8px;margin-bottom:16px;padding:10px 14px;">
<div style="color:#aaa;font-size:10px;margin-bottom:4px;">العرض المقدَّم</div>
<div style="color:#34495e;font-size:13px;line-height:1.7;">${desc.length > 120 ? desc.slice(0,120)+'...' : desc}</div>
</div>
<!-- Actions -->
<div style="align-items:center;display:flex;gap:8px;">
<button onclick="openDetail('${r.id}')" style="background-color:#f0f4ff;border-radius:8px;border:none;color:#0a3d62;cursor:pointer;flex:1;font-family:'Cairo',sans-serif;font-size:12px;font-weight:600;padding:9px;">👁 عرض التفاصيل</button>
${r.status === 'pending' ? `
<button onclick="updateStatus('${r.id}','approved')" style="background-color:#2ecc71;border-radius:8px;border:none;color:#fff;cursor:pointer;flex:1;font-family:'Cairo',sans-serif;font-size:12px;font-weight:700;padding:9px;">✅ اعتماد</button>
<button onclick="updateStatus('${r.id}','rejected')" style="background-color:#e74c3c;border-radius:8px;border:none;color:#fff;cursor:pointer;flex:1;font-family:'Cairo',sans-serif;font-size:12px;font-weight:700;padding:9px;">❌ رفض</button>
` : r.status === 'approved' ? `
<button onclick="updateStatus('${r.id}','rejected')" style="background-color:#f8d7da;border-radius:8px;border:1px solid #f5c6cb;color:#721c24;cursor:pointer;flex:1;font-family:'Cairo',sans-serif;font-size:12px;font-weight:600;padding:9px;">إلغاء الاعتماد</button>
` : `
<button onclick="updateStatus('${r.id}','approved')" style="background-color:#d4edda;border-radius:8px;border:1px solid #c3e6cb;color:#155724;cursor:pointer;flex:1;font-family:'Cairo',sans-serif;font-size:12px;font-weight:600;padding:9px;">إعادة الاعتماد</button>
`}
</div>
</div>
</div>`;
}).join('');
}
// ── Update Status ──
async function updateStatus(id, newStatus) {
const labels = { approved:'اعتماد', rejected:'رفض' };
const action = labels[newStatus] || newStatus;
try {
await db.collection('partner_requests').doc(id).update({
status: newStatus,
updatedAt: firebase.firestore.FieldValue.serverTimestamp(),
reviewedBy: 'admin'
});
// Update local
const req = allRequests.find(r => r.id === id);
if (req) req.status = newStatus;
updateCounts();
renderCards();
closeModal();
// Toast
showToast(newStatus === 'approved' ? '✅ تم اعتماد الشريك بنجاح' : '❌ تم رفض الطلب', newStatus === 'approved' ? '#2ecc71' : '#e74c3c');
} catch(e) {
console.error(e);
showToast('❌ خطأ — حاول مجدداً', '#e74c3c');
}
}
// ── Detail Modal ──
function openDetail(id) {
const r = allRequests.find(x => x.id === id);
if (!r) return;
const icon = CATEGORY_ICONS[r.offer?.category] || '✦';
const date = r.submittedAt?.toDate ? r.submittedAt.toDate().toLocaleString('ar-SA') : '—';
document.getElementById('modalContent').innerHTML = `
<div style="align-items:center;display:flex;gap:14px;margin-bottom:28px;">
<div style="align-items:center;background-color:#f0f4ff;border-radius:14px;display:flex;font-size:32px;height:56px;justify-content:center;width:56px;">${icon}</div>
<div>
<h2 style="color:#0a3d62;font-size:20px;margin:0 0 4px 0;">${r.businessInfo?.name || 'منشأة'}</h2>
<div style="color:#7f8c8d;font-size:13px;">سجل تجاري: ${r.cr} · ${r.offer?.category || '—'}</div>
</div>
</div>
<div style="display:grid;gap:16px;grid-template-columns:1fr 1fr;margin-bottom:20px;">
<div style="background-color:#f8f9fc;border-radius:10px;padding:14px 16px;"><div style="color:#aaa;font-size:11px;margin-bottom:4px;">اسم المسؤول</div><div style="color:#0a3d62;font-size:14px;font-weight:700;">${r.contact?.name||'—'}</div></div>
<div style="background-color:#f8f9fc;border-radius:10px;padding:14px 16px;"><div style="color:#aaa;font-size:11px;margin-bottom:4px;">الصفة</div><div style="color:#0a3d62;font-size:14px;font-weight:700;">${r.contact?.role||'—'}</div></div>
<div style="background-color:#f8f9fc;border-radius:10px;padding:14px 16px;"><div style="color:#aaa;font-size:11px;margin-bottom:4px;">الجوال</div><div style="color:#0a3d62;font-size:14px;font-weight:700;direction:ltr;">${r.contact?.phone||'—'}</div></div>
<div style="background-color:#f8f9fc;border-radius:10px;padding:14px 16px;"><div style="color:#aaa;font-size:11px;margin-bottom:4px;">البريد</div><div style="color:#0a3d62;font-size:13px;font-weight:600;direction:ltr;">${r.contact?.email||'—'}</div></div>
<div style="background-color:#f8f9fc;border-radius:10px;padding:14px 16px;"><div style="color:#aaa;font-size:11px;margin-bottom:4px;">بدء العرض</div><div style="color:#0a3d62;font-size:14px;font-weight:700;">${r.offer?.startDate||'—'}</div></div>
<div style="background-color:#f8f9fc;border-radius:10px;padding:14px 16px;"><div style="color:#aaa;font-size:11px;margin-bottom:4px;">انتهاء العرض</div><div style="color:#0a3d62;font-size:14px;font-weight:700;">${r.offer?.endDate||'مفتوح'}</div></div>
</div>
<div style="background-color:#f0f4ff;border-radius:10px;margin-bottom:20px;padding:16px 18px;">
<div style="color:#1a5276;font-size:11px;font-weight:700;margin-bottom:6px;">العرض المقدَّم</div>
<div style="color:#0a3d62;font-size:14px;line-height:1.8;">${r.offer?.description||'—'}</div>
</div>
${r.offer?.branches ? `<div style="background-color:#f8f9fc;border-radius:10px;margin-bottom:20px;padding:14px 16px;"><div style="color:#aaa;font-size:11px;margin-bottom:4px;">الفروع والمواقع</div><div style="color:#0a3d62;font-size:13px;">${r.offer.branches}</div></div>` : ''}
<div style="background-color:#fffbf0;border-radius:10px;border:1px solid #f0d080;margin-bottom:24px;padding:14px 16px;">
<div style="color:#7a6010;font-size:11px;font-weight:700;margin-bottom:4px;">⚖️ التوقيع الرقمي</div>
<div style="color:#0a3d62;font-size:14px;font-weight:700;">${r.signature||'—'}</div>
<div style="color:#aaa;font-size:11px;margin-top:2px;">أُرسل في: ${date}</div>
</div>
${r.documentURL ? `<div style="margin-bottom:24px;"><a href="${r.documentURL}" target="_blank" style="align-items:center;background-color:#f0f4ff;border-radius:10px;border:1px solid #ccd9ff;color:#0a3d62;display:flex;font-size:13px;font-weight:600;gap:8px;padding:12px 16px;text-decoration:none;">📄 عرض المستند المرفق ←</a></div>` : ''}
${r.status === 'pending' ? `
<div style="display:flex;gap:10px;">
<button onclick="updateStatus('${r.id}','approved')" style="background-color:#2ecc71;border-radius:10px;border:none;color:#fff;cursor:pointer;flex:1;font-family:'Cairo',sans-serif;font-size:14px;font-weight:700;padding:14px;">✅ اعتماد الشريك</button>
<button onclick="updateStatus('${r.id}','rejected')" style="background-color:#e74c3c;border-radius:10px;border:none;color:#fff;cursor:pointer;flex:1;font-family:'Cairo',sans-serif;font-size:14px;font-weight:700;padding:14px;">❌ رفض الطلب</button>
</div>` : `
<div style="background-color:${r.status==='approved'?'#f0fff4':'#fff0f0'};border-radius:10px;border:1px solid ${r.status==='approved'?'#b7dfca':'#f5c6cb'};padding:12px 16px;text-align:center;">
<span style="color:${r.status==='approved'?'#155724':'#721c24'};font-size:14px;font-weight:700;">${r.status==='approved'?'✅ هذا الطلب معتمد':'❌ هذا الطلب مرفوض'}</span>
</div>`}
`;
document.getElementById('detailModal').style.display = 'flex';
document.body.style.overflow = 'hidden';
}
function closeModal() {
document.getElementById('detailModal').style.display = 'none';
document.body.style.overflow = '';
}
// ── Toast ──
function showToast(msg, color) {
const t = document.createElement('div');
t.style.cssText = `position:fixed;bottom:30px;left:50%;transform:translateX(-50%);background-color:${color};border-radius:10px;color:#fff;font-family:'Cairo',sans-serif;font-size:14px;font-weight:700;padding:12px 28px;z-index:99999;box-shadow:0 4px 20px rgba(0,0,0,0.2);`;
t.textContent = msg;
document.body.appendChild(t);
setTimeout(() => t.remove(), 3000);
}
// ── Init ──
loadRequests();
// Auto-refresh every 30 seconds
setInterval(loadRequests, 30000);
</script>
</body>
</html>