/* QuoteFlow Prototype · shared helpers (Icon, CatTile, useStore, format). */ function qfPascal(name) { return name.split(/[-_ ]/).filter(Boolean).map(function (s) { return s[0].toUpperCase() + s.slice(1); }).join(''); } /* Lucide icon as a pure React SVG (re-render safe). */ function Icon({ name, size = 20, stroke = 2, color = 'currentColor', style, ...rest }) { var node = window.lucide && window.lucide.icons[qfPascal(name)]; if (!node) return null; var children = node[2] || []; return React.createElement('svg', { xmlns: 'http://www.w3.org/2000/svg', width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round', style: style, ...rest, }, children.map(function (c, i) { return React.createElement(c[0], Object.assign({ key: i }, c[1])); })); } var QF_CAT = { solar: ['var(--cat-solar-bg)', 'var(--cat-solar-fg)', 'sun'], battery: ['var(--cat-battery-bg)', 'var(--cat-battery-fg)', 'battery-charging'], ev: ['var(--cat-ev-bg)', 'var(--cat-ev-fg)', 'zap'], auto: ['var(--cat-auto-bg)', 'var(--cat-auto-fg)', 'layout-grid'], heat: ['var(--cat-heat-bg)', 'var(--cat-heat-fg)', 'flame'], aircon: ['var(--cat-aircon-bg)', 'var(--cat-aircon-fg)', 'air-vent'], mvhr: ['var(--cat-mvhr-bg)', 'var(--cat-mvhr-fg)', 'refresh-cw'], }; function CatTile({ cat, icon, size = 44 }) { var c = QF_CAT[cat] || QF_CAT.solar; return ( ); } /* Subscribe a component to the store; returns a bump counter. */ function useStore() { var ref = React.useReducer(function (x) { return x + 1; }, 0); var force = ref[1]; React.useEffect(function () { return window.QFStore.subscribe(force); }, []); return window.QFStore; } var gbp = function (n) { return '£' + Math.round(n).toLocaleString('en-GB'); }; var gbp2 = function (n) { return '£' + n.toLocaleString('en-GB', { minimumFractionDigits: (n % 1 ? 2 : 0), maximumFractionDigits: 2 }); }; /* Trigger a browser download of text content (used for CSV export). */ function downloadText(filename, text, mime) { var blob = new Blob([text], { type: (mime || 'text/csv') + ';charset=utf-8;' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); setTimeout(function () { URL.revokeObjectURL(url); }, 1000); } Object.assign(window, { Icon, CatTile, useStore, qfPascal, QF_CAT, gbp, gbp2, downloadText });