File size: 5,661 Bytes
f4054a2 1cbee68 f4054a2 1cbee68 f4054a2 1cbee68 f4054a2 1cbee68 f4054a2 1cbee68 f4054a2 1cbee68 f4054a2 1cbee68 f4054a2 1cbee68 f4054a2 1cbee68 f4054a2 1cbee68 f4054a2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
<script>
const state = {
step: 'tileType',
tileType: null,
length: null,
width: null,
tileSize: 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();
});
function resetConversation() {
state.step = 'tileType';
state.tileType = null;
state.length = null;
state.width = null;
state.tileSize = null;
chatArea.innerHTML = `
<div class="bot-message bg-gray-100 rounded-lg p-4 max-w-xs mb-3">
<p>Hello! ๐ I'm your Tile Calculator Assistant. Let's estimate how many tiles you need.</p>
<p class="mt-2">Are you looking for <span class="font-semibold">floor</span> or <span class="font-semibold">wall</span> tiles?</p>
<div class="flex gap-2 mt-3">
<button onclick="selectTileType('floor')" class="quick-reply bg-white text-indigo-600 border border-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50">Floor</button>
<button onclick="selectTileType('wall')" class="quick-reply bg-white text-indigo-600 border border-indigo-600 px-4 py-2 rounded-full font-medium hover:bg-indigo-50">Wall</button>
</div>
</div>
`;
recommendations.innerHTML = '';
}
function selectTileType(type) {
state.tileType = type;
state.step = 'length';
addMessage('user', type === 'floor' ? 'Floor tiles' : 'Wall tiles');
showTyping();
setTimeout(() => {
hideTyping();
addMessage('bot', `Great choice! Please enter the <strong>length</strong> of the area in feet (e.g. 10):`);
}, 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 === 'length') {
const length = parseFloat(message);
if (isNaN(length) || length <= 0) {
addMessage('bot', 'Please enter a valid number for the length in feet.');
return;
}
state.length = length;
state.step = 'width';
addMessage('bot', 'Now enter the <strong>width</strong> of the area in feet (e.g. 12):');
} else if (state.step === 'width') {
const width = parseFloat(message);
if (isNaN(width) || width <= 0) {
addMessage('bot', 'Please enter a valid number for the width in feet.');
return;
}
state.width = width;
state.step = 'tileSize';
addMessage('bot', 'What is the tile size? (e.g. "2x2", "600x600", or "300*300")');
} else if (state.step === 'tileSize') {
const tileArea = parseTileSize(message);
if (!tileArea) {
addMessage('bot', 'I couldn\'t understand that tile size. Try: "2x2", "600x600 mm", or "200*200".');
return;
}
state.tileSize = tileArea;
calculateTiles();
}
}, 800);
}
function parseTileSize(input) {
input = input.toLowerCase().replace(/ร|into|\*/g, 'x').replace(/ft|feet|mm/g, '').trim();
if (input.includes('x')) {
const [a, b] = input.split('x').map(s => parseFloat(s.replace(/[^\d.]/g, '')));
if (isNaN(a) || isNaN(b)) return null;
return (a > 20 ? (a * b) / 92903.04 : a * b);
} else if (/^\d+(\.\d+)?$/.test(input)) {
const val = parseFloat(input);
return val > 20 ? (val * val) / 92903.04 : val * val;
}
return null;
}
function calculateTiles() {
const area = state.length * state.width;
const numTiles = Math.ceil((area / state.tileSize) * 1.1);
const numBoxes = Math.ceil(numTiles / 10);
chatArea.insertAdjacentHTML('beforeend', `
<div class="bot-message bg-gray-100 rounded-lg p-4 mb-3">
<p class="font-semibold">Calculation Results:</p>
<p>๐งฑ Tile Type: ${state.tileType}</p>
<p>๐ Length: ${state.length} ft</p>
<p>๐ Width: ${state.width} ft</p>
<p>๐ฆ Area: ${area.toFixed(2)} sq.ft</p>
<p>๐งฎ Tile Size: ${state.tileSize.toFixed(2)} sq.ft per tile</p>
<p class="mt-2">๐ข <span class="font-bold">Tiles Needed:</span> ${numTiles} (${numBoxes} boxes)</p>
</div>
`);
state.step = 'complete';
}
function addMessage(sender, message) {
const messageDiv = document.createElement('div');
messageDiv.className = `${sender}-message ${sender === 'user' ? 'ml-auto bg-indigo-600 text-white' : 'bg-gray-100'} rounded-lg p-4 max-w-xs mb-3`;
messageDiv.innerHTML = message;
chatArea.appendChild(messageDiv);
chatArea.scrollTop = chatArea.scrollHeight;
}
function showTyping() {
const typingDiv = document.createElement('div');
typingDiv.className = 'typing-indicator bg-gray-100 rounded-lg p-4 max-w-xs mb-3 flex gap-1';
typingDiv.id = 'typing-indicator';
typingDiv.innerHTML = '<span class="w-2 h-2 bg-gray-400 rounded-full"></span><span class="w-2 h-2 bg-gray-400 rounded-full"></span><span class="w-2 h-2 bg-gray-400 rounded-full"></span>';
chatArea.appendChild(typingDiv);
chatArea.scrollTop = chatArea.scrollHeight;
}
function hideTyping() {
const typingIndicator = document.getElementById('typing-indicator');
if (typingIndicator) typingIndicator.remove();
}
</script>
|