Heray-Was-Here
Server : LiteSpeed
System : Linux uk-fast-web1372.main-hosting.eu 4.18.0-553.121.1.lve.el8.x86_64 #1 SMP Thu Apr 30 16:40:41 UTC 2026 x86_64
User : u390967363 ( 390967363)
PHP Version : 8.2.30
Disable Function : system, exec, shell_exec, passthru, mysql_list_dbs, ini_alter, dl, symlink, link, chgrp, leak, popen, apache_child_terminate, virtual, mb_send_mail
Directory :  /home/u390967363/domains/aibenproperties.com/public_html/app/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/u390967363/domains/aibenproperties.com/public_html/app/hr-dashboard.php
<?php
session_start();
require_once __DIR__ . '/includes/functions.php';
$roleRaw = (string)($_SESSION['user_role'] ?? 'guest');
$roleNorm = strtolower(str_replace([' ', '-'], '_', $roleRaw));
$isHrOfficer = in_array($roleNorm, ['hr', 'hr_officer'], true);
$isHrManager = in_array($roleNorm, ['hr_manager'], true);
$isAdminLike = in_array($roleNorm, ['admin', 'super_admin', 'super_admins'], true);
$isHR = $isHrOfficer || $isHrManager || $isAdminLike;
if (!$isHR) {
    header('Location: dashboard.php');
    exit;
}
include 'includes/header.php';

$companyId = getCurrentCompanyId();
$viewerId = (int)($_SESSION['user_id'] ?? 0);
$isManagerView = $isHrManager || $isAdminLike;
$canOnboardStaff = $isHrOfficer || $isHrManager || $isAdminLike;
$canPayroll = $isHrManager || $isAdminLike;
$myProcOpenCount = 0;
try {
    if ($viewerId > 0 && $pdo->query("SHOW TABLES LIKE 'procurement_requests'")->rowCount() > 0) {
        $sql = "SELECT COUNT(*) FROM procurement_requests WHERE requested_by = ? AND LOWER(TRIM(status)) NOT IN ('approved','rejected','converted_to_po')";
        $params = [$viewerId];
        if ($companyId && function_exists('tableHasColumn') && tableHasColumn('procurement_requests', 'company_id')) {
            $sql .= " AND (company_id = ? OR company_id IS NULL)";
            $params[] = $companyId;
        }
        $st = $pdo->prepare($sql);
        $st->execute($params);
        $myProcOpenCount = (int)($st->fetchColumn() ?: 0);
    }
} catch (Throwable $e) { $myProcOpenCount = 0; }

