<?php
// Include header
include_once 'includes/header.php';
// function formatUrl($url) {
// // Check if URL starts with http:// or https://
// if (stripos($url, 'http://') === 0 || stripos($url, 'https://') === 0) {
// // URL is already absolute, use as is
// return $url;
// } else {
// // URL is relative, prepend "../"
// return "../" . $url;
// }
// }
// Get user information from session
$student_id = $_SESSION['user_id'];
$success_message = '';
$error_message = '';
// Handle form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['update_profile'])) {
// Get form data
$first_name = trim($_POST['first_name'] ?? '');
$last_name = trim($_POST['last_name'] ?? '');
$email = trim($_POST['email'] ?? '');
$phone = trim($_POST['phone'] ?? '');
$address = trim($_POST['address'] ?? '');
$city = trim($_POST['city'] ?? '');
$state = trim($_POST['state'] ?? '');
$zip_code = trim($_POST['zip_code'] ?? '');
$bio = trim($_POST['bio'] ?? '');
// Initialize error array
$errors = [];
// Validate required fields
if (empty($first_name)) {
$errors[] = "First name is required.";
}
if (empty($last_name)) {
$errors[] = "Last name is required.";
}
if (empty($email)) {
$errors[] = "Email is required.";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Invalid email format.";
} else {
// Check if email already exists for another user
$email_check_query = "SELECT id FROM users WHERE email = ? AND id != ?";
$stmt = $conn->prepare($email_check_query);
$stmt->bind_param("si", $email, $student_id);
$stmt->execute();
$email_result = $stmt->get_result();
if ($email_result->num_rows > 0) {
$errors[] = "Email is already in use by another account.";
}
}
// Validate phone number (basic validation)
if (!empty($phone) && !preg_match("/^[0-9]{10}$/", $phone)) {
$errors[] = "Phone number should be 10 digits.";
}
// If no errors, proceed with update
if (empty($errors)) {
try {
// Begin transaction
$conn->begin_transaction();
// Check if address fields exist in the users table
$check_columns_query = "SHOW COLUMNS FROM users LIKE 'address'";
$check_columns_result = $conn->query($check_columns_query);
$has_address_column = $check_columns_result->num_rows > 0;
// Prepare update query based on available columns
if ($has_address_column) {
// Address column exists, use the original query
$update_query = "
UPDATE users SET
first_name = ?,
last_name = ?,
email = ?,
phone = ?,
address = ?,
city = ?,
state = ?,
zip_code = ?,
bio = ?,
updated_at = NOW()
WHERE id = ?
";
$stmt = $conn->prepare($update_query);
$stmt->bind_param("sssssssssi", $first_name, $last_name, $email, $phone, $address, $city, $state, $zip_code, $bio, $student_id);
} else {
// Address column doesn't exist, omit address fields
$update_query = "
UPDATE users SET
first_name = ?,
last_name = ?,
email = ?,
phone = ?,
bio = ?,
updated_at = NOW()
WHERE id = ?
";
$stmt = $conn->prepare($update_query);
$stmt->bind_param("sssssi", $first_name, $last_name, $email, $phone, $bio, $student_id);
}
if (!$stmt->execute()) {
throw new Exception("Error updating profile information: " . $stmt->error);
}
// Handle profile image upload
if (isset($_FILES['profile_image']) && $_FILES['profile_image']['error'] === UPLOAD_ERR_OK) {
$upload_dir = '../uploads/profile_images/';
// Create directory if it doesn't exist
if (!file_exists($upload_dir)) {
if (!mkdir($upload_dir, 0777, true)) {
throw new Exception("Failed to create upload directory");
}
}
// Get file info
$file_temp = $_FILES['profile_image']['tmp_name'];
$file_name = $student_id . '_' . time() . '_' . basename($_FILES['profile_image']['name']);
$file_size = $_FILES['profile_image']['size'];
$file_type = $_FILES['profile_image']['type'];
$file_path = $upload_dir . $file_name;
// Validate file type
$allowed_types = ['image/jpeg', 'image/png', 'image/gif'];
if (!in_array($file_type, $allowed_types)) {
throw new Exception("Invalid file type. Allowed types: JPEG, PNG, GIF");
}
// Validate file size (5MB max)
if ($file_size > 5 * 1024 * 1024) {
throw new Exception("File size exceeds the maximum limit (5MB)");
}
// Move uploaded file
if (move_uploaded_file($file_temp, $file_path)) {
// Get previous profile image to delete
$prev_image_query = "SELECT profile_image FROM users WHERE id = ?";
$stmt = $conn->prepare($prev_image_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$prev_result = $stmt->get_result();
$prev_image = $prev_result->fetch_assoc()['profile_image'] ?? '';
// Update profile image in database
$image_path = 'uploads/profile_images/' . $file_name;
$update_image_query = "UPDATE users SET profile_image = ? WHERE id = ?";
$stmt = $conn->prepare($update_image_query);
$stmt->bind_param("si", $image_path, $student_id);
if (!$stmt->execute()) {
throw new Exception("Error updating profile image: " . $stmt->error);
}
// Delete previous profile image if exists
if (!empty($prev_image) && file_exists('../' . $prev_image) && $prev_image != 'assets/img/default-avatar.png') {
@unlink('../' . $prev_image);
}
} else {
throw new Exception("Failed to upload profile image");
}
}
// Commit transaction
$conn->commit();
$success_message = "Profile updated successfully!";
// Update session variables
$_SESSION['first_name'] = $first_name;
$_SESSION['last_name'] = $last_name;
$_SESSION['email'] = $email;
// Refresh user data after update
$user_query = "
SELECT u.*,
COUNT(e.id) as total_courses
FROM users u
LEFT JOIN enrollments e ON u.id = e.user_id
WHERE u.id = ?
GROUP BY u.id
";
$stmt = $conn->prepare($user_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
} catch (Exception $e) {
// Rollback transaction on error
$conn->rollback();
$error_message = $e->getMessage();
}
} else {
// Format validation errors for display
$error_message = implode("<br>", $errors);
}
}
// Get user data
$query = "
SELECT u.*,
COUNT(e.id) as total_courses
FROM users u
LEFT JOIN enrollments e ON u.id = e.user_id
WHERE u.id = ?
GROUP BY u.id
";
$stmt = $conn->prepare($query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
// Check if attendance table exists and get attendance data
$has_attendance_data = false;
$attendance_percentage = 0;
$check_attendance_table = $conn->query("SHOW TABLES LIKE 'attendance'");
if ($check_attendance_table->num_rows > 0) {
// Get attendance data
$attendance_query = "
SELECT
COUNT(*) as total_attendance_days,
SUM(CASE WHEN a.status = 'present' THEN 1 ELSE 0 END) as total_present
FROM attendance a
INNER JOIN enrollments e ON a.enrollment_id = e.id
WHERE e.user_id = ?
";
$stmt = $conn->prepare($attendance_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$attendance_result = $stmt->get_result();
$attendance_data = $attendance_result->fetch_assoc();
// Calculate attendance percentage
$total_days = $attendance_data['total_attendance_days'] ?? 0;
$present_days = $attendance_data['total_present'] ?? 0;
if ($total_days > 0) {
$attendance_percentage = round(($present_days / $total_days) * 100);
$has_attendance_data = true;
}
}
// Get enrolled courses
$courses_query = "
SELECT c.id, c.title, c.image, c.description,
CONCAT(u.first_name, ' ', u.last_name) as instructor_name,
e.enrollment_date, e.status
FROM enrollments e
INNER JOIN courses c ON e.course_id = c.id
LEFT JOIN users u ON c.instructor_id = u.id
WHERE e.user_id = ?
ORDER BY e.enrollment_date DESC
LIMIT 3
";
$stmt = $conn->prepare($courses_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$courses_result = $stmt->get_result();
$enrolled_courses = [];
while ($row = $courses_result->fetch_assoc()) {
$enrolled_courses[] = $row;
}
// Get payment data
$payment_query = "
SELECT SUM(amount) as total_paid,
COUNT(*) as total_transactions
FROM payments
WHERE user_id = ? AND status IN ('completed', 'verified')
";
$stmt = $conn->prepare($payment_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$payment_result = $stmt->get_result();
$payment_data = $payment_result->fetch_assoc();
$total_paid = $payment_data['total_paid'] ?? 0;
$total_transactions = $payment_data['total_transactions'] ?? 0;
// Get document statistics
$document_query = "
SELECT
COUNT(*) as total_documents,
SUM(CASE WHEN status = 'verified' THEN 1 ELSE 0 END) as verified_documents,
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending_documents,
SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END) as rejected_documents
FROM student_documents
WHERE user_id = ?
";
$stmt = $conn->prepare($document_query);
$stmt->bind_param("i", $student_id);
$stmt->execute();
$document_result = $stmt->get_result();
$document_data = $document_result->fetch_assoc();
?>
<div class="container-fluid py-4">
<!-- Page Heading -->
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">My Profile</h1>
<a href="#" class="d-none d-sm-inline-block btn btn-sm btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#editProfileModal">
<i class="fas fa-edit fa-sm text-white-50"></i> Edit Profile
</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; ?>
<!-- Content Row - Profile Stats -->
<div class="row">
<!-- Total Courses -->
<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 Courses</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $user['total_courses']; ?></div>
</div>
<div class="col-auto">
<i class="fas fa-book-open fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Attendance -->
<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">
Attendance</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-success" 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-clipboard-list fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Documents -->
<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">
Documents</div>
<div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo $document_data['total_documents'] ?? 0; ?></div>
</div>
<div class="col-auto">
<i class="fas fa-file-alt fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Payments -->
<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">
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-rupee-sign fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Content Row - Profile Details -->
<div class="row">
<!-- Profile Overview -->
<div class="col-lg-4 mb-4">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Profile Information</h6>
</div>
<div class="card-body text-center">
<div class="mb-4">
<img src="<?php echo !empty($user['profile_image']) ? formatUrl($user['profile_image']) : '../assets/img/default-avatar.png'; ?>"
class="rounded-circle shadow-sm" alt="Profile Image"
style="width: 150px; height: 150px; object-fit: cover; border: 5px solid rgba(78, 115, 223, 0.1);">
</div>
<h4 class="mb-1"><?php echo htmlspecialchars($user['first_name'] . ' ' . $user['last_name']); ?></h4>
<p class="text-muted mb-3"><?php echo htmlspecialchars($user['email']); ?></p>
<div class="mb-3">
<span class="badge bg-primary">Student</span>
</div>
<hr>
<div class="text-left">
<div class="mb-2">
<strong><i class="fas fa-phone me-2 text-primary"></i> Phone:</strong>
<span><?php echo !empty($user['phone']) ? htmlspecialchars($user['phone']) : 'Not provided'; ?></span>
</div>
<div class="mb-2">
<strong><i class="fas fa-envelope me-2 text-primary"></i> Email:</strong>
<span><?php echo htmlspecialchars($user['email']); ?></span>
</div>
<div class="mb-2">
<strong><i class="fas fa-map-marker-alt me-2 text-primary"></i> Address:</strong>
<span><?php echo !empty($user['address']) ? htmlspecialchars($user['address']) : 'Not provided'; ?></span>
</div>
<div class="mb-2">
<strong><i class="fas fa-calendar me-2 text-primary"></i> Joined:</strong>
<span><?php echo date('M d, Y', strtotime($user['created_at'])); ?></span>
</div>
</div>
</div>
</div>
</div>
<!-- Profile Details and Statistics -->
<div class="col-lg-8 mb-4">
<!-- Documents Status -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Documents Status</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3 text-center mb-3">
<div class="h1 mb-0 text-primary"><?php echo $document_data['total_documents'] ?? 0; ?></div>
<div class="small text-gray-600">Total Documents</div>
</div>
<div class="col-md-3 text-center mb-3">
<div class="h1 mb-0 text-success"><?php echo $document_data['verified_documents'] ?? 0; ?></div>
<div class="small text-gray-600">Verified</div>
</div>
<div class="col-md-3 text-center mb-3">
<div class="h1 mb-0 text-warning"><?php echo $document_data['pending_documents'] ?? 0; ?></div>
<div class="small text-gray-600">Pending</div>
</div>
<div class="col-md-3 text-center mb-3">
<div class="h1 mb-0 text-danger"><?php echo $document_data['rejected_documents'] ?? 0; ?></div>
<div class="small text-gray-600">Rejected</div>
</div>
</div>
<div class="text-center mt-3">
<a href="documents.php" class="btn btn-primary btn-sm">
<i class="fas fa-eye fa-sm"></i> View All Documents
</a>
</div>
</div>
</div>
<!-- Enrolled Courses -->
<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">Enrolled Courses</h6>
<a href="my_courses.php" class="btn btn-sm btn-primary">
<i class="fas fa-book-open fa-sm"></i> View All
</a>
</div>
<div class="card-body">
<?php if (count($enrolled_courses) > 0): ?>
<div class="table-responsive">
<table class="table table-bordered" width="100%" cellspacing="0">
<thead>
<tr>
<th>Course</th>
<th>Instructor</th>
<th>Enrollment Date</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<?php foreach ($enrolled_courses as $course): ?>
<tr>
<td>
<a href="course_details.php?id=<?php echo $course['id']; ?>" class="text-primary">
<?php echo htmlspecialchars($course['title']); ?>
</a>
</td>
<td><?php echo htmlspecialchars($course['instructor_name']); ?></td>
<td><?php echo date('M d, Y', strtotime($course['enrollment_date'])); ?></td>
<td>
<span class="badge bg-<?php echo $course['status'] === 'active' ? 'success' :
($course['status'] === 'pending' ? 'warning' : 'danger'); ?>">
<?php echo ucfirst($course['status']); ?>
</span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php else: ?>
<div class="text-center py-4">
<i class="fas fa-book-open fa-4x text-gray-300 mb-3"></i>
<p class="text-gray-600 mb-0">You are not enrolled in any courses yet.</p>
<a href="../courses.php" class="btn btn-primary mt-3">
<i class="fas fa-search fa-sm"></i> Browse Courses
</a>
</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</div>
<!-- Edit Profile Modal -->
<div class="modal fade" id="editProfileModal" tabindex="-1" aria-labelledby="editProfileModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-primary text-white">
<h5 class="modal-title" id="editProfileModalLabel">Edit Profile</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form action="" method="POST" enctype="multipart/form-data">
<div class="modal-body">
<div class="row">
<div class="col-md-6 mb-3">
<label for="first_name" class="form-label">First Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="first_name" name="first_name" value="<?php echo htmlspecialchars($user['first_name']); ?>" required>
</div>
<div class="col-md-6 mb-3">
<label for="last_name" class="form-label">Last Name <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="last_name" name="last_name" value="<?php echo htmlspecialchars($user['last_name']); ?>" required>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="email" class="form-label">Email Address <span class="text-danger">*</span></label>
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($user['email']); ?>" required>
</div>
<div class="col-md-6 mb-3">
<label for="phone" class="form-label">Phone Number</label>
<input type="text" class="form-control" id="phone" name="phone" value="<?php echo htmlspecialchars($user['phone'] ?? ''); ?>">
</div>
</div>
<div class="mb-3">
<label for="address" class="form-label">Address</label>
<input type="text" class="form-control" id="address" name="address" value="<?php echo htmlspecialchars($user['address'] ?? ''); ?>">
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label for="city" class="form-label">City</label>
<input type="text" class="form-control" id="city" name="city" value="<?php echo htmlspecialchars($user['city'] ?? ''); ?>">
</div>
<div class="col-md-4 mb-3">
<label for="state" class="form-label">State</label>
<input type="text" class="form-control" id="state" name="state" value="<?php echo htmlspecialchars($user['state'] ?? ''); ?>">
</div>
<div class="col-md-4 mb-3">
<label for="zip_code" class="form-label">Zip Code</label>
<input type="text" class="form-control" id="zip_code" name="zip_code" value="<?php echo htmlspecialchars($user['zip_code'] ?? ''); ?>">
</div>
</div>
<div class="mb-3">
<label for="bio" class="form-label">About Me</label>
<textarea class="form-control" id="bio" name="bio" rows="4"><?php echo htmlspecialchars($user['bio'] ?? ''); ?></textarea>
</div>
<div class="mb-3">
<label for="profile_image" class="form-label">Profile Image</label>
<input type="file" class="form-control" id="profile_image" name="profile_image" accept="image/*">
<div class="form-text">Max size: 5MB. Allowed formats: JPEG, PNG, GIF</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" name="update_profile" class="btn btn-primary">Save Changes</button>
</div>
</form>
</div>
</div>
</div>
<!-- Hidden file input for profile image -->
<input type="file" id="profile_image_upload" accept="image/*" style="display: none;">
<script>
document.addEventListener('DOMContentLoaded', function() {
// Profile image upload via the camera icon
const profileImageUpload = document.getElementById('profile_image_upload');
const cameraIcon = document.querySelector('label[for="profile_image_upload"]');
if (profileImageUpload && cameraIcon) {
cameraIcon.addEventListener('click', function() {
profileImageUpload.click();
});
profileImageUpload.addEventListener('change', function() {
if (this.files && this.files[0]) {
// Open the edit profile modal
const editProfileModal = new bootstrap.Modal(document.getElementById('editProfileModal'));
editProfileModal.show();
// Set the file in the modal's file input
document.getElementById('profile_image').files = this.files;
}
});
}
});
</script>
<?php include_once 'includes/footer.php'; ?>