# H&M EMS Product Review Tool A web-based review tool for H&M EMS product data. Clients can review product names and prices across multiple languages, make edits, and approve changes — all saved directly back to the master JSON. ## Features - **Campaign File Selector**: Switch between different JSON campaign files from the `Master_Json/` folder - **Multi-Language Columns**: Select up to 4 target languages side-by-side for comparison - **Inline Editing**: Edit Product Name and Price fields for any target language - **Approve & Save**: Click the tick button to approve — edits are saved to the master JSON and fields are locked - **Change Logging**: Every approve/unapprove action is recorded in a changelog file - **Campaign Images**: Product images with click-to-enlarge preview popup - **Multi-Image Support**: Articles with multiple campaign images display all thumbnails - **English Reference Column**: Fixed column showing the English (GB) product name ## Folder Structure ``` deploy/ ├── server.py # Flask web server ├── html_generator.py # Shared helpers (language names, image utils) ├── static/ │ └── index.html # Review UI (single-page app) ├── Master_Json/ # Campaign JSON files │ ├── 1022A.json │ └── 2023.json ├── campaign_images/ # Product images organised by year/campaign │ ├── 2025/1022A/Automation_LR/ │ └── 2026/2023/Automation_LR/ ├── requirements.txt └── README.md ``` ## Setup ### 1. Install dependencies ```bash pip install -r requirements.txt ``` ### 2. Run locally ```bash python3 server.py ``` Open http://localhost:5000 ### 3. Run with Gunicorn (production) ```bash gunicorn server:app --bind 0.0.0.0:5000 --workers 4 ``` ## Configuration All paths are configurable via environment variables: | Variable | Default | Description | |----------|---------|-------------| | `IMAGE_BASE_PATH` | `./campaign_images` | Root folder containing `{year}/{campaign}/Automation_LR/` images | | `MASTER_JSON_DIR` | `./Master_Json` | Folder containing campaign JSON files | | `PORT` | `5000` | Server port (used by `python3 server.py` only) | Example: ```bash IMAGE_BASE_PATH=/mnt/data/images MASTER_JSON_DIR=/mnt/data/json PORT=8080 python3 server.py ``` ## Adding New Campaigns 1. Place the campaign JSON file in `Master_Json/` (e.g. `3045A.json`) 2. Place campaign images in `campaign_images/{year}/{campaign}/Automation_LR/` - The year is derived from the Season field in the JSON (first 4 digits) - The campaign prefix is derived from the filename before the first underscore 3. Refresh the browser — the new campaign appears in the dropdown ## API Endpoints | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/` | Review UI | | GET | `/api/files` | List available campaign JSON files | | GET | `/api/load/` | Load campaign data, images, languages, approvals | | POST | `/api/approve` | Approve/unapprove a record, save edits to master JSON | | GET | `/images///` | Serve campaign images | ## Requirements - Python 3.6+ - flask - gunicorn (for production deployment)