Path : /home/vishqocm/pcib.in/admin/
File Upload :
Current File : /home/vishqocm/pcib.in/admin/index.php

<?php
session_start();
require_once 'database/db_config.php';

// Check if user has admin privileges
require_admin_privileges('login.php');

// Get dashboard statistics with error handling
try {
    // Get site settings
    $site_settings = [];
    $site_settings_query = "SELECT * FROM site_settings";
    $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()) {
            $site_settings[$row['setting_key']] = $row['setting_value'];
        }
    }
    
    // Check if helper messages should be shown
    $show_helper_messages = isset($site_settings['show_helper_messages']) ? 
                            ($site_settings['show_helper_messages'] === 'true') : true;
    
    // Check if sliders table exists
    $sliders_table_exists = $conn->query("SHOW TABLES LIKE 'sliders'")->num_rows > 0;
    
    // Check if tables exist
    $tables_exist = true;
    $required_tables = ['users', 'courses', 'enrollments', 'payments'];
    
    foreach ($required_tables as $table) {
        $result = $conn->query("SHOW TABLES LIKE '$table'");
        if ($result->num_rows == 0) {
            $tables_exist = false;
            break;
        }
    }
    
    if (!$tables_exist) {
        throw new Exception("Required tables do not exist. Please run the installation process first.");
    }
    
    $stats = [
        'users' => $conn->query("SELECT COUNT(*) as count FROM users")->fetch_assoc()['count'],
        'courses' => $conn->query("SELECT COUNT(*) as count FROM courses")->fetch_assoc()['count'],
        'enrollments' => $conn->query("SELECT COUNT(*) as count FROM enrollments")->fetch_assoc()['count'],
        'revenue' => $conn->query("SELECT COALESCE(SUM(amount), 0) as total FROM payments WHERE status = 'completed'")->fetch_assoc()['total']
    ];
} catch (Exception $e) {
    // Log the error and show a user-friendly message
    error_log("Dashboard statistics error: " . $e->getMessage());
    $stats = [
        'users' => 0,
        'courses' => 0,
        'enrollments' => 0,
        'revenue' => 0
    ];
    
    // If tables don't exist, redirect to installation
    if (strpos($e->getMessage(), "Required tables do not exist") !== false) {
        header('Location: install.php');
        exit();
    }
}

// Include header
include_once 'includes/header.php';
?>

