<?php
// Enable error reporting for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Start session
session_start();
// Include database configuration
require_once '../admin/database/db_config.php';
// If user is not logged in, redirect to login page
if (!isset($_SESSION['user_id'])) {
header('Location: ../login.php');
exit;
}
// Get application ID from URL parameter
$application_id = isset($_GET['application_id']) ? intval($_GET['application_id']) : 0;
// If application ID is not provided, redirect to student dashboard
if ($application_id <= 0) {
header('Location: ../student/index.php');
exit;
}
// Get user ID
$user_id = $_SESSION['user_id'];
// Get user details
$user_query = "SELECT * FROM users WHERE id = ?";
$stmt = $conn->prepare($user_query);
$stmt->bind_param("i", $user_id);
$stmt->execute();
$user_result = $stmt->get_result();
$user = $user_result->fetch_assoc();
// Get application details
$application_query = "SELECT ea.*, c.title as course_title, c.image as course_image,
c.price, c.discount_price, c.duration, c.level,
u.first_name as instructor_first_name, u.last_name as instructor_last_name,
e.verification_token, e.enrollment_number
FROM enrollment_applications ea
JOIN courses c ON ea.course_id = c.id
LEFT JOIN users u ON c.instructor_id = u.id
LEFT JOIN enrollments e ON e.course_id = c.id AND e.user_id = ea.user_id
WHERE ea.id = ? AND ea.user_id = ? AND ea.status = 'completed'";
$stmt = $conn->prepare($application_query);
$stmt->bind_param("ii", $application_id, $user_id);
$stmt->execute();
$application_result = $stmt->get_result();
$application = $application_result->fetch_assoc();
// If application not found, redirect to student dashboard
if (!$application) {
header('Location: ../student/index.php');
exit;
}
// Get payment details with payment plan
$payment_query = "SELECT p.*, e.payment_plan FROM payments p
LEFT JOIN enrollments e ON e.course_id = ? AND e.user_id = ?
WHERE p.user_id = ? AND p.course_id = ?
ORDER BY p.payment_date DESC LIMIT 1";
$stmt = $conn->prepare($payment_query);
$stmt->bind_param("iiii", $application['course_id'], $user_id, $user_id, $application['course_id']);
$stmt->execute();
$payment_result = $stmt->get_result();
$payment = $payment_result->fetch_assoc();
// Calculate course duration in months for payment plan calculation
$duration_parts = explode(' ', $application['duration']);
$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
}
// Calculate half duration in months
$half_duration_months = max(1, ceil($duration_in_months / 2));
// Get school information for receipt
$school = [
'site_name' => 'Popular Computer Institute',
'site_address' => 'Bhimpura No. 1, Ballia, Uttar Pradesh 221716, India',
'contact_phone' => '+91 9984878446',
'contact_email' => '[email protected]',
'site_logo' => 'assets/img/logo.png',
'site_url' => 'https://pcib.in'
];
try {
$site_settings_query = "SELECT * FROM site_settings WHERE setting_key IN ('site_name', 'site_address', 'contact_phone', 'contact_email', 'site_logo', 'site_url')";
$site_settings_result = $conn->query($site_settings_query);
if ($site_settings_result && $site_settings_result->num_rows > 0) {
while($row = $site_settings_result->fetch_assoc()) {
// Map site_settings keys to our school array keys
$key_mapping = [
'site_name' => 'site_name',
'site_address' => 'site_address',
'contact_phone' => 'contact_phone',
'contact_email' => 'contact_email',
'site_logo' => 'site_logo',
'site_url' => 'site_url'
];
if (isset($key_mapping[$row['setting_key']])) {
$school[$key_mapping[$row['setting_key']]] = $row['setting_value'];
}
}
}
} catch (Exception $e) {
// Silently handle the error - default values already set
error_log("Settings table error: " . $e->getMessage());
}
// Remove header include
// include_once '../includes/header.php';
// Calculate the final price
$price = $application['discount_price'] > 0 && $application['discount_price'] < $application['price']
? $application['discount_price']
: $application['price'];
// Get payment amount based on payment plan
$payment_amount = $price;
$payment_plan = $payment['payment_plan'] ?? 'full';
// Calculate payment plan details based on actual course duration
if ($payment_plan === 'monthly') {
// Calculate actual number of monthly payments based on course duration
$total_installments = $duration_in_months;
$payment_amount = round($price / $total_installments, 2);
$payment_plan_display = "Monthly Plan ({$total_installments} payments)";
$next_payment_date = date('d M Y', strtotime('+1 month'));
} else if ($payment_plan === 'half_duration' || $payment_plan === 'six_month') {
// For half duration or six_month plan, use half the duration or 6, whichever is applicable
$total_installments = $half_duration_months;
$payment_amount = round($price / $total_installments, 2);
$payment_plan_display = "Installment Plan ({$total_installments} payments)";
$next_payment_date = date('d M Y', strtotime('+2 months'));
} else {
// For full payment
$total_installments = 1;
$payment_amount = $price;
$payment_plan_display = "Full Payment (One-time)";
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Enrollment Success - <?php echo htmlspecialchars($application['course_title']); ?></title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<!-- Modern UI CSS -->
<link rel="stylesheet" href="css/modern-ui.css">
<style>
body {
font-family: 'Poppins', sans-serif;
background-color: #f8f9fa;
min-height: 100vh;
overflow-x: hidden;
}
.logo-container {
text-align: center;
margin: 20px 0;
}
.logo-container img {
max-height: 60px;
}
.logo-container h2 {
color: white;
margin: 10px 0;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
.dashboard-link {
position: absolute;
top: 20px;
right: 20px;
color: white;
text-decoration: none;
z-index: 100;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
padding: 8px 15px;
border-radius: 50px;
font-weight: 500;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
border: 1px solid rgba(255, 255, 255, 0.1);
}
.dashboard-link:hover {
background: rgba(255, 255, 255, 0.2);
transform: translateY(-2px);
color: white;
}
.step-indicator {
display: flex;
justify-content: center;
margin-bottom: 30px;
}
.step {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
z-index: 1;
margin: 0 20px;
}
.step-number {
width: 36px;
height: 36px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.2);
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
margin-bottom: 8px;
color: white;
border: 2px solid rgba(255, 255, 255, 0.3);
}
.step.active .step-number {
background: #4e73df;
border-color: white;
}
.step.completed .step-number {
background: #1cc88a;
border-color: white;
}
.step-title {
font-size: 0.8rem;
color: white;
text-align: center;
}
.step-connector {
position: absolute;
top: 18px;
height: 2px;
background: rgba(255, 255, 255, 0.2);
width: 100px;
left: -60px;
z-index: -1;
}
.step.completed .step-connector {
background: #1cc88a;
}
.step:first-child .step-connector {
display: none;
}
/* Receipt Styling */
.receipt-container {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0,0,0,0.1);
width: 100%;
max-width: 100%;
margin: 0 auto;
color: #333;
font-size: 14px;
position: relative;
z-index: 1;
}
.receipt-logo {
max-height: 80px;
max-width: 100%;
}
.receipt-title {
color: #333;
font-weight: 600;
}
.receipt-subtitle {
color: #666;
}
.receipt-footer {
color: #666;
font-size: 12px;
margin-top: 15px;
padding-top: 10px;
border-top: 1px solid #eee;
}
#receiptFooter {
display: none;
}
/* Print Optimizations */
@media print {
.animated-bg, .step-indicator, .dashboard-link, .no-print, .modal-footer, .btn-close {
display: none !important;
}
body {
background-color: white !important;
margin: 0 !important;
padding: 0 !important;
}
.glass-card {
box-shadow: none !important;
border: none !important;
background: white !important;
}
.text-white, .text-white-50 {
color: #333 !important;
}
.modal {
position: absolute !important;
left: 0 !important;
top: 0 !important;
margin: 0 !important;
padding: 0 !important;
overflow: visible !important;
background: white !important;
}
.modal-dialog {
max-width: 100% !important;
width: 100% !important;
margin: 0 !important;
transform: none !important;
}
.modal-content {
border: none !important;
box-shadow: none !important;
background: white !important;
}
.receipt-container {
box-shadow: none !important;
margin: 0 auto !important;
/* padding: 25px !important; */
width: 100% !important;
max-width: 100% !important;
font-size: 12px !important;
page-break-inside: avoid !important;
}
.card {
border: 1px solid #ddd !important;
margin-bottom: 15px !important;
page-break-inside: avoid !important;
}
.card-header {
background-color: #f5f5f5 !important;
padding: 8px 10px !important;
}
.card-body {
padding: 10px !important;
}
/* Reduce margins and paddings */
.row {
margin-left: -5px !important;
margin-right: -5px !important;
}
/* Font size optimization */
h3 { font-size: 18px !important; }
h4 { font-size: 16px !important; }
h5, h6 { font-size: 14px !important; }
p, .card-body p { font-size: 12px !important; margin-bottom: 6px !important; }
.table th, .table td {
padding: 6px !important;
font-size: 12px !important;
}
/* Ensure page breaks are controlled */
.receipt-header {
margin-top: 10px !important;
page-break-after: avoid !important;
}
.receipt-body {
page-break-before: avoid !important;
page-break-after: avoid !important;
}
.receipt-footer {
page-break-before: avoid !important;
}
@page {
margin: 10mm 20mm; /* Explicit page margins */
size: A4 portrait;
}
}
</style>
</head>
<body>
<!-- Dashboard Link -->
<a href="../student/index.php" class="dashboard-link">
<i class="fas fa-tachometer-alt me-2"></i> Go to Dashboard
</a>
<!-- Logo Container -->
<div class="logo-container">
<?php
$school_logo = '../assets/img/logo.png';
if (!empty($school['site_logo'])) {
$school_logo = $school['site_logo'];
// Add path prefix if not already present
if (substr($school_logo, 0, 1) !== '/' && substr($school_logo, 0, 4) !== 'http') {
$school_logo = '../' . $school_logo;
}
}
?>
<img src="<?php echo $school_logo; ?>" alt="<?php echo !empty($school['site_name']) ? htmlspecialchars($school['site_name']) : 'Popular Computer Institute'; ?>" class="logo" onerror="this.src='../assets/img/logo.png'; this.onerror='';">
<h2><?php echo !empty($school['site_name']) ? htmlspecialchars($school['site_name']) : 'Popular Computer Institute'; ?></h2>
</div>
<!-- Step Indicator -->
<div class="step-indicator container">
<div class="step completed">
<div class="step-number"><i class="fas fa-check"></i></div>
<div class="step-title">Application</div>
</div>
<div class="step completed">
<div class="step-connector"></div>
<div class="step-number"><i class="fas fa-check"></i></div>
<div class="step-title">Documents</div>
</div>
<div class="step completed">
<div class="step-connector"></div>
<div class="step-number"><i class="fas fa-check"></i></div>
<div class="step-title">Payment</div>
</div>
<div class="step completed">
<div class="step-connector"></div>
<div class="step-number"><i class="fas fa-check"></i></div>
<div class="step-title">Confirmation</div>
</div>
</div>
<!-- Animated Background -->
<div class="animated-bg">
<div class="animated-shape shape-1"></div>
<div class="animated-shape shape-2"></div>
<div class="animated-shape shape-3"></div>
<div class="animated-shape shape-4"></div>
</div>
<!-- Begin Page Content -->
<div class="container mt-5 mb-5">
<div class="row justify-content-center">
<div class="col-lg-10">
<div class="glass-card shadow fade-in">
<div class="modern-card-header success-header">
<div class="glow-effect glow-1"></div>
<div class="glow-effect glow-2"></div>
<div class="modern-card-header-content">
<i class="fas fa-check-circle"></i>
<h4 class="mb-0 text-center">Enrollment Successful</h4>
</div>
<span class="floating-label">Complete</span>
</div>
<div class="card-body text-center">
<div class="mb-4">
<div class="display-1 text-white mb-3 bounce-in">
<i class="fas fa-check-circle"></i>
</div>
<h3 class="text-white">You have successfully enrolled in</h3>
<h2 class="text-white"><?php echo htmlspecialchars($application['course_title']); ?></h2>
</div>
<div class="glass-card mb-4 mx-auto" style="max-width: 500px; background: rgba(255, 255, 255, 0.2);">
<div class="modern-card-header" style="border-radius: 12px 12px 0 0;">
<div class="modern-card-header-content">
<i class="fas fa-key"></i>
<h5 class="mb-0">Enrollment Information</h5>
</div>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-md-6">
<p class="mb-1 text-white">Enrollment Number:</p>
<div class="bg-light p-2 rounded border">
<h5 class="mb-0 font-monospace">
<?php
// Check if enrollment number exists
if (isset($application['enrollment_number']) && !empty($application['enrollment_number'])) {
echo htmlspecialchars($application['enrollment_number']);
} else {
// Fallback display if enrollment number is not available
$year = date('Y');
$course_code = 'C001';
echo $year . "-" . $course_code . "-" . "0001";
}
?>
</h5>
</div>
</div>
<div class="col-md-6">
<p class="mb-1 text-white">Verification Token:</p>
<div class="bg-light p-2 rounded border">
<h5 class="mb-0 font-monospace"><?php echo $application['verification_token']; ?></h5>
</div>
</div>
</div>
<p class="mb-1 text-white">Please save this information and present it at our institute to start your classes:</p>
<button class="btn btn-3d btn-outline-3d" onclick="copyToken()">
<i class="fas fa-copy me-1"></i> Copy Token
</button>
</div>
</div>
<div class="alert" style="background: rgba(255, 255, 255, 0.2); color: white;">
<i class="fas fa-info-circle me-2"></i> A confirmation email has been sent to your registered email address with all the details.
</div>
<div class="text-center mt-4">
<button class="btn btn-3d btn-success-3d btn-lg" onclick="showReceipt()">
<i class="fas fa-file-invoice me-2"></i> View Receipt
</button>
<a href="../student/index.php" class="btn btn-3d btn-primary-3d btn-lg">
<i class="fas fa-home me-2"></i> Go to Dashboard
</a>
<a href="../courses.php" class="btn btn-3d btn-outline-3d btn-lg">
<i class="fas fa-book me-2"></i> Browse More Courses
</a>
</div>
</div>
</div>
</div>
</div>
<!-- Payment Receipt Modal -->
<div class="modal fade" id="receiptModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modern-card-header">
<div class="modern-card-header-content">
<i class="fas fa-file-invoice"></i>
<h5 class="mb-0">Payment Receipt</h5>
</div>
<button type="button" class="btn-close text-white" data-bs-dismiss="modal" aria-label="Close" style="position: absolute; right: 15px; top: 15px; z-index: 5;"></button>
</div>
<div class="modal-body p-4" id="receiptContent">
<div class="receipt-container" id="receiptToPrint">
<div class="receipt-header">
<div class="row align-items-center">
<div class="col-md-3 text-center">
<?php
$receipt_logo = '../assets/img/logo.png';
if (!empty($school['site_logo'])) {
$receipt_logo = $school['site_logo'];
// Add path prefix if not already present
if (substr($receipt_logo, 0, 1) !== '/' && substr($receipt_logo, 0, 4) !== 'http') {
$receipt_logo = '../' . $receipt_logo;
}
}
?>
<img src="<?php echo $receipt_logo; ?>" class="receipt-logo" alt="Institute Logo" style="max-width: 100px; max-height: 80px;" onerror="this.src='../assets/img/logo.png'; this.onerror='';">
</div>
<div class="col-md-9 text-center text-md-start">
<h3 class="receipt-title mb-0"><?php echo isset($school['site_name']) ? $school['site_name'] : 'Popular Computer Institute'; ?></h3>
<p class="receipt-subtitle mb-0 small"><?php echo isset($school['site_address']) ? $school['site_address'] : 'Bhimpura No.1, Ballia, Uttar Pradesh 221716'; ?></p>
<p class="receipt-subtitle small mb-0">
<?php echo isset($school['contact_phone']) ? 'Phone: ' . $school['contact_phone'] : $contact_phone; ?> |
<?php echo isset($school['contact_email']) ? 'Email: ' . $school['contact_email'] : $contact_email; ?> |
<?php echo isset($school['site_url']) ? 'Website: ' . $school['site_url'] : $site_url; ?>
</p>
</div>
</div>
<div class="text-center mt-3 mb-2">
<h4 class="border-bottom border-top py-2">PAYMENT RECEIPT</h4>
</div>
</div>
<div class="receipt-body">
<div class="row g-3 mb-2">
<div class="col-md-6">
<div class="card h-100">
<div class="card-header bg-light py-1">
<h6 class="mb-0">Student Information</h6>
</div>
<div class="card-body py-2">
<p class="mb-1 small"><strong>Name:</strong> <?php echo $user['first_name'] . ' ' . $user['last_name']; ?></p>
<p class="mb-1 small"><strong>Email:</strong> <?php echo $user['email']; ?></p>
<p class="mb-0 small"><strong>Phone:</strong> <?php echo $user['phone'] ?? 'N/A'; ?></p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100">
<div class="card-header bg-light py-1">
<h6 class="mb-0">Payment Information</h6>
</div>
<div class="card-body py-2">
<p class="mb-1 small"><strong>Receipt No:</strong> <?php echo isset($payment['transaction_id']) ? $payment['transaction_id'] : 'N/A'; ?></p>
<p class="mb-1 small"><strong>Date:</strong> <?php echo isset($payment['payment_date']) ? date('d M Y, h:i A', strtotime($payment['payment_date'])) : date('d M Y'); ?></p>
<p class="mb-0 small"><strong>Method:</strong> <?php echo isset($payment['payment_method']) ? ucwords(str_replace('_', ' ', $payment['payment_method'])) : 'N/A'; ?></p>
</div>
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header bg-light py-1">
<h6 class="mb-0">Course Details & Payment Summary</h6>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-bordered table-sm mb-0">
<thead class="table-light">
<tr>
<th width="40%">Course Description</th>
<th width="15%">Duration</th>
<th width="25%">Payment Plan</th>
<th width="20%" class="text-end">Amount</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<strong><?php echo htmlspecialchars($application['course_title']); ?></strong><br>
<small class="text-muted">Level: <?php echo ucfirst(htmlspecialchars($application['level'])); ?></small><br>
<small class="text-muted">Enrollment #:
<?php
// Check if enrollment number exists
if (isset($application['enrollment_number']) && !empty($application['enrollment_number'])) {
echo htmlspecialchars($application['enrollment_number']);
} else {
// Fallback display if enrollment number is not available
$year = date('Y');
$course_code = 'C001';
echo $year . "-" . $course_code . "-" . "0001";
}
?>
</small>
</td>
<td><?php echo htmlspecialchars($application['duration']); ?></td>
<td>
<?php
$payment_plan = $payment['payment_plan'] ?? 'full';
if ($payment_plan === 'monthly') {
echo "Monthly Plan<br><small class=\"text-muted\">({$total_installments} monthly payments)</small>";
} else if ($payment_plan === 'half_duration' || $payment_plan === 'six_month') {
echo "Installment Plan<br><small class=\"text-muted\">({$total_installments} installments)</small>";
} else {
echo "Full Payment<br><small class=\"text-muted\">(One-time payment)</small>";
}
?>
</td>
<td class="text-end">₹<?php echo number_format($payment['amount'] ?? 0, 2); ?></td>
</tr>
<?php if (!empty($payment['payment_details'])):
$payment_details = json_decode($payment['payment_details'], true);
if (!empty($payment_details['razorpay_fee']) || isset($payment_details['processing_fee'])):
// Calculate or use existing processing fee
$processing_fee = $payment_details['razorpay_fee'] ?? ($payment_details['processing_fee'] ?? 0);
$gst = $payment_details['gst'] ?? ($payment_details['tax'] ?? 0);
?>
<tr>
<td colspan="3" class="text-end text-muted">Base Course Fee:</td>
<td class="text-end">₹<?php
$base_amount = $payment['amount'] - $processing_fee - $gst;
echo number_format($base_amount > 0 ? $base_amount : $payment['amount'], 2);
?></td>
</tr>
<tr>
<td colspan="3" class="text-end text-muted">Processing Fee:</td>
<td class="text-end">₹<?php echo number_format($processing_fee, 2); ?></td>
</tr>
<tr>
<td colspan="3" class="text-end text-muted">GST (18%):</td>
<td class="text-end">₹<?php echo number_format($gst, 2); ?></td>
</tr>
<?php endif; endif; ?>
<tr>
<td colspan="3" class="text-end"><strong>Total Paid:</strong></td>
<td class="text-end"><strong>₹<?php echo number_format($payment['amount'] ?? 0, 2); ?></strong></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<?php if (($payment_plan === 'monthly' || $payment_plan === 'half_duration' || $payment_plan === 'six_month') && $total_installments > 1): ?>
<div class="alert alert-info py-2 small mb-3">
<strong>Note:</strong> This is the first of <?php echo $total_installments; ?> <?php echo $payment_plan === 'monthly' ? 'monthly' : 'installment'; ?> payments.
The next payment of ₹<?php echo number_format($payment['amount'] ?? $payment_amount, 2); ?> will be due on
<?php echo $next_payment_date; ?>.
</div>
<?php endif; ?>
<div class="row">
<div class="col-md-0 d-flex flex-column justify-content-end">
<div class="text-end mt-3">
<p class="mb-5 pt-5 small">Authorized Signature</p>
<hr style="width: 150px; border-top: 1px solid #333; float: right;">
<p class="small mb-0">For <?php echo !empty($school['site_name']) ? $school['site_name'] : 'Popular Computer Institute'; ?></p>
</div>
</div>
</div>
<div class="receipt-header">
<div class="row align-items-center">
<div class="col-md-3 text-center">
<?php
$receipt_logo = '../assets/img/logo.png';
if (!empty($school['site_logo'])) {
$receipt_logo = $school['site_logo'];
// Add path prefix if not already present
if (substr($receipt_logo, 0, 1) !== '/' && substr($receipt_logo, 0, 4) !== 'http') {
$receipt_logo = '../' . $receipt_logo;
}
}
?>
<img src="<?php echo $receipt_logo; ?>" class="receipt-logo" alt="Institute Logo" style="max-width: 100px; max-height: 80px;" onerror="this.src='../assets/img/logo.png'; this.onerror='';">
</div>
<div class="col-md-9 text-center text-md-start">
<h3 class="receipt-title mb-0"><?php echo isset($school['site_name']) ? $school['site_name'] : 'Popular Computer Institute'; ?></h3>
<p class="receipt-subtitle mb-0 small"><?php echo isset($school['site_address']) ? $school['site_address'] : 'Bhimpura No.1, Ballia, Uttar Pradesh 221716'; ?></p>
<p class="receipt-subtitle small mb-0">
<?php echo isset($school['contact_phone']) ? 'Phone: ' . $school['contact_phone'] : $contact_phone; ?> |
<?php echo isset($school['contact_email']) ? 'Email: ' . $school['contact_email'] : $contact_email; ?> |
<?php echo isset($school['site_url']) ? 'Website: ' . $school['site_url'] : $site_url; ?>
</p>
</div>
</div>
<div class="text-center mt-3 mb-2">
<h4 class="border-bottom border-top py-2">Enrollment Verification</h4>
</div>
</div>
<div class="col-md-0">
<div class="d-flex flex-column align-items-center mt-15">
<div class="qr-code mx-auto">
<img src="https://api.qrserver.com/v1/create-qr-code/?size=80x80&data=<?php echo urlencode($application['verification_token']); ?>" alt="Verification QR" style="max-width: 80px;">
</div>
<p class="text-center mb-0"><small>Verification Token<br><?php echo $application['verification_token']; ?></small></p>
</div>
</div>
</div>
<div class="receipt-footer mt-3 pt-2 border-top small text-center">
<p class="mb-0">This is a computer generated receipt and does not require a physical signature.</p>
<p class="mb-0">For any queries, please contact: <?php echo !empty($school['contact_phone']) ? $school['contact_phone'] : 'Your Contact Phone'; ?> |
<?php echo !empty($school['contact_email']) ? $school['contact_email'] : '[email protected]'; ?></p>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" onclick="printReceipt()">
<i class="fas fa-print me-2"></i> Print Receipt
</button>
<!-- <button type="button" class="btn btn-success" onclick="downloadPDF()">
<i class="fas fa-download me-2"></i> Download PDF
</button> -->
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
<script>
function copyToken() {
const token = "<?php echo $application['verification_token']; ?>";
navigator.clipboard.writeText(token).then(function() {
alert("Verification token copied to clipboard!");
}).catch(function(err) {
console.error('Could not copy text: ', err);
});
}
function showReceipt() {
var receiptModal = new bootstrap.Modal(document.getElementById('receiptModal'));
receiptModal.show();
}
function printReceipt() {
const printContent = document.getElementById('receiptToPrint').innerHTML;
const originalContent = document.body.innerHTML;
document.body.innerHTML = printContent;
window.print();
document.body.innerHTML = originalContent;
// Re-initialize receipt modal
setTimeout(function() {
showReceipt();
}, 500);
}
function downloadPDF() {
// Show a loading indicator
const loadingIndicator = document.createElement('div');
loadingIndicator.innerHTML = '<div style="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:9999;display:flex;align-items:center;justify-content:center;"><div style="background:white;padding:20px;border-radius:5px;"><i class="fas fa-spinner fa-spin me-2"></i> Generating PDF...</div></div>';
document.body.appendChild(loadingIndicator);
const element = document.getElementById('receiptToPrint');
// Create a clean version for PDF generation
const printElement = element.cloneNode(true);
// Apply print-specific styles for better PDF generation
printElement.style.width = '210mm'; // A4 width
printElement.style.padding = '10mm';
printElement.style.boxSizing = 'border-box';
printElement.style.fontSize = '10pt';
printElement.style.backgroundColor = 'white';
printElement.style.color = 'black';
// Ensure text is black, not white
const textElements = printElement.querySelectorAll('.text-white, .text-white-50');
textElements.forEach(el => {
el.style.color = '#000000';
});
// Remove any elements that should not be in the PDF
const unwantedElements = printElement.querySelectorAll('.no-print, .btn, .modal-footer, .btn-close');
unwantedElements.forEach(el => el.remove());
// Configure PDF options for text-based output
const opt = {
margin: [15, 15, 15, 15], // Margins [top, right, bottom, left] in mm
filename: 'payment-receipt-<?php echo isset($payment['transaction_id']) ? $payment['transaction_id'] : date('YmdHis'); ?>.pdf',
image: { type: 'jpeg', quality: 1.0 }, // Higher quality for images
html2canvas: {
scale: 2, // Higher scale for better quality
useCORS: true,
logging: false,
letterRendering: true,
allowTaint: true,
backgroundColor: '#ffffff'
},
jsPDF: {
unit: 'mm',
format: 'a4',
orientation: 'portrait',
compress: true,
precision: 16,
putOnlyUsedFonts: true,
floatPrecision: "smart",
userUnit: 1.0
},
fontFaces: [
{ family: 'Poppins', style: 'normal', weight: 'normal', src: ['https://fonts.gstatic.com/s/poppins/v20/pxiEyp8kv8JHgFVrJJfecg.woff2'] }
],
enableLinks: true,
pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }
};
// Use a hidden container for better rendering
const hiddenContainer = document.createElement('div');
hiddenContainer.style.position = 'absolute';
hiddenContainer.style.width = '210mm';
hiddenContainer.style.height = 'auto';
hiddenContainer.style.left = '-9999px';
hiddenContainer.appendChild(printElement);
document.body.appendChild(hiddenContainer);
// Use html2pdf with improved settings
html2pdf().from(printElement).set(opt)
.toPdf()
.get('pdf')
.then((pdf) => {
// Add page numbers
const totalPages = pdf.internal.getNumberOfPages();
for (let i = 1; i <= totalPages; i++) {
pdf.setPage(i);
pdf.setFontSize(8);
pdf.setTextColor(100);
pdf.text('Page ' + i + ' of ' + totalPages,
pdf.internal.pageSize.getWidth() - 25,
pdf.internal.pageSize.getHeight() - 10);
}
return pdf;
})
.save()
.then(() => {
// Clean up
document.body.removeChild(hiddenContainer);
document.body.removeChild(loadingIndicator);
})
.catch(error => {
console.error('Error generating PDF:', error);
alert('There was an error generating the PDF. Please try again.');
document.body.removeChild(hiddenContainer);
document.body.removeChild(loadingIndicator);
});
}
// Alternative implementation using jsPDF and html2canvas directly for better text handling
function downloadPDFAlternative() {
const loadingIndicator = document.createElement('div');
loadingIndicator.innerHTML = '<div style="position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.7);z-index:9999;display:flex;align-items:center;justify-content:center;"><div style="background:white;padding:20px;border-radius:5px;"><i class="fas fa-spinner fa-spin me-2"></i> Generating PDF...</div></div>';
document.body.appendChild(loadingIndicator);
const element = document.getElementById('receiptToPrint');
// Create clean clone and prep for PDF
const printElement = element.cloneNode(true);
document.body.appendChild(printElement);
// Style for PDF output
printElement.style.position = 'absolute';
printElement.style.left = '-9999px';
printElement.style.width = '210mm';
printElement.style.backgroundColor = 'white';
printElement.style.padding = '10mm';
printElement.style.color = 'black';
// Fix color issues
const textElements = printElement.querySelectorAll('.text-white, .text-white-50, .text-muted');
textElements.forEach(el => {
el.style.color = '#000000';
});
// Initialize PDF document
const pdfWidth = 210; // A4 width in mm
const pdfHeight = 297; // A4 height in mm
const pdf = new jspdf.jsPDF('p', 'mm', 'a4');
// Capture the HTML as an image first
html2canvas(printElement, {
scale: 2,
useCORS: true,
allowTaint: true,
backgroundColor: '#FFFFFF',
logging: false,
letterRendering: true
}).then(canvas => {
// Calculate the number of pages
const imgHeight = canvas.height * pdfWidth / canvas.width;
let heightLeft = imgHeight;
let position = 0;
let pageCount = 1;
// Add first page image
const imgData = canvas.toDataURL('image/jpeg', 1.0);
pdf.addImage(imgData, 'JPEG', 0, position, pdfWidth, imgHeight);
heightLeft -= pdfHeight;
// Add additional pages if content overflows
while (heightLeft > 0) {
position = heightLeft - imgHeight;
pdf.addPage();
pdf.addImage(imgData, 'JPEG', 0, position, pdfWidth, imgHeight);
heightLeft -= pdfHeight;
pageCount++;
}
// Add page numbers
for (let i = 1; i <= pageCount; i++) {
pdf.setPage(i);
pdf.setFontSize(8);
pdf.setTextColor(100);
pdf.text('Page ' + i + ' of ' + pageCount, pdfWidth - 25, pdfHeight - 10);
}
// Save the PDF
pdf.save('payment-receipt-<?php echo isset($payment["transaction_id"]) ? $payment["transaction_id"] : date("YmdHis"); ?>.pdf');
// Clean up
document.body.removeChild(printElement);
document.body.removeChild(loadingIndicator);
});
}
// Add 3D hover effect to buttons
document.addEventListener('DOMContentLoaded', function() {
const buttons = document.querySelectorAll('.btn-3d');
buttons.forEach(button => {
button.addEventListener('mousemove', function(e) {
const rect = this.getBoundingClientRect();
const x = (e.clientX - rect.left) / this.offsetWidth;
const y = (e.clientY - rect.top) / this.offsetHeight;
const rotateY = 5 * (0.5 - x);
const rotateX = 5 * (y - 0.5);
this.style.transform = `perspective(500px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(1.05, 1.05, 1.05)`;
});
button.addEventListener('mouseleave', function() {
this.style.transform = '';
});
});
});
</script>
<!-- Bootstrap JS Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
?>