// Mock data for FLUX const FLUXData = (() => { const stores = [ { id:'CDMX', name:'Tienda CDMX', city:'Ciudad de México', sales:2450230, salesDelta:18.2, breakages:-76, breakagesDelta:20.5, inventory:1245, rotation:24, alerts:2, lat:19.43, lng:-99.13, manager:'Lucía Reyes' }, { id:'MTY', name:'Tienda Monterrey', city:'Monterrey', sales:1870540, salesDelta:14.7, breakages:-68, breakagesDelta:15.3, inventory:980, rotation:21, alerts:0, lat:25.67, lng:-100.31, manager:'Diego Salinas' }, { id:'GDL', name:'Tienda Guadalajara', city:'Guadalajara', sales:1450330, salesDelta:11.3, breakages:-72, breakagesDelta:18.1, inventory:865, rotation:20, alerts:0, lat:20.66, lng:-103.34, manager:'Ana Cervantes' }, { id:'PUE', name:'Tienda Puebla', city:'Puebla', sales:950120, salesDelta:9.8, breakages:-65, breakagesDelta:10.2, inventory:710, rotation:19, alerts:1, lat:19.04, lng:-98.20, manager:'Roberto Mejía' }, { id:'CUN', name:'Tienda Cancún', city:'Cancún', sales:845300, salesDelta:8.1, breakages:-71, breakagesDelta:12.4, inventory:620, rotation:18, alerts:0, lat:21.16, lng:-86.85, manager:'Sofía Vargas' }, { id:'TIJ', name:'Tienda Tijuana', city:'Tijuana', sales:780210, salesDelta:6.4, breakages:-58, breakagesDelta:7.9, inventory:540, rotation:17, alerts:1, lat:32.51, lng:-117.04, manager:'Mateo Ríos' }, { id:'MID', name:'Tienda Mérida', city:'Mérida', sales:640150, salesDelta:12.1, breakages:-62, breakagesDelta:9.4, inventory:485, rotation:16, alerts:0, lat:20.97, lng:-89.62, manager:'Carla Montero' }, { id:'QRO', name:'Tienda Querétaro', city:'Querétaro', sales:710480, salesDelta:15.6, breakages:-69, breakagesDelta:14.2, inventory:512, rotation:18, alerts:0, lat:20.59, lng:-100.39, manager:'Hugo Bautista' }, ]; // 31 days of inventory + demand const days = Array.from({length:31}, (_,i) => { const t = i / 30; const base = 28000 + Math.sin(i*0.42)*8500 + Math.cos(i*0.25)*3000; const inventory = Math.round(base + (i===14 ? 1500 : 0)); const demand = Math.round(base*0.86 + Math.sin(i*0.55+1)*4000 - i*120); return { day:i+1, label:`${i+1} may`, inventory, demand }; }); const categories = [ { id:'electronica', name:'Electrónica', breakReduction:-82, demand:8200, color:'#F5A524' }, { id:'hogar', name:'Hogar', breakReduction:-74, demand:5400, color:'#E8941A' }, { id:'moda', name:'Moda', breakReduction:-66, demand:4900, color:'#D97706' }, { id:'deportes', name:'Deportes', breakReduction:-65, demand:3100, color:'#B45309' }, { id:'belleza', name:'Belleza', breakReduction:-58, demand:2530, color:'#92400E' }, ]; const inventoryStatus = [ { label:'Disponible', count:3215, pct:47, color:'#16A34A' }, { label:'En tránsito', count:1128, pct:16, color:'#2563EB' }, { label:'Reservado', count:1045, pct:15, color:'#7C3AED' }, { label:'Sin stock', count:982, pct:14, color:'#DC2626' }, { label:'Dañado', count:472, pct:7, color:'#F5A524' }, ]; const channels = [ { label:'Tienda física', count:12450, pct:52, color:'#F5A524' }, { label:'E-commerce', count:7210, pct:30, color:'#E8941A' }, { label:'Marketplaces', count:3350, pct:14, color:'#FCE9C2' }, { label:'Otros', count:1120, pct:4, color:'#ECE6DC' }, ]; const alerts = [ { id:1, level:'critical', title:'Stock mínimo alcanzado', detail:'SKU-1248 · Tienda CDMX', time:'Hoy, 09:15', sku:'SKU-1248', store:'CDMX', action:'Solicitar reabasto' }, { id:2, level:'critical', title:'Alta probabilidad de quiebre', detail:'SKU-8872 · Tienda Monterrey', time:'Hoy, 08:40', sku:'SKU-8872', store:'MTY', action:'Transferir desde GDL' }, { id:3, level:'warning', title:'Retraso en entrega', detail:'PO-3392 · Proveedor ABC', time:'Ayer, 17:35', sku:'PO-3392', store:'—', action:'Contactar proveedor' }, { id:4, level:'warning', title:'Variación inusual de demanda', detail:'SKU-2311 · Tienda Guadalajara', time:'Ayer, 14:20', sku:'SKU-2311', store:'GDL', action:'Revisar pronóstico' }, { id:5, level:'info', title:'Nueva integración disponible', detail:'Conector Shopify v2.4', time:'Ayer, 11:02', sku:'—', store:'—', action:'Configurar' }, { id:6, level:'critical', title:'Quiebre detectado', detail:'SKU-5519 · Tienda Puebla', time:'Hoy, 07:22', sku:'SKU-5519', store:'PUE', action:'Reabastecer urgente' }, { id:7, level:'warning', title:'Caducidad próxima (30 días)', detail:'SKU-7104 · 142 unidades', time:'Ayer, 09:50', sku:'SKU-7104', store:'CDMX', action:'Promocionar' }, ]; const integrations = [ { id:'sap', name:'ERP · SAP S/4HANA', vendor:'SAP', kind:'ERP', status:'connected', last:'hace 2 min' }, { id:'wms', name:'WMS · Manhattan', vendor:'Manhattan', kind:'WMS', status:'connected', last:'hace 5 min' }, { id:'pos', name:'POS · Oracle Retail', vendor:'Oracle', kind:'POS', status:'connected', last:'hace 1 min' }, { id:'pbi', name:'Power BI', vendor:'Microsoft', kind:'BI', status:'connected', last:'hace 12 min' }, { id:'shopify', name:'Shopify Plus', vendor:'Shopify', kind:'E-commerce', status:'available', last:'—' }, { id:'salesforce', name:'Salesforce CRM', vendor:'Salesforce', kind:'CRM', status:'available', last:'—' }, { id:'slack', name:'Slack', vendor:'Slack', kind:'Comms', status:'connected', last:'hace 30 min' }, { id:'twilio', name:'Twilio', vendor:'Twilio', kind:'SMS', status:'available', last:'—' }, ]; // Top SKUs const skus = [ { sku:'SKU-1248', name:'Audífonos Bluetooth Pro X', category:'Electrónica', stock:8, threshold:50, sold30:412, forecast30:480, store:'CDMX', risk:0.92, price:1899, supplier:'TechCorp MX' }, { sku:'SKU-8872', name:'Cafetera Espresso Compact', category:'Hogar', stock:14, threshold:60, sold30:298, forecast30:340, store:'MTY', risk:0.88, price:3499, supplier:'HomeWare SA' }, { sku:'SKU-2311', name:'Mochila trail 28L', category:'Deportes', stock:142, threshold:80, sold30:188, forecast30:265, store:'GDL', risk:0.41, price:1290, supplier:'OutdoorMex' }, { sku:'SKU-5519', name:'Smart TV 55" 4K', category:'Electrónica', stock:0, threshold:25, sold30:156, forecast30:175, store:'PUE', risk:0.99, price:12499, supplier:'TechCorp MX' }, { sku:'SKU-7104', name:'Set crema facial AM/PM', category:'Belleza', stock:286, threshold:100, sold30:142, forecast30:130, store:'CDMX', risk:0.18, price:899, supplier:'BeautyLine' }, { sku:'SKU-3382', name:'Tenis running W12', category:'Moda', stock:62, threshold:75, sold30:240, forecast30:280, store:'CDMX', risk:0.71, price:2199, supplier:'StrideMex' }, { sku:'SKU-9920', name:'Aspiradora Inalámbrica V8', category:'Hogar', stock:38, threshold:40, sold30:95, forecast30:120, store:'MTY', risk:0.62, price:5499, supplier:'HomeWare SA' }, { sku:'SKU-4471', name:'Bicicleta urbana 26"', category:'Deportes', stock:24, threshold:30, sold30:48, forecast30:62, store:'GDL', risk:0.55, price:6890, supplier:'OutdoorMex' }, { sku:'SKU-6602', name:'Auriculares ANC studio', category:'Electrónica', stock:194, threshold:120, sold30:312, forecast30:340, store:'CUN', risk:0.34, price:2790, supplier:'TechCorp MX' }, { sku:'SKU-1130', name:'Camisa lino slim', category:'Moda', stock:88, threshold:60, sold30:155, forecast30:170, store:'TIJ', risk:0.29, price:790, supplier:'TextilNorte' }, ]; const suppliers = [ { id:'TC', name:'TechCorp MX', contact:'Juan Marín', email:'jmarin@techcorp.mx', skus:142, otd:96, leadTime:7, rating:4.8, status:'active' }, { id:'HW', name:'HomeWare SA', contact:'Patricia Lima', email:'plima@homeware.com', skus:88, otd:91, leadTime:11, rating:4.5, status:'active' }, { id:'OM', name:'OutdoorMex', contact:'Tomás Rivas', email:'trivas@outdoormex.mx', skus:64, otd:88, leadTime:9, rating:4.3, status:'active' }, { id:'BL', name:'BeautyLine', contact:'Renata Ojeda', email:'renata@beautyline.mx', skus:112, otd:94, leadTime:5, rating:4.7, status:'active' }, { id:'SM', name:'StrideMex', contact:'Iván Pacheco', email:'ipacheco@stride.mx', skus:53, otd:82, leadTime:14, rating:3.9, status:'review' }, { id:'TN', name:'TextilNorte', contact:'Adriana Solís', email:'asolis@textilnorte.mx', skus:96, otd:90, leadTime:10, rating:4.4, status:'active' }, { id:'AB', name:'Proveedor ABC', contact:'Mario Quezada', email:'mario@abc.mx', skus:34, otd:74, leadTime:18, rating:3.4, status:'review' }, ]; const users = [ { name:'María González', role:'Admin', email:'maria@flux.mx', team:'Operaciones', status:'active', last:'En línea', avatar:'MG' }, { name:'Lucía Reyes', role:'Manager', email:'lucia@flux.mx', team:'Tienda CDMX', status:'active', last:'hace 5 min', avatar:'LR' }, { name:'Diego Salinas', role:'Manager', email:'diego@flux.mx', team:'Tienda MTY', status:'active', last:'hace 12 min', avatar:'DS' }, { name:'Ana Cervantes', role:'Manager', email:'ana@flux.mx', team:'Tienda GDL', status:'active', last:'hace 30 min', avatar:'AC' }, { name:'Bruno Aldama', role:'Analyst', email:'bruno@flux.mx', team:'Analytics', status:'active', last:'hace 1 h', avatar:'BA' }, { name:'Sofía Vargas', role:'Manager', email:'sofia@flux.mx', team:'Tienda CUN', status:'active', last:'hace 3 h', avatar:'SV' }, { name:'Roberto Mejía', role:'Manager', email:'roberto@flux.mx', team:'Tienda PUE', status:'active', last:'hace 1 d', avatar:'RM' }, { name:'Karla Núñez', role:'Viewer', email:'karla@flux.mx', team:'Finanzas', status:'invited', last:'—', avatar:'KN' }, ]; // Forecast data — 60d historical + 30d forecast const forecast = (() => { const arr = []; for(let i=0;i<90;i++){ const t = i; const base = 22000 + Math.sin(t*0.18)*5000 + Math.cos(t*0.09)*3000 + t*45; arr.push({ day:i+1, actual: i<60 ? Math.round(base + (Math.sin(t*1.3)*1500)) : null, forecast: i>=58 ? Math.round(base + Math.sin(t*0.2)*1000) : null, upper: i>=58 ? Math.round(base*1.08 + Math.sin(t*0.2)*1000 + 1500) : null, lower: i>=58 ? Math.round(base*0.92 + Math.sin(t*0.2)*1000 - 1500) : null, }); } return arr; })(); // AI insights const insights = [ { id:1, severity:'high', icon:'Sparkles', title:'Transferencia recomendada', body:'SKU-8872 (Cafetera Espresso) tiene 14 u. en MTY con riesgo 88% de quiebre, y 67 u. en GDL con baja rotación. Transferir 25 u. equilibraría ambas tiendas.', cta:'Ejecutar transferencia' }, { id:2, severity:'high', icon:'Brain', title:'Patrón estacional detectado', body:'La demanda de Electrónica en Cancún sube 34% durante temporada de cruceros (mayo-jun). Sugiero subir cobertura de SKU-6602 a 240 u. antes del 20 may.', cta:'Aplicar pronóstico' }, { id:3, severity:'medium', icon:'Target', title:'Promoción inteligente', body:'SKU-7104 tiene 286 u. y caducidad en 30 días. Una promoción 2x1 absorbería el inventario en ~9 días y mantendría margen ≥18%.', cta:'Crear promoción' }, { id:4, severity:'medium', icon:'Activity', title:'Anomalía de tráfico', body:'Tienda Tijuana muestra -23% de tráfico los miércoles vs. promedio. Posible problema operativo o de horarios.', cta:'Investigar' }, ]; return { stores, days, categories, inventoryStatus, channels, alerts, integrations, skus, suppliers, users, forecast, insights }; })(); window.FLUXData = FLUXData;