PATH:
home
/
u865795251
/
domains
/
whatisnewis.com
/
public_html
/
vfa
/
Editing: admin.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>VFA Academy - Admin Management Console</title> <!-- Google Fonts & FontAwesome --> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <style> :root { --bg-dark: #0a0e17; --bg-card: rgba(18, 24, 38, 0.6); --green-primary: #00e676; --neon-blue: #00b0ff; --text-white: #ffffff; --text-muted: #8892b0; --glass-border: rgba(255, 255, 255, 0.08); --glass-bg: rgba(255, 255, 255, 0.03); --radius: 12px; --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', sans-serif; } body { background-color: var(--bg-dark); color: var(--text-white); min-height: 100vh; overflow-x: hidden; display: flex; justify-content: center; align-items: center; } /* Ambient glowing backgrounds */ .glowing-bg { position: absolute; width: 400px; height: 400px; border-radius: 50%; filter: blur(120px); opacity: 0.12; pointer-events: none; z-index: 0; } .glow-1 { top: -10%; left: 10%; background: var(--green-primary); } .glow-2 { bottom: 10%; right: 10%; background: var(--neon-blue); } /* Login Card Panel */ .login-wrapper { position: relative; z-index: 10; width: 100%; max-width: 420px; padding: 20px; display: block; } .login-card { background: var(--bg-card); border: 1px solid var(--glass-border); border-radius: var(--radius); padding: 40px 30px; backdrop-filter: blur(20px); box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5); text-align: center; } .logo-main { font-size: 24px; font-weight: 800; letter-spacing: 1px; margin-bottom: 30px; color: var(--text-white); } .logo-main span { color: var(--green-primary); } .input-group { margin-bottom: 20px; text-align: left; } .input-group label { display: block; font-size: 13px; color: var(--text-muted); margin-bottom: 8px; font-weight: 500; } .input-field { width: 100%; padding: 14px 16px; background: rgba(10, 14, 23, 0.8); border: 1px solid var(--glass-border); border-radius: 8px; color: var(--text-white); font-size: 15px; outline: none; transition: var(--transition); } .input-field:focus { border-color: var(--green-primary); box-shadow: 0 0 10px rgba(0, 230, 118, 0.15); } .btn-action { width: 100%; padding: 14px; background: linear-gradient(135deg, var(--green-primary), #00b248); border: none; border-radius: 8px; color: #0a0e17; font-weight: 700; font-size: 15px; cursor: pointer; transition: var(--transition); margin-top: 10px; } .btn-action:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(0, 230, 118, 0.3); } .error-msg { color: #ff5252; font-size: 14px; margin-bottom: 20px; display: none; } /* Dashboard Console Panel */ .dashboard-container { display: none; width: 100%; max-width: 1300px; padding: 40px 20px; position: relative; z-index: 10; } .header-panel { display: flex; justify-content: space-between; align-items: center; margin-bottom: 40px; } .header-title h2 { font-size: 28px; font-weight: 800; } .header-title p { color: var(--text-muted); font-size: 14px; margin-top: 4px; } .btn-secondary { background: var(--glass-bg); border: 1px solid var(--glass-border); color: var(--text-white); padding: 10px 20px; border-radius: 8px; font-weight: 600; font-size: 14px; cursor: pointer; transition: var(--transition); display: flex; align-items: center; gap: 8px; } .btn-secondary:hover { background: rgba(255,255,255,0.08); border-color: var(--text-white); } /* Performance Stats Grid */ .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 20px; margin-bottom: 40px; } .stat-card { background: var(--bg-card); border: 1px solid var(--glass-border); border-radius: var(--radius); padding: 24px; backdrop-filter: blur(10px); display: flex; align-items: center; gap: 20px; } .stat-icon { width: 56px; height: 56px; border-radius: 12px; background: rgba(0, 230, 118, 0.08); border: 1px solid rgba(0, 230, 118, 0.2); color: var(--green-primary); display: flex; align-items: center; justify-content: center; font-size: 24px; } .stat-card:nth-child(2) .stat-icon { background: rgba(0, 176, 255, 0.08); border-color: rgba(0, 176, 255, 0.2); color: var(--neon-blue); } .stat-card:nth-child(3) .stat-icon { background: rgba(255, 179, 0, 0.08); border-color: rgba(255, 179, 0, 0.2); color: #ffb300; } .stat-info h3 { font-size: 13px; color: var(--text-muted); font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px; } .stat-info h2 { font-size: 28px; font-weight: 700; margin-top: 5px; } /* Filter Dashboard & Controls */ .controls-panel { background: var(--bg-card); border: 1px solid var(--glass-border); border-radius: var(--radius); padding: 24px; margin-bottom: 24px; backdrop-filter: blur(10px); display: flex; flex-wrap: wrap; gap: 16px; align-items: center; justify-content: space-between; } .filters-left { display: flex; flex-wrap: wrap; gap: 12px; flex-grow: 1; } .filter-input { padding: 10px 16px; background: rgba(10, 14, 23, 0.7); border: 1px solid var(--glass-border); border-radius: 8px; color: var(--text-white); font-size: 14px; outline: none; transition: var(--transition); } .filter-input:focus { border-color: var(--green-primary); } .search-box { position: relative; max-width: 320px; width: 100%; } .search-box input { width: 100%; padding-left: 40px; } .search-box i { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--text-muted); } /* Settings Panel UI */ .settings-panel { background: var(--bg-card); border: 1px solid var(--glass-border); border-radius: var(--radius); padding: 24px; margin-bottom: 24px; display: flex; flex-direction: column; gap: 16px; backdrop-filter: blur(10px); } .settings-header h3 { font-size: 18px; font-weight: 700; color: #fff; display: flex; align-items: center; gap: 8px; margin-bottom: 4px; } .settings-header p { font-size: 13px; color: var(--text-muted); } .settings-form { display: grid; grid-template-columns: 1fr 1fr auto; gap: 20px; align-items: flex-end; } .settings-field { display: flex; flex-direction: column; gap: 8px; } .settings-field label { font-size: 13px; font-weight: 600; color: var(--text-muted); } .settings-input { background: rgba(10, 14, 23, 0.7); border: 1px solid var(--glass-border); border-radius: 8px; padding: 10px 16px; font-size: 14px; color: #fff; outline: none; transition: var(--transition); } .settings-input:focus { border-color: var(--green-primary); } .settings-message { font-size: 13px; padding: 10px 16px; border-radius: 8px; display: none; } .settings-message.success { display: block; background: rgba(0,230,118,0.1); color: var(--green-primary); border: 1px solid rgba(0,230,118,0.2); } .settings-message.error { display: block; background: rgba(239,68,68,0.1); color: #ef4444; border: 1px solid rgba(239,68,68,0.2); } @media(max-width: 768px) { .settings-form { grid-template-columns: 1fr; } } /* Grid Table User Interface */ .grid-panel { background: var(--bg-card); border: 1px solid var(--glass-border); border-radius: var(--radius); overflow: hidden; backdrop-filter: blur(10px); margin-bottom: 24px; } .table-responsive { overflow-x: auto; } table { width: 100%; border-collapse: collapse; text-align: left; } th { background: rgba(255,255,255,0.02); padding: 16px 20px; font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); border-bottom: 1px solid var(--glass-border); } td { padding: 16px 20px; font-size: 14px; border-bottom: 1px solid rgba(255, 255, 255, 0.04); color: rgba(255,255,255,0.85); } tr:last-child td { border-bottom: none; } tr:hover td { background: rgba(255, 255, 255, 0.01); } /* Custom Status and Badge designs */ .badge { padding: 6px 12px; border-radius: 20px; font-size: 11px; font-weight: 700; text-transform: uppercase; display: inline-block; } .badge.paid { background: rgba(0, 230, 118, 0.1); color: var(--green-primary); border: 1px solid rgba(0, 230, 118, 0.2); } .badge.pending { background: rgba(255, 179, 0, 0.1); color: #ffb300; border: 1px solid rgba(255, 179, 0, 0.2); } .badge.failed { background: rgba(255, 82, 82, 0.1); color: #ff5252; border: 1px solid rgba(255, 82, 82, 0.2); } .addon-tag { font-size: 12px; color: var(--green-primary); background: rgba(0, 230, 118, 0.05); padding: 2px 6px; border-radius: 4px; border: 1px solid rgba(0, 230, 118, 0.1); } .actions-cell { display: flex; gap: 8px; } .btn-icon { width: 32px; height: 32px; border-radius: 6px; border: 1px solid var(--glass-border); background: var(--glass-bg); color: var(--text-white); cursor: pointer; display: flex; align-items: center; justify-content: center; font-size: 13px; transition: var(--transition); } .btn-icon:hover { border-color: var(--text-white); } .btn-icon.delete:hover { border-color: #ff5252; color: #ff5252; background: rgba(255, 82, 82, 0.05); } /* Pagination design */ .pagination { display: flex; justify-content: space-between; align-items: center; padding: 20px; border-top: 1px solid var(--glass-border); } .pagination-info { font-size: 13px; color: var(--text-muted); } .pagination-buttons { display: flex; gap: 8px; } /* Dynamic Popup Modal */ .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(5, 7, 12, 0.85); backdrop-filter: blur(10px); z-index: 100; display: none; align-items: center; justify-content: center; padding: 20px; } .modal-card { background: var(--bg-card); border: 1px solid var(--glass-border); border-radius: var(--radius); width: 100%; max-width: 550px; padding: 30px; position: relative; box-shadow: 0 25px 50px rgba(0,0,0,0.6); } .modal-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--glass-border); padding-bottom: 15px; margin-bottom: 20px; } .modal-close { background: transparent; border: none; color: var(--text-muted); font-size: 20px; cursor: pointer; } .modal-close:hover { color: var(--text-white); } .modal-row { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px dashed rgba(255,255,255,0.05); font-size: 14px; } .modal-row:last-child { border-bottom: none; } .modal-row strong { color: var(--text-muted); font-weight: 500; } .modal-row span { color: var(--text-white); } </style> </head> <body> <div class="glowing-bg glow-1"></div> <div class="glowing-bg glow-2"></div> <!-- 1. Secure Admin Login Panel --> <div class="login-wrapper" id="loginWrapper"> <div class="login-card"> <h1 class="logo-main">VFA<span>ACADEMY</span></h1> <h3 style="margin-bottom: 24px; font-weight: 600; font-size: 18px;">Admin Console Access</h3> <div id="loginError" class="error-msg">Invalid administrator credentials!</div> <form id="loginForm" onsubmit="event.preventDefault(); submitLogin();"> <div class="input-group"> <label for="username">Admin Username</label> <input type="text" id="username" class="input-field" placeholder="Enter username" required> </div> <div class="input-group"> <label for="password">Password Key</label> <input type="password" id="password" class="input-field" placeholder="Enter password" required> </div> <button type="submit" class="btn-action">Verify Identity</button> </form> </div> </div> <!-- 2. Interactive Admin Management Console --> <div class="dashboard-container" id="dashboardContainer"> <div class="header-panel"> <div class="header-title"> <h2>VFA Webinar Registry</h2> <p>Monitor registrations, transaction logs, and performance metrics securely.</p> </div> <div style="display: flex; gap: 12px;"> <button class="btn-secondary" onclick="exportData()"><i class="fa-solid fa-file-export"></i> Export CSV</button> <button class="btn-secondary" onclick="submitLogout()"><i class="fa-solid fa-sign-out-alt"></i> Logout</button> </div> </div> <!-- Metrics Dashboard Stats --> <div class="stats-grid"> <div class="stat-card"> <div class="stat-icon"><i class="fa-solid fa-users"></i></div> <div class="stat-info"> <h3>Paid Seats</h3> <h2 id="statPaid">0</h2> </div> </div> <div class="stat-card"> <div class="stat-icon"><i class="fa-solid fa-indian-rupee-sign"></i></div> <div class="stat-info"> <h3>Total Revenue</h3> <h2 id="statRevenue">₹0.00</h2> </div> </div> <div class="stat-card"> <div class="stat-icon"><i class="fa-solid fa-hourglass-half"></i></div> <div class="stat-info"> <h3>Pending Orders</h3> <h2 id="statPending">0</h2> </div> </div> <div class="stat-card"> <div class="stat-icon"><i class="fa-solid fa-phone-volume"></i></div> <div class="stat-info"> <h3>Add-on Sales</h3> <h2 id="statReminders">0</h2> </div> </div> </div> <!-- Pricing Configurations Panel --> <div class="settings-panel"> <div class="settings-header"> <h3><i class="fa-solid fa-gears"></i> Dynamic Price Configurations</h3> <p>Instantly update the webinar tuition fees and call support add-on pricing across the application.</p> </div> <div class="settings-form"> <div class="settings-field"> <label for="webinarPriceInput"><i class="fa-solid fa-graduation-cap"></i> Webinar Tuition Price (₹)</label> <input type="number" id="webinarPriceInput" min="0" step="1" value="289" class="settings-input"> </div> <div class="settings-field"> <label for="reminderPriceInput"><i class="fa-solid fa-phone"></i> Call Support Price (₹)</label> <input type="number" id="reminderPriceInput" min="0" step="1" value="40" class="settings-input"> </div> <button class="btn-primary" onclick="saveSettings()" style="height: 40px; font-size: 14px; margin-top: auto; padding: 10px 24px;"> <i class="fa-solid fa-save"></i> Save Settings </button> </div> <div id="settingsMessage" class="settings-message"></div> </div> <!-- Filter Grid Tool controls --> <div class="controls-panel"> <div class="filters-left"> <div class="search-box"> <i class="fa-solid fa-magnifying-glass"></i> <input type="text" id="filterSearch" class="filter-input" placeholder="Search by name, email, transaction..." oninput="fetchUsers()"> </div> <select id="filterStatus" class="filter-input" onchange="fetchUsers()"> <option value="All">All Statuses</option> <option value="Paid">Paid Only</option> <option value="Pending">Pending Only</option> <option value="Failed">Failed Only</option> </select> <input type="date" id="filterDate" class="filter-input" onchange="fetchUsers()"> </div> <button class="btn-secondary" onclick="resetFilters()"><i class="fa-solid fa-rotate-left"></i> Reset</button> </div> <!-- Users Data Registry --> <div class="grid-panel"> <div class="table-responsive"> <table> <thead> <tr> <th>Reg Date</th> <th>Full Name</th> <th>Email Address</th> <th>Phone Contact</th> <th>Add-on</th> <th>Amount (₹)</th> <th>Status</th> <th style="width: 140px;">Operations</th> </tr> </thead> <tbody id="usersGridBody"> <tr><td colspan="8" style="text-align: center; color: var(--text-muted); padding: 40px;">Initializing secure connection...</td></tr> </tbody> </table> </div> <div class="pagination"> <div class="pagination-info" id="paginationInfo">Showing 0 of 0 entries</div> <div class="pagination-buttons"> <button class="btn-secondary" id="btnPrev" onclick="changePage(-1)">Previous</button> <button class="btn-secondary" id="btnNext" onclick="changePage(1)">Next</button> </div> </div> </div> </div> <!-- 3. Details Visualizer Modal Popup --> <div class="modal" id="detailsModal"> <div class="modal-card"> <div class="modal-header"> <h3 style="font-weight: 700; font-size: 18px; color: var(--green-primary);">Registration Details</h3> <button class="modal-close" onclick="closeDetails()">×</button> </div> <div id="modalContent"> <!-- Injected dynamically --> </div> </div> </div> <script> let currentPage = 1; const recordsPerPage = 10; let totalPages = 1; // Perform instant Authentication Check on Page Boot window.addEventListener('DOMContentLoaded', () => { fetch('check-auth.php') .then(res => res.json()) .then(data => { if (data.authenticated) { displayDashboard(); } else { document.getElementById('loginWrapper').style.display = 'block'; } }); }); // Submit Administrator credentials function submitLogin() { const user = document.getElementById('username').value; const pass = document.getElementById('password').value; const errorMsg = document.getElementById('loginError'); fetch('login.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: user, password: pass }) }) .then(res => { if (!res.ok) throw new Error('Unverified'); return res.json(); }) .then(data => { if (data.success) { errorMsg.style.display = 'none'; displayDashboard(); } }) .catch(() => { errorMsg.style.display = 'block'; }); } // Display dashboard view and initialize database sync function displayDashboard() { document.getElementById('loginWrapper').style.display = 'none'; document.getElementById('dashboardContainer').style.display = 'block'; document.body.style.alignItems = 'flex-start'; fetchStats(); fetchUsers(); fetchSettings(); } // Fetch webinar and call reminder price settings from db function fetchSettings() { fetch('get-settings.php') .then(res => res.json()) .then(settings => { document.getElementById('webinarPriceInput').value = settings.webinar_price; document.getElementById('reminderPriceInput').value = settings.reminder_price; }) .catch(err => console.error("Error loading pricing config:", err)); } // Save updated webinar and call reminder prices function saveSettings() { const webinarPrice = parseFloat(document.getElementById('webinarPriceInput').value); const reminderPrice = parseFloat(document.getElementById('reminderPriceInput').value); const msg = document.getElementById('settingsMessage'); if (isNaN(webinarPrice) || isNaN(reminderPrice) || webinarPrice < 0 || reminderPrice < 0) { msg.className = 'settings-message error'; msg.innerText = '⚠️ Please enter valid non-negative numbers for prices.'; return; } fetch('save-settings.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ webinar_price: webinarPrice, reminder_price: reminderPrice }) }) .then(res => res.json()) .then(data => { if (data.success) { msg.className = 'settings-message success'; msg.innerText = '✅ Pricing settings saved and updated successfully!'; setTimeout(() => { msg.style.display = 'none'; }, 3000); } else { msg.className = 'settings-message error'; msg.innerText = `❌ Error: ${data.error || 'Failed to update settings'}`; } }) .catch(err => { msg.className = 'settings-message error'; msg.innerText = '❌ Network error while saving configuration.'; }); } // Fetch analytical statistics function fetchStats() { fetch('admin-stats.php') .then(res => res.json()) .then(stats => { document.getElementById('statPaid').innerText = stats.totalRegistrations; document.getElementById('statRevenue').innerText = `₹${parseFloat(stats.totalRevenue).toLocaleString('en-IN')}`; document.getElementById('statPending').innerText = stats.pendingPayments; document.getElementById('statReminders').innerText = stats.reminderCount; }); } // Fetch registry users lists dynamically function fetchUsers() { const search = document.getElementById('filterSearch').value; const status = document.getElementById('filterStatus').value; const date = document.getElementById('filterDate').value; const url = `admin-users.php?page=${currentPage}&limit=${recordsPerPage}&search=${encodeURIComponent(search)}&status=${status}&date=${date}`; fetch(url) .then(res => res.json()) .then(data => { totalPages = data.totalPages; renderTable(data.users); renderPagination(data.totalCount); }) .catch(err => console.error('Fetch users error:', err)); } // Render Table list securely function renderTable(users) { const tbody = document.getElementById('usersGridBody'); tbody.innerHTML = ''; if (users.length === 0) { tbody.innerHTML = `<tr><td colspan="8" style="text-align: center; color: var(--text-muted); padding: 40px;">No registrations match your search.</td></tr>`; return; } users.forEach(u => { const regDate = new Date(u.date).toLocaleDateString(undefined, { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); const statusBadge = u.payment_status === 'Paid' ? 'paid' : (u.payment_status === 'Pending' ? 'pending' : 'failed'); const addOn = u.reminder_added ? '<span class="addon-tag">Reminder</span>' : '<span style="color:var(--text-muted);">-</span>'; const phoneStr = u.country_code ? `+${u.country_code} ${u.phone}` : u.phone; tbody.innerHTML += ` <tr> <td style="font-size: 13px; color: var(--text-muted);">${regDate}</td> <td style="font-weight: 600; color: #fff;">${u.name}</td> <td>${u.email}</td> <td>${phoneStr}</td> <td>${addOn}</td> <td style="font-weight: 600; color: #fff;">₹${u.amount_paid.toFixed(2)}</td> <td><span class="badge ${statusBadge}">${u.payment_status}</span></td> <td> <div class="actions-cell"> <button class="btn-icon" onclick="viewDetails(${JSON.stringify(u).replace(/"/g, '"')})" title="View Details"><i class="fa-solid fa-eye"></i></button> <button class="btn-icon" onclick="toggleStatus(${u.id}, '${u.payment_status}')" title="Change Payment Status"><i class="fa-solid fa-toggle-on"></i></button> <button class="btn-icon delete" onclick="deleteUser(${u.id})" title="Remove Record"><i class="fa-solid fa-trash-can"></i></button> </div> </td> </tr> `; }); } // Render table pagination logic function renderPagination(totalCount) { const info = document.getElementById('paginationInfo'); const start = totalCount === 0 ? 0 : (currentPage - 1) * recordsPerPage + 1; const end = Math.min(currentPage * recordsPerPage, totalCount); info.innerText = `Showing ${start} to ${end} of ${totalCount} entries`; document.getElementById('btnPrev').disabled = currentPage === 1; document.getElementById('btnNext').disabled = currentPage >= totalPages || totalPages === 0; } // Change Pagination Page index function changePage(direction) { currentPage += direction; fetchUsers(); } // Reset Filter settings function resetFilters() { document.getElementById('filterSearch').value = ''; document.getElementById('filterStatus').value = 'All'; document.getElementById('filterDate').value = ''; currentPage = 1; fetchUsers(); } // Open details modal function viewDetails(user) { const modal = document.getElementById('detailsModal'); const content = document.getElementById('modalContent'); const date = new Date(user.date).toLocaleString(); const phoneStr = user.country_code ? `+${user.country_code} ${user.phone}` : user.phone; content.innerHTML = ` <div class="modal-row"><strong>Registered Date:</strong> <span>${date}</span></div> <div class="modal-row"><strong>Full Name:</strong> <span>${user.name}</span></div> <div class="modal-row"><strong>Email Address:</strong> <span>${user.email}</span></div> <div class="modal-row"><strong>Phone Number:</strong> <span>${phoneStr}</span></div> <div class="modal-row"><strong>Call Reminder Add-on:</strong> <span>${user.reminder_added ? 'Yes (+₹40)' : 'No'}</span></div> <div class="modal-row"><strong>Webinar Subtotal:</strong> <span>₹${parseFloat(user.subtotal).toFixed(2)}</span></div> <div class="modal-row"><strong>GST Amount (18%):</strong> <span>₹${parseFloat(user.gst_amount).toFixed(2)}</span></div> <div class="modal-row"><strong>Final Total Paid:</strong> <span style="color:var(--green-primary); font-weight:700;">₹${parseFloat(user.amount_paid).toFixed(2)}</span></div> <div class="modal-row"><strong>Razorpay Order ID:</strong> <span>${user.razorpay_order_id || 'N/A'}</span></div> <div class="modal-row"><strong>Payment Transaction ID:</strong> <span style="font-family: monospace;">${user.payment_id || 'N/A'}</span></div> <div class="modal-row"><strong>Payment Status:</strong> <span class="badge ${user.payment_status.toLowerCase()}">${user.payment_status}</span></div> <div class="modal-row" style="flex-direction: column; align-items: flex-start; gap: 8px; margin-top: 10px;"> <strong>Student Goal Message:</strong> <div style="background: rgba(0,0,0,0.2); border: 1px solid var(--glass-border); padding: 12px; border-radius: 8px; width: 100%; min-height: 80px; font-size: 13px; color: var(--text-muted); line-height: 1.5;"> ${user.message || 'No goal statement entered.'} </div> </div> `; modal.style.display = 'flex'; } // Close details modal function closeDetails() { document.getElementById('detailsModal').style.display = 'none'; } // Toggle user status function toggleStatus(id, currentStatus) { const nextStatus = currentStatus === 'Paid' ? 'Pending' : 'Paid'; if (confirm(`Do you want to update payment status to ${nextStatus}?`)) { fetch(`update-status.php?id=${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: nextStatus }) }) .then(res => res.json()) .then(() => { fetchStats(); fetchUsers(); }); } } // Delete user record function deleteUser(id) { if (confirm('Are you absolutely sure you want to permanently delete this registration record? This action cannot be undone.')) { fetch(`delete-user.php?id=${id}`, { method: 'DELETE' }) .then(res => res.json()) .then(() => { fetchStats(); fetchUsers(); }); } } // Export secure CSV download stream function exportData() { window.location.href = 'export-csv.php'; } // Submit Logout request function submitLogout() { fetch('logout.php', { method: 'POST' }) .then(() => { document.getElementById('dashboardContainer').style.display = 'none'; document.getElementById('loginWrapper').style.display = 'block'; document.body.style.alignItems = 'center'; }); } </script> </body> </html>
SAVE
CANCEL