|
| 1 | +import Component from '../../../../../src/component/Base.mjs'; |
| 2 | + |
| 3 | +/** |
| 4 | + * @class DevIndex.view.home.component.Heuristics |
| 5 | + * @extends Neo.component.Base |
| 6 | + */ |
| 7 | +class Heuristics extends Component { |
| 8 | + static config = { |
| 9 | + /** |
| 10 | + * @member {String} className='DevIndex.view.home.component.Heuristics' |
| 11 | + * @protected |
| 12 | + */ |
| 13 | + className: 'DevIndex.view.home.component.Heuristics', |
| 14 | + /** |
| 15 | + * @member {String[]} cls=['devindex-heuristics'] |
| 16 | + */ |
| 17 | + cls: ['devindex-heuristics'], |
| 18 | + /** |
| 19 | + * @member {Object|null} heuristics_=null |
| 20 | + */ |
| 21 | + heuristics_: null, |
| 22 | + /** |
| 23 | + * @member {Object} _vdom |
| 24 | + */ |
| 25 | + _vdom: |
| 26 | + {cn: [ |
| 27 | + {tag: 'span', cls: ['devindex-badge']}, // Velocity |
| 28 | + {tag: 'span', cls: ['devindex-badge']}, // Acceleration |
| 29 | + {tag: 'span', cls: ['devindex-badge']} // Consistency |
| 30 | + ]} |
| 31 | + } |
| 32 | + |
| 33 | + /** |
| 34 | + * @param {Object|null} value |
| 35 | + * @param {Object|null} oldValue |
| 36 | + */ |
| 37 | + afterSetHeuristics(value, oldValue) { |
| 38 | + let me = this, |
| 39 | + {vdom} = me, |
| 40 | + nodes = vdom.cn, |
| 41 | + badges, v, a, c; |
| 42 | + |
| 43 | + if (value) { |
| 44 | + ({v, a, c} = value); |
| 45 | + badges = []; |
| 46 | + |
| 47 | + // 1. Velocity (v) |
| 48 | + if (v > 1000) { |
| 49 | + badges.push({cls: 'fire', icon: '🔥', title: 'Velocity: Superhuman (>1k/day)'}) |
| 50 | + } else if (v > 100) { |
| 51 | + badges.push({cls: 'bolt', icon: '⚡', title: 'Velocity: High (>100/day)'}) |
| 52 | + } |
| 53 | + |
| 54 | + // 2. Acceleration (a) |
| 55 | + if (a > 10) { |
| 56 | + badges.push({cls: 'rocket', icon: '🚀', title: 'Acceleration: Explosive Growth (>10x)'}) |
| 57 | + } else if (a > 2) { |
| 58 | + badges.push({cls: 'trend-up', icon: '📈', title: 'Acceleration: Rising Star (>2x)'}) |
| 59 | + } |
| 60 | + |
| 61 | + // 3. Consistency (c) |
| 62 | + if (c > 10) { |
| 63 | + badges.push({cls: 'pillar', icon: '🏛️', title: 'Consistency: Community Pillar (>10y)'}) |
| 64 | + } else if (c > 5) { |
| 65 | + badges.push({cls: 'shield', icon: '🛡️', title: 'Consistency: Veteran (>5y)'}) |
| 66 | + } |
| 67 | + |
| 68 | + // Zero State |
| 69 | + if (badges.length === 0 && c <= 1) { |
| 70 | + badges.push({cls: 'seedling', icon: '🌱', title: 'New Contributor'}) |
| 71 | + } |
| 72 | + |
| 73 | + // Map badges to fixed nodes |
| 74 | + nodes.forEach((node, index) => { |
| 75 | + let badge = badges[index]; |
| 76 | + |
| 77 | + if (badge) { |
| 78 | + node.cls = ['devindex-badge', badge.cls]; |
| 79 | + node.title = badge.title; |
| 80 | + node.html = badge.icon; // Using html for emoji chars is fine, but text is safer? Emoji IS text. |
| 81 | + node.style = null // Remove visibility: hidden |
| 82 | + } else { |
| 83 | + node.style = {visibility: 'hidden'} |
| 84 | + } |
| 85 | + }); |
| 86 | + } else { |
| 87 | + // Hide all if no data |
| 88 | + nodes.forEach(node => { |
| 89 | + node.style = {visibility: 'hidden'} |
| 90 | + }) |
| 91 | + } |
| 92 | + |
| 93 | + me.update() |
| 94 | + } |
| 95 | +} |
| 96 | + |
| 97 | +export default Neo.setupClass(Heuristics); |
0 commit comments