« Back to History
gray_solution.php
|
20260721_154032.php
Initial Bulk Import
Copy Code
<?php ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); require_once __DIR__ . '/modules/auth/page_acl.php'; $ctx = page_require_access('gray_to_va_receive_report'); if (!function_exists('h')) { function h($value) { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); } } $pdo = $ctx['pdo']; $company_id = (int)$ctx['company_id']; $user_role = strtolower((string)($ctx['user']['role'] ?? '')); // --- ACTION HANDLING (STRICTLY FOR OWNER AND ADMIN ONLY) --- if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { if (in_array($user_role, ['owner', 'admin'], true)) { // 1. COMMENT VISIBILITY TOGGLE if ($_POST['action'] === 'toggle_visibility') { $cmt_id = (int)($_POST['comment_id'] ?? 0); $new_status = trim((string)($_POST['new_status'] ?? 'active')); $up_sql = "UPDATE gray_receive_comments SET status = :stat WHERE comment_id = :cid AND company_id = :comp_id"; $up_st = $pdo->prepare($up_sql); $up_st->execute([ ':stat' => $new_status === 'hidden' ? 'hidden' : 'active', ':cid' => $cmt_id, ':comp_id' => $company_id ]); } // 2. UPDATE GRAY RECEIVE CHECK STATUS (ok / need_check) if ($_POST['action'] === 'update_check_status') { $gray_id = trim((string)($_POST['gray_id'] ?? '')); $new_check_status = trim((string)($_POST['check_status'] ?? 'need_check')); $up_sql = "UPDATE gray_receive SET check_status = :cstat WHERE gray_id = :gid AND company_id = :comp_id"; $up_st = $pdo->prepare($up_sql); $up_st->execute([ ':cstat' => $new_check_status, ':gid' => $gray_id, ':comp_id' => $company_id ]); } // 3. TOGGLE COMPLETE GRAY ID VISIBILITY (status = open / hidden) if ($_POST['action'] === 'toggle_gray_visibility') { $gray_id = trim((string)($_POST['gray_id'] ?? '')); $new_status = trim((string)($_POST['new_status'] ?? 'open')); $up_sql = "UPDATE gray_receive SET status = :stat WHERE gray_id = :gid AND company_id = :comp_id"; $up_st = $pdo->prepare($up_sql); $up_st->execute([ ':stat' => $new_status === 'hidden' ? 'hidden' : 'open', ':gid' => $gray_id, ':comp_id' => $company_id ]); } } header("Location: " . $_SERVER['PHP_SELF'] . (isset($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '')); exit; } // --- FILTERS --- $filter_status = isset($_GET['check_status']) ? trim((string)$_GET['check_status']) : ''; $show_hidden = isset($_GET['show_hidden']) ? (int)$_GET['show_hidden'] : 0; // 1 = Show Hidden, 0 = Hide Hidden // --- MAIN DATATABLE QUERY --- $where_clauses = ["g.company_id = :cid"]; $params = [':cid' => $company_id]; // Filtering Hidden Gray IDs based on access and user choice if (!in_array($user_role, ['owner', 'admin'], true)) { // Normal users can NEVER see hidden ones $where_clauses[] = "g.status = 'open'"; } else { // Owners/Admins will only see hidden ones if they check the "Show Hidden" checkbox if ($show_hidden !== 1) { $where_clauses[] = "g.status = 'open'"; } } if ($filter_status !== '') { $where_clauses[] = "g.check_status = :cstat"; $params[':cstat'] = $filter_status; } $where_str = implode(" AND ", $where_clauses); $sql = " SELECT g.gray_id, g.check_status, g.status AS gray_hidden_status, c.comment_id, c.comment, c.created_at AS comment_time, c.status AS comment_status, u.name AS user_fullname, u.dp_url AS user_avatar, u.username AS user_uname, (SELECT MAX(inner_c.comment_id) FROM gray_receive_comments inner_c WHERE inner_c.gray_id = g.gray_id) as max_comment_id FROM gray_receive g INNER JOIN gray_receive_comments c ON c.gray_id = g.gray_id AND c.company_id = g.company_id LEFT JOIN users u ON u.id = c.created_by WHERE {$where_str} ORDER BY max_comment_id DESC, c.comment_id ASC "; $st = $pdo->prepare($sql); $st->execute($params); $raw_rows = $st->fetchAll(PDO::FETCH_ASSOC); // PHP in-memory grouping $grouped_records = []; foreach ($raw_rows as $row) { $gid = $row['gray_id']; $is_hidden = ($row['comment_status'] === 'hidden'); // Skip hidden comments for non-privileged roles if ($is_hidden && !in_array($user_role, ['owner', 'admin'], true)) { continue; } if (!isset($grouped_records[$gid])) { $grouped_records[$gid] = [ 'gray_id' => $row['gray_id'], 'check_status' => $row['check_status'], 'gray_hidden_status' => $row['gray_hidden_status'], 'comments' => [] ]; } $grouped_records[$gid]['comments'][] = [ 'comment_id' => $row['comment_id'], 'comment' => $row['comment'], 'comment_time' => $row['comment_time'], 'comment_status' => $row['comment_status'], 'user_fullname' => $row['user_fullname'], 'user_avatar' => $row['user_avatar'], 'user_uname' => $row['user_uname'], 'is_hidden' => $is_hidden ]; } // Distinct check_status for filters dropdown $status_stmt = $pdo->prepare("SELECT DISTINCT check_status FROM gray_receive WHERE company_id = :cid AND check_status IS NOT NULL AND check_status != ''"); $status_stmt->execute([':cid' => $company_id]); $all_statuses = $status_stmt->fetchAll(PDO::FETCH_COLUMN); require_once __DIR__ . '/partials/header.php'; ?> <style> .mobile-card { display: none; } .desktop-table-view { display: block; } @media (max-width: 767.98px) { .desktop-table-view { display: none; } .mobile-card { display: block; } } .comment-display-box { border-left: 3px solid #0d6efd; background: #f8f9fa; font-weight: 500; } .comment-box-hidden { border-left: 3px solid #dc3545 !important; background: #fff5f5 !important; } .nested-comment-item { border-bottom: 1px dashed #e2e8f0; padding-bottom: 10px; margin-bottom: 10px; } .nested-comment-item:last-child { border-bottom: none; padding-bottom: 0; margin-bottom: 0; } .gray-card-hidden { background-color: #f8fafc !important; border: 2px dashed #94a3b8 !important; } .gray-row-hidden { background-color: #f8fafc !important; } </style> <div class="container-fluid py-3 px-2 px-md-4"> <div class="d-flex justify-content-between align-items-center mb-3 flex-wrap gap-2"> <h4 class="fw-bold text-dark mb-0">Gray Solutions Dashboard</h4> <span class="badge bg-secondary px-3 py-2 fw-bold">Role: <?= h(strtoupper($user_role)) ?></span> </div> <!-- Filters Section --> <div class="card shadow-sm border-0 mb-3 bg-white"> <div class="card-body p-3"> <form method="get" class="row align-items-end g-2"> <div class="col-10 col-md-4"> <label class="form-label small fw-bold text-secondary mb-1">Filter by Check Status</label> <select name="check_status" class="form-select fw-bold text-dark form-select-sm"> <option value="">-- All Statuses --</option> <?php foreach ($all_statuses as $st_val): ?> <option value="<?= h($st_val) ?>" <?= $filter_status === $st_val ? 'selected' : '' ?>><?= h(strtoupper($st_val)) ?></option> <?php endforeach; ?> </select> </div> <?php if (in_array($user_role, ['owner', 'admin'], true)): ?> <!-- Admin Option to see hidden items --> <div class="col-12 col-md-3"> <div class="form-check form-switch mb-2"> <input class="form-check-input" type="checkbox" name="show_hidden" value="1" id="showHiddenCheck" <?= $show_hidden === 1 ? 'checked' : '' ?> onchange="this.form.submit()"> <label class="form-check-label small fw-bold text-danger" for="showHiddenCheck"> Show Hidden Gray IDs </label> </div> </div> <?php endif; ?> <div class="col-2 col-md-1 d-md-none text-end"> <a href="gray_solution.php" class="btn btn-sm btn-light border fw-bold w-100 py-1 mt-4" title="Reset">✕</a> </div> <div class="col-6 col-md-2"> <button type="submit" class="btn btn-primary btn-sm w-100 fw-bold">Filter</button> </div> <div class="col-6 col-md-2 d-none d-md-block"> <a href="gray_solution.php" class="btn btn-light btn-sm border w-100 fw-bold">Reset</a> </div> </form> </div> </div> <!-- 1. MOBILE RESPONSIVE CARDS VIEW --> <div class="mobile-card"> <?php if (empty($grouped_records)): ?> <div class="alert alert-light text-center fw-bold border text-muted py-4">No records found.</div> <?php else: ?> <?php foreach ($grouped_records as $r): $is_gray_hidden = ($r['gray_hidden_status'] === 'hidden'); ?> <div class="card shadow-sm border-0 mb-3 bg-white overflow-hidden <?= $is_gray_hidden ? 'gray-card-hidden' : '' ?>"> <div class="card-body p-3"> <div class="d-flex justify-content-between align-items-center mb-2 pb-2 border-bottom flex-wrap gap-2"> <div> <span class="text-secondary small fw-bold">Grey ID:</span> <span class="fw-bold text-primary">#<?= h($r['gray_id']) ?></span> <?php if ($is_gray_hidden): ?> <span class="badge bg-danger ms-1" style="font-size: 10px;">HIDDEN</span> <?php endif; ?> </div> <div class="d-flex align-items-center gap-2"> <?php if (in_array($user_role, ['owner', 'admin'], true)): ?> <form method="post" class="m-0"> <input type="hidden" name="action" value="update_check_status"> <input type="hidden" name="gray_id" value="<?= h($r['gray_id']) ?>"> <select name="check_status" class="form-select form-select-sm fw-bold border-dark bg-light py-0 px-2" onchange="this.form.submit()" style="font-size: 12px; height: 26px;"> <option value="need_check" <?= strtolower($r['check_status']) === 'need_check' ? 'selected' : '' ?>>NEED CHECK</option> <option value="ok" <?= strtolower($r['check_status']) === 'ok' ? 'selected' : '' ?>>OK</option> </select> </form> <?php else: ?> <span class="badge <?= strtolower($r['check_status']) === 'ok' ? 'bg-success' : 'bg-warning text-dark' ?> fw-bold px-2 py-1"> <?= h(strtoupper($r['check_status'] ?: 'N/A')) ?> </span> <?php endif; ?> </div> </div> <!-- All Nested Comments --> <div class="mb-3"> <label class="form-label small fw-bold text-muted mb-1">Comment Logs:</label> <?php foreach ($r['comments'] as $cmt): ?> <div class="p-2 border rounded comment-display-box <?= $cmt['is_hidden'] ? 'comment-box-hidden' : '' ?> mb-2" style="<?= $cmt['is_hidden'] ? 'opacity: 0.75;' : '' ?>"> <div class="d-flex align-items-center gap-2 mb-1"> <img src="<?= !empty($cmt['user_avatar']) ? h($cmt['user_avatar']) : 'assets/images/users/avatar-blank.png' ?>" class="rounded-circle border" style="width: 22px; height: 22px; object-fit: cover;" alt="Avatar"> <span class="fw-bold text-dark small" style="font-size: 11px;"><?= h($cmt['user_fullname'] ?: ($cmt['user_uname'] ?: 'System User')) ?></span> <?php if ($cmt['is_hidden']): ?> <span class="badge bg-danger ms-auto" style="font-size: 9px;">HIDDEN CMT</span> <?php endif; ?> </div> <div class="text-dark small ps-1" style="white-space: pre-line; word-break: break-word; font-size: 13px;"><?= h($cmt['comment']) ?></div> <div class="d-flex justify-content-between align-items-center mt-1 border-top pt-1 text-muted" style="font-size: 9px;"> <span><?= date('d-m-Y H:i', strtotime($cmt['comment_time'])) ?></span> <?php if (in_array($user_role, ['owner', 'admin'], true)): ?> <form method="post" class="m-0 d-inline"> <input type="hidden" name="action" value="toggle_visibility"> <input type="hidden" name="comment_id" value="<?= (int)$cmt['comment_id'] ?>"> <?php if ($cmt['is_hidden']): ?> <input type="hidden" name="new_status" value="active"> <button type="submit" class="btn btn-link p-0 text-success fw-bold text-decoration-none" style="font-size: 10px;">Show</button> <?php else: ?> <input type="hidden" name="new_status" value="hidden"> <button type="submit" class="btn btn-link p-0 text-danger fw-bold text-decoration-none" style="font-size: 10px;">Hide</button> <?php endif; ?> </form> <?php endif; ?> </div> </div> <?php endforeach; ?> </div> <!-- Action Buttons Mobile --> <div class="d-flex gap-2"> <a href="gray_to_va_receive_report.php?gray_id=<?= urlencode($r['gray_id']) ?>" class="btn btn-sm btn-primary fw-bold flex-grow-1 text-center py-2"> Reply / History </a> <?php if (in_array($user_role, ['owner', 'admin'], true)): ?> <form method="post" class="m-0 flex-grow-1"> <input type="hidden" name="action" value="toggle_gray_visibility"> <input type="hidden" name="gray_id" value="<?= h($r['gray_id']) ?>"> <?php if ($is_gray_hidden): ?> <input type="hidden" name="new_status" value="open"> <button type="submit" class="btn btn-sm btn-success fw-bold w-100 py-2">Show Gray ID</button> <?php else: ?> <input type="hidden" name="new_status" value="hidden"> <button type="submit" class="btn btn-sm btn-danger fw-bold w-100 py-2">Hide Gray ID</button> <?php endif; ?> </form> <?php endif; ?> </div> </div> </div> <?php endforeach; ?> <?php endif; ?> </div> <!-- 2. DESKTOP STANDARD TABLE VIEW --> <div class="desktop-table-view card shadow-sm border-0 bg-white"> <div class="card-body p-0"> <div class="table-responsive"> <table class="table table-hover align-middle mb-0"> <thead class="table-dark"> <tr> <th class="ps-3" style="width: 140px;">Grey ID</th> <th style="width: 180px;">Check Status</th> <th>All Comment Logs & Posted By</th> <th class="text-center no-print" style="width: 200px;">Actions</th> </tr> </thead> <tbody> <?php if (empty($grouped_records)): ?> <tr> <td colspan="4" class="text-center py-5 text-muted fw-bold">No comment records found matching criteria.</td> </tr> <?php else: ?> <?php foreach ($grouped_records as $r): $is_gray_hidden = ($r['gray_hidden_status'] === 'hidden'); ?> <tr class="<?= $is_gray_hidden ? 'gray-row-hidden table-light' : '' ?>"> <td class="ps-3 fw-bold text-primary"> #<?= h($r['gray_id']) ?> <?php if ($is_gray_hidden): ?> <div class="text-danger small font-monospace" style="font-size: 10px;">[HIDDEN ID]</div> <?php endif; ?> </td> <td> <?php if (in_array($user_role, ['owner', 'admin'], true)): ?> <form method="post" class="m-0"> <input type="hidden" name="action" value="update_check_status"> <input type="hidden" name="gray_id" value="<?= h($r['gray_id']) ?>"> <select name="check_status" class="form-select form-select-sm fw-bold border-secondary bg-white text-dark" onchange="this.form.submit()"> <option value="need_check" <?= strtolower($r['check_status']) === 'need_check' ? 'selected' : '' ?>>NEED CHECK</option> <option value="ok" <?= strtolower($r['check_status']) === 'ok' ? 'selected' : '' ?>>OK</option> </select> </form> <?php else: ?> <span class="badge <?= strtolower($r['check_status']) === 'ok' ? 'bg-success' : 'bg-warning text-dark' ?> fw-bold px-2 py-1"> <?= h(strtoupper($r['check_status'] ?: 'N/A')) ?> </span> <?php endif; ?> </td> <td> <div class="p-3 border rounded bg-light"> <?php foreach ($r['comments'] as $cmt): ?> <div class="nested-comment-item" style="<?= $cmt['is_hidden'] ? 'opacity: 0.65;' : '' ?>"> <div class="d-flex align-items-center justify-content-between mb-1"> <div class="d-flex align-items-center gap-2"> <img src="<?= !empty($cmt['user_avatar']) ? h($cmt['user_avatar']) : 'assets/images/users/avatar-blank.png' ?>" class="rounded-circle border" style="width: 24px; height: 24px; object-fit: cover;" alt="Avatar"> <span class="fw-bold text-dark" style="font-size: 12px;"> <?= h($cmt['user_fullname'] ?: ($cmt['user_uname'] ?: 'System User')) ?> </span> <span class="text-muted" style="font-size: 11px;">• <?= date('d-m-Y H:i', strtotime($cmt['comment_time'])) ?></span> </div> <?php if (in_array($user_role, ['owner', 'admin'], true)): ?> <form method="post" class="d-inline m-0"> <input type="hidden" name="action" value="toggle_visibility"> <input type="hidden" name="comment_id" value="<?= (int)$cmt['comment_id'] ?>"> <?php if ($cmt['is_hidden']): ?> <input type="hidden" name="new_status" value="active"> <button type="submit" class="btn btn-sm btn-outline-success py-0 px-2 fw-bold" style="font-size: 10px;">Show Comment</button> <?php else: ?> <input type="hidden" name="new_status" value="hidden"> <button type="submit" class="btn btn-sm btn-outline-danger py-0 px-2 fw-bold" style="font-size: 10px;">Hide Comment</button> <?php endif; ?> </form> <?php endif; ?> </div> <div class="text-dark ps-4 fw-medium" style="font-size: 14px; white-space: pre-line; word-break: break-word;"> <?php if ($cmt['is_hidden']): ?> <small class="text-danger fw-bold d-block mb-1">[HIDDEN FROM DASHBOARD]</small> <?php endif; ?> <?= h($cmt['comment']) ?> </div> </div> <?php endforeach; ?> </div> </td> <td class="text-center no-print"> <div class="d-grid gap-2"> <a href="gray_to_va_receive_report.php?gray_id=<?= urlencode($r['gray_id']) ?>" class="btn btn-sm btn-primary fw-bold px-3"> Reply </a> <?php if (in_array($user_role, ['owner', 'admin'], true)): ?> <form method="post" class="m-0 w-100"> <input type="hidden" name="action" value="toggle_gray_visibility"> <input type="hidden" name="gray_id" value="<?= h($r['gray_id']) ?>"> <?php if ($is_gray_hidden): ?> <input type="hidden" name="new_status" value="open"> <button type="submit" class="btn btn-sm btn-success fw-bold w-100">Show Gray ID</button> <?php else: ?> <input type="hidden" name="new_status" value="hidden"> <button type="submit" class="btn btn-sm btn-danger fw-bold w-100">Hide Gray ID</button> <?php endif; ?> </form> <?php endif; ?> </div> </td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> </div> </div> </div> <?php require_once __DIR__ . '/partials/footer.php'; ?>