39644-vm/admin.html
2026-04-14 08:30:02 +03:00

1187 lines
43 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Admin Panel - Lebanon Sports Hub</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
:root {
--primary: #ed1c24;
--secondary: #00a651;
--dark: #1a1a1a;
--light: #f5f5f5;
--gray: #777;
--shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
--pending: #FFA726;
--approved: #4CAF50;
--rejected: #F44336;
}
body {
background-color: #f5f7fa;
color: var(--dark);
line-height: 1.6;
}
.container {
width: 95%;
max-width: 1400px;
margin: 0 auto;
padding: 0 15px;
}
/* Header */
header {
background: white;
box-shadow: var(--shadow);
padding: 15px 0;
position: sticky;
top: 0;
z-index: 1000;
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
display: flex;
align-items: center;
gap: 10px;
font-size: 1.5rem;
font-weight: 700;
color: var(--primary);
}
.logo i {
color: var(--secondary);
}
.admin-info {
display: flex;
align-items: center;
gap: 20px;
}
.admin-name {
font-weight: 600;
color: var(--dark);
}
.logout-btn {
background: var(--primary);
color: white;
border: none;
padding: 8px 20px;
border-radius: 4px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s;
}
.logout-btn:hover {
background: #c5161c;
}
/* Login Form */
.login-container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.login-form {
background: white;
padding: 40px;
border-radius: 15px;
width: 100%;
max-width: 400px;
box-shadow: var(--shadow);
}
.login-form h2 {
text-align: center;
margin-bottom: 30px;
color: var(--dark);
}
.form-group {
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 600;
}
.form-group input {
width: 100%;
padding: 12px 15px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 1rem;
}
.login-btn {
width: 100%;
padding: 14px;
background: var(--primary);
color: white;
border: none;
border-radius: 5px;
font-weight: 600;
font-size: 1rem;
cursor: pointer;
margin-top: 10px;
}
.login-btn:hover {
background: #c5161c;
}
.error-message {
color: var(--rejected);
text-align: center;
margin-top: 10px;
font-size: 0.9rem;
}
/* Dashboard */
.dashboard {
padding: 30px 0;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.stat-card {
background: white;
padding: 25px;
border-radius: 10px;
box-shadow: var(--shadow);
display: flex;
align-items: center;
gap: 20px;
}
.stat-icon {
width: 60px;
height: 60px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.5rem;
color: white;
}
.stat-icon.pending {
background: var(--pending);
}
.stat-icon.approved {
background: var(--approved);
}
.stat-icon.rejected {
background: var(--rejected);
}
.stat-icon.total {
background: var(--primary);
}
.stat-info h3 {
font-size: 2rem;
margin-bottom: 5px;
color: var(--dark);
}
.stat-info p {
color: var(--gray);
font-size: 0.9rem;
}
/* Tabs */
.tabs {
display: flex;
gap: 10px;
margin-bottom: 30px;
border-bottom: 2px solid #eee;
padding-bottom: 10px;
}
.tab-btn {
background: none;
border: none;
padding: 10px 25px;
font-size: 1rem;
font-weight: 600;
color: var(--gray);
cursor: pointer;
border-radius: 5px 5px 0 0;
transition: all 0.3s;
}
.tab-btn.active {
color: var(--primary);
border-bottom: 3px solid var(--primary);
background: rgba(237, 28, 36, 0.1);
}
/* Tables */
.table-container {
background: white;
border-radius: 10px;
overflow: hidden;
box-shadow: var(--shadow);
margin-bottom: 30px;
}
table {
width: 100%;
border-collapse: collapse;
}
thead {
background: var(--primary);
color: white;
}
th {
padding: 15px;
text-align: left;
font-weight: 600;
}
tbody tr {
border-bottom: 1px solid #eee;
}
tbody tr:hover {
background: #f9f9f9;
}
td {
padding: 15px;
}
.status-badge {
display: inline-block;
padding: 5px 15px;
border-radius: 20px;
font-size: 0.85rem;
font-weight: 600;
}
.status-pending {
background: #FFF3E0;
color: var(--pending);
}
.status-approved {
background: #E8F5E9;
color: var(--approved);
}
.status-rejected {
background: #FFEBEE;
color: var(--rejected);
}
.action-buttons {
display: flex;
gap: 10px;
}
.btn-approve {
background: var(--approved);
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: 600;
transition: background 0.3s;
}
.btn-approve:hover {
background: #388e3c;
}
.btn-reject {
background: var(--rejected);
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: 600;
transition: background 0.3s;
}
.btn-reject:hover {
background: #d32f2f;
}
.btn-view {
background: var(--primary);
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
font-weight: 600;
transition: background 0.3s;
}
.btn-view:hover {
background: #c5161c;
}
.user-info {
display: flex;
flex-direction: column;
gap: 5px;
}
.user-name {
font-weight: 600;
}
.user-email {
color: var(--gray);
font-size: 0.9rem;
}
/* Events List */
.events-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
gap: 25px;
margin-bottom: 30px;
}
.event-admin-card {
background: white;
border-radius: 10px;
overflow: hidden;
box-shadow: var(--shadow);
}
.event-admin-header {
background: var(--primary);
color: white;
padding: 15px;
}
.event-admin-header h3 {
font-size: 1.2rem;
margin-bottom: 5px;
}
.event-category {
display: inline-block;
background: var(--secondary);
color: white;
padding: 3px 10px;
border-radius: 15px;
font-size: 0.8rem;
font-weight: 600;
}
.event-admin-body {
padding: 20px;
}
.event-meta {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 15px;
color: var(--gray);
font-size: 0.9rem;
}
.event-meta i {
color: var(--primary);
margin-right: 5px;
}
.event-price {
background: #f8f9fa;
padding: 10px 15px;
border-radius: 8px;
margin-bottom: 20px;
border-left: 3px solid var(--primary);
}
.registrations-list {
max-height: 200px;
overflow-y: auto;
}
.registration-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #eee;
}
.registration-item:last-child {
border-bottom: none;
}
.registration-actions {
display: flex;
gap: 5px;
}
/* Modal */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.7);
z-index: 2000;
justify-content: center;
align-items: center;
}
.modal-content {
background: white;
padding: 30px;
border-radius: 10px;
width: 90%;
max-width: 500px;
max-height: 80vh;
overflow-y: auto;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.modal-header h2 {
color: var(--dark);
}
.close-modal {
font-size: 1.5rem;
cursor: pointer;
color: var(--gray);
}
/* Responsive */
@media (max-width: 768px) {
.stats-grid {
grid-template-columns: 1fr;
}
.tabs {
flex-wrap: wrap;
}
table {
display: block;
overflow-x: auto;
}
.events-container {
grid-template-columns: 1fr;
}
.action-buttons {
flex-direction: column;
}
}
</style>
</head>
<body>
<!-- Login Screen -->
<div id="loginScreen" class="login-container">
<div class="login-form">
<h2><i class="fas fa-user-shield"></i> Admin Login</h2>
<form id="adminLoginForm">
<div class="form-group">
<label>Email</label>
<input type="email" id="adminEmail" placeholder="Enter admin email" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" id="adminPassword" placeholder="Enter password" required>
</div>
<button type="submit" class="login-btn">Login</button>
<div id="loginError" class="error-message"></div>
</form>
</div>
</div>
<!-- Admin Dashboard (hidden until login) -->
<div id="adminDashboard" style="display: none;">
<!-- Header -->
<header>
<div class="container">
<div class="header-content">
<div class="logo">
<i class="fas fa-user-shield"></i>
<span>Lebanon Sports Hub - Admin Panel</span>
</div>
<div class="admin-info">
<div class="admin-name" id="adminName"></div>
<button class="logout-btn" id="logoutBtn">
<i class="fas fa-sign-out-alt"></i> Logout
</button>
</div>
</div>
</div>
</header>
<!-- Dashboard Content -->
<div class="dashboard container">
<!-- Statistics -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-icon total">
<i class="fas fa-calendar-alt"></i>
</div>
<div class="stat-info">
<h3 id="totalEvents">22</h3>
<p>Total Events</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon pending">
<i class="fas fa-clock"></i>
</div>
<div class="stat-info">
<h3 id="pendingRegistrations">0</h3>
<p>Pending Approvals</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon approved">
<i class="fas fa-check-circle"></i>
</div>
<div class="stat-info">
<h3 id="approvedRegistrations">0</h3>
<p>Approved Registrations</p>
</div>
</div>
<div class="stat-card">
<div class="stat-icon rejected">
<i class="fas fa-times-circle"></i>
</div>
<div class="stat-info">
<h3 id="rejectedRegistrations">0</h3>
<p>Rejected Registrations</p>
</div>
</div>
</div>
<!-- Tabs -->
<div class="tabs">
<button class="tab-btn active" data-tab="pending">Pending Approvals</button>
<button class="tab-btn" data-tab="all">All Registrations</button>
<button class="tab-btn" data-tab="events">Events Management</button>
</div>
<!-- Pending Approvals Tab -->
<div id="pendingTab" class="tab-content">
<div class="table-container">
<table>
<thead>
<tr>
<th>User</th>
<th>Event</th>
<th>Location</th>
<th>Date</th>
<th>Price</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="pendingTableBody">
<!-- Pending registrations loaded here -->
</tbody>
</table>
</div>
</div>
<!-- All Registrations Tab -->
<div id="allTab" class="tab-content" style="display: none;">
<div class="table-container">
<table>
<thead>
<tr>
<th>User</th>
<th>Event</th>
<th>Location</th>
<th>Date</th>
<th>Price</th>
<th>Status</th>
<th>Registration Date</th>
</tr>
</thead>
<tbody id="allTableBody">
<!-- All registrations loaded here -->
</tbody>
</table>
</div>
</div>
<!-- Events Management Tab -->
<div id="eventsTab" class="tab-content" style="display: none;">
<div class="events-container" id="eventsList">
<!-- Events loaded here -->
</div>
</div>
</div>
<!-- Registration Details Modal -->
<div class="modal" id="registrationModal">
<div class="modal-content">
<div class="modal-header">
<h2>Registration Details</h2>
<span class="close-modal" id="closeModal">&times;</span>
</div>
<div id="registrationDetails">
<!-- Details loaded here -->
</div>
</div>
</div>
</div>
<script src="data.js"></script>
<script>
// Admin credentials
const ADMIN_EMAIL = 'tamernasr1717@gmail.com';
const ADMIN_PASSWORD = 'TAML76';
// App State
let adminLoggedIn = false;
let pendingRegistrations = JSON.parse(localStorage.getItem('pendingRegistrations')) || [];
let allRegistrations = JSON.parse(localStorage.getItem('allRegistrations')) || [];
let eventsData = window.sportsEventsData || [];
// DOM Elements
const loginScreen = document.getElementById('loginScreen');
const adminDashboard = document.getElementById('adminDashboard');
const adminLoginForm = document.getElementById('adminLoginForm');
const adminEmail = document.getElementById('adminEmail');
const adminPassword = document.getElementById('adminPassword');
const loginError = document.getElementById('loginError');
const logoutBtn = document.getElementById('logoutBtn');
const adminName = document.getElementById('adminName');
const tabBtns = document.querySelectorAll('.tab-btn');
const tabContents = document.querySelectorAll('.tab-content');
const pendingTableBody = document.getElementById('pendingTableBody');
const allTableBody = document.getElementById('allTableBody');
const eventsList = document.getElementById('eventsList');
const totalEvents = document.getElementById('totalEvents');
const pendingRegistrationsCount = document.getElementById('pendingRegistrations');
const approvedRegistrationsCount = document.getElementById('approvedRegistrations');
const rejectedRegistrationsCount = document.getElementById('rejectedRegistrations');
const registrationModal = document.getElementById('registrationModal');
const closeModal = document.getElementById('closeModal');
const registrationDetails = document.getElementById('registrationDetails');
// Initialize Admin App
function initAdminApp() {
loadEventsData();
setupEventListeners();
// Check if already logged in
if (localStorage.getItem('adminLoggedIn') === 'true') {
adminLoggedIn = true;
showDashboard();
}
}
// Load events data
function loadEventsData() {
// Get events from shared data.js file
if (typeof sportsEventsData !== 'undefined' && sportsEventsData.length > 0) {
eventsData = sportsEventsData;
} else {
// Fallback: get from localStorage
eventsData = JSON.parse(localStorage.getItem('sportsEvents')) || [];
}
// Load pending and all registrations
pendingRegistrations = JSON.parse(localStorage.getItem('pendingRegistrations')) || [];
allRegistrations = JSON.parse(localStorage.getItem('allRegistrations')) || [];
// Update total events count
totalEvents.textContent = eventsData.length;
updateStats();
}
// Update Statistics
function updateStats() {
totalEvents.textContent = eventsData.length || 0;
pendingRegistrationsCount.textContent = pendingRegistrations.length;
const approved = allRegistrations.filter(r => r.status === 'approved').length;
const rejected = allRegistrations.filter(r => r.status === 'rejected').length;
approvedRegistrationsCount.textContent = approved;
rejectedRegistrationsCount.textContent = rejected;
}
// Show Pending Registrations
function showPendingRegistrations() {
pendingTableBody.innerHTML = '';
if (pendingRegistrations.length === 0) {
pendingTableBody.innerHTML = `
<tr>
<td colspan="7" style="text-align: center; padding: 40px; color: var(--gray);">
<i class="fas fa-check-circle" style="font-size: 2rem; margin-bottom: 10px; display: block; color: #ddd;"></i>
No pending registrations
</td>
</tr>
`;
return;
}
pendingRegistrations.forEach(reg => {
const event = eventsData.find(e => e.id === reg.eventId);
if (!event) return;
const row = document.createElement('tr');
row.innerHTML = `
<td>
<div class="user-info">
<div class="user-name">${reg.userName || 'Unknown User'}</div>
<div class="user-email">${reg.userEmail || 'No email'}</div>
</div>
</td>
<td>${event.title}</td>
<td>${event.location}</td>
<td>${event.date}</td>
<td>${event.price === 0 ? 'FREE' : '$' + event.price}</td>
<td><span class="status-badge status-pending">PENDING</span></td>
<td>
<div class="action-buttons">
<button class="btn-approve" onclick="approveRegistration('${reg.registrationId}')">
<i class="fas fa-check"></i> Approve
</button>
<button class="btn-reject" onclick="rejectRegistration('${reg.registrationId}')">
<i class="fas fa-times"></i> Reject
</button>
<button class="btn-view" onclick="viewRegistrationDetails('${reg.registrationId}')">
<i class="fas fa-eye"></i> View
</button>
</div>
</td>
`;
pendingTableBody.appendChild(row);
});
}
// Show All Registrations
function showAllRegistrations() {
allTableBody.innerHTML = '';
if (allRegistrations.length === 0) {
allTableBody.innerHTML = `
<tr>
<td colspan="7" style="text-align: center; padding: 40px; color: var(--gray);">
<i class="fas fa-users" style="font-size: 2rem; margin-bottom: 10px; display: block; color: #ddd;"></i>
No registrations yet
</td>
</tr>
`;
return;
}
allRegistrations.forEach(reg => {
const event = eventsData.find(e => e.id === reg.eventId);
if (!event) return;
let statusClass = 'status-pending';
let statusText = 'PENDING';
if (reg.status === 'approved') {
statusClass = 'status-approved';
statusText = 'APPROVED';
} else if (reg.status === 'rejected') {
statusClass = 'status-rejected';
statusText = 'REJECTED';
}
const row = document.createElement('tr');
row.innerHTML = `
<td>
<div class="user-info">
<div class="user-name">${reg.userName || 'Unknown User'}</div>
<div class="user-email">${reg.userEmail || 'No email'}</div>
</div>
</td>
<td>${event.title}</td>
<td>${event.location}</td>
<td>${event.date}</td>
<td>${event.price === 0 ? 'FREE' : '$' + event.price}</td>
<td><span class="status-badge ${statusClass}">${statusText}</span></td>
<td>${reg.registrationDate || 'Unknown'}</td>
`;
allTableBody.appendChild(row);
});
}
// Show Events Management
function showEventsManagement() {
eventsList.innerHTML = '';
console.log('Total events:', eventsData.length);
if (eventsData.length === 0) {
eventsList.innerHTML = `
<div style="grid-column: 1/-1; text-align: center; padding: 40px; color: var(--gray);">
<i class="fas fa-calendar-times" style="font-size: 3rem; margin-bottom: 20px; display: block;"></i>
<h3>No events found</h3>
<p>Make sure data.js file is loaded correctly.</p>
</div>
`;
return;
}
eventsData.forEach(event => {
const eventRegistrations = allRegistrations.filter(r => r.eventId === event.id);
const pendingCount = eventRegistrations.filter(r => r.status === 'pending').length;
const approvedCount = eventRegistrations.filter(r => r.status === 'approved').length;
const card = document.createElement('div');
card.className = 'event-admin-card';
card.innerHTML = `
<div class="event-admin-header">
<h3>${event.title}</h3>
<span class="event-category">${event.category}</span>
</div>
<div class="event-admin-body">
<div class="event-meta">
<div><i class="fas fa-map-marker-alt"></i> ${event.location}</div>
<div><i class="fas fa-calendar-alt"></i> ${event.date}</div>
<div><i class="fas fa-clock"></i> ${event.time}</div>
</div>
<div class="event-price">
<i class="fas fa-tag"></i> Price: ${event.price === 0 ? 'FREE' : '$' + event.price}
</div>
<div style="display: flex; justify-content: space-between; margin-bottom: 15px; padding: 10px; background: #f8f9fa; border-radius: 5px;">
<div>
<small>Total Registrations</small>
<div style="font-weight: 600; font-size: 1.2rem;">${eventRegistrations.length}</div>
</div>
<div>
<small>Pending</small>
<div style="font-weight: 600; color: var(--pending);">${pendingCount}</div>
</div>
<div>
<small>Approved</small>
<div style="font-weight: 600; color: var(--approved);">${approvedCount}</div>
</div>
</div>
${eventRegistrations.length > 0 ? `
<h4 style="margin-bottom: 10px; font-size: 1rem;">Recent Registrations:</h4>
<div class="registrations-list">
${eventRegistrations.slice(0, 3).map(reg => `
<div class="registration-item">
<div>
<div style="font-weight: 600;">${reg.userName || 'Unknown'}</div>
<small>${reg.registrationDate || 'Unknown date'}</small>
</div>
<div>
${reg.status === 'pending' ?
'<span style="color: var(--pending); font-weight: 600;">Pending</span>' :
reg.status === 'approved' ?
'<span style="color: var(--approved); font-weight: 600;">Approved</span>' :
'<span style="color: var(--rejected); font-weight: 600;">Rejected</span>'
}
</div>
</div>
`).join('')}
</div>
` : `
<div style="text-align: center; color: var(--gray); padding: 20px;">
<i class="fas fa-users" style="font-size: 2rem; margin-bottom: 10px; display: block;"></i>
No registrations yet
</div>
`}
</div>
`;
eventsList.appendChild(card);
});
}
// Approve Registration
function approveRegistration(registrationId) {
const regIndex = pendingRegistrations.findIndex(r => r.registrationId === registrationId);
if (regIndex === -1) return;
const registration = pendingRegistrations[regIndex];
// Update registration status
registration.status = 'approved';
registration.approvedDate = new Date().toLocaleString();
// Move to all registrations
const existingIndex = allRegistrations.findIndex(r => r.registrationId === registrationId);
if (existingIndex === -1) {
allRegistrations.push(registration);
} else {
allRegistrations[existingIndex] = registration;
}
// Remove from pending
pendingRegistrations.splice(regIndex, 1);
// Update localStorage
localStorage.setItem('pendingRegistrations', JSON.stringify(pendingRegistrations));
localStorage.setItem('allRegistrations', JSON.stringify(allRegistrations));
// Update user's localStorage (to notify them)
notifyUserRegistration(registration.userId, registration.eventId, 'approved');
// Update UI
updateStats();
showPendingRegistrations();
showAllRegistrations();
alert('Registration approved successfully!');
}
// Reject Registration
function rejectRegistration(registrationId) {
const regIndex = pendingRegistrations.findIndex(r => r.registrationId === registrationId);
if (regIndex === -1) return;
const registration = pendingRegistrations[regIndex];
// Update registration status
registration.status = 'rejected';
registration.rejectedDate = new Date().toLocaleString();
// Move to all registrations
const existingIndex = allRegistrations.findIndex(r => r.registrationId === registrationId);
if (existingIndex === -1) {
allRegistrations.push(registration);
} else {
allRegistrations[existingIndex] = registration;
}
// Remove from pending
pendingRegistrations.splice(regIndex, 1);
// Update localStorage
localStorage.setItem('pendingRegistrations', JSON.stringify(pendingRegistrations));
localStorage.setItem('allRegistrations', JSON.stringify(allRegistrations));
// Update user's localStorage (to notify them)
notifyUserRegistration(registration.userId, registration.eventId, 'rejected');
// Update UI
updateStats();
showPendingRegistrations();
showAllRegistrations();
alert('Registration rejected!');
}
// View Registration Details
function viewRegistrationDetails(registrationId) {
const registration = [...pendingRegistrations, ...allRegistrations].find(r => r.registrationId === registrationId);
if (!registration) return;
const event = eventsData.find(e => e.id === registration.eventId);
registrationDetails.innerHTML = `
<div style="margin-bottom: 20px;">
<h3 style="color: var(--dark); margin-bottom: 10px;">${event ? event.title : 'Event not found'}</h3>
<p><strong>Registration ID:</strong> ${registration.registrationId}</p>
<p><strong>Registration Date:</strong> ${registration.registrationDate}</p>
</div>
<div style="background: #f8f9fa; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
<h4 style="margin-bottom: 10px; color: var(--dark);">User Information</h4>
<p><strong>Name:</strong> ${registration.userName || 'Not provided'}</p>
<p><strong>Email:</strong> ${registration.userEmail || 'Not provided'}</p>
<p><strong>User ID:</strong> ${registration.userId || 'Not available'}</p>
</div>
${event ? `
<div style="background: #f8f9fa; padding: 15px; border-radius: 8px; margin-bottom: 20px;">
<h4 style="margin-bottom: 10px; color: var(--dark);">Event Details</h4>
<p><strong>Location:</strong> ${event.location}</p>
<p><strong>Date:</strong> ${event.date} at ${event.time}</p>
<p><strong>Venue:</strong> ${event.venue}</p>
<p><strong>Price:</strong> ${event.price === 0 ? 'FREE' : '$' + event.price}</p>
</div>
` : ''}
<div style="background: #f8f9fa; padding: 15px; border-radius: 8px;">
<h4 style="margin-bottom: 10px; color: var(--dark);">Registration Status</h4>
<p><strong>Status:</strong> <span style="color: ${
registration.status === 'approved' ? 'var(--approved)' :
registration.status === 'rejected' ? 'var(--rejected)' :
'var(--pending)'
}; font-weight: 600;">${registration.status ? registration.status.toUpperCase() : 'PENDING'}</span></p>
${registration.approvedDate ? `<p><strong>Approved Date:</strong> ${registration.approvedDate}</p>` : ''}
${registration.rejectedDate ? `<p><strong>Rejected Date:</strong> ${registration.rejectedDate}</p>` : ''}
</div>
${registration.status === 'pending' ? `
<div style="display: flex; gap: 10px; margin-top: 20px;">
<button class="btn-approve" style="flex: 1;" onclick="approveRegistration('${registration.registrationId}')">
<i class="fas fa-check"></i> Approve Registration
</button>
<button class="btn-reject" style="flex: 1;" onclick="rejectRegistration('${registration.registrationId}')">
<i class="fas fa-times"></i> Reject Registration
</button>
</div>
` : ''}
`;
registrationModal.style.display = 'flex';
}
// Notify User about Registration Status
function notifyUserRegistration(userId, eventId, status) {
// Create notification for user
const notification = {
userId: userId,
eventId: eventId,
status: status,
notificationDate: new Date().toLocaleString(),
read: false
};
// Get existing notifications
let userNotifications = JSON.parse(localStorage.getItem('userNotifications')) || [];
userNotifications.push(notification);
// Save notifications
localStorage.setItem('userNotifications', JSON.stringify(userNotifications));
}
// Setup Event Listeners
function setupEventListeners() {
// Admin Login
adminLoginForm.addEventListener('submit', function(e) {
e.preventDefault();
const email = adminEmail.value.trim();
const password = adminPassword.value.trim();
if (email === ADMIN_EMAIL && password === ADMIN_PASSWORD) {
adminLoggedIn = true;
localStorage.setItem('adminLoggedIn', 'true');
showDashboard();
loginError.textContent = '';
} else {
loginError.textContent = 'Invalid email or password';
}
});
// Logout
logoutBtn.addEventListener('click', function() {
adminLoggedIn = false;
localStorage.removeItem('adminLoggedIn');
showLoginScreen();
});
// Tab Navigation
tabBtns.forEach(btn => {
btn.addEventListener('click', function() {
const tabId = this.getAttribute('data-tab');
// Update active tab button
tabBtns.forEach(b => b.classList.remove('active'));
this.classList.add('active');
// Show corresponding tab content
tabContents.forEach(content => {
content.style.display = 'none';
});
document.getElementById(tabId + 'Tab').style.display = 'block';
// Load appropriate data
if (tabId === 'pending') {
showPendingRegistrations();
} else if (tabId === 'all') {
showAllRegistrations();
} else if (tabId === 'events') {
showEventsManagement();
}
});
});
// Close modal
closeModal.addEventListener('click', () => {
registrationModal.style.display = 'none';
});
// Close modal on outside click
window.addEventListener('click', (e) => {
if (e.target === registrationModal) {
registrationModal.style.display = 'none';
}
});
}
// Show Dashboard
function showDashboard() {
loginScreen.style.display = 'none';
adminDashboard.style.display = 'block';
adminName.textContent = 'Admin: tamernasr1717@gmail.com';
// Load initial data
updateStats();
showPendingRegistrations();
showAllRegistrations();
showEventsManagement();
}
// Show Login Screen
function showLoginScreen() {
loginScreen.style.display = 'flex';
adminDashboard.style.display = 'none';
adminLoginForm.reset();
}
// Initialize on load
document.addEventListener('DOMContentLoaded', initAdminApp);
</script>
</body>
</html>