undefined / index.html
halil339's picture
دع اللوحة تعمل بدون مشاكل
1d9bb30 verified
Raw History Blame Contribute Delete
19.6 kB
<!DOCTYPE html>
<html lang="ar" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cash Control Pro | لوحة الإدارة الفاخرة</title>
<link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Tajawal', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #1E293B;
min-height: 100vh;
}
.glass-effect {
background: rgba(255, 255, 255, 0.25);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.18);
}
.gradient-text {
background: linear-gradient(135deg, #0034FF 0%, #8B5CF6 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.stats-card {
transition: all 0.3s ease;
border-left: 4px solid #0034FF;
}
.stats-card:hover {
transform: translateY(-5px);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.user-card {
transition: all 0.3s ease;
border-right: 3px solid transparent;
}
.user-card:hover {
border-right-color: #0034FF;
transform: scale(1.02);
}
.medal-gold { background: linear-gradient(135deg, #FFD700 0%, #FFA500 100%); }
.medal-silver { background: linear-gradient(135deg, #C0C0C0 0%, #A9A9A9 100%); }
.medal-bronze { background: linear-gradient(135deg, #CD7F32 0%, #8B4513 100%); }
.floating-btn {
animation: float 3s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
.pulse-glow {
animation: pulse-glow 2s ease-in-out infinite alternate;
}
@keyframes pulse-glow {
from { box-shadow: 0 0 20px rgba(0, 52, 255, 0.3); }
to { box-shadow: 0 0 30px rgba(0, 52, 255, 0.6); }
}
</style>
</head>
<body class="min-h-screen py-8 px-4">
<div class="container mx-auto max-w-7xl">
<!-- Header -->
<header class="glass-effect rounded-2xl p-8 mb-8 text-center pulse-glow">
<h1 class="text-4xl font-bold gradient-text mb-4">Cash Control Pro 💰</h1>
<p class="text-white text-lg opacity-90">لوحة التحكم الفاخرة لإدارة المستخدمين والمزادات</p>
</header>
<!-- Stats Cards -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<div class="stats-card glass-effect rounded-xl p-6 text-center">
<div class="text-3xl mb-2">👥</div>
<h3 class="text-gray-600 text-sm mb-2">إجمالي المستخدمين</h3>
<p class="text-2xl font-bold text-blue-600" id="totalUsers">0</p>
</div>
<div class="stats-card glass-effect rounded-xl p-6 text-center">
<div class="text-3xl mb-2">💰</div>
<h3 class="text-gray-600 text-sm mb-2">إجمالي النقاط</h3>
<p class="text-2xl font-bold text-green-600" id="totalPoints">0</p>
</div>
<div class="stats-card glass-effect rounded-xl p-6 text-center">
<div class="text-3xl mb-2">⚡</div>
<h3 class="text-gray-600 text-sm mb-2">المزادات النشطة</h3>
<p class="text-2xl font-bold text-purple-600" id="activeAuctions">0</p>
</div>
<div class="stats-card glass-effect rounded-xl p-6 text-center">
<div class="text-3xl mb-2">🏆</div>
<h3 class="text-gray-600 text-sm mb-2">المزايدون اليوم</h3>
<p class="text-2xl font-bold text-orange-600" id="todayBidders">0</p>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Left Column -->
<div class="lg:col-span-2 space-y-8">
<!-- Top Users -->
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-xl font-bold text-white mb-6 flex items-center">
<span class="bg-gradient-to-r from-yellow-400 to-orange-500 p-2 rounded-lg mr-3">🏆</span>
أعلى 10 مستخدمين بالنقاط
</h2>
<div class="space-y-3" id="topUsersList"></div>
</div>
<!-- Send Points -->
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-xl font-bold text-white mb-4">🎯 إرسال النقاط لجميع المستخدمين</h2>
<div class="flex gap-4">
<input type="number" id="pointsAmount" placeholder="عدد النقاط المراد إرسالها"
class="flex-1 bg-white/80 backdrop-blur-sm border border-white/30 rounded-xl px-4 py-3 text-gray-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<button id="sendPointsBtn" class="bg-gradient-to-r from-blue-500 to-purple-600 text-white px-6 py-3 rounded-xl font-medium hover:from-blue-600 hover:to-purple-700 transition-all duration-300 transform hover:scale-105 floating-btn">
<i class="fas fa-paper-plane mr-2"></i>إرسال النقاط
</button>
</div>
</div>
<!-- Search -->
<div class="glass-effect rounded-2xl p-6">
<div class="relative">
<i class="fas fa-search absolute right-4 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
<input type="text" id="searchInput" placeholder="🔍 ابحث باسم المستخدم أو الـ ID"
class="w-full bg-white/80 backdrop-blur-sm border border-white/30 rounded-xl px-12 py-3 text-gray-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
</div>
</div>
<!-- All Users -->
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-xl font-bold text-white mb-6">👥 جميع المستخدمين</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4" id="usersGrid"></div>
</div>
</div>
<!-- Right Column - Auctions -->
<div class="space-y-8">
<!-- Add Auction -->
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-xl font-bold text-white mb-6">⚡ إضافة مزاد جديد</h2>
<div class="space-y-4">
<input type="text" id="auctionTitle" placeholder="عنوان المزاد"
class="w-full bg-white/80 backdrop-blur-sm border border-white/30 rounded-xl px-4 py-3 text-gray-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<input type="number" id="auctionStartPrice" placeholder="السعر الابتدائي (نقاط)"
class="w-full bg-white/80 backdrop-blur-sm border border-white/30 rounded-xl px-4 py-3 text-gray-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<input type="datetime-local" id="auctionEndTime"
class="w-full bg-white/80 backdrop-blur-sm border border-white/30 rounded-xl px-4 py-3 text-gray-800 placeholder-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent">
<button id="addAuctionBtn" class="w-full bg-gradient-to-r from-green-500 to-teal-600 text-white py-3 rounded-xl font-medium hover:from-green-600 hover:to-teal-700 transition-all duration-300 transform hover:scale-105">
<i class="fas fa-plus mr-2"></i>إضافة مزاد جديد
</button>
</div>
</div>
<!-- All Auctions -->
<div class="glass-effect rounded-2xl p-6">
<h2 class="text-xl font-bold text-white mb-6">📊 المزادات النشطة</h2>
<div class="space-y-4" id="auctionsList"></div>
</div>
</div>
</div>
</div>
<script type="module">
import { initializeApp } from 'https://www.gstatic.com/firebasejs/10.13.1/firebase-app.js';
import { getFirestore, collection, getDocs, updateDoc, doc, onSnapshot, deleteDoc, addDoc } from 'https://www.gstatic.com/firebasejs/10.13.1/firebase-firestore.js';
const firebaseConfig = {
apiKey: "AIzaSyDe2eYGjNwhAxoURly4J16uXJU60U6-x4A",
authDomain: "cashup-29abe.firebaseapp.com",
projectId: "cashup-29abe",
storageBucket: "cashup-29abe.firebasestorage.app",
messagingSenderId: "918029234311",
appId: "1:918029234311:web:b2aa4777c72fb1d5d54822",
measurementId: "G-9SX5X89TJH"
};
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
// عناصر DOM
const totalUsersElement = document.getElementById('totalUsers');
const totalPointsElement = document.getElementById('totalPoints');
const usersGrid = document.getElementById('usersGrid');
const sendPointsBtn = document.getElementById('sendPointsBtn');
const pointsAmountInput = document.getElementById('pointsAmount');
const searchInput = document.getElementById('searchInput');
const topUsersList = document.getElementById('topUsersList');
const auctionsList = document.getElementById('auctionsList');
let allUsers = [];
// تحديث الإحصائيات
function updateStats(snapshot){
totalUsersElement.textContent = snapshot.size;
let totalPoints = 0;
snapshot.forEach(doc => {
totalPoints += doc.data().balance || 0;
});
totalPointsElement.textContent = totalPoints.toLocaleString();
}
// تحميل المستخدمين
async function loadUsers(){
const snapshot = await getDocs(collection(db,'users'));
allUsers = [];
usersGrid.innerHTML = '';
snapshot.forEach(docItem => {
const data = docItem.data();
allUsers.push({id: docItem.id, ...data});
});
// ترتيب المستخدمين من الأعلى إلى الأدنى حسب النقاط
allUsers.sort((a, b) => (b.balance || 0) - (a.balance || 0));
// عرض أعلى 10 مستخدمين
renderTopUsers(allUsers.slice(0, 10));
// عرض كل المستخدمين
renderUsers(allUsers);
}
function renderTopUsers(users){
topUsersList.innerHTML = '';
users.forEach((user, index) => {
const medalClass = index === 0 ? 'medal-gold' : index === 1 ? 'medal-silver' : index === 2 ? 'medal-bronze' : 'bg-white/20';
const medal = index === 0 ? "🥇" : index === 1 ? "🥈" : index === 2 ? "🥉" : `${index + 1}.`;
const div = document.createElement('div');
div.className = `flex items-center justify-between p-4 rounded-xl ${medalClass} backdrop-blur-sm border border-white/20`;
div.innerHTML = `
<div class="flex items-center space-x-3">
<span class="text-lg font-bold">${medal}</span>
<div>
<div class="font-medium text-white">${user.name || 'مستخدم'}</div>
<div class="text-sm opacity-75">ID: ${user.uniqueId || ''}</div>
</div>
</div>
<div class="text-xl font-bold text-white">${user.balance || 0} نقطة</div>
`;
topUsersList.appendChild(div);
});
}
function renderUsers(users){
usersGrid.innerHTML = '';
users.forEach(user => {
const div = document.createElement('div');
div.className = 'user-card glass-effect rounded-xl p-4';
div.innerHTML = `
<div class="flex justify-between items-start mb-3">
<div>
<div class="font-bold text-white text-lg">${user.name || 'مستخدم'}</div>
<div class="text-blue-200 text-sm">ID: ${user.uniqueId || ''}</div>
</div>
<div class="bg-blue-500 text-white px-2 py-1 rounded-lg text-sm font-bold">
${user.balance || 0} نقطة
</div>
</div>
<div class="flex gap-2">
<input type="number" value="${user.balance || 0}" data-type="points"
class="flex-1 bg-white/20 border border-white/30 rounded-lg px-3 py-2 text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-blue-500">
<button class="save-btn bg-green-500 hover:bg-green-600 text-white px-3 py-2 rounded-lg transition-colors">
<i class="fas fa-save"></i>
</button>
<button class="delete-btn bg-red-500 hover:bg-red-600 text-white px-3 py-2 rounded-lg transition-colors">
<i class="fas fa-trash"></i>
</button>
</div>
`;
div.querySelector('.save-btn').addEventListener('click', async() => {
const newPoints = parseInt(div.querySelector('input[data-type="points"]').value) || 0;
await updateDoc(doc(db,'users',user.id), {balance: newPoints});
loadUsers();
});
div.querySelector('.delete-btn').addEventListener('click', async() => {
if(!confirm('هل أنت متأكد من حذف المستخدم؟')) return;
await deleteDoc(doc(db,'users',user.id));
loadUsers();
});
usersGrid.appendChild(div);
});
}
// إرسال النقاط
sendPointsBtn.addEventListener('click', async() => {
const amount = parseInt(pointsAmountInput.value);
if(!amount || amount <= 0){
alert('يرجى إدخال رقم صحيح موجب');
return;
}
if(!confirm(`هل تريد إرسال ${amount} نقطة لجميع المستخدمين؟`)) return;
const snapshot = await getDocs(collection(db,'users'));
const promises = [];
snapshot.forEach(docItem => {
promises.push(updateDoc(doc(db,'users',docItem.id), {
balance: (docItem.data().balance || 0) + amount
}));
});
await Promise.all(promises);
pointsAmountInput.value = '';
loadUsers();
});
// البحث
searchInput.addEventListener('input', () => {
const term = searchInput.value.toLowerCase();
const filtered = allUsers.filter(u =>
(u.name || '').toLowerCase().includes(term) ||
(u.uniqueId || '').toLowerCase().includes(term)
);
renderUsers(filtered);
});
// إدارة المزادات
const auctionTitle = document.getElementById('auctionTitle');
const auctionStartPrice = document.getElementById('auctionStartPrice');
const auctionEndTime = document.getElementById('auctionEndTime');
const addAuctionBtn = document.getElementById('addAuctionBtn');
// إضافة مزاد جديد
addAuctionBtn.addEventListener('click', async() => {
if(!auctionTitle.value || !auctionStartPrice.value || !auctionEndTime.value){
alert("يرجى ملء جميع الحقول المطلوبة");
return;
}
await addDoc(collection(db, "auctions"), {
title: auctionTitle.value,
startPrice: parseInt(auctionStartPrice.value),
currentPrice: parseInt(auctionStartPrice.value),
highestBidder: null,
endTime: auctionEndTime.value,
createdAt: new Date().toISOString()
});
auctionTitle.value = '';
auctionStartPrice.value = '';
auctionEndTime.value = '';
loadAuctions();
});
// تحميل المزادات
async function loadAuctions(){
const snapshot = await getDocs(collection(db, "auctions"));
auctionsList.innerHTML = '';
snapshot.forEach(docItem => {
const data = docItem.data();
const div = document.createElement('div');
div.className = "glass-effect rounded-xl p-4 border border-white/20";
div.innerHTML = `
<h3 class="font-bold text-white text-lg mb-2">${data.title}</h3>
<div class="space-y-2 text-sm">
<div class="flex justify-between">
<span class="text-blue-200">السعر الحالي:</span>
<span class="text-white font-bold">${data.currentPrice} نقطة</span>
</div>
<div class="flex justify-between">
<span class="text-blue-200">أعلى مزايد:</span>
<span class="text-white">${data.highestBidder || "لا يوجد"}</span>
</div>
<div class="flex justify-between">
<span class="text-blue-200">ينتهي في:</span>
<span class="text-white">${new Date(data.endTime).toLocaleString('ar-SA')}</span>
</div>
</div>
`;
auctionsList.appendChild(div);
});
}
// البدء بتحميل البيانات
onSnapshot(collection(db, 'users'), snapshot => updateStats(snapshot));
loadUsers();
loadAuctions();
</script>
</body>
</html>