<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">Dashboard</h1>
        <a href="reports.php" class="d-none d-sm-inline-block btn btn-primary shadow-sm">
            <i class="fas fa-download fa-sm text-white-50"></i> Generate Report
        </a>
    </div>

    <!-- Messages for new installation -->
    <div class="row">
        <?php if ($show_helper_messages): ?>
        <div class="col-12 mb-4">
            <div class="alert alert-info alert-dismissible fade show">
                <div class="d-flex justify-content-between align-items-center">
                    <div>
                        <strong>Helper Messages</strong>
                        <p class="mb-0">These messages will guide you through setting up your website. You can dismiss them permanently using the button below.</p>
                    </div>
                    <div>
                        <a href="update_site_settings.php?action=disable" class="btn btn-sm btn-outline-danger me-2">
                            <i class="fas fa-times-circle me-1"></i> Dismiss Permanently
                        </a>
                        <a href="site_settings.php" class="btn btn-sm btn-primary">
                            <i class="fas fa-cog me-1"></i> Site Settings
                        </a>
                    </div>
                </div>
            </div>
        </div>
        
        <?php if (!$sliders_table_exists): ?>
        <div class="col-12 mb-4">
            <div class="alert alert-warning">
                <i class="fas fa-exclamation-triangle"></i> The sliders table has not been created yet. 
                <a href="create_sliders_table_manual.php" class="alert-link">Click here to create it</a> before managing hero sliders.
            </div>
        </div>
        <?php else: ?>
        <div class="col-12 mb-4">
            <div class="alert alert-info">
                <i class="fas fa-info-circle"></i> 
                <a href="create_slider_images.php" class="alert-link">Click here to generate default slider images</a> if they are missing.
                Or <a href="sliders.php" class="alert-link">manage your hero sliders</a>.
            </div>
        </div>
        <?php endif; ?>

        <div class="col-12 mb-4">
            <div class="alert alert-info">
                <i class="fas fa-database"></i> 
                <a href="update_database.php" class="alert-link">Click here to update your database structure</a> to ensure all tables have the latest fields.
            </div>
        </div>
        
        <div class="col-12 mb-4">
            <div class="alert alert-info">
                <i class="fas fa-users"></i> 
                <a href="fix_is_team_member.php" class="alert-link">Click here to fix team member database issue</a> if you're seeing errors related to 'is_team_member' column.
            </div>
        </div>
        
        <div class="col-12 mb-4">
            <div class="alert alert-info">
                <i class="fas fa-image"></i> 
                <a href="create_default_course_image.php" class="alert-link">Click here to generate the default course image</a> that will be used when no specific course image is available.
            </div>
        </div>
        <?php endif; ?>
        
        <!-- Total Users 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">
                                Total Users</div>
                            <div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo number_format($stats['users']); ?></div>
                        </div>
                        <div class="col-auto">
                            <i class="fas fa-users fa-2x text-gray-300"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Total 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">
                                Total Courses</div>
                            <div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo number_format($stats['courses']); ?></div>
                        </div>
                        <div class="col-auto">
                            <i class="fas fa-book fa-2x text-gray-300"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Enrollments 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">
                                Enrollments</div>
                            <div class="h5 mb-0 font-weight-bold text-gray-800"><?php echo number_format($stats['enrollments']); ?></div>
                        </div>
                        <div class="col-auto">
                            <i class="fas fa-clipboard-list fa-2x text-gray-300"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Revenue 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">
                                Total Revenue</div>
                            <div class="h5 mb-0 font-weight-bold text-gray-800">₹<?php echo number_format($stats['revenue'], 2); ?></div>
                        </div>
                        <div class="col-auto">
                            <i class="fas fa-money-bill-wave fa-2x text-gray-300"></i>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Content Row -->
    <div class="row">
        <!-- Area Chart -->
        <div class="col-xl-8 col-lg-7">
            <div class="card shadow mb-4">
                <!-- Card Header -->
                <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">Revenue Overview</h6>
                </div>
                <!-- Card Body -->
                <div class="card-body">
                    <div class="chart-area">
                        <div id="revenueChart" style="height: 300px;"></div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Pie Chart -->
        <div class="col-xl-4 col-lg-5">
            <div class="card shadow mb-4">
                <!-- Card Header -->
                <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">Course Enrollments</h6>
                </div>
                <!-- Card Body -->
                <div class="card-body">
                    <div class="chart-pie">
                        <div id="enrollmentsPieChart" style="height: 300px;"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <!-- Recent Activity Row -->
    <div class="row">
        <!-- Recent Enrollments -->
        <div class="col-lg-6 mb-4">
            <div class="card shadow mb-4">
                <div class="card-header py-3">
                    <h6 class="m-0 font-weight-bold text-primary">Recent Enrollments</h6>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table class="table table-bordered" width="100%" cellspacing="0">
                            <thead>
                                <tr>
                                    <th>Student</th>
                                    <th>Course</th>
                                    <th>Date</th>
                                    <th>Status</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php
                                $enrollments_query = "SELECT e.*, u.first_name, u.last_name, c.title 
                                                   FROM enrollments e 
                                                   JOIN users u ON e.user_id = u.id 
                                                   JOIN courses c ON e.course_id = c.id 
                                                   ORDER BY e.enrollment_date DESC LIMIT 5";
                                $enrollments_result = $conn->query($enrollments_query);
                                
                                if ($enrollments_result && $enrollments_result->num_rows > 0) {
                                    while ($enrollment = $enrollments_result->fetch_assoc()) {
                                ?>
                                <tr>
                                    <td><?php echo $enrollment['first_name'] . ' ' . $enrollment['last_name']; ?></td>
                                    <td><?php echo $enrollment['title']; ?></td>
                                    <td><?php echo date('M d, Y', strtotime($enrollment['enrollment_date'])); ?></td>
                                    <td>
                                        <span class="badge bg-success">Enrolled</span>
                                    </td>
                                </tr>
                                <?php
                                    }
                                } else {
                                ?>
                                <tr>
                                    <td colspan="4" class="text-center">No recent enrollments</td>
                                </tr>
                                <?php } ?>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>

        <!-- Recent Payments -->
        <div class="col-lg-6 mb-4">
            <div class="card shadow mb-4">
                <div class="card-header py-3">
                    <h6 class="m-0 font-weight-bold text-primary">Recent Payments</h6>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table class="table table-bordered" width="100%" cellspacing="0">
                            <thead>
                                <tr>
                                    <th>User</th>
                                    <th>Amount</th>
                                    <th>Date</th>
                                    <th>Status</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php
                                $payments_query = "SELECT p.*, CONCAT(u.first_name, ' ', u.last_name) as user_name 
                                                FROM payments p 
                                                JOIN users u ON p.user_id = u.id 
                                                ORDER BY p.payment_date DESC LIMIT 5";
                                $payments_result = $conn->query($payments_query);
                                
                                if ($payments_result && $payments_result->num_rows > 0) {
                                    while ($payment = $payments_result->fetch_assoc()) {
                                ?>
                                <tr>
                                    <td><?php echo $payment['user_name']; ?></td>
                                    <td>₹<?php echo number_format($payment['amount'], 2); ?></td>
                                    <td><?php echo date('M d, Y', strtotime($payment['payment_date'])); ?></td>
                                    <td>
                                        <span class="badge bg-success">Completed</span>
                                    </td>
                                </tr>
                                <?php
                                    }
                                } else {
                                ?>
                                <tr>
                                    <td colspan="4" class="text-center">No recent payments</td>
                                </tr>
                                <?php } ?>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<!-- Animated background elements -->
