A complete Point of Sale (POS) system built for perfume retail in the United Arab Emirates. Full-stack web and mobile-responsive application with inventory management, sales tracking, VAT calculation, and comprehensive reporting.
- Product catalog with search and filtering by category
- Real-time inventory display (stock levels)
- Shopping cart management with quantity adjustment
- Multiple payment methods (Cash, Card, Bank Transfer)
- Automatic 5% VAT calculation (UAE compliant)
- Transaction ID generation for every sale
- Immediate inventory reduction on purchase
- Real-time stock tracking
- Low stock alerts (items below 20 units)
- Inventory history and movement logs
- Stock adjustment interface for receiving/adjustments
- Categorized product organization
- Product details: SKU, cost, selling price, description
- Daily sales reports
- Date range filtering for sales history
- Transaction summaries with VAT breakdown
- Inventory status dashboard
- Sales statistics and trends
- Revenue tracking by payment method
- Fully responsive design - Works on desktop, tablet, and mobile
- Twind/Tailwind CSS styling
- Real-time updates
- Clean, intuitive interface
- Arabic-ready UI (component structure prepared)
- Professional typography and spacing
- SQLite database for reliable data storage
- Transactional integrity for sales
- Complete audit trail via inventory logs
- Multi-user support structure (ready for expansion)
- Indexed queries for performance
perfume-pos-uae/
โโโ index.ts # Hono HTTP server with API endpoints
โโโ db/
โ โโโ schema.ts # Database initialization and demo data
โโโ frontend/
โ โโโ index.tsx # React app entry point
โ โโโ root.tsx # HTML shell with asset loading
โ โโโ favicon.svg # App icon
โ โโโ components/
โ โโโ App.tsx # Main app layout
โ โโโ ProductCatalog.tsx # Product display & search
โ โโโ Cart.tsx # Shopping cart interface
โ โโโ Checkout.tsx # Payment processing UI
โโโ README.md # Documentation
The app loads with 6 demo perfume products:
- Oud Al Amerat (AED 450)
- Rose Oud (AED 350)
- Musk Al Noor (AED 280)
- Attar Al Khaleej (AED 320)
- Agarwood Premium (AED 550)
- Rose Water (AED 150)
All products have 100 units in stock initially.
- Visit the live application URL
- Browse products by category or search by name/SKU
- Add items to cart
- Click "Checkout" to complete a sale
- Choose payment method and confirm
GET /api/products # All products with stock
GET /api/products/:id # Single product details
POST /api/sales # Create new sale transaction
Body: { items: [{id, name, price, quantity}], paymentMethod }
GET /api/inventory # All products with low stock alerts
POST /api/inventory/stock # Update stock (receive/adjust)
Body: { productId, quantity, type, reference }
GET /api/reports/sales # Sales report with filtering
Query: ?startDate=2026-08-01&endDate=2026-08-31
GET /api/dashboard # Stats: today's sales, low stock alerts, totals
id,name,sku(unique),category,price,cost,stockdescription,barcode(for future barcode scanning)- Timestamps for tracking
id,transactionId(unique),total,subtotal,vatAmountpaymentMethod(cash, card, transfer)status,createdAt
- Links products to sales with quantity and pricing
- Stores unit price at time of sale (prevents price change conflicts)
- Discount field for promotions
- Tracks all stock movements (sales, adjustments, returns)
- References transaction IDs for traceability
- Type: "sale", "adjustment", "return", etc.
- Structure for multi-user support
- PIN-based authentication (expandable)
- Roles: admin, cashier (ready for implementation)
- Frontend: React 18 with TypeScript
- Backend: Hono (lightweight HTTP framework)
- Database: SQLite (Val Town's std/sqlite)
- Styling: Twind (Tailwind CSS runtime)
- Runtime: Deno (on Val Town)
Edit db/schema.ts seedDemoData() function or use admin panel (future feature)
VAT is calculated as 5% in:
frontend/components/Cart.tsx(line withsubtotal * 0.05)frontend/components/Checkout.tsx(same calculation)index.ts/api/salesendpoint
Change 0.05 to your desired rate everywhere.
Categories are auto-detected from products. Add new products with new category names.
Update the <select> in frontend/components/Checkout.tsx to add/remove payment options.
The POS is 100% mobile-responsive:
- Stack layout on small screens (product list above cart)
- Touch-friendly buttons and inputs
- Optimized for portrait and landscape
- Works offline with local cart (data syncs on reconnect)
User Selects Products
โ
Cart Updates (Local State)
โ
User Clicks Checkout
โ
Checkout Modal Shows (VAT Calculated)
โ
Payment Method Selected
โ
POST /api/sales
โ
Database Transaction:
1. Create sale record
2. Create sale_items (line items)
3. Update product stock
4. Log inventory movements
โ
Success Response + Transaction ID
โ
Cart Cleared, UI Reset
- User Authentication - Implement PIN login for cashiers
- Barcode Scanning - Integrate barcode reader for faster checkout
- Receipt Printing - Generate and print itemized receipts
- Arabic Localization - Full RTL support for Arabic cashiers
- Discounts & Promotions - Percentage/fixed discounts per transaction
- Refunds & Returns - Process returns and credit notes
- Advanced Analytics - Charts, graphs, profitability analysis
- Multi-Location - Support multiple stores with sync
- Supplier Management - Track suppliers and purchase orders
- Cost Tracking - Monitor profit margins by product/category
- Cloud Sync - Backup sales data to cloud
- Offline Mode - Complete offline functionality with sync queue
- Single-user (PIN auth not yet implemented)
- No persistent cart between sessions (by design)
- No barcode scanning support
- Reports run in-memory (suitable for high volume due to SQLite performance)
Built on Val Town โข Full Stack โข Production-Ready
Need help? Check the source code at View Source