diff --git a/public/pdf.html b/public/pdf.html
index 6e97ef3..2b67e3d 100644
--- a/public/pdf.html
+++ b/public/pdf.html
@@ -193,6 +193,18 @@
justify-content: center;
transition: color .15s, background .15s;
}
+ /* Page thumbnails grid */
+ .page-grid { display:grid; grid-template-columns:repeat(auto-fill, minmax(80px,1fr)); gap:8px; margin-top:10px; max-height:400px; overflow-y:auto; }
+ .page-thumb { position:relative; border:2px solid var(--surface-600); border-radius:8px; overflow:hidden; cursor:pointer; transition:all .15s; aspect-ratio:3/4; background:var(--surface-700); }
+ .page-thumb:hover { border-color:var(--text-muted); }
+ .page-thumb.selected { border-color:var(--accent); box-shadow:0 0 0 2px rgba(0,84,230,.3); }
+ .page-thumb img { width:100%; height:100%; object-fit:cover; }
+ .page-thumb-num { position:absolute; bottom:0; left:0; right:0; background:rgba(0,0,0,.6); color:#fff; font-size:10px; text-align:center; padding:2px 0; font-family:'JetBrains Mono',monospace; }
+ .page-thumb-check { position:absolute; top:4px; right:4px; width:18px; height:18px; border-radius:50%; border:2px solid rgba(255,255,255,.5); background:rgba(0,0,0,.3); display:none; align-items:center; justify-content:center; }
+ .page-thumb.selected .page-thumb-check { display:flex; background:var(--accent); border-color:var(--accent); }
+ .page-thumb-check svg { width:12px; height:12px; }
+ .page-grid-hint { font-size:11px; color:var(--text-muted); margin-top:6px; font-family:'JetBrains Mono',monospace; }
+
.file-card-remove:hover {
color: #ff5252;
background: rgba(255,82,82,.1);
@@ -715,27 +727,27 @@
- Страницы
-
-
Введите all для всех страниц или номера через запятую.
+ Страницы (нажмите для выбора)
+
+ Загрузите файл для просмотра страниц
-
Номера страниц для удаления
-
-
Страницы нумеруются с 1. Разделяйте номера запятыми.
+
Выберите страницы для удаления
+
+
Загрузите файл для просмотра страниц
-
Новый порядок страниц
-
-
Перечислите все номера страниц в новом порядке через запятую.
+
Перетаскивайте страницы для изменения порядка
+
+
Загрузите файл для просмотра страниц
@@ -1646,6 +1658,52 @@
state.securitySub = 'protect';
})();
+
+ // ─── Page Grid Thumbnails ─────────────────────────────────────────────────
+ function renderPageGrid(gridId, hintId, fileId, pages, mode) {
+ const grid = document.getElementById(gridId);
+ const hint = document.getElementById(hintId);
+ if (!grid) return;
+ if (!fileId || pages < 1) {
+ grid.innerHTML = '';
+ if (hint) hint.textContent = 'Выберите файл';
+ return;
+ }
+ if (hint) hint.textContent = mode === 'delete' ? 'Нажмите на страницы для выбора' : mode === 'rotate' ? 'Нажмите для выбора страниц' : 'Перетаскивайте для изменения порядка';
+
+ grid.innerHTML = '';
+ for (let i = 1; i <= pages; i++) {
+ const thumb = document.createElement('div');
+ thumb.className = 'page-thumb';
+ thumb.dataset.page = i;
+ thumb.innerHTML = `
${i}
`;
+
+ if (mode === 'delete' || mode === 'rotate') {
+ thumb.addEventListener('click', () => {
+ thumb.classList.toggle('selected');
+ });
+ }
+ grid.appendChild(thumb);
+ }
+ }
+
+ function getSelectedPages(gridId) {
+ const grid = document.getElementById(gridId);
+ if (!grid) return [];
+ return Array.from(grid.querySelectorAll('.page-thumb.selected')).map(t => parseInt(t.dataset.page));
+ }
+
+ // Re-render grids when file selection changes
+ const origRenderSingle = renderSingleFileSelectors;
+ renderSingleFileSelectors = function() {
+ origRenderSingle();
+ const sel = state.files.find(f => f.id === state.selectedFileId);
+ if (sel) {
+ renderPageGrid('deletePageGrid', 'deleteHint', sel.id, sel.pages, 'delete');
+ renderPageGrid('rotatePageGrid', 'rotateHint', sel.id, sel.pages, 'rotate');
+ renderPageGrid('reorderPageGrid', 'reorderHint', sel.id, sel.pages, 'reorder');
+ }
+ };