diff --git a/public/userarea/add_record.php b/public/userarea/add_record.php index 80eb1e5..fa711f7 100644 --- a/public/userarea/add_record.php +++ b/public/userarea/add_record.php @@ -5,6 +5,7 @@ header('Content-Type: application/json'); try { $input = json_decode(file_get_contents('php://input'), true); $templateId = intval($input['template_id'] ?? 0); + $importRefFromClient = trim($input['importreferencecode'] ?? ''); if (!$templateId) { throw new Exception('Template ID missing'); @@ -21,8 +22,8 @@ try { $template = $stmt->fetch(PDO::FETCH_ASSOC); $idclient = $template['idclient'] ?? null; - // Generate import reference code - $importReferenceCode = date('YmdHis') . '-' . uniqid(); + // Use provided importreferencecode (from filtered page) or generate new + $importReferenceCode = $importRefFromClient !== '' ? $importRefFromClient : date('YmdHis') . '-' . uniqid(); // Insert empty record $stmt = $pdo->prepare(" diff --git a/public/userarea/gridRenderer.js b/public/userarea/gridRenderer.js index 4416509..63c2c96 100644 --- a/public/userarea/gridRenderer.js +++ b/public/userarea/gridRenderer.js @@ -18,7 +18,7 @@ const data = window.gridData || []; const meta = window.gridMeta || {}; const columns = meta.columns || []; - const totalRows = data.length; + let totalRows = data.length; // ── DOM refs ──────────────────────────────────────────────────────────── let rowContainer = null; @@ -463,6 +463,10 @@ function renderVisibleRows() { if (!rowContainer) return; + // Refresh totalRows in case data was modified externally + totalRows = data.length; + if (revealedCount < totalRows) revealedCount = totalRows; + // Destroy Select2 on existing rows $(rowContainer).find('.select2-hidden-accessible').select2('destroy'); diff --git a/public/userarea/import_insert.php b/public/userarea/import_insert.php index 7b19854..8ddd231 100644 --- a/public/userarea/import_insert.php +++ b/public/userarea/import_insert.php @@ -147,28 +147,6 @@ foreach ($selected_rows as $rowIndex) { $_SESSION['inserted_ids'] = $insertedIds; -$params = [ - 'template_id' => $template_id, - 'filename' => $newFilename, -]; - -?> -
- - \ No newline at end of file diff --git a/public/userarea/imported.php b/public/userarea/imported.php index 8afa340..77223e6 100644 --- a/public/userarea/imported.php +++ b/public/userarea/imported.php @@ -13,6 +13,12 @@ if (!$template_id) { $user_id = $iduserlogin ?? 1; $show_all_users = isset($_GET['all_users']) && $_GET['all_users'] == '1'; +$importref = trim($_GET['importref'] ?? ''); +$usePagination = ($importref === ''); +$allowedLimits = [20, 40, 60, 100]; +$rawLimit = (int)($_GET['limit'] ?? 20); +$perPage = in_array($rawLimit, $allowedLimits) ? $rawLimit : 20; +$page = max(1, (int)($_GET['page'] ?? 1)); $db = DBHandlerSelect::getInstance(); $pdo = $db->getConnection(); @@ -70,16 +76,29 @@ $default_idclient = $template['idclient'] ?? null; // Fetch records with status='i' for this template $userFilter = $show_all_users ? '' : 'AND d.user_id = ?'; +$importrefFilter = $importref !== '' ? 'AND d.importreferencecode = ?' : ''; +$baseWhere = "WHERE d.templateid = ? AND d.status = 'i' {$userFilter} {$importrefFilter}"; +$baseParams = [$template_id]; +if (!$show_all_users) $baseParams[] = $user_id; +if ($importref !== '') $baseParams[] = $importref; + +// Count total records +$countStmt = $pdo->prepare("SELECT COUNT(*) FROM datadb d {$baseWhere}"); +$countStmt->execute($baseParams); +$totalRows = (int)$countStmt->fetchColumn(); +$totalPages = $usePagination ? max(1, (int)ceil($totalRows / $perPage)) : 1; +if ($page > $totalPages) $page = $totalPages; + +$limitClause = $usePagination ? 'LIMIT ' . $perPage . ' OFFSET ' . (($page - 1) * $perPage) : ''; $stmt = $pdo->prepare(" SELECT d.*, CONCAT(u.first_name, ' ', u.last_name) AS user_name FROM datadb d LEFT JOIN auth_users u ON d.user_id = u.id - WHERE d.templateid = ? AND d.status = 'i' {$userFilter} + {$baseWhere} ORDER BY d.iddatadb DESC + {$limitClause} "); -$params = [$template_id]; -if (!$show_all_users) $params[] = $user_id; -$stmt->execute($params); +$stmt->execute($baseParams); $importedData = $stmt->fetchAll(PDO::FETCH_ASSOC); $insertedIds = array_column($importedData, 'iddatadb'); @@ -872,6 +891,14 @@ window.gridMeta = = json_encode($gridMeta, JSON_UNESCAPED_UNICODE | JSON_UNESC transition: background-color 0.3s ease; } + @keyframes new-row-pulse { + 0%, 100% { background-color: transparent; } + 50% { background-color: #cce5ff; } + } + .row-just-created { + animation: new-row-pulse 1s ease-in-out 3; + } + .actions-dropdown .dropdown-toggle { background-color: #6c757d; color: white; @@ -990,6 +1017,87 @@ window.gridMeta = = json_encode($gridMeta, JSON_UNESCAPED_UNICODE | JSON_UNESC border-color: #dc3545 !important; } + /* ── Pagination bar ── */ + .pager-bar { + display: flex; + align-items: center; + justify-content: space-between; + background: #f8f9fa; + border: 1px solid #dee2e6; + border-radius: 6px; + padding: 6px 14px; + font-size: 13px; + color: #495057; + } + .pager-rows-per-page { + display: flex; + align-items: center; + gap: 8px; + } + .pager-label { + font-weight: 500; + white-space: nowrap; + } + .pager-limit-group { + display: inline-flex; + border: 1px solid #ced4da; + border-radius: 4px; + overflow: hidden; + } + .pager-limit-btn { + padding: 3px 10px; + text-decoration: none; + color: #495057; + border-right: 1px solid #ced4da; + transition: background .15s, color .15s; + font-weight: 500; + } + .pager-limit-btn:last-child { border-right: none; } + .pager-limit-btn:hover { background: #e9ecef; text-decoration: none; color: #212529; } + .pager-limit-btn.active { + background: #0d6efd; + color: #fff; + } + .pager-limit-btn.active:hover { background: #0b5ed7; color: #fff; } + .pager-nav { + display: flex; + align-items: center; + gap: 4px; + } + .pager-info { + margin-right: 8px; + font-weight: 500; + white-space: nowrap; + } + .pager-btn, .pager-num { + display: inline-flex; + align-items: center; + justify-content: center; + min-width: 28px; + height: 28px; + padding: 0 6px; + border: 1px solid #ced4da; + border-radius: 4px; + text-decoration: none; + color: #495057; + font-weight: 500; + transition: background .15s, color .15s, border-color .15s; + } + .pager-btn:hover, .pager-num:hover { background: #e9ecef; text-decoration: none; color: #212529; } + .pager-num.active { + background: #0d6efd; + color: #fff; + border-color: #0d6efd; + } + .pager-btn.disabled { + pointer-events: none; + opacity: .4; + } + .pager-dots { + padding: 0 2px; + color: #adb5bd; + user-select: none; + }