<?php
// Include header
include_once 'includes/header.php';
// Get student ID from session
$student_id = $_SESSION['user_id'];
$success_message = '';
$error_message = '';
// Handle flash messages
if (isset($_SESSION['success_message'])) {
$success_message = $_SESSION['success_message'];
unset($_SESSION['success_message']);
}
if (isset($_SESSION['error_message'])) {
$error_message = $_SESSION['error_message'];
unset($_SESSION['error_message']);
}
// Get all payments for this student
$payments_query = "
SELECT p.id, p.amount, p.payment_method, p.status as payment_status,
p.transaction_id, p.payment_date, p.payment_details, p.screenshot_path,
c.title as course_title, c.id as course_id
FROM payments p
INNER JOIN courses c ON p.course_id = c.id
WHERE p.user_id = ?
ORDER BY p.payment_date DESC
";
$stmt = $conn->prepare($payments_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$payments_result = $stmt->get_result();
$payments = [];
while ($row = $payments_result->fetch_assoc()) {
$payments[] = $row;
}
// Get month-wise payment data for chart
$monthly_data_query = "
SELECT
MONTH(payment_date) as month,
YEAR(payment_date) as year,
SUM(amount) as total_amount
FROM payments
WHERE user_id = ? AND (status = 'completed' OR status = 'verified')
AND payment_date >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
GROUP BY YEAR(payment_date), MONTH(payment_date)
ORDER BY YEAR(payment_date), MONTH(payment_date)
";
$stmt = $conn->prepare($monthly_data_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$monthly_result = $stmt->get_result();
$monthly_data = [];
$chart_labels = [];
$chart_values = [];
while ($row = $monthly_result->fetch_assoc()) {
$month_name = date("M Y", mktime(0, 0, 0, $row['month'], 1, $row['year']));
$chart_labels[] = $month_name;
$chart_values[] = floatval($row['total_amount']);
$monthly_data[$month_name] = $row['total_amount'];
}
// Get payment method distribution for pie chart
$payment_methods_query = "
SELECT
payment_method,
COUNT(*) as count,
SUM(amount) as total_amount
FROM payments
WHERE user_id = ? AND (status = 'completed' OR status = 'verified')
GROUP BY payment_method
";
$stmt = $conn->prepare($payment_methods_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$methods_result = $stmt->get_result();
$payment_methods = [];
$method_labels = [];
$method_values = [];
while ($row = $methods_result->fetch_assoc()) {
$method_labels[] = ucfirst($row['payment_method']);
$method_values[] = floatval($row['total_amount']);
$payment_methods[$row['payment_method']] = [
'count' => $row['count'],
'amount' => $row['total_amount']
];
}
// Get payment totals
$totals_query = "
SELECT
SUM(amount) as total_paid,
COUNT(*) as total_transactions
FROM payments
WHERE user_id = ? AND (status = 'completed' OR status = 'verified')
";
$stmt = $conn->prepare($totals_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$totals = $stmt->get_result()->fetch_assoc();
$total_paid = $totals['total_paid'] ?? 0;
$total_transactions = $totals['total_transactions'] ?? 0;
// Get pending payments total
$pending_query = "
SELECT
SUM(amount) as total_pending,
COUNT(*) as pending_transactions
FROM payments
WHERE user_id = ? AND status = 'pending'
";
$stmt = $conn->prepare($pending_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$pending_data = $stmt->get_result()->fetch_assoc();
$total_pending = $pending_data['total_pending'] ?? 0;
$pending_transactions = $pending_data['pending_transactions'] ?? 0;
// Get course enrollment fees
$enrollments_query = "
SELECT
e.id, e.course_id, e.enrollment_date, e.payment_plan,
c.title, c.price, c.discount_price
FROM enrollments e
INNER JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ?
";
$stmt = $conn->prepare($enrollments_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$enrollments_result = $stmt->get_result();
$enrollments = [];
$total_fees = 0;
while ($row = $enrollments_result->fetch_assoc()) {
$price = $row['discount_price'] > 0 ? $row['discount_price'] : $row['price'];
$row['fee'] = $price;
$total_fees += $price;
$enrollments[] = $row;
}
// Calculate due amount
$due_amount = max(0, $total_fees - $total_paid);
$payment_progress = $total_fees > 0 ? min(100, round(($total_paid / $total_fees) * 100)) : 0;
?>
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0 text-gray-800">Payment History</h1>
<a href="payments.php" class="btn btn-primary">
<i class="fas fa-plus-circle me-2"></i> Make New Payment
</a>
</div>
<?php if ($success_message): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<i class="fas fa-check-circle me-2"></i> <?php echo $success_message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if ($error_message): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<i class="fas fa-exclamation-circle me-2"></i> <?php echo $error_message; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<!-- Payment Overview Cards -->
<div class="row mb-4">
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Total Fees</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">₹<?php echo number_format($total_fees, 2); ?></div>
</div>
<div class="col-auto">
<i class="fas fa-rupee-sign fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Total Paid</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">₹<?php echo number_format($total_paid, 2); ?></div>
</div>
<div class="col-auto">
<i class="fas fa-check-circle fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-warning shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Pending Payments</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">₹<?php echo number_format($total_pending, 2); ?></div>
</div>
<div class="col-auto">
<i class="fas fa-clock fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-danger shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-danger text-uppercase mb-1">Due Amount</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">₹<?php echo number_format($due_amount, 2); ?></div>
</div>
<div class="col-auto">
<i class="fas fa-exclamation-circle fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Payment Progress -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Payment Progress</h6>
</div>
<div class="card-body">
<h4 class="small font-weight-bold">Overall Payment Progress <span class="float-right"><?php echo $payment_progress; ?>%</span></h4>
<div class="progress mb-4">
<div class="progress-bar <?php echo $payment_progress < 50 ? 'bg-danger' : ($payment_progress < 75 ? 'bg-warning' : 'bg-success'); ?>" role="progressbar" style="width: <?php echo $payment_progress; ?>%" aria-valuenow="<?php echo $payment_progress; ?>" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<div class="mt-4 text-center small">
<span class="me-2">
<i class="fas fa-circle text-success"></i> Paid: ₹<?php echo number_format($total_paid, 2); ?>
</span>
<span class="me-2">
<i class="fas fa-circle text-warning"></i> Pending: ₹<?php echo number_format($total_pending, 2); ?>
</span>
<span class="me-2">
<i class="fas fa-circle text-danger"></i> Due: ₹<?php echo number_format($due_amount, 2); ?>
</span>
</div>
</div>
</div>
<div class="row">
<!-- Payment History Chart -->
<div class="col-xl-8 col-lg-7">
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Payment History (Last 12 Months)</h6>
</div>
<div class="card-body">
<div class="chart-area">
<canvas id="paymentHistoryChart"></canvas>
</div>
</div>
</div>
</div>
<!-- Payment Method Distribution -->
<div class="col-xl-4 col-lg-5">
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">Payment Methods</h6>
</div>
<div class="card-body">
<div class="chart-pie pt-4 pb-2">
<canvas id="paymentMethodsChart"></canvas>
</div>
<div class="mt-4 text-center small">
<?php foreach ($method_labels as $index => $method): ?>
<span class="me-2">
<i class="fas fa-circle text-<?php echo $index === 0 ? 'primary' : ($index === 1 ? 'success' : ($index === 2 ? 'info' : 'warning')); ?>"></i> <?php echo $method; ?>
</span>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
</div>
<!-- Payment Transactions Table -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Payment Transactions</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-bordered" id="paymentTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>Date</th>
<th>Course</th>
<th>Description</th>
<th>Method</th>
<th>Amount</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php if (empty($payments)): ?>
<tr>
<td colspan="7" class="text-center">No payment records found.</td>
</tr>
<?php else: ?>
<?php foreach ($payments as $payment): ?>
<tr>
<td><?php echo date('d M Y', strtotime($payment['payment_date'])); ?></td>
<td><?php echo htmlspecialchars($payment['course_title']); ?></td>
<td><?php echo htmlspecialchars($payment['payment_details']); ?></td>
<td><?php echo ucfirst($payment['payment_method']); ?></td>
<td class="font-weight-bold">₹<?php echo number_format($payment['amount'], 2); ?></td>
<td>
<span class="badge bg-<?php
echo $payment['payment_status'] === 'completed' || $payment['payment_status'] === 'verified'
? 'success'
: ($payment['payment_status'] === 'pending'
? 'warning'
: 'danger');
?>"><?php echo ucfirst($payment['payment_status']); ?></span>
</td>
<td>
<a href="payment_receipt.php?payment_id=<?php echo $payment['id']; ?>" class="btn btn-sm btn-info">
<i class="fas fa-receipt"></i> Receipt
</a>
<?php if ($payment['payment_status'] === 'pending' && !empty($payment['screenshot_path'])): ?>
<button type="button" class="btn btn-sm btn-primary view-screenshot" data-payment-id="<?php echo $payment['id']; ?>" data-screenshot="<?php echo htmlspecialchars($payment['screenshot_path']); ?>">
<i class="fas fa-image"></i> View Proof
</button>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- Screenshot Modal -->
<div class="modal fade" id="screenshotModal" tabindex="-1" aria-labelledby="screenshotModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="screenshotModalLabel">Payment Screenshot</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body text-center">
<img id="screenshotImage" src="" class="img-fluid" alt="Payment Screenshot">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Include Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Configure Payment History Line Chart
var historyCtx = document.getElementById('paymentHistoryChart').getContext('2d');
var historyChart = new Chart(historyCtx, {
type: 'line',
data: {
labels: <?php echo json_encode($chart_labels); ?>,
datasets: [{
label: 'Payment Amount (₹)',
lineTension: 0.3,
backgroundColor: "rgba(78, 115, 223, 0.05)",
borderColor: "rgba(78, 115, 223, 1)",
pointRadius: 3,
pointBackgroundColor: "rgba(78, 115, 223, 1)",
pointBorderColor: "rgba(78, 115, 223, 1)",
pointHoverRadius: 5,
pointHoverBackgroundColor: "rgba(78, 115, 223, 1)",
pointHoverBorderColor: "rgba(78, 115, 223, 1)",
pointHitRadius: 10,
pointBorderWidth: 2,
data: <?php echo json_encode($chart_values); ?>,
}],
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: {
grid: {
display: false,
drawBorder: false
}
},
y: {
ticks: {
callback: function(value) {
return '₹' + value.toLocaleString();
}
}
}
},
plugins: {
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if (label) {
label += ': ';
}
if (context.parsed.y !== null) {
label += '₹' + context.parsed.y.toLocaleString();
}
return label;
}
}
}
}
}
});
// Configure Payment Methods Pie Chart
var methodsCtx = document.getElementById('paymentMethodsChart').getContext('2d');
var methodsChart = new Chart(methodsCtx, {
type: 'doughnut',
data: {
labels: <?php echo json_encode($method_labels); ?>,
datasets: [{
data: <?php echo json_encode($method_values); ?>,
backgroundColor: ['#4e73df', '#1cc88a', '#36b9cc', '#f6c23e'],
hoverBackgroundColor: ['#2e59d9', '#17a673', '#2c9faf', '#d4a636'],
hoverBorderColor: "rgba(234, 236, 244, 1)",
}],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
tooltip: {
callbacks: {
label: function(context) {
let label = context.label || '';
if (label) {
label += ': ';
}
if (context.parsed !== null) {
label += '₹' + context.parsed.toLocaleString();
}
return label;
}
}
}
}
}
});
// Initialize DataTable
$('#paymentTable').DataTable({
order: [[0, 'desc']], // Order by date descending
pageLength: 10,
lengthMenu: [[5, 10, 25, 50, -1], [5, 10, 25, 50, "All"]],
language: {
emptyTable: "No payment records found."
}
});
// View Screenshot Modal
const screenshotModal = document.getElementById('screenshotModal');
const screenshotImage = document.getElementById('screenshotImage');
document.querySelectorAll('.view-screenshot').forEach(button => {
button.addEventListener('click', function() {
const screenshotPath = this.getAttribute('data-screenshot');
screenshotImage.src = '../uploads/payments/' + screenshotPath;
const modal = new bootstrap.Modal(screenshotModal);
modal.show();
});
});
});
</script>
<?php
// Include footer
include_once 'includes/footer.php';
?>