- Category icons: images/code/web/utils have proper SVG (not empty rect)
- Auth check: if logged in, show user name + Выйти instead of Войти/Регистрация
- Cat-cards: white background (surface-800)
- Remove sidebar-logo WA text
- Mobile: icons 32px, gap 2px, overflow hidden (no horizontal scroll)
- Hide dividers on mobile
- Hide admin link on mobile
- Compact bottom bar fits all 16 tools
- Undo button appears after deleting pages
- Restores original file with all pages
- Re-renders all grids with restored pages
- Auto-hides after 30 seconds
- Pages tab (delete/rotate/reorder) has inline action buttons, no main Execute
- Download link hidden when switching tabs
- Result section reset on tab switch
- Sortable file list with drag handles in merge panel
- Visual order numbers, file info (pages, size)
- Drag to reorder files before merging
- mergeOrder state synced with file list changes
- Execute uses mergeOrder for merge API call
- After any page operation, result PDF re-uploaded as new working file
- All grids (delete/rotate/reorder) refresh with updated pages
- File list updates with new page count
- Previews regenerated from modified PDF
- Seamless workflow: delete pages → rotate remaining → reorder
- Reorder: drag-drop auto-saves after 800ms, no button needed
- Delete: selected pages fade out + shrink on delete click
- Delete button shows Удаление... state
- Reorder hint shows Сохранение.../Порядок сохранён
- Better drop positioning (left/right of target)
- Fixed JS references to removed deletePages/rotatePages/reorderPages inputs
- Execute function now reads from visual page grid selections
- Fixed reorder URL (/pdf/reorder instead of /pdf/rotate)
- Preview API confirmed working (200, image/png)
- Replace text inputs with visual page grid (thumbnails)
- Click to select pages for delete/rotate
- Drag to reorder pages (visual)
- Thumbnails loaded lazily from /pdf/preview/:id/:page
- Selected pages highlighted with blue border + checkmark
- Grid auto-fills, max-height with scroll
- GET /pdf/preview/:fileId — renders first page as PNG (72 DPI)
- GET /pdf/preview/:fileId/:page — specific page preview
- GET /pdf/thumbnails/:fileId — list of all page preview URLs
- File cards show actual PDF thumbnail instead of icon
- Cached previews (30 min cleanup)
- Fallback to PDF icon if preview fails
- Fix multer encoding: decode Latin-1 to UTF-8 for Cyrillic names
- Use pdf-lib instead of pdf-parse for page count (more reliable)
- ignoreEncryption flag for encrypted PDFs
- 15 API endpoints for PDF operations (pdf-lib, pdf-parse, Ghostscript)
- Frontend with 8 operation tabs
- Merge multiple PDFs, split by page ranges
- Rotate/delete/reorder pages
- Add watermark text, page numbers
- Compress via Ghostscript (screen/ebook/printer quality)
- PDF to PNG/JPG, Images to PDF
- Password protection, text extraction
- Added to sidebar, dashboard (Utils category), DB
- Landing: replaced custom landing-nav with standard top-header
- Removed scroll listener for nav (no longer needed)
- Header CSS moved to shared.css (single source)
- Removed duplicate header CSS from login, register, status
- All 4 public pages now have identical header with theme toggle
- Only /api/settings, /api/tools, /api/content/advantages|dashboard public
- All other /api/* require authentication (401)
- Moved API mount after auth middleware, public endpoints before
- Parse time= from each stderr chunk (not accumulated buffer)
- Add -progress pipe:2 flag for frequent progress output
- Support both time= and out_time= formats
- Progress only increases (no jumps back)
- /convert now returns immediately, ffmpeg runs in background
- Client polls /progress every second for live progress %
- Progress endpoint returns downloadUrl/outputSize when done
- UI shows real-time percentage during conversion
- AdminJS uses main site session (no separate login)
- Login once at /auth/login → /admin accessible if role=admin
- Non-admin users redirected to /auth/login from /admin
- Removed separate AdminJS authentication (cookieName/cookiePassword)
- Added password_confirm field in user edit/new forms
- Validation: passwords must match, min 6 chars
- New user: password required
- Edit user: password optional (leave empty to keep)
- Virtual password field in AdminJS user edit form
- Auto-hashes with bcrypt on save (edit + new actions)
- Leave empty to keep current password
- Description hint in UI
- Landing hero texts (headline, description, badge) from settings table
- Landing categories from /api/tools (dynamic from DB)
- Landing advantages from /api/content/advantages
- Dashboard about block from /api/content/dashboard
- Static HTML remains as fallback if API fails
- All editable via AdminJS admin panel
- AdminJS at /admin with auth (admin role only)
- Manage: users, categories, tools, content blocks, settings
- DB tables: settings, categories, tools, content_blocks
- Users table: added role (user/admin) and is_blocked fields
- API: /api/settings, /api/tools, /api/content/:section
- Sidebar: admin link visible only for admin users
- Removed /logs from public routes (now in AdminJS)
- Video converter: fixed ffmpeg codecs for RPi5 (h264_v4l2m2m)
- Dependencies: sequelize, @adminjs/sequelize, mariadb
- Login/register now use CSS variables (--surface-*, --text-*, --accent)
- Dark/light theme toggle on auth pages (synced with localStorage)
- Unified nav menu: Главная, Инструменты, Возможности across all pages
- Consistent header style (backdrop blur, border)