A full-stack web application that automates generating and printing offer tags from CSV files. Supports both preset and custom HTML/CSS templates for PDF generation.
- CSV Upload: Batch import offers from CSV files
- Offer Management: View and select offers in an intuitive grid
- Template System: Choose from preset templates or upload custom designs
- PDF Generation: Server-side rendering with Jinja2 templating
- Responsive Design: Works seamlessly on all devices
- Real-time Preview: See changes instantly
- Batch Processing: Generate PDFs for multiple offers at once
- FastAPI - Modern Python web framework
- Motor - Async MongoDB driver
- Pyppeteer - Headless browser for PDF generation
- Pydantic - Data validation
- Jinja2 - Template rendering
- React 18 - UI framework
- Vite - Build tool
- Tailwind CSS - Utility-first CSS
- Axios - HTTP client
- React Hot Toast - Notifications
- MongoDB - NoSQL database for offers and templates
aops/
βββ backend/
β βββ app/
β β βββ api/
β β β βββ offers.py # Offer endpoints
β β β βββ templates.py # Template endpoints
β β β βββ pdf.py # PDF generation endpoints
β β βββ models/
β β β βββ offer.py # Offer Pydantic model
β β β βββ template.py # Template Pydantic model
β β βββ services/
β β β βββ db.py # MongoDB operations
β β β βββ pdfgen.py # PDF generation service
β β β βββ storage.py # File storage service
β β βββ templates/
β β β βββ preset_minimal.html # Minimal template
β β β βββ preset_promo.html # Promotional template
β β β βββ preset_multi.html # Multi-column template
β β βββ main.py # FastAPI app entry point
β βββ requirements.txt
βββ frontend/
β βββ src/
β β βββ components/
β β β βββ UploadCSV.jsx # CSV upload component
β β β βββ OfferPreview.jsx # Offer grid component
β β β βββ TemplateManager.jsx # Template selection
β β β βββ PDFGenerator.jsx # PDF generation
β β βββ pages/
β β β βββ Dashboard.jsx # Main dashboard
β β β βββ Settings.jsx # Settings page
β β βββ services/
β β β βββ api.js # API calls
β β βββ App.jsx # Main app component
β β βββ main.jsx # React entry point
β β βββ index.css # Global styles
β βββ vite.config.js
β βββ tailwind.config.js
β βββ package.json
βββ README.md
- Install Dependencies
cd backend
pip install -r requirements.txt- Configure MongoDB
# Default: mongodb://localhost:27017
# Or set env variable: MONGODB_URI=your_mongodb_url- Run Server
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000Backend will be available at http://localhost:8000
API docs available at http://localhost:8000/docs
- Install Dependencies
cd frontend
npm install- Start Development Server
npm run devFrontend will be available at http://localhost:5173
- Build for Production
npm run buildPOST /offers/upload-csv- Upload CSV fileGET /offers?skip=0&limit=50- Get offers with paginationGET /offers/{offer_id}- Get single offer
POST /templates/upload- Upload custom template ZIPGET /templates- Get all templatesGET /templates/preset- Get preset templates onlyGET /templates/{template_id}- Get single template
POST /pdf/generate- Generate PDF with selected offersPOST /pdf/preview- Preview PDF as HTML
Expected columns in CSV file:
product_id,product_name,brand,offer_type,offer_details,price,mrp,valid_till
PRD-001,Wireless Headphones,TechBrand,Discount,20% off,4999,6999,2025-12-31
PRD-002,Smart Watch,TechBrand,Seasonal,Limited Time,7999,9999,2025-12-15
- Minimal Clean - Simple 4-column grid with essential info
- Promotional Bold - Eye-catching design with vibrant colors
- Detailed Multi-Column - 2-column layout with pricing breakdown
Upload a ZIP file containing:
index.html- Main template file with Jinja2 syntaxstyles.css(optional) - Additional CSS- Other assets (images, fonts, etc.)
Use {{ offer.field }} in templates to reference offer data:
{{ offer.product_name }}{{ offer.brand }}{{ offer.price }}{{ offer.mrp }}{{ offer.valid_till }}{{ offer.offer_type }}{{ offer.offer_details }}
MONGODB_URI=mongodb://localhost:27017
ENVIRONMENT=development
DEBUG=true
VITE_API_URL=http://localhost:8000
- Upload CSV - Select and upload your offers CSV file
- Preview Offers - View uploaded offers in grid format
- Select Offers - Check which offers to include in PDF
- Choose Template - Select a preset or upload custom template
- Generate PDF - Click to create PDF with selected offers
- Download - Download the generated PDF to print
- Validates data against Pydantic models
- Skips invalid rows and provides feedback
- Shows preview of first 5 uploaded offers
- Returns count of successfully inserted documents
- Responsive grid with auto-fill columns
- Checkbox selection for batch operations
- Pagination support for large datasets
- Shows key offer information
- Preset templates with professional designs
- Custom template upload via ZIP files
- Live template selection with instant preview
- Layout options (page size, offers per page, orientation)
- Server-side rendering using Jinja2
- Async processing with pyppeteer
- Configurable page layout and spacing
- Download links for generated PDFs
# Ensure MongoDB is running
mongod
# Check connection string in .env
MONGODB_URI=mongodb://localhost:27017- Ensure Node.js dependencies are installed
- Check pyppeteer installation
- Verify sufficient disk space for temporary files
- Backend CORS is configured for localhost:3000 and localhost:5173
- Add additional origins in
app/main.pyif needed
- Preset templates are auto-initialized on server startup
- Check database connection and permissions
- Build Frontend
cd frontend
npm run build- Set Environment Variables
ENVIRONMENT=production
MONGODB_URI=your_production_mongodb
FRONTEND_URL=your_frontend_url- Run Backend
uvicorn app.main:app --host 0.0.0.0 --port 8000- Serve Frontend
- Deploy
frontend/distto static file server - Or use FastAPI static file serving
MIT
Contributions are welcome! Please feel free to submit a Pull Request.
For issues or questions, please open an issue on GitHub.
AOPS - Making offer tag printing automated and effortless! π·οΈ