<?php
session_start();
require_once 'database/db_config.php';
// Debugging information
$debug_info = [];
$debug_info['session_active'] = session_status() === PHP_SESSION_ACTIVE ? 'Yes' : 'No';
$debug_info['user_id'] = $_SESSION['user_id'] ?? 'Not set';
$debug_info['role'] = $_SESSION['role'] ?? 'Not set';
$debug_info['db_connected'] = isset($conn) && $conn->ping() ? 'Yes' : 'No';
// Log debugging info
error_log("Dashboard Debug - Session active: " . $debug_info['session_active'] .
", User ID: " . $debug_info['user_id'] .
", Role: " . $debug_info['role'] .
", DB Connected: " . $debug_info['db_connected']);
// Check if database connection is valid
if (!isset($conn) || $conn->connect_error) {
$db_error = "Database connection error. Please contact support.";
error_log("Dashboard database connection error: " . ($conn->connect_error ?? 'Unknown error'));
}
// Check if user has student privileges
require_student_privileges('../login.php');
// Get dashboard statistics with error handling
try {
// Get student-specific statistics
$user_id = $_SESSION['user_id'];
// Verify user_id is valid
if (!is_numeric($user_id) || $user_id <= 0) {
throw new Exception("Invalid user ID: $user_id");
}
// Additional debugging
error_log("Dashboard - Using user_id: $user_id for queries");
// Get student information
$student_query = "SELECT * FROM users WHERE id = ?";
$stmt = $conn->prepare($student_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$student_result = $stmt->get_result();
$student = $student_result->fetch_assoc();
// Check if student record was found
if (!$student) {
error_log("Dashboard - No student record found for user_id: $user_id");
} else {
error_log("Dashboard - Found student: " . $student['first_name'] . " " . $student['last_name']);
}
// Get enrolled courses count
$enrolled_courses_query = "SELECT COUNT(*) as count FROM enrollments WHERE user_id = ?";
$stmt = $conn->prepare($enrolled_courses_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$enrolled_result = $stmt->get_result();
$enrolled_data = $enrolled_result->fetch_assoc();
$enrolled_courses_count = $enrolled_data ? $enrolled_data['count'] : 0;
error_log("Dashboard - Enrolled courses count: $enrolled_courses_count");
// Get completed courses count
$completed_courses_query = "SELECT COUNT(*) as count FROM enrollments WHERE user_id = ? AND status = 'completed'";
$stmt = $conn->prepare($completed_courses_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$completed_result = $stmt->get_result();
$completed_data = $completed_result->fetch_assoc();
$completed_courses_count = $completed_data ? $completed_data['count'] : 0;
error_log("Dashboard - Completed courses count: $completed_courses_count");
// Get active courses
$active_courses_query = "
SELECT c.*, e.enrollment_date, e.status as enrollment_status
FROM enrollments e
JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ? AND e.status = 'active'
ORDER BY e.enrollment_date DESC LIMIT 5";
$stmt = $conn->prepare($active_courses_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$active_courses_result = $stmt->get_result();
$active_courses_count = $active_courses_result->num_rows;
error_log("Dashboard - Active courses count: $active_courses_count");
// Check if active courses are fetched properly
if ($active_courses_count === 0) {
error_log("Dashboard - No active courses found for user_id: $user_id");
}
// Get recent activities - example query, adjust according to your database schema
$activities_query = "SELECT * FROM activities WHERE user_id = ? ORDER BY created_at DESC LIMIT 5";
$stmt = $conn->prepare($activities_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$activities_result = $stmt->get_result();
$activities_count = $activities_result->num_rows;
// Get application status
$applications_query = "
SELECT a.*, c.title as course_title
FROM enrollment_applications a
JOIN courses c ON a.course_id = c.id
WHERE a.user_id = ?
ORDER BY a.application_date DESC LIMIT 5";
$stmt = $conn->prepare($applications_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$applications_result = $stmt->get_result();
$applications_count = $applications_result->num_rows;
// Get certificate count
try {
$table_check = $conn->query("SHOW COLUMNS FROM enrollments LIKE 'certificate_number'");
if ($table_check && $table_check->num_rows > 0) {
$certificates_query = "SELECT COUNT(*) as count FROM enrollments WHERE user_id = ? AND status = 'completed' AND certificate_number IS NOT NULL";
$stmt = $conn->prepare($certificates_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$certificates_result = $stmt->get_result();
$certificates_data = $certificates_result->fetch_assoc();
$certificates_count = $certificates_data ? $certificates_data['count'] : 0;
error_log("Dashboard - Certificates count: $certificates_count");
} else {
error_log("Dashboard - certificate_number column doesn't exist in enrollments table");
$certificates_count = 0;
}
} catch (Exception $e) {
error_log("Certificate count error: " . $e->getMessage());
$certificates_count = 0;
}
// Get due payments
$due_payments_query = "
SELECT
e.course_id,
c.title as course_title,
c.duration,
e.payment_plan,
(CASE WHEN c.discount_price > 0 THEN c.discount_price ELSE c.price END) - IFNULL(
(SELECT SUM(amount) FROM payments
WHERE user_id = e.user_id AND course_id = e.course_id AND status IN ('completed', 'verified')),
0
) as remaining,
CASE
WHEN e.payment_plan = 'monthly' THEN
DATEDIFF(
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date) FROM payments
WHERE user_id = e.user_id AND course_id = e.course_id AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 1 MONTH
),
CURRENT_DATE
)
WHEN e.payment_plan = 'half_duration' THEN
DATEDIFF(
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date) FROM payments
WHERE user_id = e.user_id AND course_id = e.course_id AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL CEILING(
CASE
WHEN c.duration LIKE '%month%' THEN CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) / 2
WHEN c.duration LIKE '%year%' THEN CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) * 6
WHEN c.duration LIKE '%week%' THEN CEILING(CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) / 8)
WHEN c.duration LIKE '%day%' THEN CEILING(CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) / 60)
ELSE 3
END
) MONTH
),
CURRENT_DATE
)
WHEN e.payment_plan = 'six_month' THEN
DATEDIFF(
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date) FROM payments
WHERE user_id = e.user_id AND course_id = e.course_id AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 6 MONTH
),
CURRENT_DATE
)
ELSE 0
END as days_until_due
FROM
enrollments e
JOIN
courses c ON e.course_id = c.id
WHERE
e.user_id = ? AND
e.status = 'active' AND
(CASE WHEN c.discount_price > 0 THEN c.discount_price ELSE c.price END) > IFNULL(
(SELECT SUM(amount) FROM payments
WHERE user_id = e.user_id AND course_id = e.course_id AND status IN ('completed', 'verified')),
0
)
";
$stmt = $conn->prepare($due_payments_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$due_payments_result = $stmt->get_result();
$due_payments = [];
$total_due = 0;
$upcoming_dues = [];
while ($due = $due_payments_result->fetch_assoc()) {
$due_payments[] = $due;
$total_due += $due['remaining'];
$upcoming_dues[] = [
'course_id' => $due['course_id'] ?? 0,
'course_title' => $due['course_title'] ?? 'Unknown Course',
'remaining' => $due['remaining'] ?? 0,
'days_until_due' => $due['days_until_due'] ?? 0
];
}
// Sort upcoming dues by closest date first
usort($upcoming_dues, function($a, $b) {
return $a['days_until_due'] - $b['days_until_due'];
});
// Get attendance percentage
$attendance_query = "
SELECT
COALESCE(
(SELECT
(SUM(CASE WHEN status = 'present' THEN 1 ELSE 0 END) * 100.0 /
NULLIF(COUNT(*), 0))
FROM attendance
WHERE student_id = ?),
0) as attendance_percentage
";
try {
// First check if attendance table exists
$table_check = $conn->query("SHOW TABLES LIKE 'attendance'");
if ($table_check && $table_check->num_rows > 0) {
$stmt = $conn->prepare($attendance_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$attendance_result = $stmt->get_result();
$attendance_data = $attendance_result->fetch_assoc();
$attendance_percentage = $attendance_data ? round($attendance_data['attendance_percentage']) : 0;
// Ensure attendance percentage is within valid range
$attendance_percentage = max(0, min(100, $attendance_percentage));
error_log("Dashboard - Attendance percentage: $attendance_percentage");
} else {
error_log("Dashboard - Attendance table doesn't exist");
$attendance_percentage = 0;
}
} catch (Exception $e) {
error_log("Attendance calculation error: " . $e->getMessage());
$attendance_percentage = 0;
}
} catch (Exception $e) {
// Log the error and show a user-friendly message
error_log("Dashboard statistics error: " . $e->getMessage());
// Initialize empty values if there's an error
$enrolled_courses_count = 0;
$completed_courses_count = 0;
$active_courses_result = false;
$activities_result = false;
$applications_result = false;
$certificates_count = 0;
$due_payments = [];
$total_due = 0;
$upcoming_dues = [];
$attendance_percentage = 0;
}
// Include header
include_once 'includes/header.php';
?>
<!-- Begin Page Content -->
<div class="container-fluid">
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">Student Dashboard</h1>
<a href="profile.php" class="d-none d-sm-inline-block btn btn-primary shadow-sm">
<i class="fas fa-user fa-sm text-white-50"></i> View Profile
</a>
</div>
<?php if (isset($db_error)): ?>
<div class="alert alert-danger">
<strong>Error:</strong> <?php echo $db_error; ?>
</div>
<?php endif; ?>
<?php if ($enrolled_courses_count == 0): ?>
<div class="alert alert-info">
<strong>Welcome!</strong> It seems you haven't enrolled in any courses yet.
<a href="../courses.php" class="alert-link">Browse our courses</a> to get started with your learning journey.
</div>
<?php endif; ?>
<!-- Statistics Cards -->
<div class="row">
<!-- Enrolled Courses Card -->
<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">
Enrolled Courses</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo number_format($enrolled_courses_count); ?></div>
</div>
<div class="col-auto">
<i class="fas fa-book fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Completed Courses Card -->
<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">
Completed Courses</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo number_format($completed_courses_count); ?></div>
</div>
<div class="col-auto">
<i class="fas fa-graduation-cap fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Attendance Percentage Card -->
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-info 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-info text-uppercase mb-1">
Attendance Percentage</div>
<div class="row no-gutters align-items-center">
<div class="col-auto">
<div class="h5 mb-0 mr-3 font-weight-bold text-gray-800">
<?php echo $attendance_percentage; ?>%
</div>
</div>
<div class="col">
<div class="progress progress-sm mr-2">
<div class="progress-bar bg-info" role="progressbar"
style="width: <?php echo $attendance_percentage; ?>%"
aria-valuenow="<?php echo $attendance_percentage; ?>"
aria-valuemin="0"
aria-valuemax="100"></div>
</div>
</div>
</div>
</div>
<div class="col-auto">
<i class="fas fa-calendar-check fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Certificates Card -->
<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">
Certificates Earned</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo number_format($certificates_count); ?></div>
</div>
<div class="col-auto">
<i class="fas fa-certificate fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Content Row -->
<div class="row">
<!-- Payment Overview -->
<div class="col-lg-12 mb-4">
<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 Overview</h6>
<a href="payments.php#payment-options" class="btn btn-sm btn-primary shadow-sm">
<i class="fas fa-credit-card fa-sm text-white-50"></i> Make Payment
</a>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h4 class="small font-weight-bold">Payment Progress <span class="float-right">
<?php
// Calculate overall payment progress
$total_course_fees = 0;
$total_paid_amount = 0;
// Get total fees and paid amount data for all enrollments
$payment_data_query = "
SELECT
e.course_id,
c.price,
c.discount_price,
e.status,
COALESCE(
(SELECT SUM(amount)
FROM payments
WHERE user_id = ?
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
0
) as paid_amount
FROM enrollments e
JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ? AND e.status = 'active'
";
try {
$stmt = $conn->prepare($payment_data_query);
$stmt->bind_param("ii", $user_id, $user_id);
$stmt->execute();
$payment_data_result = $stmt->get_result();
while ($payment_data = $payment_data_result->fetch_assoc()) {
// Calculate course price (using discount if available)
$course_price = $payment_data['discount_price'] > 0 && $payment_data['discount_price'] < $payment_data['price']
? $payment_data['discount_price'] : $payment_data['price'];
$total_course_fees += $course_price;
$total_paid_amount += $payment_data['paid_amount'];
}
// Calculate payment progress
$payment_progress = $total_course_fees > 0 ?
min(100, round(($total_paid_amount / $total_course_fees) * 100)) : 100;
} catch (Exception $e) {
error_log("Payment progress calculation error: " . $e->getMessage());
$payment_progress = 0;
}
echo $payment_progress . '%';
?>
</span></h4>
<div class="progress mb-4">
<div class="progress-bar <?php echo $payment_progress < 50 ? '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="row">
<div class="col-md-6">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
Total Due Amount
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
₹<?php echo number_format(max(0, $total_course_fees - $total_paid_amount), 2); ?>
</div>
</div>
<div class="col-md-6">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">
Next Payment Due
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
<?php
// Get the next due payment date
$next_payment_query = "
SELECT
MIN(DATEDIFF(
CASE
WHEN e.payment_plan = 'monthly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 1 MONTH
)
WHEN e.payment_plan = 'six_month' OR e.payment_plan = 'half_duration' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 6 MONTH
)
WHEN e.payment_plan = 'quarterly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 3 MONTH
)
ELSE e.enrollment_date
END,
CURRENT_DATE
)) as days_until_due,
c.title as course_title
FROM enrollments e
JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ?
AND e.status = 'active'
AND (CASE WHEN c.discount_price > 0 AND c.discount_price < c.price THEN c.discount_price ELSE c.price END) >
COALESCE(
(SELECT SUM(amount)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
0
)
";
try {
$stmt = $conn->prepare($next_payment_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$next_payment_result = $stmt->get_result()->fetch_assoc();
if ($next_payment_result && $next_payment_result['days_until_due'] !== null) {
$days_until_due = $next_payment_result['days_until_due'];
if ($days_until_due <= 0) {
echo '<span class="text-danger">Overdue</span>';
} elseif ($days_until_due == 1) {
echo '<span class="text-warning">Tomorrow</span>';
} elseif ($days_until_due <= 7) {
echo '<span class="text-warning">In ' . $days_until_due . ' days</span>';
} else {
echo '<span class="text-success">In ' . $days_until_due . ' days</span>';
}
} else {
echo '<span class="text-success">No payments due</span>';
}
} catch (Exception $e) {
error_log("Next payment calculation error: " . $e->getMessage());
echo '<span class="text-muted">Unavailable</span>';
}
?>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<?php if (!empty($upcoming_dues)): ?>
<h4 class="small font-weight-bold">Upcoming Payments</h4>
<div class="list-group">
<?php
// Get upcoming payments with installment information
$upcoming_payments_query = "
SELECT
e.course_id,
c.title as course_title,
c.image as course_image,
c.duration,
e.payment_plan,
(CASE WHEN c.discount_price > 0 AND c.discount_price < c.price THEN c.discount_price ELSE c.price END) as course_price,
COALESCE(
(SELECT SUM(amount)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
0
) as paid_amount,
CASE
WHEN e.payment_plan = 'monthly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 1 MONTH
)
WHEN e.payment_plan = 'half_duration' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL CEILING(
CASE
WHEN c.duration LIKE '%month%' THEN CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) / 2
WHEN c.duration LIKE '%year%' THEN CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) * 6
WHEN c.duration LIKE '%week%' THEN CEILING(CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) / 8)
WHEN c.duration LIKE '%day%' THEN CEILING(CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) / 60)
ELSE 3
END
) MONTH
)
WHEN e.payment_plan = 'six_month' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 6 MONTH
)
WHEN e.payment_plan = 'quarterly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 3 MONTH
)
ELSE e.enrollment_date
END as next_payment_date,
DATEDIFF(
CASE
WHEN e.payment_plan = 'monthly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 1 MONTH
)
WHEN e.payment_plan = 'half_duration' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL CEILING(
CASE
WHEN c.duration LIKE '%month%' THEN CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) / 2
WHEN c.duration LIKE '%year%' THEN CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) * 6
WHEN c.duration LIKE '%week%' THEN CEILING(CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) / 8)
WHEN c.duration LIKE '%day%' THEN CEILING(CAST(SUBSTRING_INDEX(c.duration, ' ', 1) AS UNSIGNED) / 60)
ELSE 3
END
) MONTH
)
WHEN e.payment_plan = 'six_month' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 6 MONTH
)
WHEN e.payment_plan = 'quarterly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 3 MONTH
)
ELSE e.enrollment_date
END,
CURRENT_DATE
) as days_until_due
FROM enrollments e
JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ?
AND e.status = 'active'
AND (CASE WHEN c.discount_price > 0 AND c.discount_price < c.price THEN c.discount_price ELSE c.price END) >
COALESCE(
(SELECT SUM(amount)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
0
)
ORDER BY days_until_due
LIMIT 3
";
try {
$stmt = $conn->prepare($upcoming_payments_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$upcoming_payments_result = $stmt->get_result();
$displayed = 0;
if ($upcoming_payments_result->num_rows > 0) {
while ($payment = $upcoming_payments_result->fetch_assoc()) {
// Calculate installment details based on payment plan and course duration
$course_price = $payment['course_price'];
$installment_amount = 0;
$total_installments = 1;
// Parse course duration to get value and unit
$duration_parts = explode(' ', $payment['duration'] ?? '3 months');
$duration_value = isset($duration_parts[0]) ? intval($duration_parts[0]) : 3; // Default to 3 if not specified
$duration_unit = isset($duration_parts[1]) ? strtolower($duration_parts[1]) : 'months'; // Default to months
// Normalize to months for calculation
$duration_in_months = $duration_value;
if ($duration_unit === 'days') {
$duration_in_months = max(1, ceil($duration_value / 30)); // Convert days to months (minimum 1 month)
} else if ($duration_unit === 'weeks') {
$duration_in_months = max(1, ceil($duration_value / 4)); // Convert weeks to months (minimum 1 month)
} else if ($duration_unit === 'years') {
$duration_in_months = $duration_value * 12; // Convert years to months
}
if ($payment['payment_plan'] === 'monthly') {
$total_installments = $duration_in_months;
$installment_amount = round($course_price / $duration_in_months);
} else if ($payment['payment_plan'] === 'half_duration') {
$total_installments = max(1, ceil($duration_in_months / 2));
$installment_amount = round($course_price / $total_installments);
} else if ($payment['payment_plan'] === 'six_month') {
$total_installments = max(1, ceil($duration_in_months / 6) * 2);
$installment_amount = round($course_price / $total_installments);
} else {
$installment_amount = $course_price;
}
// Calculate current installment number
$installment_number = floor($payment['paid_amount'] / $installment_amount) + 1;
if ($installment_number > $total_installments) {
$installment_number = $total_installments;
}
// Calculate amount due (remaining for current installment)
$amount_due = min($course_price - $payment['paid_amount'], $installment_amount);
// Format payment date
$due_date = new DateTime($payment['next_payment_date']);
$today = new DateTime();
$days_remaining = $today->diff($due_date)->days;
$date_class = $days_remaining <= 7 ? 'text-danger' : 'text-primary';
?>
<a href="payments.php?course_id=<?php echo $payment['course_id']; ?>&amount=<?php echo $amount_due; ?>#payment-options"
class="list-group-item list-group-item-action flex-column align-items-start">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1"><?php echo htmlspecialchars($payment['course_title'] ?? 'Unknown Course'); ?></h5>
<small class="<?php echo $payment['days_until_due'] <= 0 ? 'text-danger' :
($payment['days_until_due'] <= 7 ? 'text-warning' : 'text-primary'); ?>">
<?php
if ($payment['days_until_due'] <= 0) {
echo '<span class="badge badge-danger">Overdue</span>';
} elseif ($payment['days_until_due'] == 1) {
echo '<span class="badge badge-warning">Tomorrow</span>';
} else {
echo '<span class="badge badge-info">In ' . $payment['days_until_due'] . ' days</span>';
}
?>
</small>
</div>
<div class="d-flex justify-content-between align-items-center mt-2">
<p class="mb-1">Amount Due: ₹<?php echo number_format($amount_due, 2); ?></p>
<small>Installment <?php echo $installment_number; ?> of <?php echo $total_installments; ?></small>
</div>
<div class="progress mt-1" style="height: 5px;">
<div class="progress-bar" role="progressbar"
style="width: <?php echo ($installment_number / $total_installments) * 100; ?>%"
aria-valuenow="<?php echo ($installment_number / $total_installments) * 100; ?>"
aria-valuemin="0"
aria-valuemax="100">
</div>
</div>
</a>
<?php
}
} else {
?>
<div class="list-group-item">
<p class="mb-0 text-center">No upcoming payments found.</p>
</div>
<?php
}
// Check if there are more payments
$total_payments_query = "
SELECT COUNT(*) as total
FROM enrollments e
JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ?
AND e.status = 'active'
AND (CASE WHEN c.discount_price > 0 AND c.discount_price < c.price THEN c.discount_price ELSE c.price END) >
COALESCE(
(SELECT SUM(amount)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
0
)
";
$stmt = $conn->prepare($total_payments_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$total_payments_result = $stmt->get_result()->fetch_assoc();
if ($total_payments_result['total'] > 3) {
?>
<div class="list-group-item text-center">
<a href="payments.php" class="text-primary">View all payments</a>
</div>
<?php
}
} catch (Exception $e) {
error_log("Upcoming payments calculation error: " . $e->getMessage());
?>
<div class="list-group-item">
<p class="mb-0 text-center text-danger">Error loading payment information.</p>
</div>
<?php
}
?>
</div>
<?php else: ?>
<div class="alert alert-success">
<i class="fas fa-check-circle mr-2"></i> You don't have any pending payments at this time.
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
<!-- Application Status Column -->
<div class="col-lg-6 mb-4">
<!-- Application Status Card -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">My Application Status</h6>
</div>
<div class="card-body">
<?php if ($applications_result && $applications_result->num_rows > 0): ?>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Course</th>
<th>Applied On</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php while ($app = $applications_result->fetch_assoc()): ?>
<tr>
<td><?php echo htmlspecialchars($app['course_title'] ?? 'Unknown Course'); ?></td>
<td><?php echo date('M d, Y', strtotime($app['application_date'])); ?></td>
<td>
<span class="badge badge-<?php
if ($app['status'] === 'pending') {
echo 'warning';
} elseif ($app['status'] === 'approved') {
echo 'success';
} elseif ($app['status'] === 'documents_pending') {
echo 'info';
} else {
echo 'primary';
}
?>">
<?php
if ($app['status'] === 'pending') {
echo 'Pending Review';
} elseif ($app['status'] === 'approved') {
echo 'Approved';
} elseif ($app['status'] === 'documents_pending') {
echo 'Documents Pending';
} elseif ($app['status'] === 'payment_pending') {
echo 'Payment Pending';
} else {
echo ucfirst($app['status']);
}
?>
</span>
</td>
<td>
<?php if ($app['status'] === 'documents_pending'): ?>
<a href="documents.php" class="btn btn-sm btn-info">
<i class="fas fa-file-alt"></i> Manage Docs
</a>
<?php elseif ($app['status'] === 'payment_pending'): ?>
<a href="payments.php?course_id=<?php echo $app['course_id']; ?>#payment-options" class="btn btn-sm btn-success">
<i class="fas fa-credit-card"></i> Pay Now
</a>
<?php else: ?>
<a href="documents.php" class="btn btn-sm btn-primary">
<i class="fas fa-eye"></i> View
</a>
<?php endif; ?>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="alert alert-info">
<p class="mb-0">You don't have any pending applications. <a href="../courses.php">Apply for a course</a> to get started!</p>
</div>
<?php endif; ?>
</div>
</div>
</div>
<!-- Active Courses Column -->
<div class="col-lg-6 mb-4">
<!-- Active Courses Card -->
<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">My Active Courses</h6>
<a href="my_courses.php" class="btn btn-sm btn-light shadow-sm">View All</a>
</div>
<div class="card-body">
<?php if ($active_courses_result && $active_courses_result->num_rows > 0): ?>
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Course</th>
<th>Enrollment Date</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php while ($course = $active_courses_result->fetch_assoc()): ?>
<tr>
<td><?php echo htmlspecialchars($course['title']); ?></td>
<td>
<?php
// Get enrollment date
$enrollment_query = "SELECT enrollment_date FROM enrollments WHERE user_id = ? AND course_id = ? LIMIT 1";
$stmt = $conn->prepare($enrollment_query);
$stmt->bind_param("ii", $user_id, $course['id']);
$stmt->execute();
$enrollment = $stmt->get_result()->fetch_assoc();
echo $enrollment ? date('M d, Y', strtotime($enrollment['enrollment_date'])) : 'N/A';
?>
</td>
<td>
<span class="badge badge-success">Active</span>
</td>
<td>
<a href="course_details.php?id=<?php echo $course['id']; ?>" class="btn btn-sm btn-info">
<i class="fas fa-eye"></i> View
</a>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="alert alert-info">
<p class="mb-0">You are not enrolled in any courses yet. <a href="../courses.php">Browse courses</a> to get started!</p>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
<!-- Due Payment Notifications -->
<?php
// Get all upcoming payments
$all_payments_query = "
SELECT
e.course_id,
c.title as course_title,
e.payment_plan,
(CASE WHEN c.discount_price > 0 AND c.discount_price < c.price THEN c.discount_price ELSE c.price END) as course_price,
COALESCE(
(SELECT SUM(amount)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
0
) as paid_amount,
CASE
WHEN e.payment_plan = 'monthly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 1 MONTH
)
WHEN e.payment_plan = 'six_month' OR e.payment_plan = 'half_duration' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 6 MONTH
)
WHEN e.payment_plan = 'quarterly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 3 MONTH
)
ELSE e.enrollment_date
END as next_payment_date,
DATEDIFF(
CASE
WHEN e.payment_plan = 'monthly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 1 MONTH
)
WHEN e.payment_plan = 'six_month' OR e.payment_plan = 'half_duration' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 6 MONTH
)
WHEN e.payment_plan = 'quarterly' THEN
DATE_ADD(
IFNULL(
(SELECT MAX(payment_date)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
e.enrollment_date
),
INTERVAL 3 MONTH
)
ELSE e.enrollment_date
END,
CURRENT_DATE
) as days_until_due
FROM enrollments e
JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ?
AND e.status = 'active'
AND (CASE WHEN c.discount_price > 0 AND c.discount_price < c.price THEN c.discount_price ELSE c.price END) >
COALESCE(
(SELECT SUM(amount)
FROM payments
WHERE user_id = e.user_id
AND course_id = e.course_id
AND status IN ('completed', 'verified')),
0
)
ORDER BY days_until_due
";
try {
$stmt = $conn->prepare($all_payments_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$all_payments_result = $stmt->get_result();
if ($all_payments_result->num_rows > 0):
?>
<div class="container-fluid mb-4">
<div class="card shadow border-left-warning">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-warning">
<i class="fas fa-exclamation-triangle mr-2"></i>Payment Due Reminder
</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Course</th>
<th>Amount Due</th>
<th>Due Date</th>
<th>Status</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php
while ($payment = $all_payments_result->fetch_assoc()):
// Calculate installment details based on payment plan
$course_price = $payment['course_price'];
$installment_amount = 0;
$total_installments = 1;
if ($payment['payment_plan'] === 'monthly') {
$total_installments = 12;
$installment_amount = round($course_price / 12);
} else if ($payment['payment_plan'] === 'six_month' || $payment['payment_plan'] === 'half_duration') {
$total_installments = 6;
$installment_amount = round($course_price / 6);
} else if ($payment['payment_plan'] === 'quarterly') {
$total_installments = 4;
$installment_amount = round($course_price / 4);
} else {
$installment_amount = $course_price;
}
// Calculate current installment number
$installment_number = floor($payment['paid_amount'] / $installment_amount) + 1;
if ($installment_number > $total_installments) {
$installment_number = $total_installments;
}
// Calculate amount due (remaining for current installment)
$amount_due = min($course_price - $payment['paid_amount'], $installment_amount);
// Format due date
$payment_date = new DateTime($payment['next_payment_date']);
$formatted_date = $payment_date->format('M d, Y');
?>
<tr>
<td><?php echo htmlspecialchars($payment['course_title'] ?? 'Unknown Course'); ?></td>
<td>₹<?php echo number_format($amount_due, 2); ?></td>
<td>
<?php if ($payment['days_until_due'] <= 0): ?>
<span class="text-danger font-weight-bold">Overdue</span>
<?php elseif ($payment['days_until_due'] <= 7): ?>
<span class="text-warning font-weight-bold">
<?php echo $payment['days_until_due'] == 1 ? 'Tomorrow' : 'In ' . $payment['days_until_due'] . ' days'; ?>
</span>
<?php else: ?>
<span class="text-primary">
<?php echo $formatted_date; ?>
</span>
<?php endif; ?>
</td>
<td>
<?php if ($payment['days_until_due'] <= 0): ?>
<span class="badge badge-danger">Overdue</span>
<?php elseif ($payment['days_until_due'] <= 7): ?>
<span class="badge badge-warning">Due Soon</span>
<?php else: ?>
<span class="badge badge-info">Upcoming</span>
<?php endif; ?>
</td>
<td>
<a href="payments.php?course_id=<?php echo $payment['course_id']; ?>&amount=<?php echo $amount_due; ?>#payment-options" class="btn btn-sm btn-primary">
<i class="fas fa-credit-card mr-1"></i> Pay Now
</a>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<div class="mt-3 text-right">
<a href="payments.php" class="btn btn-outline-primary">
<i class="fas fa-list mr-1"></i> View All Payments
</a>
</div>
</div>
</div>
</div>
<?php
endif;
} catch (Exception $e) {
error_log("Due payments calculation error: " . $e->getMessage());
}
?>
<section class="container-fluid">
<div class="row">
<div class="col-lg-12">
<!-- Enrollment Verification Tokens -->
<div class="col-lg-12 mb-4">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary"><i class="fas fa-key mr-2"></i> Enrollment Verification Tokens</h6>
</div>
<div class="card-body">
<p class="text-muted mb-3">Present these tokens at the institute to start your classes.</p>
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Course</th>
<th>Enrollment Date</th>
<th>Status</th>
<th>Verification Token</th>
</tr>
</thead>
<tbody>
<?php
// Get all enrollments with verification tokens
$tokens_query = "SELECT e.*, c.title as course_title, c.image
FROM enrollments e
JOIN courses c ON e.course_id = c.id
WHERE e.user_id = ?
ORDER BY e.enrollment_date DESC";
$stmt = $conn->prepare($tokens_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$tokens_result = $stmt->get_result();
if ($tokens_result && $tokens_result->num_rows > 0):
while ($token = $tokens_result->fetch_assoc()):
?>
<tr>
<td>
<div class="d-flex align-items-center">
<img src="<?php echo $token['image'] ? '../' . $token['image'] : '../assets/img/course-placeholder.jpg'; ?>"
class="rounded mr-2" alt="Course Image" width="40" height="40">
<div>
<?php echo htmlspecialchars($token['course_title']); ?>
</div>
</div>
</td>
<td><?php echo date('M d, Y', strtotime($token['enrollment_date'])); ?></td>
<td>
<span class="badge badge-<?php echo ($token['status'] === 'active') ? 'success' :
(($token['status'] === 'completed') ? 'primary' : 'warning'); ?>">
<?php echo ucfirst($token['status']); ?>
</span>
</td>
<td>
<div class="input-group">
<input type="text" class="form-control bg-light" value="<?php echo $token['verification_token']; ?>" readonly>
<div class="input-group-append">
<button class="btn btn-outline-primary copy-token-btn" type="button" data-token="<?php echo $token['verification_token']; ?>">
<i class="fas fa-copy"></i>
</button>
</div>
</div>
</td>
</tr>
<?php
endwhile;
else:
?>
<tr>
<td colspan="4" class="text-center">No enrollment tokens found.</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Load application status
loadApplicationStatus();
// Copy verification token to clipboard
const copyButtons = document.querySelectorAll('.copy-token-btn');
copyButtons.forEach(button => {
button.addEventListener('click', function() {
const token = this.getAttribute('data-token');
navigator.clipboard.writeText(token).then(() => {
// Change button text temporarily
const originalHTML = this.innerHTML;
this.innerHTML = '<i class="fas fa-check"></i>';
setTimeout(() => {
this.innerHTML = originalHTML;
}, 1500);
}).catch(err => {
console.error('Could not copy text: ', err);
});
});
});
});
function loadApplicationStatus() {
$.ajax({
url: 'ajax/check_application_status.php',
type: 'GET',
success: function(response) {
try {
const result = typeof response === 'string' ? JSON.parse(response) : response;
if (result.success) {
let html = '';
if (result.has_application) {
// Application status
const app = result.application;
const docs = result.documents;
// Determine badge color
let badgeClass = 'badge-secondary';
switch(app.status) {
case 'submitted':
badgeClass = 'badge-info';
break;
case 'document_verification':
badgeClass = 'badge-info';
break;
case 'payment_pending':
badgeClass = 'badge-warning';
break;
case 'enrollment_pending':
badgeClass = 'badge-warning';
break;
case 'enrolled':
badgeClass = 'badge-success';
break;
case 'completed':
badgeClass = 'badge-primary';
break;
case 'rejected':
badgeClass = 'badge-danger';
break;
}
html += '<div class="card border-left-primary shadow h-100 mb-4">';
html += '<div class="card-body">';
html += '<div class="d-flex justify-content-between align-items-center mb-3">';
html += '<h5 class="card-title mb-0">Application Status</h5>';
html += `<span class="badge ${badgeClass}">${app.status.replace('_', ' ').toUpperCase()}</span>`;
html += '</div>';
html += `<p class="card-text">${app.status_message}</p>`;
// Document verification progress
if (docs) {
html += '<div class="mt-3">';
html += '<h6>Document Verification</h6>';
const docProgress = docs.verified_documents > 0 ? Math.round((docs.verified_documents / docs.total_documents) * 100) : 0;
html += '<div class="progress mb-2">';
html += `<div class="progress-bar bg-success" role="progressbar" style="width: ${docProgress}%" `;
html += `aria-valuenow="${docProgress}" aria-valuemin="0" aria-valuemax="100">${docProgress}%</div>`;
html += '</div>';
html += '<div class="small text-muted">';
html += `Verified: ${docs.verified_documents} | Pending: ${docs.pending_documents} | Rejected: ${docs.rejected_documents}`;
html += '</div>';
if (docs.pending_documents > 0 || docs.total_documents < 4) {
html += '<a href="documents.php" class="btn btn-sm btn-primary mt-2">';
html += '<i class="fas fa-file-alt mr-1"></i> Manage Documents';
html += '</a>';
}
}
// Payment information if available
if (result.payment && app.status === 'payment_pending') {
html += '<div class="mt-3">';
html += '<h6>Payment</h6>';
html += '<a href="payments.php" class="btn btn-sm btn-success mt-2">';
html += '<i class="fas fa-credit-card mr-1"></i> Make Payment';
html += '</a>';
} else if (result.payment && result.payment.status === 'completed') {
html += '<div class="mt-3">';
html += '<h6>Payment</h6>';
html += '<div class="alert alert-success mb-0"><i class="fas fa-check-circle mr-1"></i> Payment complete</div>';
}
// Next steps
html += '<div class="mt-4">';
html += '<h6>Next Steps</h6>';
html += `<p class="mb-0">${app.next_step}</p>`;
html += '</div>';
html += '</div>';
html += '</div>';
} else {
html += '<div class="alert alert-info mb-0">';
html += '<p class="mb-0">You have not submitted any applications yet. ';
html += '<a href="../courses.php">Browse courses</a> to apply!</p>';
html += '</div>';
}
$('#applicationStatus').html(html);
} else {
$('#applicationStatus').html(`<div class="alert alert-danger mb-0">${result.message}</div>`);
}
} catch (e) {
console.error(e);
$('#applicationStatus').html('<div class="alert alert-danger mb-0">An error occurred while loading application status.</div>');
}
},
error: function() {
$('#applicationStatus').html('<div class="alert alert-danger mb-0">Failed to connect to the server.</div>');
}
});
}
</script>
<?php
// Include footer
include_once 'includes/footer.php';
?>