feat: rebuild Catalog with collapsible tree + product table + photo upload

- Left panel: collapsible tree (Country → City → District → Category → Subcategory)
  - Quick-add buttons: + City, + District, + Category, + Subcategory
  - Delete buttons with confirmation on all nodes
  - Product count badges on each node
  - Click node to filter right panel
- Right panel: Product table with Photo, Name, Category, Subcategory, Price, Stock
  - Edit (✎) and Delete (✕) buttons per row
  - Add Product modal with all fields
- Product edit form: name, price, stock, description, category, subcategory (JS filtered),
  photo_url/hidden_photo_url (URL or file upload), hidden_coordinates, hidden_description, private_data
- Multer file upload for photos stored in /uploads/
- Routes: add-city, add-district, product CRUD with photo upload
- Product JSON API for modal editing
- Responsive grid: tree (320px) + table (1fr)
This commit is contained in:
NW
2026-06-22 21:42:56 +01:00
parent c7bf3f132c
commit 935c6df1dc
9 changed files with 374 additions and 316 deletions

View File

@@ -6,6 +6,7 @@ import logger from '../utils/logger.js';
import { requireAuth, handleLogin, handleLogout, renderLogin } from './auth.js';
import dashboardRouter from './routes/dashboard.js';
import catalogRouter from './routes/catalog.js';
import catalogProductsRouter from './routes/catalogProducts.js';
import usersRouter from './routes/users.js';
import productsRouter from './routes/products.js';
import walletsRouter from './routes/wallets.js';
@@ -23,6 +24,7 @@ const app = express();
app.use(cookieParser());
app.use(express.urlencoded({ extended: true }));
app.use('/admin/style.css', express.static(join(__dirname, 'public', 'style.css')));
app.use('/uploads', express.static(join(__dirname, '..', '..', 'uploads')));
app.get('/health', (req, res) => {
res.json({ status: 'ok', uptime: process.uptime() });
@@ -39,6 +41,7 @@ app.use(requireAuth);
app.use('/', dashboardRouter);
app.use('/catalog', catalogRouter);
app.use('/catalog', catalogProductsRouter);
app.use('/users', usersRouter);
app.use('/products', productsRouter);
app.use('/wallets', walletsRouter);