diff --git a/Documents/Vibe Coding Projects/dedicatednodes-redesign/dedicatednodes-bare-metal/new-baremetal.html b/Documents/Vibe Coding Projects/dedicatednodes-redesign/dedicatednodes-bare-metal/new-baremetal.html index df2f6c1..64f110c 100644 --- a/Documents/Vibe Coding Projects/dedicatednodes-redesign/dedicatednodes-bare-metal/new-baremetal.html +++ b/Documents/Vibe Coding Projects/dedicatednodes-redesign/dedicatednodes-bare-metal/new-baremetal.html @@ -4205,76 +4205,18 @@ var wpcf7 = { }); } - // Enhanced matching for instant server specs - options.forEach(opt => { + // For storage options, we'll handle them in the pooled grid + // So we skip individual storage matching here + const storageOptions = options.filter(opt => opt.type === 'storage'); + const nonStorageOptions = options.filter(opt => opt.type !== 'storage'); + + // Enhanced matching for non-storage instant server specs + nonStorageOptions.forEach(opt => { let selectedValId = null; let urlId = preselected[opt.id]; - // Enhanced storage matching - if (opt.type === 'storage') { - // Create a score for each option based on how well it matches the requirements - const scores = opt.values.map(val => { - let score = 0; - const valText = val.text.toLowerCase(); - - // Check against each storage requirement - for (const req of storageRequirements) { - // Extract capacity from value (e.g., "1tb", "2tb") - const valCapacityMatch = valText.match(/(\d+)\s*tb/i); - const valCapacity = valCapacityMatch ? parseInt(valCapacityMatch[1]) : 0; - - // Extract capacity from requirement - const reqCapacityMatch = req.spec.match(/(\d+)\s*tb/i); - const reqCapacity = reqCapacityMatch ? parseInt(reqCapacityMatch[1]) : 0; - - // Score based on capacity match - if (valCapacity === reqCapacity && reqCapacity > 0) { - score += 100; - } - - // Score based on type keywords - const keywords = ['nvme', 'ssd', 'gen4', 'gen5', 'enterprise', 'consumer']; - keywords.forEach(keyword => { - if (valText.includes(keyword) && req.spec.includes(keyword)) { - score += 20; - } - }); - - // Score based on brand - const brands = ['samsung', 'crucial', 'wd', 'seagate', 'kingston']; - brands.forEach(brand => { - if (valText.includes(brand) && req.spec.includes(brand)) { - score += 30; - } - }); - - // Bonus for exact text match - if (valText.includes(req.spec) || req.spec.includes(valText.replace(/\s?\(.*?\)/, '').trim())) { - score += 50; - } - } - - return { id: val.id, score }; - }); - - // Select the highest scoring option - scores.sort((a, b) => b.score - a.score); - if (scores[0] && scores[0].score > 0) { - selectedValId = scores[0].id; - } - - // If no good match, try to use "None" option - if (!selectedValId) { - const noneOpt = opt.values.find(v => - v.text.trim() === '-' || - v.text.toLowerCase().includes('none') || - v.text.toLowerCase().includes('no hard drive') - ); - selectedValId = noneOpt ? noneOpt.id : null; - } - } // Enhanced RAM matching - else if (opt.type === 'ram') { + if (opt.type === 'ram') { const ramMatch = selectedServer.ram.match(/(\d+)\s*GB/i); const ramAmount = ramMatch ? parseInt(ramMatch[1]) : 0; @@ -4834,7 +4776,7 @@ var wpcf7 = { container.appendChild(visualContainer); // Always use pooled grid for these groups as they are by definition identical - container.appendChild(createPooledStorageGrid(groupOpts, isInstant, preselected, groupIndex)); + container.appendChild(createPooledStorageGrid(groupOpts, isInstant, preselected, groupIndex, storageRequirements)); }); } @@ -4861,7 +4803,7 @@ var wpcf7 = { } // New Pooled Storage Grid - function createPooledStorageGrid(storageOptions, isInstant, preselected = {}, groupIndex = 0) { + function createPooledStorageGrid(storageOptions, isInstant, preselected = {}, groupIndex = 0, storageRequirements = []) { const grid = document.createElement('div'); grid.className = 'config-grid'; @@ -4871,27 +4813,7 @@ var wpcf7 = { // Use a unique key for each group to prevent conflicts const poolKey = (isInstant ? 'instant' : 'custom') + '-g' + groupIndex; - // For instant customization, try to match storage requirements from server specs - let storageRequirements = []; - if (isInstant && selectedServer && selectedServer.storage) { - const parts = selectedServer.storage.split('+'); - parts.forEach(part => { - const trimmed = part.trim(); - if (!trimmed) return; - const match = trimmed.match(/^(\d+)x\s+(.+)$/); - if (match) { - storageRequirements.push({ - qty: parseInt(match[1]), - spec: match[2].trim().toLowerCase() - }); - } else { - storageRequirements.push({ - qty: 1, - spec: trimmed.toLowerCase() - }); - } - }); - } + // Storage requirements are now passed as a parameter for instant customization // Initialize slots with preselected values or defaults const initializedSlots = storageOptions.map(opt => { @@ -4916,6 +4838,20 @@ var wpcf7 = { // For instant customization, pre-fill with the server's storage configuration if (isInstant && storageRequirements.length > 0) { + // First, reset all slots to None + initializedSlots.forEach(slot => { + const noneOption = slot.values.find(v => + v.text.trim() === '-' || + v.text.toLowerCase().includes('none') || + v.text.toLowerCase().includes('no hard drive') + ); + if (noneOption) { + slot.currentVal = noneOption; + configState[slot.label] = noneOption.price; + configIds[slot.id] = noneOption.id; + } + }); + // Fill slots based on storage requirements storageRequirements.forEach(req => { for (let i = 0; i < req.qty; i++) { @@ -4927,31 +4863,46 @@ var wpcf7 = { ); if (emptySlot) { - // Find matching drive type + // Find exact matching drive type const match = emptySlot.values.find(v => { const vText = v.text.toLowerCase(); + + // Parse both to normalized form for comparison + const normalizeSpec = (spec) => { + return spec.toLowerCase() + .replace(/\s+/g, ' ') + .replace(/nvme/g, '') + .replace(/ssd/g, '') + .replace(/\s+/g, ' ') + .trim(); + }; + // Extract capacity from value - const valCapacityMatch = vText.match(/(\d+)\s*tb/i); - const valCapacity = valCapacityMatch ? parseInt(valCapacityMatch[1]) : 0; + const valCapacityMatch = vText.match(/(\d+(?:\.\d+)?)(?:\s*tb)?/i); + const valCapacity = valCapacityMatch ? parseFloat(valCapacityMatch[1]) : 0; + // Extract capacity from requirement - const reqCapacityMatch = req.spec.match(/(\d+)\s*tb/i); - const reqCapacity = reqCapacityMatch ? parseInt(reqCapacityMatch[1]) : 0; + const reqCapacityMatch = req.spec.match(/(\d+(?:\.\d+)?)(?:\s*tb)?/i); + const reqCapacity = reqCapacityMatch ? parseFloat(reqCapacityMatch[1]) : 0; - // Match capacity and keywords - if (valCapacity === reqCapacity && reqCapacity > 0) { - // Check for type keywords - const keywords = ['nvme', 'ssd', 'gen4', 'gen5', 'enterprise', 'consumer']; - const hasKeyword = keywords.some(k => - vText.includes(k) && req.spec.includes(k) - ); - // Check for brand - const brands = ['samsung', 'crucial', 'wd', 'seagate', 'kingston']; - const hasBrand = brands.some(b => - vText.includes(b) && req.spec.includes(b) - ); + // Match capacity exactly + if (Math.abs(valCapacity - reqCapacity) < 0.1) { + // Check for exact brand match first + if (vText.includes('crucial') && req.spec.includes('crucial')) return true; + if (vText.includes('kioxia') && req.spec.includes('kioxia')) return true; + if (vText.includes('samsung') && req.spec.includes('samsung')) return true; + if (vText.includes('solidigm') && req.spec.includes('solidigm')) return true; + if (vText.includes('wd') && req.spec.includes('wd')) return true; + if (vText.includes('seagate') && req.spec.includes('seagate')) return true; + if (vText.includes('kingston') && req.spec.includes('kingston')) return true; - return hasKeyword || hasBrand || vText.includes(req.spec); + // If no brand match, check if it's just generic NVMe + if (!req.spec.includes('crucial') && !req.spec.includes('kioxia') && + !req.spec.includes('samsung') && !req.spec.includes('solidigm')) { + return vText.includes('nvme'); + } } + return false; }); @@ -4959,7 +4910,11 @@ var wpcf7 = { emptySlot.currentVal = match; configState[emptySlot.label] = match.price; configIds[emptySlot.id] = match.id; + } else { + console.warn(`Could not find matching drive for requirement: ${req.spec}`); } + } else { + console.warn(`No empty slots available for requirement: ${req.spec}`); } } });