<?php
// Start session
session_start();
// Include database configuration
require_once 'admin/database/db_config.php';
// Include header
include 'includes/header.php';
// Get all published courses
$courses_query = "SELECT c.*, cat.name as category_name, u.first_name, u.last_name,
COUNT(DISTINCT e.id) as enrollment_count
FROM courses c
LEFT JOIN categories cat ON c.category = cat.id
LEFT JOIN users u ON c.instructor_id = u.id
LEFT JOIN enrollments e ON c.id = e.course_id
WHERE c.status = 'active'
GROUP BY c.id
ORDER BY c.is_featured DESC, c.created_at DESC";
$courses_result = $conn->query($courses_query);
$courses = [];
if ($courses_result && $courses_result->num_rows > 0) {
while ($row = $courses_result->fetch_assoc()) {
$courses[] = $row;
}
}
// Get categories for filter
$categories_query = "SELECT * FROM categories ORDER BY name";
$categories_result = $conn->query($categories_query);
$categories = [];
if ($categories_result && $categories_result->num_rows > 0) {
while ($row = $categories_result->fetch_assoc()) {
$categories[] = $row;
}
}
?>
<!-- Page Header -->
<div class="page-header">
<div class="container">
<div class="row align-items-center">
<div class="col-lg-6">
<h1 class="page-title">Explore Our Courses</h1>
<p class="page-description">Discover a wide range of quality courses to enhance your skills</p>
</div>
<div class="col-lg-6">
<nav aria-label="breadcrumb">
<ol class="breadcrumb justify-content-lg-end">
<li class="breadcrumb-item"><a href="index.php">Home</a></li>
<li class="breadcrumb-item active" aria-current="page">Courses</li>
</ol>
</nav>
</div>
</div>
</div>
<!-- 3D Objects Animation -->
<div class="floating-shapes">
<div class="shape shape-1" data-parallax='{"y": 150, "x": 50}'></div>
<div class="shape shape-2" data-parallax='{"y": -100, "x": -70}'></div>
<div class="shape shape-3" data-parallax='{"y": 80, "x": -120}'></div>
<div class="shape shape-4" data-parallax='{"y": -50, "x": 100}'></div>
</div>
</div>
<!-- Courses Section -->
<section class="courses-page-section py-5">
<div class="container">
<!-- Filters -->
<div class="courses-filters mb-5 wow fadeInUp" data-wow-delay="0.2s">
<div class="row">
<div class="col-md-4 mb-3 mb-md-0">
<select class="form-select category-filter">
<option value="">All Categories</option>
<?php foreach ($categories as $category): ?>
<option value="<?php echo $category['id']; ?>"><?php echo htmlspecialchars($category['name']); ?></option>
<?php endforeach; ?>
</select>
</div>
<div class="col-md-4 mb-3 mb-md-0">
<select class="form-select sort-filter">
<option value="latest">Latest</option>
<option value="popular">Most Popular</option>
<option value="rating">Highest Rated</option>
<option value="price-low">Price: Low to High</option>
<option value="price-high">Price: High to Low</option>
</select>
</div>
<div class="col-md-4">
<div class="search-box">
<input type="text" class="form-control course-search" placeholder="Search courses...">
<i class="fas fa-search"></i>
</div>
</div>
</div>
</div>
<!-- Courses Grid -->
<div class="row courses-grid">
<?php
if (!empty($courses)) {
foreach ($courses as $index => $course):
$delay = 0.1 * ($index % 8 + 1);
$course_image = !empty($course['image']) ? $course['image'] : 'assets/img/defaults/default-course-image.jpg';
$price_display = ($course['price'] > 0) ? '₹' . number_format($course['price'], 2) : 'Free';
$discount_price = null;
if (!empty($course['discount_price']) && $course['discount_price'] > 0 && $course['discount_price'] < $course['price']) {
$discount_price = $course['discount_price'];
$price_display = '<span class="original-price">₹' . number_format($course['price'], 2) . '</span> ₹' . number_format($discount_price, 2);
}
?>
<div class="col-lg-4 col-md-6 mb-4 course-item wow fadeInUp" data-wow-delay="<?php echo $delay; ?>s" data-category="<?php echo $course['category']; ?>">
<div class="course-card">
<div class="course-card-img">
<img src="<?php echo htmlspecialchars($course_image); ?>" alt="<?php echo htmlspecialchars($course['title']); ?>" class="img-fluid">
<?php if ($course['is_featured']): ?>
<div class="featured-badge">Featured</div>
<?php endif; ?>
<div class="course-card-category">
<span><?php echo htmlspecialchars($course['category_name']); ?></span>
</div>
</div>
<div class="course-card-content">
<div class="course-card-info">
<div class="info-item">
<i class="fas fa-user-graduate"></i>
<span><?php echo $course['enrollment_count'] ?? 0; ?> students</span>
</div>
<div class="info-item">
<i class="fas fa-clock"></i>
<span><?php echo htmlspecialchars($course['duration'] ?? '0 months'); ?></span>
</div>
<div class="info-item">
<i class="fas fa-signal"></i>
<span><?php echo ucfirst($course['level'] ?? 'beginner'); ?></span>
</div>
</div>
<h3 class="course-card-title">
<a href="course-details.php?id=<?php echo $course['id']; ?>"><?php echo htmlspecialchars($course['title']); ?></a>
</h3>
<p class="course-card-description">
<?php
if (!empty($course['short_description'])) {
echo htmlspecialchars(substr($course['short_description'], 0, 100) . (strlen($course['short_description']) > 100 ? '...' : ''));
} else {
echo "Learn this course to enhance your skills and knowledge in " . htmlspecialchars($course['category_name'] ?? 'this field');
}
?>
</p>
<div class="course-card-footer">
<div class="course-card-instructor">
<?php if (!empty($course['first_name']) && !empty($course['last_name'])): ?>
<span>By <?php echo htmlspecialchars($course['first_name'] . ' ' . $course['last_name']); ?></span>
<?php else: ?>
<span>Popular Computer Institute</span>
<?php endif; ?>
</div>
</div>
<div class="course-card-actions">
<div class="course-price"><?php echo $price_display; ?></div>
<a href="course-details.php?id=<?php echo $course['id']; ?>" class="btn btn-outline-primary btn-sm">View Details</a>
</div>
</div>
</div>
</div>
<?php endforeach;
} else { ?>
<div class="col-12 text-center py-5">
<div class="empty-courses">
<img src="https://cdn.jsdelivr.net/gh/refinedev/refine@master/examples/no-data.svg" alt="No courses" class="empty-img">
<h3>No Courses Found</h3>
<p>We're working on adding more courses. Please check back later!</p>
</div>
</div>
<?php } ?>
</div>
<!-- Pagination -->
<div class="pagination-container mt-5 wow fadeInUp" data-wow-delay="0.3s">
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
<li class="page-item disabled">
<a class="page-link" href="#" tabindex="-1">
<i class="fas fa-chevron-left"></i>
</a>
</li>
<li class="page-item active"><a class="page-link" href="#">1</a></li>
<li class="page-item"><a class="page-link" href="#">2</a></li>
<li class="page-item"><a class="page-link" href="#">3</a></li>
<li class="page-item">
<a class="page-link" href="#">
<i class="fas fa-chevron-right"></i>
</a>
</li>
</ul>
</nav>
</div>
</div>
</section>
<!-- CTA Section -->
<section class="cta-section py-5">
<div class="container">
<div class="cta-box wow fadeInUp" data-wow-delay="0.2s">
<div class="row align-items-center">
<div class="col-lg-8 mb-4 mb-lg-0">
<h2 class="cta-title">Can't find what you're looking for?</h2>
<p class="cta-text">Contact us to suggest new courses or topics you'd like to learn about.</p>
</div>
<div class="col-lg-4 text-lg-end">
<a href="contact.php" class="btn btn-light btn-lg">Contact Us</a>
</div>
</div>
</div>
</div>
</section>
<style>
/* Page Header */
.page-header {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
padding: 100px 0 100px;
color: white;
margin-bottom: 60px;
position: relative;
overflow: hidden;
}
.page-title {
font-size: 2.75rem;
font-weight: 700;
margin-bottom: 15px;
animation: fadeInUp 1s ease;
}
.page-description {
font-size: 1.2rem;
opacity: 0.9;
animation: fadeInUp 1s ease 0.2s;
animation-fill-mode: both;
}
.breadcrumb {
background: transparent;
padding: 0;
margin: 0;
animation: fadeInRight 1s ease 0.3s;
animation-fill-mode: both;
}
.breadcrumb-item a {
color: rgba(255, 255, 255, 0.8);
text-decoration: none;
transition: color 0.3s ease;
}
.breadcrumb-item a:hover {
color: white;
}
.breadcrumb-item.active {
color: white;
}
.breadcrumb-item+.breadcrumb-item::before {
color: rgba(255, 255, 255, 0.5);
}
/* Empty Courses Section */
.empty-courses {
padding: 40px;
background-color: #f8f9fc;
border-radius: 20px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
max-width: 600px;
margin: 0 auto;
}
.empty-img {
max-width: 280px;
height: auto;
margin-bottom: 25px;
animation: float 6s ease-in-out infinite;
}
.empty-courses h3 {
color: var(--primary-color);
font-size: 1.75rem;
font-weight: 700;
margin-bottom: 15px;
}
.empty-courses p {
color: #718096;
font-size: 1.1rem;
margin-bottom: 0;
}
/* 3D Floating Shapes */
.floating-shapes {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1;
pointer-events: none;
overflow: hidden;
}
.shape {
position: absolute;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(5px);
border-radius: 15px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
animation: float 8s infinite ease-in-out;
}
.shape-1 {
width: 100px;
height: 100px;
top: 20%;
left: 15%;
animation-delay: 0s;
transform: rotateZ(25deg);
}
.shape-2 {
width: 150px;
height: 150px;
top: 60%;
left: 75%;
animation-delay: 2s;
transform: rotateZ(-15deg);
}
.shape-3 {
width: 80px;
height: 80px;
top: 30%;
left: 85%;
animation-delay: 4s;
transform: rotateZ(45deg);
}
.shape-4 {
width: 120px;
height: 120px;
top: 70%;
left: 25%;
animation-delay: 6s;
transform: rotateZ(-30deg);
}
@keyframes float {
0%, 100% {
transform: translateY(0) rotateZ(0deg);
}
50% {
transform: translateY(-20px) rotateZ(10deg);
}
}
.container {
position: relative;
z-index: 2;
}
/* Courses Section */
.courses-page-section {
padding: 0 0 80px;
position: relative;
}
/* Filters */
.courses-filters {
background-color: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
margin-top: -80px;
position: relative;
z-index: 10;
}
.form-select, .form-control {
border: 1px solid #e2e8f0;
padding: 12px 20px;
border-radius: 10px;
font-size: 0.95rem;
transition: all 0.3s ease;
}
.form-select:focus, .form-control:focus {
border-color: var(--primary-color);
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.2);
}
.search-box {
position: relative;
}
.search-box i {
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
color: #a0aec0;
pointer-events: none;
}
/* Course Card */
.course-card {
background-color: white;
border-radius: 15px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05);
transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
height: 100%;
display: flex;
flex-direction: column;
}
.course-card:hover {
transform: translateY(-10px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.course-card-img {
position: relative;
height: 200px;
overflow: hidden;
}
.course-card-img img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
}
.course-card:hover .course-card-img img {
transform: scale(1.05);
}
.featured-badge {
position: absolute;
top: 15px;
left: 15px;
background-color: var(--primary-color);
color: white;
padding: 5px 12px;
border-radius: 20px;
font-size: 0.75rem;
font-weight: 600;
z-index: 2;
}
.course-card-category {
position: absolute;
bottom: 15px;
right: 15px;
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 5px 12px;
border-radius: 20px;
font-size: 0.75rem;
font-weight: 600;
z-index: 2;
}
.course-card-content {
padding: 25px;
flex: 1;
display: flex;
flex-direction: column;
}
.course-card-info {
display: flex;
justify-content: space-between;
margin-bottom: 15px;
}
.info-item {
display: flex;
align-items: center;
font-size: 0.85rem;
color: #718096;
}
.info-item i {
color: var(--primary-color);
margin-right: 5px;
}
.course-card-title {
font-size: 1.25rem;
font-weight: 700;
margin-bottom: 10px;
line-height: 1.4;
}
.course-card-title a {
color: #1a202c;
text-decoration: none;
transition: color 0.3s ease;
}
.course-card-title a:hover {
color: var(--primary-color);
}
.course-card-description {
font-size: 0.95rem;
color: #718096;
margin-bottom: 15px;
flex: 1;
}
.course-card-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 15px;
border-top: 1px solid #e2e8f0;
margin-bottom: 15px;
}
.course-card-instructor {
font-size: 0.85rem;
color: #718096;
}
.course-card-actions {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: auto;
}
.course-price {
font-size: 1.25rem;
font-weight: 700;
color: var(--primary-color);
}
.original-price {
font-size: 0.95rem;
color: #a0aec0;
text-decoration: line-through;
margin-right: 5px;
}
.btn-outline-primary {
border-color: var(--primary-color);
color: var(--primary-color);
transition: all 0.3s ease;
}
.btn-outline-primary:hover {
background-color: var(--primary-color);
color: white;
}
/* Pagination */
.pagination .page-link {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
margin: 0 5px;
border-radius: 50%;
border: none;
color: #4a5568;
font-weight: 600;
transition: all 0.3s ease;
}
.pagination .page-item.active .page-link {
background-color: var(--primary-color);
color: white;
}
.pagination .page-link:hover {
background-color: #e2e8f0;
}
.pagination .page-item.active .page-link:hover {
background-color: var(--primary-color);
}
/* CTA Section */
.cta-section {
background-color: #f8f9fc;
}
.cta-box {
background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
border-radius: 15px;
padding: 50px;
color: white;
}
.cta-title {
font-size: 2rem;
font-weight: 700;
margin-bottom: 10px;
}
.cta-text {
font-size: 1.1rem;
opacity: 0.9;
margin-bottom: 0;
}
.btn-light {
background-color: white;
color: var(--primary-color);
font-weight: 600;
border: none;
padding: 10px 25px;
border-radius: 30px;
transition: all 0.3s ease;
}
.btn-light:hover {
background-color: rgba(255, 255, 255, 0.9);
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
}
/* Responsive */
@media (max-width: 991.98px) {
.page-header {
padding: 60px 0 80px;
}
.page-title {
font-size: 2.25rem;
}
.cta-box {
padding: 30px;
}
.cta-title {
font-size: 1.75rem;
}
}
@media (max-width: 767.98px) {
.page-header {
padding: 50px 0 70px;
}
.page-title {
font-size: 2rem;
}
.courses-filters {
padding: 20px;
}
.cta-box {
padding: 25px;
}
.cta-title {
font-size: 1.5rem;
}
}
@media (max-width: 575.98px) {
.page-header {
padding: 40px 0 60px;
}
.page-title {
font-size: 1.75rem;
}
.course-card-info {
flex-wrap: wrap;
gap: 10px;
}
.info-item {
margin-right: 10px;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Initialize WOW.js for animations
new WOW().init();
// Initialize parallax effect for 3D shapes
const shapes = document.querySelectorAll('.shape');
shapes.forEach(shape => {
const data = shape.getAttribute('data-parallax');
if (data) {
const options = JSON.parse(data);
window.addEventListener('mousemove', function(e) {
const x = (window.innerWidth - e.pageX * options.x) / 90;
const y = (window.innerHeight - e.pageY * options.y) / 90;
shape.style.transform = `translateX(${x}px) translateY(${y}px)`;
});
}
});
// Filter functionality
const categoryFilter = document.querySelector('.category-filter');
const sortFilter = document.querySelector('.sort-filter');
const searchInput = document.querySelector('.course-search');
if (categoryFilter && sortFilter && searchInput) {
const filterCourses = () => {
const categoryValue = categoryFilter.value;
const searchValue = searchInput.value.toLowerCase();
const courseItems = document.querySelectorAll('.course-item');
courseItems.forEach(item => {
const categoryMatch = categoryValue === '' || item.dataset.category === categoryValue;
const titleElement = item.querySelector('.course-card-title');
const title = titleElement ? titleElement.textContent.toLowerCase() : '';
const descElement = item.querySelector('.course-card-description');
const desc = descElement ? descElement.textContent.toLowerCase() : '';
const searchMatch = title.includes(searchValue) || desc.includes(searchValue);
if (categoryMatch && searchMatch) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
});
};
categoryFilter.addEventListener('change', filterCourses);
searchInput.addEventListener('input', filterCourses);
sortFilter.addEventListener('change', function() {
const value = this.value;
const courseGrid = document.querySelector('.courses-grid');
const courseItems = Array.from(document.querySelectorAll('.course-item'));
switch(value) {
case 'latest':
// Already sorted by latest
break;
case 'popular':
courseItems.sort((a, b) => {
const aStudents = parseInt(a.querySelector('.info-item span').textContent);
const bStudents = parseInt(b.querySelector('.info-item span').textContent);
return bStudents - aStudents;
});
break;
case 'rating':
// Remove rating sorting since we don't have ratings
break;
case 'price-low':
courseItems.sort((a, b) => {
const aPrice = parseFloat(a.querySelector('.course-price').textContent.replace('₹', '').replace(',', ''));
const bPrice = parseFloat(b.querySelector('.course-price').textContent.replace('₹', '').replace(',', ''));
return aPrice - bPrice;
});
break;
case 'price-high':
courseItems.sort((a, b) => {
const aPrice = parseFloat(a.querySelector('.course-price').textContent.replace('₹', '').replace(',', ''));
const bPrice = parseFloat(b.querySelector('.course-price').textContent.replace('₹', '').replace(',', ''));
return bPrice - aPrice;
});
break;
}
courseItems.forEach(item => courseGrid.appendChild(item));
});
}
});
</script>
<?php
// Include footer
include 'includes/footer.php';
?>