/* global React, ReactDOM */ const { useState, useEffect, useMemo, useRef } = React; // ============================================================================= // DEMO MODE — append ?demo=1 to URL. Stubs all /api/* calls with seeded data // so the admin can be previewed with no backend. Production: do not pass flag. // ============================================================================= if (location.search.indexOf('demo=1') !== -1) { const demoUser = { id: 1, name: 'Anita (Demo)', email: 'demo@lacquerynails.in', role: 'admin', permissions: [] }; const today = new Date().toISOString().slice(0, 10); const tomorrow = new Date(Date.now() + 86400000).toISOString().slice(0, 10); const minusDays = (n) => new Date(Date.now() - n * 86400000).toISOString().slice(0, 19).replace('T', ' '); const STUBS = { '/csrf': { csrf: 'demo-token', user: demoUser }, '/dashboard': { stats: { today_appointments: 6, pending_orders: 3, refill_due: 4, low_stock: 2, total_clients: 142, completed_this_week: 23, }, upcoming: [ { id: 101, name: 'Ananya Reddy', mobile: '+91 98765 43210', service: 'Gel Polish', appt_date: today, appt_time: '11:00 AM', status: 'confirmed' }, { id: 102, name: 'Priya Sharma', mobile: '+91 99876 54321', service: 'Gel Extensions', appt_date: today, appt_time: '2:30 PM', status: 'pending' }, { id: 103, name: 'Meera Iyer', mobile: '+91 91234 56789', service: 'Nail Art', appt_date: tomorrow, appt_time: '10:30 AM', status: 'confirmed' }, { id: 104, name: 'Kavya Nair', mobile: '+91 99887 76655', service: 'Refill', appt_date: tomorrow, appt_time: '4:00 PM', status: 'pending' }, { id: 105, name: 'Riya Menon', mobile: '+91 98123 45670', service: 'Pedicure', appt_date: tomorrow, appt_time: '6:30 PM', status: 'confirmed' }, ], recent_orders: [ { id: 201, order_code: 'LQ-260501-A4F2', customer_name: 'Tara Kapoor', product_name: 'Aurora Chrome', total: 999, status: 'pending', created_at: minusDays(0) }, { id: 202, order_code: 'LQ-260501-B81C', customer_name: 'Aisha Rao', product_name: 'Vintage Rose', total: 1199, status: 'processing', created_at: minusDays(1) }, { id: 203, order_code: 'LQ-260430-C2E0', customer_name: 'Naina Patel', product_name: 'Pearl Drop', total: 1499, status: 'shipped', created_at: minusDays(2) }, { id: 204, order_code: 'LQ-260430-D915', customer_name: 'Sanya Joshi', product_name: 'Cat Eye Galaxy', total: 1099, status: 'delivered', created_at: minusDays(3) }, ], }, '/appointments': [ { id: 101, name: 'Ananya Reddy', mobile: '+91 98765 43210', service: 'Gel Polish', appt_date: today, appt_time: '11:00 AM', status: 'confirmed', source: 'online' }, { id: 102, name: 'Priya Sharma', mobile: '+91 99876 54321', service: 'Gel Extensions', appt_date: today, appt_time: '2:30 PM', status: 'pending', source: 'whatsapp'}, { id: 103, name: 'Meera Iyer', mobile: '+91 91234 56789', service: 'Nail Art', appt_date: tomorrow, appt_time: '10:30 AM', status: 'confirmed', source: 'online' }, { id: 104, name: 'Kavya Nair', mobile: '+91 99887 76655', service: 'Refill', appt_date: tomorrow, appt_time: '4:00 PM', status: 'pending', source: 'walk_in' }, { id: 105, name: 'Riya Menon', mobile: '+91 98123 45670', service: 'Pedicure', appt_date: tomorrow, appt_time: '6:30 PM', status: 'confirmed', source: 'phone' }, { id: 106, name: 'Tara Kapoor', mobile: '+91 99988 77665', service: 'Manicure', appt_date: today, appt_time: '5:00 PM', status: 'completed', source: 'online' }, ], '/clients': [ { id: 1, name: 'Ananya Reddy', mobile: '+91 98765 43210', email: 'ananya@example.com', total_visits: 8, total_spend: 9800, no_show_count: 0, last_visit_at: '2026-04-22 14:30:00', last_service: 'Gel Polish', refill_due_at: null, tags: ['Bestseller'] }, { id: 2, name: 'Priya Sharma', mobile: '+91 99876 54321', email: 'priya@example.com', total_visits: 4, total_spend: 6800, no_show_count: 1, last_visit_at: '2026-04-15 11:00:00', last_service: 'Gel Extensions', refill_due_at: today, tags: [] }, { id: 3, name: 'Meera Iyer', mobile: '+91 91234 56789', email: null, total_visits: 12,total_spend: 15200, no_show_count: 0, last_visit_at: '2026-04-28 16:00:00', last_service: 'Nail Art', refill_due_at: null, tags: ['VIP'] }, { id: 4, name: 'Kavya Nair', mobile: '+91 99887 76655', email: 'kavya@example.com', total_visits: 2, total_spend: 2998, no_show_count: 0, last_visit_at: '2026-04-08 13:00:00', last_service: 'Acrylic Extensions', refill_due_at: minusDays(2).slice(0,10), tags: [] }, ], '/products': [ { id: 1, name: 'Aurora Chrome', category: 'Chrome', shape: 'Almond', price: 999, purchase_price: 350, stock: 8, low_stock_alert: 3, tags: ['Bestseller'], photo_path: null, is_active: 1 }, { id: 2, name: 'Vintage Rose', category: 'Florals', shape: 'Coffin', price: 1199, purchase_price: 420, stock: 4, low_stock_alert: 3, tags: ['Hand-painted'], photo_path: null, is_active: 1 }, { id: 3, name: 'Micro French', category: 'French', shape: 'Stiletto', price: 899, purchase_price: 300, stock: 2, low_stock_alert: 3, tags: [], photo_path: null, is_active: 1 }, { id: 4, name: 'Pearl Drop', category: '3D Charms', shape: 'Square', price: 1499, purchase_price: 580, stock: 6, low_stock_alert: 3, tags: ['Bridal'], photo_path: null, is_active: 1 }, { id: 5, name: 'Cat Eye Galaxy',category: 'Glitter', shape: 'Almond', price: 1099, purchase_price: 380, stock: 9, low_stock_alert: 3, tags: ['New'], photo_path: null, is_active: 1 }, { id: 6, name: 'Butter Nude', category: 'Minimal', shape: 'Short Square', price: 799, purchase_price: 280, stock: 1, low_stock_alert: 3, tags: [], photo_path: null, is_active: 1 }, ], '/orders': [ { id: 201, order_code: 'LQ-260501-A4F2', customer_name: 'Tara Kapoor', customer_mobile: '+91 99988 77665', product_name: 'Aurora Chrome', quantity: 1, total: 999, status: 'pending', label_printed: 0, created_at: minusDays(0) }, { id: 202, order_code: 'LQ-260501-B81C', customer_name: 'Aisha Rao', customer_mobile: '+91 99001 23456', product_name: 'Vintage Rose', quantity: 1, total: 1199, status: 'processing', label_printed: 0, created_at: minusDays(1) }, { id: 203, order_code: 'LQ-260430-C2E0', customer_name: 'Naina Patel', customer_mobile: '+91 90909 90909', product_name: 'Pearl Drop', quantity: 1, total: 1499, status: 'shipped', label_printed: 1, created_at: minusDays(2) }, { id: 204, order_code: 'LQ-260430-D915', customer_name: 'Sanya Joshi', customer_mobile: '+91 98765 12340', product_name: 'Cat Eye Galaxy', quantity: 2, total: 2198, status: 'delivered', label_printed: 1, created_at: minusDays(3) }, ], '/photos': {}, '/settings/site': { whatsappNumber: '918317451779', phone: '+91 83174 51779', email: 'hello@lacquerynails.in', address: 'Near Shrirampura Metro, Bengaluru', hours: 'Mon to Sun · 10 AM to 9 PM' }, '/settings/offers_banner': { enabled: true, text: 'Festive offer · 20% off all press-on sets · code LACQUER20' }, '/settings/shipping': { provider: 'manual', shiprocket_email: '', shiprocket_password: '' }, '/settings/payment': { razorpay_key_id: '', razorpay_key_secret: '', webhook_secret: '', enable_booking_fee: false, enable_shop_payment: true }, '/settings/refill_rules': { days: 21, services: ['Gel Extensions', 'Acrylic Extensions', 'Permanent Extensions'], message: '' }, '/blog': [ { id: 1, title: 'Best Gel Polish Salon Near Shrirampura', slug: 'best-gel-polish-shrirampura', status: 'published', updated_at: minusDays(2) }, { id: 2, title: 'Press-On Nails vs Gel Extensions: What to Pick', slug: 'press-on-vs-gel-extensions', status: 'published', updated_at: minusDays(5) }, { id: 3, title: 'Bridal Nail Trends 2026 — Bengaluru Edition', slug: 'bridal-nail-trends-2026', status: 'draft', updated_at: minusDays(1) }, ], '/users': [ { id: 1, name: 'Anita (Demo)', email: 'demo@lacquerynails.in', role: 'admin', permissions: [], is_active: 1, last_login_at: minusDays(0), created_at: minusDays(45) }, { id: 2, name: 'Sneha Technician', email: 'sneha@lacquerynails.in', role: 'staff', permissions: ['dashboard','appointments','clients','reminders','shipping'], is_active: 1, last_login_at: minusDays(1), created_at: minusDays(20) }, ], '/audit': [ { id: 1, user_id: 1, user_email: 'demo@lacquerynails.in', action: 'login', entity_type: 'user', entity_id: 1, meta: null, ip: '127.0.0.1', created_at: minusDays(0) }, { id: 2, user_id: 1, user_email: 'demo@lacquerynails.in', action: 'appointment_create', entity_type: 'appointment', entity_id: 106, meta: { source: 'walk_in' }, ip: '127.0.0.1', created_at: minusDays(0) }, { id: 3, user_id: 2, user_email: 'sneha@lacquerynails.in', action: 'order_update', entity_type: 'order', entity_id: 203, meta: { fields: ['status'] }, ip: '127.0.0.1', created_at: minusDays(1) }, { id: 4, user_id: 1, user_email: 'demo@lacquerynails.in', action: 'photo_upload', entity_type: 'photo', entity_id: null, meta: { slot_key: 'hero-photo' },ip: '127.0.0.1', created_at: minusDays(2) }, ], '/reminders': { one_day: [ { id: 103, name: 'Meera Iyer', mobile: '+91 91234 56789', service: 'Nail Art', appt_time: '10:30 AM' }, { id: 104, name: 'Kavya Nair', mobile: '+91 99887 76655', service: 'Refill', appt_time: '4:00 PM' }, ], two_hour: [ { id: 102, name: 'Priya Sharma', mobile: '+91 99876 54321', service: 'Gel Extensions', appt_time: '2:30 PM' }, ], refill: [ { id: 2, name: 'Priya Sharma', mobile: '+91 99876 54321', email: 'priya@example.com', last_service: 'Gel Extensions', last_visit_at: '2026-04-15' }, { id: 4, name: 'Kavya Nair', mobile: '+91 99887 76655', email: 'kavya@example.com', last_service: 'Acrylic Extensions', last_visit_at: '2026-04-08' }, ], }, '/notifications': { max_appointment_id: 106, max_order_id: 204, new_appointments: [], new_orders: [] }, }; window.LQ = { API_BASE: '/api', request: function (path) { const cleanPath = path.split('?')[0]; const data = STUBS[cleanPath]; if (data !== undefined) return Promise.resolve(JSON.parse(JSON.stringify(data))); return Promise.resolve(null); }, refreshSession: function () { return Promise.resolve(demoUser); }, login: function () { return Promise.resolve(demoUser); }, logout: function () { return Promise.resolve(); }, requestReset: function () { return Promise.resolve(); }, confirmReset: function () { return Promise.resolve(); }, uploadPhoto: function () { return Promise.resolve({ slot_key: 'demo', file_path: '' }); }, downloadFile: function () { alert('Demo mode: download disabled.'); }, user: function () { return demoUser; }, onAuthChange: function () { return function () {}; }, }; } // Manual shipping label — opens printable window. No backend required. window.LQ_printManualLabel = function (order, shipping) { shipping = shipping || {}; function esc(s) { return String(s == null ? '' : s).replace(/[&<>"]/g, c => ({'&':'&','<':'<','>':'>','"':'"'})[c]); } const fromBlock = [ esc(shipping.from_name || 'Lacquery Nails'), esc(shipping.from_address || 'Near Shrirampura Metro'), [esc(shipping.from_city || 'Bengaluru'), esc(shipping.from_state || 'Karnataka'), esc(shipping.from_pincode || '')].filter(Boolean).join(' · '), 'Phone: ' + esc(shipping.from_phone || '+91 83174 51779'), shipping.from_gstin ? 'GSTIN: ' + esc(shipping.from_gstin) : '' ].filter(Boolean).join('
'); const toBlock = [ '' + esc(order.customer_name) + '', esc(order.customer_address || '— address pending, ask on WhatsApp —'), 'Phone: ' + esc(order.customer_mobile), order.customer_email ? esc(order.customer_email) : '' ].filter(Boolean).join('
'); const html = ` Shipping Label · ${esc(order.order_code)}
Lacquery Nails
${esc(order.order_code)}
From
${fromBlock}
Ship To
${toBlock}
Contents
${esc(order.product_name)} × ${esc(order.quantity || 1)}