<div class="dashboard-bg-elements">
    <div class="bg-element element-1"></div>
    <div class="bg-element element-2"></div>
    <div class="bg-element element-3"></div>
    <div class="bg-element element-4"></div>
</div>

<style>
    /* Dashboard Styles */
    :root {
        --dashboard-transition: all 0.4s cubic-bezier(0.25, 0.8, 0.25, 1);
        --glass-bg: rgba(255, 255, 255, 0.25);
        --glass-border: rgba(255, 255, 255, 0.18);
        --glass-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.15);
    }
    
    /* Animated Background */
    .dashboard-bg-elements {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: -1;
        overflow: hidden;
        opacity: 0.3;
    }
    
    .bg-element {
        position: absolute;
        border-radius: 50%;
        filter: blur(70px);
        animation: float 40s infinite ease-in-out;
    }
    
    .element-1 {
        width: 600px;
        height: 600px;
        background: var(--primary-color);
        top: 10%;
        left: -10%;
        animation-delay: 0s;
    }
    
    .element-2 {
        width: 500px;
        height: 500px;
        background: var(--warning-color);
        bottom: -15%;
        right: 5%;
        animation-delay: -10s;
        filter: blur(80px);
    }
    
    .element-3 {
        width: 450px;
        height: 450px;
        background: var(--info-color);
        top: 40%;
        left: 25%;
        animation-delay: -20s;
        filter: blur(60px);
    }
    
    .element-4 {
        width: 400px;
        height: 400px;
        background: var(--success-color);
        top: 5%;
        right: 15%;
        animation-delay: -30s;
        filter: blur(50px);
    }
    
    @keyframes float {
        0%, 100% {
            transform: translate(0, 0) scale(1) rotate(0deg);
        }
        25% {
            transform: translate(4%, 4%) scale(1.05) rotate(5deg);
        }
        50% {
            transform: translate(2%, -6%) scale(0.95) rotate(10deg);
        }
        75% {
            transform: translate(-6%, 2%) scale(1.02) rotate(-5deg);
        }
    }
    
    /* Dashboard header */
    .container-fluid {
        padding: 2rem;
    }
    
    h1.h3.text-gray-800 {
        font-weight: 800;
        letter-spacing: -0.5px;
        background: linear-gradient(120deg, var(--primary-color), var(--info-color));
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
        margin-bottom: 1.5rem;
        font-size: 2.2rem;
        animation: text-shimmer 3s infinite linear;
        text-shadow: 0px 2px 5px rgba(0,0,0,0.1);
        position: relative;
    }
    
    @keyframes text-shimmer {
        0% { background-position: 0% 50%; }
        50% { background-position: 100% 50%; }
        100% { background-position: 0% 50%; }
    }
    
    /* Enhanced Stats Cards */
    .card {
        border: none;
        overflow: hidden;
        border-radius: 16px !important;
        box-shadow: var(--glass-shadow);
        background: var(--glass-bg);
        backdrop-filter: blur(10px);
        transition: var(--dashboard-transition);
        border: 1px solid var(--glass-border);
        transform: translateY(20px);
        opacity: 0;
        animation: card-appear 0.8s forwards cubic-bezier(0.22, 1, 0.36, 1);
    }
    
    .card:hover {
        transform: translateY(-7px) scale(1.02);
        box-shadow: 0 15px 30px rgba(0,0,0,0.1);
        border: 1px solid rgba(255,255,255,0.3);
    }
    
    @keyframes card-appear {
        to {
            transform: translateY(0);
            opacity: 1;
        }
    }
    
    .card-body {
        padding: 1.5rem;
    }
    
    .card-header {
        background: rgba(255,255,255,0.1);
        border-bottom: 1px solid rgba(255,255,255,0.1);
        padding: 1.25rem 1.5rem;
        backdrop-filter: blur(5px);
    }
    
    .card.border-left-primary {
        border-left: 4px solid var(--primary-color) !important;
    }
    
    .card.border-left-success {
        border-left: 4px solid var(--success-color) !important;
    }
    
    .card.border-left-info {
        border-left: 4px solid var(--info-color) !important;
    }
    
    .card.border-left-warning {
        border-left: 4px solid var(--warning-color) !important;
    }
    
    .text-xs {
        font-size: 0.8rem;
        letter-spacing: 1px;
        font-weight: 700 !important;
    }
    
    .fa-2x {
        transition: all 0.3s ease;
    }
    
    .card:hover .fa-2x {
        transform: scale(1.2);
        color: var(--primary-color) !important;
    }
    
    /* Enhanced Tables */
    .table {
        border-collapse: separate;
        border-spacing: 0 8px;
        margin-top: -8px;
    }
    
    .table th {
        border-top: none;
        border-bottom: 1px solid rgba(var(--primary-rgb), 0.1);
        background: transparent;
        padding: 1rem 1.5rem;
        font-size: 0.85rem;
        letter-spacing: 1px;
        text-transform: uppercase;
        font-weight: 700;
        color: var(--gray-600);
    }
    
    .table td {
        border: none;
        background: rgba(255,255,255,0.15);
        padding: 1.2rem 1.5rem;
        vertical-align: middle;
        font-weight: 500;
    }
    
    .table tr {
        transition: all 0.3s ease;
    }
    
    .table tbody tr:first-child td:first-child {
        border-top-left-radius: 12px;
        border-bottom-left-radius: 12px;
    }
    
    .table tbody tr:first-child td:last-child {
        border-top-right-radius: 12px;
        border-bottom-right-radius: 12px;
    }
    
    .table tbody tr:hover {
        transform: translateY(-3px);
        box-shadow: 0 5px 15px rgba(0,0,0,0.05);
    }
    
    .badge {
        padding: 0.5em 1em;
        border-radius: 8px;
        font-weight: 600;
    }
    
    .bg-success {
        background: linear-gradient(45deg, var(--success-color), #4cd964) !important;
    }
    
    .btn-primary {
        background: linear-gradient(135deg, var(--primary-color), var(--info-color));
        border: none;
        box-shadow: 0 5px 15px rgba(var(--primary-rgb), 0.3);
        border-radius: 12px;
        padding: 0.6rem 1.5rem;
        transition: all 0.3s ease;
        font-weight: 600;
    }
    
    .btn-primary:hover {
        transform: translateY(-3px);
        box-shadow: 0 8px 20px rgba(var(--primary-rgb), 0.4);
    }
    
    /* Animation delays for cards */
    .col-xl-3:nth-child(1) .card {
        animation-delay: 0.1s;
    }
    
    .col-xl-3:nth-child(2) .card {
        animation-delay: 0.2s;
    }
    
    .col-xl-3:nth-child(3) .card {
        animation-delay: 0.3s;
    }
    
    .col-xl-3:nth-child(4) .card {
        animation-delay: 0.4s;
    }
    
    .col-xl-8 .card {
        animation-delay: 0.5s;
    }
    
    .col-xl-4 .card {
        animation-delay: 0.6s;
    }
    
    .col-lg-6:nth-child(1) .card {
        animation-delay: 0.7s;
    }
    
    .col-lg-6:nth-child(2) .card {
        animation-delay: 0.8s;
    }
</style>

<script>
document.addEventListener('DOMContentLoaded', function() {
    // Initialize charts with animation
    initCharts();
    
    // Add parallax effect on mouse move
    document.addEventListener('mousemove', function(e) {
        const mouseX = e.clientX / window.innerWidth;
        const mouseY = e.clientY / window.innerHeight;
        
        document.querySelectorAll('.bg-element').forEach((element, index) => {
            const speed = 0.03 + (index * 0.01);
            const x = (mouseX - 0.5) * speed * 100;
            const y = (mouseY - 0.5) * speed * 100;
            
            element.style.transform = `translate(${x}px, ${y}px)`;
        });
    });
    
    // Animation for titles
    const dashboardTitle = document.querySelector('h1.h3.text-gray-800');
    if (dashboardTitle) {
        dashboardTitle.innerHTML = dashboardTitle.textContent.split('').map((char, i) => 
            char === ' ' ? ' ' : `<span style="display:inline-block; opacity:0; transform:translateY(20px); transition: all 0.3s ease ${i * 0.05}s;">${char}</span>`
        ).join('');
        
        setTimeout(() => {
            dashboardTitle.querySelectorAll('span').forEach(span => {
                span.style.opacity = '1';
                span.style.transform = 'translateY(0)';
            });
        }, 100);
    }
    
    // Add subtle hover effects to table rows
    const tableRows = document.querySelectorAll('tbody tr');
    tableRows.forEach(row => {
        row.addEventListener('mouseenter', () => {
            row.style.background = 'rgba(255,255,255,0.25)';
            row.style.transform = 'translateY(-3px)';
            row.style.boxShadow = '0 5px 15px rgba(0,0,0,0.05)';
            
            // Add a subtle glow to the row
            row.querySelectorAll('td').forEach(td => {
                td.style.background = 'rgba(255,255,255,0.2)';
            });
        });
        
        row.addEventListener('mouseleave', () => {
            row.style.background = '';
            row.style.transform = '';
            row.style.boxShadow = '';
            
            row.querySelectorAll('td').forEach(td => {
                td.style.background = 'rgba(255,255,255,0.15)';
            });
        });
    });
});

// Initialize charts with animation
function initCharts() {
    // Revenue chart - simplified example (you can connect to actual data)
    if (document.getElementById('revenueChart')) {
        const options = {
            chart: {
                type: 'area',
                height: 300,
                toolbar: {
                    show: false
                },
                animations: {
                    enabled: true,
                    easing: 'easeinout',
                    speed: 800,
                    animateGradually: {
                        enabled: true,
                        delay: 150
                    },
                    dynamicAnimation: {
                        enabled: true,
                        speed: 350
                    }
                }
            },
            colors: [getComputedStyle(document.documentElement).getPropertyValue('--primary-color')],
            series: [{
                name: 'Revenue',
                data: [30, 40, 35, 50, 49, 60, 70, 91, 125, 150, 160, 180]
            }],
            xaxis: {
                categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
            },
            fill: {
                type: 'gradient',
                gradient: {
                    shadeIntensity: 1,
                    opacityFrom: 0.7,
                    opacityTo: 0.9,
                    stops: [0, 90, 100]
                }
            },
            stroke: {
                curve: 'smooth'
            },
            dataLabels: {
                enabled: false
            },
            tooltip: {
                x: {
                    format: 'dd/MM/yy HH:mm'
                },
            }
        };

        const chart = new ApexCharts(document.getElementById('revenueChart'), options);
        chart.render();
    }
    
    // Enrollments pie chart - simplified example
    if (document.getElementById('enrollmentsPieChart')) {
        const options = {
            chart: {
                type: 'donut',
                height: 300,
                animations: {
                    enabled: true,
                    easing: 'easeinout',
                    speed: 800,
                    animateGradually: {
                        enabled: true,
                        delay: 150
                    },
                    dynamicAnimation: {
                        enabled: true,
                        speed: 350
                    }
                }
            },
            series: [44, 55, 13, 33],
            labels: ['Web Development', 'Data Science', 'Design', 'Mobile Dev'],
            colors: [
                getComputedStyle(document.documentElement).getPropertyValue('--primary-color'),
                getComputedStyle(document.documentElement).getPropertyValue('--success-color'),
                getComputedStyle(document.documentElement).getPropertyValue('--info-color'),
                getComputedStyle(document.documentElement).getPropertyValue('--warning-color')
            ],
            plotOptions: {
                pie: {
                    donut: {
                        size: '55%'
                    }
                }
            },
            legend: {
                position: 'bottom'
            },
            responsive: [{
                breakpoint: 480,
                options: {
                    chart: {
                        width: 200
                    },
                    legend: {
                        position: 'bottom'
                    }
                }
            }]
        };

        const chart = new ApexCharts(document.getElementById('enrollmentsPieChart'), options);
        chart.render();
    }
}
</script>

<?php
// Include footer
include_once 'includes/footer.php';
?>