X7ROOT File Manager
Current Path:
/home/u126090504/domains/oceanicabeachresort.com/public_html/admin
home
/
u126090504
/
domains
/
oceanicabeachresort.com
/
public_html
/
admin
/
📁
..
📁
assets
📄
banners.php
(9.78 KB)
📄
booking-dashboard.php
(4.93 KB)
📄
booking_status_update.php
(6.14 KB)
📄
booking_view.php
(4.04 KB)
📄
branding_settings.php
(5.93 KB)
📄
change_password.php
(3.01 KB)
📄
contacts.php
(3.83 KB)
📄
dashboard.php
(5.64 KB)
📁
dompdf
📄
downloads.php
(4.91 KB)
📄
forgot_password.php
(5.76 KB)
📄
gallery.php
(3.08 KB)
📁
img
📁
includes
📄
index.php
(82 B)
📁
invoices
📄
login.php
(13.47 KB)
📄
logo.png
(19.29 KB)
📄
logout.php
(102 B)
📄
manage_albums.php
(10.82 KB)
📄
manage_media.php
(11.77 KB)
📄
manage_photos.php
(6.35 KB)
📄
manage_videos.php
(18.38 KB)
📄
new_password.php
(3.9 KB)
📄
notice.php
(15.52 KB)
📄
notice_error.log
(38.45 KB)
📄
notices.php
(8.24 KB)
📄
payments.php
(14.96 KB)
📄
pdf_bill_template.php
(30.69 KB)
📁
phpmailer
📄
popup.php
(14.07 KB)
📄
reset_password.php
(2.27 KB)
📄
secure_session.php
(1000 B)
📄
settings.php
(8.34 KB)
📄
test.php
(239 B)
📄
test_pdf.php
(1.58 KB)
📄
testimonials.php
(15.15 KB)
📁
tmp
📄
update_status.php
(1.66 KB)
📄
upi_settings.php
(1.52 KB)
Editing: payments.php
<?php include 'secure_session.php'; include 'includes/auth.php'; require_once '../config.php'; include 'includes/header.php'; $result = $conn->query("SELECT * FROM payments ORDER BY id DESC"); /* ---------- Helpers ---------- */ function e($v){ return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); } function base_url(){ $proto = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; return rtrim($proto.$host, '/'); } function photo_url($p, $abs=false){ $p = trim((string)$p); if ($p === '') return ''; if (preg_match('~^https?://~i', $p)) return $p; $rel = '/' . ltrim($p, '/'); // /uploads/students/xxx.jpg return $abs ? base_url().$rel : $rel; } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Payment Records</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="https://cdn.datatables.net/1.13.7/css/dataTables.bootstrap5.min.css"> <link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.4.2/css/buttons.bootstrap5.min.css"> <style> :root{ --brand:#c40000; --ink:#0b1220; } body{ background:linear-gradient(180deg,#f8f9ff 0%,#eef3ff 40%,#f8f9fa 100%); font-family:system-ui,-apple-system,"Segoe UI",Roboto,Inter,Arial; } .card{ border:0; border-radius:18px; box-shadow:0 8px 24px rgba(15,23,42,.08); } .card-header{ background:var(--brand); color:#fff; border-top-left-radius:18px!important;border-top-right-radius:18px!important; } .brand-title{ margin:0; font-weight:800; letter-spacing:.2px; } .kpi{ background:#fff; border:1px solid rgba(15,23,42,.08); border-radius:16px; padding:14px 16px; box-shadow:0 6px 18px rgba(15,23,42,.06); } .kpi .label{ font-weight:700; color:#991b1b; font-size:.9rem; } .kpi .val{ font-size:1.6rem; font-weight:800; color:#111827; } .range-bar{ background:#fff; border:1px solid rgba(15,23,42,.08); border-radius:12px; padding:10px 12px; box-shadow:0 4px 12px rgba(15,23,42,.06); } .range-bar label{ font-weight:600; margin-right:6px; color:#334155; } .table>thead.table-dark th{ background:var(--ink)!important; border-color:var(--ink)!important; } .table td,.table th{ vertical-align:middle; } .thumb{ width:44px; height:44px; border-radius:50%; object-fit:cover; border:1px solid #e5e7eb; cursor:pointer; } .status-dropdown{ border:0; font-weight:700; border-radius:999px!important; padding:.25rem .75rem!important; width:120px; text-align:center; color:#fff; } .status-pending{ background:#ff9800; } .status-paid{ background:#2e7d32; } .status-failed{ background:#d32f2f; } .status-cancelled{ background:#616161; } .dt-buttons{ margin-bottom:12px; } @media print { img.thumb{ width:60px; height:60px; border-radius:50%; object-fit:cover; } } </style> </head> <body> <div class="container py-5"> <div class="card"> <div class="card-header d-flex justify-content-between align-items-center"> <h3 class="brand-title">Payment Records</h3> <a href="dashboard.php" class="btn btn-light btn-sm">← Go to Dashboard</a> </div> <div class="card-body"> <!-- KPI Row --> <div class="row g-3 mb-3"> <div class="col-12 col-md-4"><div class="kpi"><div class="label">Total Students</div><div id="kpi-students" class="val">0</div></div></div> <div class="col-12 col-md-4"><div class="kpi"><div class="label">Paid Amount</div><div id="kpi-amount" class="val">₹0.00</div></div></div> <div class="col-12 col-md-4"><div class="kpi"><div class="label">Records</div><div id="kpi-records" class="val">0</div></div></div> </div> <!-- Date Range --> <div class="range-bar d-flex flex-wrap align-items-center gap-2 mb-3"> <label>From:</label><input type="date" id="fromDate" class="form-control" style="max-width:190px"> <label class="ms-2">To:</label><input type="date" id="toDate" class="form-control" style="max-width:190px"> <button id="clearRange" class="btn btn-outline-secondary btn-sm ms-2">Clear</button> </div> <div class="table-responsive"> <table id="paymentsTable" class="table table-bordered table-striped align-middle w-100"> <thead class="table-dark text-center"> <tr> <th>ID</th> <th>Photo</th> <th>Student</th> <th>Father</th> <th>Mother</th> <th>Sex</th> <th>Caste</th> <th>Blood</th> <th>Aadhaar</th> <th>DOB</th> <th>Age</th> <th>School</th> <th>Class</th> <th>Section</th> <th>Roll No</th> <th>Payment Type</th> <th>Amount</th> <th>Status</th> <th>Date</th> </tr> </thead> <tbody> <?php while($row = $result->fetch_assoc()): $status = $row['status'] ?? 'Pending'; $cls = match($status){ 'Paid'=>'status-paid','Failed'=>'status-failed','Cancelled'=>'status-cancelled',default=>'status-pending' }; $amt = (float)($row['amount'] ?? 0); $photoR = photo_url($row['photo'] ?? '', false); // relative $photoA = photo_url($row['photo'] ?? '', true); // absolute (for exports) ?> <tr data-amount="<?= $amt ?>" data-status="<?= e($status) ?>"> <td><?= e($row['id']) ?></td> <td class="text-center" data-photo-abs="<?= e($photoA) ?>"> <?php if($photoR): ?> <img src="<?= e($photoR) ?>?v=<?= e($row['id']) ?>" class="thumb" alt="Photo" onerror="this.onerror=null;this.src='/assets/img/no-avatar.png'"> <?php else: ?><span class="text-muted">—</span><?php endif; ?> </td> <td><?= e($row['student_name']) ?></td> <td><?= e($row['father_name']) ?></td> <td><?= e($row['mother_name']) ?></td> <td><?= e($row['sex']) ?></td> <td><?= e($row['caste']) ?></td> <td><?= e($row['blood_group']) ?></td> <td><?= e($row['aadhaar']) ?></td> <td><?= e($row['dob']) ?></td> <td><?= e($row['age']) ?></td> <td><?= e($row['school']) ?></td> <td><?= e($row['class']) ?></td> <td><?= e($row['tuition_section']) ?></td> <td><?= e($row['rollno']) ?></td> <td><?= e($row['payment_type']) ?></td> <td class="fw-bold text-success">₹<?= e(number_format($amt,2)) ?></td> <td class="text-center"> <select class="form-select form-select-sm status-dropdown <?= $cls ?>" data-id="<?= e($row['id']) ?>"> <option value="Pending" <?= $status=='Pending'?'selected':'' ?>>Pending</option> <option value="Paid" <?= $status=='Paid'?'selected':'' ?>>Paid</option> <option value="Failed" <?= $status=='Failed'?'selected':'' ?>>Failed</option> <option value="Cancelled" <?= $status=='Cancelled'?'selected':'' ?>>Cancelled</option> </select> </td> <td><?= e($row['created_at']) ?></td> </tr> <?php endwhile; ?> </tbody> </table> </div> </div> </div> </div> <!-- Lightbox Modal --> <div class="modal fade" id="photoModal" tabindex="-1" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered modal-lg"> <div class="modal-content"> <div class="modal-body p-0"> <img id="lightboxImg" src="" alt="Student Photo" style="width:100%;height:auto;display:block;"> </div> <div class="modal-footer"> <a id="downloadImg" class="btn btn-primary" href="#" download>Download</a> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script> <script src="https://code.jquery.com/jquery-3.7.0.min.js"></script> <script src="https://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js"></script> <script src="https://cdn.datatables.net/1.13.7/js/dataTables.bootstrap5.min.js"></script> <script src="https://cdn.datatables.net/buttons/2.4.2/js/dataTables.buttons.min.js"></script> <script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.bootstrap5.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script> <script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.html5.min.js"></script> <script src="https://cdn.datatables.net/buttons/2.4.2/js/buttons.print.min.js"></script> <script> $(function(){ const currencyIN = new Intl.NumberFormat('en-IN', { style:'currency', currency:'INR' }); // Date range filter based on last column (Date) $.fn.dataTable.ext.search.push(function(settings, data, dataIndex){ const from = $('#fromDate').val(), to = $('#toDate').val(); if(!from && !to) return true; const row = table.row(dataIndex).node(); const txt = $('td:last', row).text().trim(); // created_at if(!txt) return false; const parts = (txt.split(' ')[0] || '').split('-').map(Number); const d = new Date(parts[0], (parts[1]||1)-1, parts[2]||1); const f = from ? new Date(from+'T00:00:00') : null; const t = to ? new Date(to +'T23:59:59') : null; if (f && d < f) return false; if (t && d > t) return false; return true; }); const table = $('#paymentsTable').DataTable({ order: [[0,'desc']], dom: 'Bfrtip', buttons: [ { extend:'excelHtml5', title:'Payments_Report', exportOptions:{ // Use custom formatter to export photo URL in place of thumbnail columns: ':visible', format: { body: function (data, row, col, node) { if (col === 1) { // Photo column const abs = $(node).closest('td').attr('data-photo-abs') || ''; return abs || ''; } // strip ₹ in amount for csv/xlsx numeric correctness if (col === 16) { // Amount column index const num = String($(node).text() || data).replace(/[^\d.]/g,''); return num; } return $(node).text() || data; } } } }, { extend:'csvHtml5', title:'Payments_Report', exportOptions:{ columns: ':visible', format: { body: function (data, row, col, node) { if (col === 1) { const abs = $(node).closest('td').attr('data-photo-abs') || ''; return abs || ''; } if (col === 16) { const num = String($(node).text() || data).replace(/[^\d.]/g,''); return num; } return $(node).text() || data; } } } }, { extend:'pdfHtml5', title:'Payments_Report', orientation:'landscape', pageSize:'A4', exportOptions:{ columns: ':visible', format: { body: function (data, row, col, node) { if (col === 1) { const abs = $(node).closest('td').attr('data-photo-abs') || ''; return abs || ''; // PDF: show absolute URL (embedding images via pdfmake needs base64; out of scope here) } if (col === 16) { const num = String($(node).text() || data).replace(/[^\d.]/g,''); return num; } return $(node).text() || data; } } } }, { extend:'print', title:'Payments Report', exportOptions:{ columns: ':visible' }, customize: function (win) { // Ensure images look good on print const css = 'img.thumb{width:60px;height:60px;border-radius:50%;object-fit:cover;border:1px solid #ccc;}'; const head = win.document.head || win.document.getElementsByTagName('head')[0]; const style = win.document.createElement('style'); style.type='text/css'; style.appendChild(win.document.createTextNode(css)); head.appendChild(style); } } ] }); // Range events $('#fromDate, #toDate').on('change', function(){ table.draw(); refreshKPIs(); }); $('#clearRange').on('click', function(){ $('#fromDate').val(''); $('#toDate').val(''); table.draw(); refreshKPIs(); }); // Status change AJAX + update row dataset (so KPIs recalc sahi ho) $(document).on('change','.status-dropdown',function(){ const el = $(this), id = el.data('id'), status = el.val(); $.post('update_status.php',{id, status}, function(){ el.removeClass('status-pending status-paid status-failed status-cancelled'); if (status==='Paid') el.addClass('status-paid'); else if (status==='Failed') el.addClass('status-failed'); else if (status==='Cancelled') el.addClass('status-cancelled'); else el.addClass('status-pending'); const row = el.closest('tr').get(0); if (row) row.dataset.status = status; refreshKPIs(); }).fail(()=>alert('❌ Error updating status')); }); // Compute KPIs from filtered rows function getMetrics(){ const nodes = table.rows({search:'applied'}).nodes(); let paid = 0, records = 0; nodes.each(function(_, i){ const row = nodes[i]; const amt = parseFloat(row.dataset.amount || '0') || 0; const st = row.dataset.status || ''; if (st === 'Paid') paid += amt; records++; }); return { paidAmount: paid, records, students: records }; } function refreshKPIs(){ const m = getMetrics(); $('#kpi-amount').text(currencyIN.format(m.paidAmount)); $('#kpi-records').text(m.records); $('#kpi-students').text(m.students); } table.on('draw', refreshKPIs); refreshKPIs(); // initial // ---------- Lightbox: click on photo to view + download ---------- const modalEl = document.getElementById('photoModal'); const modal = new bootstrap.Modal(modalEl); $(document).on('click','img.thumb', function(){ // original URL without cache buster const raw = this.src.split('?')[0]; $('#lightboxImg').attr('src', raw); $('#downloadImg').attr('href', raw); modal.show(); }); }); </script> </body> </html> <?php include 'includes/footer.php'; ?>
Upload File
Create Folder