// --- DATA AGGREGATION ---
try {
    $absBaseUrl = function_exists('buildAbsBaseUrl') ? (string)buildAbsBaseUrl() : '';
    $isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
        || (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower((string)$_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https');
    if ($isHttps && is_string($absBaseUrl) && str_starts_with($absBaseUrl, 'http://')) {
        $absBaseUrl = 'https://' . substr($absBaseUrl, 7);
    }
    $userAvatarCol = null;
    if (function_exists('tableHasColumn')) {
        if (tableHasColumn('users', 'avatar_path')) $userAvatarCol = 'avatar_path';
        elseif (tableHasColumn('users', 'avatar')) $userAvatarCol = 'avatar';
        elseif (tableHasColumn('users', 'profile_photo')) $userAvatarCol = 'profile_photo';
        elseif (tableHasColumn('users', 'photo')) $userAvatarCol = 'photo';
        elseif (tableHasColumn('users', 'picture')) $userAvatarCol = 'picture';
        elseif (tableHasColumn('users', 'image_path')) $userAvatarCol = 'image_path';
    }
    $normalizeAvatar = function($p) use ($absBaseUrl, $isHttps) {
        if (!is_string($p) || trim($p) === '') return '';
        $p = str_replace('\\', '/', trim($p));
        if (function_exists('normalizeUrlPath')) {
            try { return (string)normalizeUrlPath($p, $absBaseUrl); } catch (Throwable $e) {}
        }
        if ($isHttps && str_starts_with($p, 'http://')) {
            $p = 'https://' . substr($p, 7);
        }
        if (preg_match('#^https?://#i', $p)) return $p;
        return $p;
    };

    $stmt = $pdo->prepare("SELECT COUNT(*) FROM hr_staff WHERE status = 'active'" . ($companyId ? " AND company_id = ?" : ""));
    if ($companyId) $stmt->execute([$companyId]); else $stmt->execute();
    $total_staff = $stmt->fetchColumn() ?: 0;

    $pending_registrations = 0;
    if (function_exists('tableHasColumn')) {
        $hasApprovalStatus = tableHasColumn('users', 'approval_status');
        $hasStatus = tableHasColumn('users', 'status');
        $hasDept = tableHasColumn('users', 'department');
        $hasCompany = tableHasColumn('users', 'company_id');
        if ($hasApprovalStatus || $hasStatus) {
            $where = [];
            $params = [];
            $where[] = $hasApprovalStatus ? "approval_status = 'pending'" : "status = 'pending'";
            $where[] = $hasDept ? "(role = 'staff' OR (department IS NOT NULL AND department <> ''))" : "role = 'staff'";
            if ($companyId && $hasCompany) {
                $where[] = "(company_id = ? OR company_id IS NULL)";
                $params[] = $companyId;
            }
            $stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE " . implode(" AND ", $where));
            $stmt->execute($params);
            $pending_registrations = $stmt->fetchColumn() ?: 0;
        }
    }

    $stmt = $pdo->prepare("SELECT COUNT(*) FROM hr_leaves WHERE status = 'pending'" . ($companyId ? " AND company_id = ?" : ""));
    if ($companyId) $stmt->execute([$companyId]); else $stmt->execute();
    $pending_leaves = $stmt->fetchColumn() ?: 0;

    $stmt = $pdo->prepare("SELECT SUM(net_pay) FROM hr_payroll WHERE status = 'paid' AND period_month = MONTH(CURRENT_DATE) AND period_year = YEAR(CURRENT_DATE)" . ($companyId ? " AND company_id = ?" : ""));
    if ($companyId) $stmt->execute([$companyId]); else $stmt->execute();
    $monthly_payroll = $stmt->fetchColumn() ?: 0;

    // Performance - Top Marketers
    $avatarSel = $userAvatarCol ? "u.{$userAvatarCol} AS avatar_path" : "NULL AS avatar_path";
    $top_marketers = $pdo->query("
        SELECT s.user_id, s.name, COUNT(d.id) as total_deals, SUM(d.amount_offered) as total_value, {$avatarSel}
        FROM hr_staff s
        JOIN deals_submit d ON d.user_id = s.user_id
        LEFT JOIN users u ON u.id = s.user_id
        WHERE s.role = 'marketer'
        GROUP BY s.user_id, s.name
        ORDER BY total_value DESC
        LIMIT 5
    ")->fetchAll();

    $open_complaints = 0;
    $recent_complaints = [];
    if (function_exists('ensureSupportTicketsSchema')) {
        ensureSupportTicketsSchema();
    }
    if ($pdo->query("SHOW TABLES LIKE 'support_tickets'")->rowCount() > 0) {
        $hasType = function_exists('tableHasColumn') ? tableHasColumn('support_tickets', 'ticket_type') : false;
        $hasTicketCompany = function_exists('tableHasColumn') ? tableHasColumn('support_tickets', 'company_id') : false;
        $hasUsersRole = function_exists('tableHasColumn') ? tableHasColumn('users', 'role') : false;
        $hasUsersName = function_exists('tableHasColumn') ? tableHasColumn('users', 'name') : false;
        $nameExpr = $hasUsersName ? "u.name" : "CONCAT('User #', u.id)";
        $where = [];
        $params = [];
        if ($hasType) { $where[] = "t.ticket_type = 'complaint'"; }
        else { $where[] = "t.subject LIKE 'Complaint:%'"; }
        if ($hasUsersRole) { $where[] = "(u.role IS NULL OR u.role <> 'client')"; }
        if ($companyId && $hasTicketCompany) { $where[] = "(t.company_id = ? OR t.company_id IS NULL)"; $params[] = $companyId; }
        $sqlCount = "SELECT COUNT(*) FROM support_tickets t LEFT JOIN users u ON u.id = t.user_id WHERE " . implode(" AND ", $where) . " AND t.status IN ('open','pending')";
        $st = $pdo->prepare($sqlCount);
        $st->execute($params);
        $open_complaints = (int)($st->fetchColumn() ?: 0);

        $staffAvatarSel = $userAvatarCol ? "u.{$userAvatarCol} AS staff_avatar_path" : "NULL AS staff_avatar_path";
        $sqlList = "SELECT t.id, t.subject, t.status, t.created_at, {$nameExpr} AS staff_name, u.id AS staff_user_id, {$staffAvatarSel} FROM support_tickets t LEFT JOIN users u ON u.id = t.user_id WHERE " . implode(" AND ", $where) . " ORDER BY t.created_at DESC LIMIT 10";
        $st2 = $pdo->prepare($sqlList);
        $st2->execute($params);
        $recent_complaints = $st2->fetchAll(PDO::FETCH_ASSOC) ?: [];
    }
} catch (Exception $e) {
    $total_staff = 0;
    $pending_registrations = 0;
    $pending_leaves = 0;
    $monthly_payroll = 0;
    $top_marketers = [];
    $open_complaints = 0;
    $recent_complaints = [];
}
?>

<style>
    .hrd-staff-ava{width:30px;height:30px;border-radius:999px;object-fit:cover;flex:0 0 auto;border:1px solid rgba(148,163,184,.35);background:#fff}
</style>

<div class="container-fluid py-4">
    <div class="d-flex justify-content-between align-items-center mb-4">
        <div>
            <h1 class="h3 mb-1 text-gray-800"><?= $isManagerView ? 'HR Manager Dashboard' : 'HR Officer Dashboard' ?></h1>
            <div class="small text-muted"><?= $isManagerView ? 'Approvals, oversight, and workforce performance.' : 'Daily HR operations and staff support.' ?></div>
        </div>
        <div class="d-flex gap-2">
            <a href="procurement-requests.php" class="btn btn-outline-dark btn-sm d-flex align-items-center gap-2">
                <i class="fa-solid fa-cart-shopping"></i>
                <span>Purchase Requests</span>
                <span class="badge bg-dark"><?= number_format((int)$myProcOpenCount) ?></span>
            </a>
            <?php if ($canOnboardStaff): ?>
            <a href="hr-staff.php?action=add" class="btn btn-primary btn-sm"><i class="fa-solid fa-user-plus me-2"></i>Onboard Staff</a>
            <?php endif; ?>
            <?php if ($canPayroll): ?>
            <a href="hr-payroll.php?action=prepare" class="btn btn-success btn-sm"><i class="fa-solid fa-file-invoice-dollar me-2"></i>Prepare Payroll</a>
            <?php endif; ?>
        </div>
    </div>

    <div class="row g-3 mb-4">
        <div class="col-xl-3 col-md-6">
            <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 Active Staff</div>
                            <div class="h5 mb-0 font-weight-bold text-gray-800"><?= number_format($total_staff) ?></div>
                        </div>
                        <div class="col-auto"><i class="fas fa-users fa-2x text-gray-300"></i></div>
                    </div>
                </div>
            </div>
        </div>
        <?php if ($isManagerView): ?>
            <div class="col-xl-3 col-md-6">
                <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">Monthly Payroll (Paid)</div>
                                <div class="h5 mb-0 font-weight-bold text-gray-800">₦<?= number_format($monthly_payroll, 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>
        <?php else: ?>
            <div class="col-xl-3 col-md-6">
                <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">Open/Pending Complaints</div>
                                <div class="h5 mb-0 font-weight-bold text-gray-800"><?= number_format((int)$open_complaints) ?></div>
                            </div>
                            <div class="col-auto"><i class="fas fa-headset fa-2x text-gray-300"></i></div>
                        </div>
                    </div>
                </div>
            </div>
        <?php endif; ?>
        <div class="col-xl-3 col-md-6">
            <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"><?= $isManagerView ? 'Pending Leave Approvals' : 'Pending Leave Requests' ?></div>
                            <div class="h5 mb-0 font-weight-bold text-gray-800"><?= number_format($pending_leaves) ?></div>
                        </div>
                        <div class="col-auto"><i class="fas fa-calendar-alt fa-2x text-gray-300"></i></div>
                    </div>
                </div>
            </div>
        </div>
        <?php if ($isManagerView): ?>
            <div class="col-xl-3 col-md-6">
                <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">Pending Staff Registrations</div>
                                <div class="h5 mb-0 font-weight-bold text-gray-800"><?= number_format($pending_registrations) ?></div>
                                <div class="mt-2 small">
                                    <a href="hr-staff.php?action=registrations">View</a>
                                </div>
                            </div>
                            <div class="col-auto"><i class="fas fa-user-clock fa-2x text-gray-300"></i></div>
                        </div>
                    </div>
                </div>
            </div>
        <?php else: ?>
            <div class="col-xl-3 col-md-6">
                <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">My Purchase Requests</div>
                                <div class="h5 mb-0 font-weight-bold text-gray-800"><?= number_format((int)$myProcOpenCount) ?></div>
                                <div class="mt-2 small">
                                    <a href="procurement-requests.php">View</a>
                                </div>
                            </div>
                            <div class="col-auto"><i class="fas fa-cart-shopping fa-2x text-gray-300"></i></div>
                        </div>
                    </div>
                </div>
            </div>
        <?php endif; ?>
    </div>

    <div class="row g-3">
        <div class="col-lg-8">
            <div class="card shadow mb-4">
                <div class="card-header py-3">
                    <h6 class="m-0 font-weight-bold text-primary">Top Performing Marketers</h6>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        <table class="table table-bordered">
                            <thead>
                                <tr>
                                    <th>Name</th>
                                    <th>Total Deals</th>
                                    <th>Sales Value</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php foreach ($top_marketers as $m): ?>
                                <tr>
                                    <td>
                                        <div class="d-flex align-items-center gap-2">
                                            <?php
                                                $av = $normalizeAvatar($m['avatar_path'] ?? '');
                                                if ($av === '' && function_exists('getClientAvatarUrl')) {
                                                    try { $av = (string)getClientAvatarUrl($pdo, (int)($m['user_id'] ?? 0)); } catch (Throwable $e) { $av = ''; }
                                                }
                                            ?>
                                            <?php if ($av !== ''): ?>
                                                <img src="<?= htmlspecialchars($av) ?>" alt="" class="hrd-staff-ava">
                                            <?php endif; ?>
                                            <span><?= htmlspecialchars((string)($m['name'] ?? '')) ?></span>
                                        </div>
                                    </td>
                                    <td><?= number_format($m['total_deals']) ?></td>
                                    <td>₦<?= number_format($m['total_value'], 2) ?></td>
                                </tr>
                                <?php endforeach; ?>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
            <div class="card shadow mb-4">
                <div class="card-header py-3 d-flex justify-content-between align-items-center">
                    <h6 class="m-0 font-weight-bold text-primary">Staff Complaints</h6>
                    <div class="small">
                        <a href="support.php?type=complaint&scope=all">View all</a>
                    </div>
                </div>
                <div class="card-body">
                    <div class="mb-2 small text-muted">Open/Pending: <strong><?= number_format($open_complaints) ?></strong></div>
                    <div class="table-responsive">
                        <table class="table table-bordered">
                            <thead>
                                <tr>
                                    <th>#</th>
                                    <th>Staff</th>
                                    <th>Subject</th>
                                    <th>Status</th>
                                    <th>Created</th>
                                    <th>Action</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php if (empty($recent_complaints)): ?>
                                    <tr><td colspan="6" class="text-center text-muted py-3">No complaints yet.</td></tr>
                                <?php else: foreach ($recent_complaints as $c): ?>
                                    <tr>
                                        <td><?= (int)$c['id'] ?></td>
                                        <td>
                                            <div class="d-flex align-items-center gap-2">
                                                <?php
                                                    $av = $normalizeAvatar($c['staff_avatar_path'] ?? '');
                                                    if ($av === '' && function_exists('getClientAvatarUrl')) {
                                                        try { $av = (string)getClientAvatarUrl($pdo, (int)($c['staff_user_id'] ?? 0)); } catch (Throwable $e) { $av = ''; }
                                                    }
                                                ?>
                                                <?php if ($av !== ''): ?>
                                                    <img src="<?= htmlspecialchars($av) ?>" alt="" class="hrd-staff-ava">
                                                <?php endif; ?>
                                                <span><?= htmlspecialchars($c['staff_name'] ?? 'Unknown') ?></span>
                                            </div>
                                        </td>
                                        <td><?= htmlspecialchars($c['subject'] ?? '') ?></td>
                                        <td><?= htmlspecialchars(ucfirst((string)($c['status'] ?? 'open'))) ?></td>
                                        <td><?= !empty($c['created_at']) ? date('M j, Y', strtotime($c['created_at'])) : '-' ?></td>
                                        <td><a class="btn btn-sm btn-outline-primary" href="ticket-details.php?id=<?= (int)$c['id'] ?>&back=hr">View</a></td>
                                    </tr>
                                <?php endforeach; endif; ?>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
        <div class="col-lg-4">
            <div class="card shadow mb-4">
                <div class="card-header py-3">
                    <h6 class="m-0 font-weight-bold text-primary">Quick Actions</h6>
                </div>
                <div class="card-body">
                    <div class="list-group">
                        <a href="hr-attendance.php" class="list-group-item list-group-item-action">Track Daily Attendance</a>
                        <a href="hr-leaves.php" class="list-group-item list-group-item-action"><?= $isManagerView ? 'Approve Leave Requests' : 'Review Leave Applications' ?></a>
                        <?php if ($canOnboardStaff): ?>
                        <a href="hr-staff.php" class="list-group-item list-group-item-action"><?= $isManagerView ? 'Manage Staff Directory' : 'Manage Staff Records' ?></a>
                        <?php endif; ?>
                        <?php if ($canPayroll): ?>
                        <a href="hr-payroll.php" class="list-group-item list-group-item-action">Manage Payroll Approvals</a>
                        <?php endif; ?>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<?php include 'includes/footer.php'; ?>

Hry