const state = { step: 'tileType', tileType: null, area: null, tileLength: null, tileWidth: null }; const chatArea = document.getElementById('chat-area'); const userInput = document.getElementById('user-input'); const recommendations = document.getElementById('recommendations'); const resetBtn = document.getElementById('reset-btn'); resetBtn.addEventListener('click', resetConversation); userInput.addEventListener('keypress', (e) => { if (e.key === 'Enter') sendMessage(); }); resetConversation(); function resetConversation() { Object.assign(state, { step: 'tileType', tileType: null, area: null, tileLength: null, tileWidth: null }); chatArea.innerHTML = `

Hello! 👋 I'm your Tile Calculator Assistant. Let's estimate how many tiles you need.

Are you looking for floor or wall tiles?

`; recommendations.innerHTML = ''; } function selectTileType(type) { state.tileType = type; state.step = 'area'; addMessage('user', `${type.charAt(0).toUpperCase() + type.slice(1)} tiles`); showTyping(); setTimeout(() => { hideTyping(); addMessage('bot', 'Great! What is the total area to cover (in sq.ft)?'); }, 800); } function sendMessage() { const message = userInput.value.trim(); if (!message) return; addMessage('user', message); userInput.value = ''; processUserMessage(message); } function processUserMessage(message) { showTyping(); setTimeout(() => { hideTyping(); if (state.step === 'area') { const area = parseFloat(message); if (isNaN(area) || area <= 0) { return addMessage('bot', '❗ Please enter a valid positive number for area (e.g., 100).'); } state.area = area; state.step = 'tileLength'; addMessage('bot', 'Now enter the tile length (in feet):'); } else if (state.step === 'tileLength') { const length = parseFloat(message); if (isNaN(length) || length <= 0) { return addMessage('bot', '❗ Please enter a valid positive number for tile length.'); } state.tileLength = length; state.step = 'tileWidth'; addMessage('bot', 'Now enter the tile width (in feet):'); } else if (state.step === 'tileWidth') { const width = parseFloat(message); if (isNaN(width) || width <= 0) { return addMessage('bot', '❗ Please enter a valid positive number for tile width.'); } state.tileWidth = width; calculateTiles(); } }, 800); } function calculateTiles() { const { tileLength, tileWidth, area, tileType } = state; const tileArea = tileLength * tileWidth; if (tileArea <= 0) { return addMessage('bot', `❗ Invalid tile dimensions. Length × width must be greater than 0.`); } if (tileArea > area) { return addMessage('bot', `⚠ The tile size (${tileLength}×${tileWidth} = ${tileArea} sq.ft) is larger than the total area (${area} sq.ft). Please enter smaller tile dimensions.`); } if (tileArea > 20) { addMessage('bot', `🔍 That's a large tile (${tileArea.toFixed(2)} sq.ft). Please confirm the size is correct.`); } const aspectRatio = Math.max(tileLength / tileWidth, tileWidth / tileLength); if (aspectRatio > 10) { addMessage('bot', `📐 This tile has a very high aspect ratio (${aspectRatio.toFixed(1)}:1). Please double-check if that's correct.`); } const numTiles = Math.ceil((area / tileArea) * 1.1); const numBoxes = Math.ceil(numTiles / 10); chatArea.insertAdjacentHTML('beforeend', `

Calculation Results:

🧱 Tile Type: ${tileType}

📐 Area to Cover: ${area} sq.ft

🧮 Tile Size: ${tileLength} ft × ${tileWidth} ft

🔢 Tiles Needed: ${numTiles} (${numBoxes} boxes)

`); state.step = 'complete'; const sizeLabel = `${Math.round(tileLength * 304.8)}x${Math.round(tileWidth * 304.8)} MM`; fetch('/recommend', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ tile_type: tileType, coverage: tileArea, area: area, preferred_sizes: [sizeLabel] }) }) .then(res => res.json()) .then(data => { if (data.recommended_products?.length) { loadProductRecommendations(data.recommended_products); } else { recommendations.innerHTML = `
No product recommendations found.
`; } }) .catch(err => { console.error('Recommendation error:', err); recommendations.innerHTML = `
Error fetching recommendations.
`; }); } function loadProductRecommendations(products) { recommendations.innerHTML = ''; products.slice(0, 4).forEach(p => { recommendations.insertAdjacentHTML('beforeend', `
${p.image_url ? `${p.name}` : ` `}

${p.name || 'Tile Product'}

${p.price ? `₹${p.price}/box` : 'Price N/A'}

View Details
`); }); } function addMessage(sender, text) { const div = document.createElement('div'); div.className = `${sender}-message ${sender === 'user' ? 'ml-auto bg-indigo-600 text-white' : 'bg-gray-100'} rounded-lg p-4 max-w-xs mb-3`; div.textContent = text; chatArea.appendChild(div); chatArea.scrollTop = chatArea.scrollHeight; } function showTyping() { const typing = document.createElement('div'); typing.className = 'typing-indicator bg-gray-100 rounded-lg p-4 max-w-xs mb-3 flex gap-1'; typing.id = 'typing-indicator'; typing.innerHTML = ''; chatArea.appendChild(typing); chatArea.scrollTop = chatArea.scrollHeight; } function hideTyping() { const el = document.getElementById('typing-indicator'); if (el) el.remove(); }