| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>RealEstate AI Assistant</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .chat-container { |
| height: calc(100vh - 180px); |
| } |
| .agent-1-bg { |
| background-color: #f0f9ff; |
| } |
| .agent-2-bg { |
| background-color: #f5f3ff; |
| } |
| .message-animation { |
| animation: fadeIn 0.3s ease-in-out; |
| } |
| @keyframes fadeIn { |
| from { opacity: 0; transform: translateY(10px); } |
| to { opacity: 1; transform: translateY(0); } |
| } |
| .file-input-label { |
| transition: all 0.3s ease; |
| } |
| .file-input-label:hover { |
| background-color: #e0e7ff; |
| } |
| .preview-image { |
| max-height: 200px; |
| max-width: 100%; |
| border-radius: 8px; |
| object-fit: contain; |
| } |
| .typing-indicator span { |
| display: inline-block; |
| width: 8px; |
| height: 8px; |
| border-radius: 50%; |
| background-color: #6366f1; |
| margin: 0 2px; |
| animation: bounce 1.4s infinite ease-in-out both; |
| } |
| .typing-indicator span:nth-child(1) { |
| animation-delay: -0.32s; |
| } |
| .typing-indicator span:nth-child(2) { |
| animation-delay: -0.16s; |
| } |
| @keyframes bounce { |
| 0%, 80%, 100% { transform: scale(0); } |
| 40% { transform: scale(1); } |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50"> |
| |
| <div class="bg-indigo-900 text-white p-2 text-center text-sm"> |
| <p>Developed by: Jatinkumar Parmar | Contact: parmarjatin4911@gmail.com</p> |
| </div> |
|
|
| <div class="container mx-auto max-w-4xl p-4"> |
| |
| <div class="flex flex-col md:flex-row justify-between items-center mb-6"> |
| <div class="flex items-center mb-4 md:mb-0"> |
| <i class="fas fa-home text-indigo-600 text-3xl mr-3"></i> |
| <h1 class="text-2xl font-bold text-gray-800">RealEstate AI Assistant</h1> |
| </div> |
| <div class="flex space-x-2"> |
| <button id="agent1Btn" class="px-4 py-2 bg-indigo-600 text-white rounded-lg shadow-md hover:bg-indigo-700 transition flex items-center"> |
| <i class="fas fa-search mr-2"></i> Property Inspector |
| </button> |
| <button id="agent2Btn" class="px-4 py-2 bg-purple-600 text-white rounded-lg shadow-md hover:bg-purple-700 transition flex items-center"> |
| <i class="fas fa-question-circle mr-2"></i> Tenancy FAQ |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="chatContainer" class="chat-container bg-white rounded-xl shadow-lg overflow-hidden flex flex-col"> |
| |
| <div id="chatHeader" class="agent-1-bg p-4 flex items-center border-b"> |
| <div id="agent1Icon" class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center mr-3"> |
| <i class="fas fa-search text-indigo-600"></i> |
| </div> |
| <div id="agent2Icon" class="w-10 h-10 rounded-full bg-purple-100 flex items-center justify-center mr-3 hidden"> |
| <i class="fas fa-question-circle text-purple-600"></i> |
| </div> |
| <div> |
| <h2 id="agentTitle" class="font-semibold text-gray-800">Property Inspector</h2> |
| <p id="agentDescription" class="text-sm text-gray-600">Upload property images or describe issues for expert analysis</p> |
| </div> |
| </div> |
|
|
| |
| <div id="messagesArea" class="flex-1 overflow-y-auto p-4 space-y-4"> |
| |
| <div class="flex justify-start"> |
| <div class="max-w-xs md:max-w-md lg:max-w-lg bg-indigo-100 rounded-lg p-4 message-animation"> |
| <p class="text-gray-800">Hello! I'm your Real Estate AI Assistant. I can help with:</p> |
| <ul class="list-disc pl-5 mt-2 text-gray-700"> |
| <li>Identifying property issues from images</li> |
| <li>Answering tenancy law questions</li> |
| </ul> |
| <p class="mt-2 text-gray-800">How can I assist you today?</p> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="border-t p-4 bg-gray-50"> |
| |
| <div id="imagePreviewContainer" class="mb-3 hidden"> |
| <div class="flex items-center justify-between bg-indigo-50 p-2 rounded-lg"> |
| <div class="flex items-center"> |
| <img id="previewImage" src="" alt="Preview" class="preview-image mr-3"> |
| <span id="fileName" class="text-sm text-gray-700"></span> |
| </div> |
| <button id="removeImageBtn" class="text-red-500 hover:text-red-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| </div> |
|
|
| |
| <div id="typingIndicator" class="typing-indicator mb-2 hidden"> |
| <div class="flex items-center text-indigo-600"> |
| <span></span> |
| <span></span> |
| <span></span> |
| <span class="ml-2 text-sm">Agent is typing...</span> |
| </div> |
| </div> |
|
|
| |
| <form id="chatForm" class="flex items-end space-x-2"> |
| <div class="flex-1 relative"> |
| <textarea id="messageInput" rows="1" class="w-full border border-gray-300 rounded-lg py-2 px-4 focus:outline-none focus:ring-2 focus:ring-indigo-500 resize-none" placeholder="Type your message..."></textarea> |
| <label for="fileInput" class="file-input-label absolute right-2 bottom-2 bg-indigo-100 p-2 rounded-full cursor-pointer hover:bg-indigo-200"> |
| <i class="fas fa-camera text-indigo-600"></i> |
| <input type="file" id="fileInput" accept="image/*" class="hidden"> |
| </label> |
| </div> |
| <button type="submit" class="bg-indigo-600 text-white p-2 rounded-lg hover:bg-indigo-700 transition"> |
| <i class="fas fa-paper-plane"></i> |
| </button> |
| </form> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| |
| const agent1Btn = document.getElementById('agent1Btn'); |
| const agent2Btn = document.getElementById('agent2Btn'); |
| const chatHeader = document.getElementById('chatHeader'); |
| const agentTitle = document.getElementById('agentTitle'); |
| const agentDescription = document.getElementById('agentDescription'); |
| const agent1Icon = document.getElementById('agent1Icon'); |
| const agent2Icon = document.getElementById('agent2Icon'); |
| const messagesArea = document.getElementById('messagesArea'); |
| const chatForm = document.getElementById('chatForm'); |
| const messageInput = document.getElementById('messageInput'); |
| const fileInput = document.getElementById('fileInput'); |
| const imagePreviewContainer = document.getElementById('imagePreviewContainer'); |
| const previewImage = document.getElementById('previewImage'); |
| const fileName = document.getElementById('fileName'); |
| const removeImageBtn = document.getElementById('removeImageBtn'); |
| const typingIndicator = document.getElementById('typingIndicator'); |
| |
| |
| let currentAgent = 'agent1'; |
| let selectedFile = null; |
| |
| |
| agent1Btn.addEventListener('click', () => { |
| currentAgent = 'agent1'; |
| chatHeader.className = 'agent-1-bg p-4 flex items-center border-b'; |
| agentTitle.textContent = 'Property Inspector'; |
| agentDescription.textContent = 'Upload property images or describe issues for expert analysis'; |
| agent1Icon.classList.remove('hidden'); |
| agent2Icon.classList.add('hidden'); |
| addMessage('agent', 'Switched to Property Inspector mode. You can upload images of property issues or describe them to me.'); |
| }); |
| |
| agent2Btn.addEventListener('click', () => { |
| currentAgent = 'agent2'; |
| chatHeader.className = 'agent-2-bg p-4 flex items-center border-b'; |
| agentTitle.textContent = 'Tenancy FAQ'; |
| agentDescription.textContent = 'Ask questions about tenancy laws, agreements, and rental processes'; |
| agent1Icon.classList.add('hidden'); |
| agent2Icon.classList.remove('hidden'); |
| addMessage('agent', 'Switched to Tenancy FAQ mode. Ask me anything about rental agreements, tenant rights, or landlord responsibilities.'); |
| }); |
| |
| |
| fileInput.addEventListener('change', (e) => { |
| if (e.target.files.length > 0) { |
| selectedFile = e.target.files[0]; |
| const reader = new FileReader(); |
| reader.onload = (event) => { |
| previewImage.src = event.target.result; |
| fileName.textContent = selectedFile.name; |
| imagePreviewContainer.classList.remove('hidden'); |
| }; |
| reader.readAsDataURL(selectedFile); |
| } |
| }); |
| |
| removeImageBtn.addEventListener('click', () => { |
| selectedFile = null; |
| fileInput.value = ''; |
| imagePreviewContainer.classList.add('hidden'); |
| }); |
| |
| |
| chatForm.addEventListener('submit', (e) => { |
| e.preventDefault(); |
| const message = messageInput.value.trim(); |
| |
| if (message || selectedFile) { |
| |
| addMessage('user', message, selectedFile); |
| |
| |
| messageInput.value = ''; |
| if (selectedFile) { |
| fileInput.value = ''; |
| selectedFile = null; |
| imagePreviewContainer.classList.add('hidden'); |
| } |
| |
| |
| typingIndicator.classList.remove('hidden'); |
| |
| |
| setTimeout(() => { |
| typingIndicator.classList.add('hidden'); |
| generateAgentResponse(message); |
| }, 1500); |
| } |
| }); |
| |
| |
| messageInput.addEventListener('input', () => { |
| messageInput.style.height = 'auto'; |
| messageInput.style.height = (messageInput.scrollHeight) + 'px'; |
| }); |
| |
| |
| function addMessage(sender, text, file = null) { |
| const messageDiv = document.createElement('div'); |
| messageDiv.className = `flex ${sender === 'user' ? 'justify-end' : 'justify-start'}`; |
| |
| const contentDiv = document.createElement('div'); |
| contentDiv.className = `max-w-xs md:max-w-md lg:max-w-lg rounded-lg p-4 message-animation ${sender === 'user' ? 'bg-indigo-600 text-white' : currentAgent === 'agent1' ? 'bg-indigo-100 text-gray-800' : 'bg-purple-100 text-gray-800'}`; |
| |
| if (file) { |
| const imgPreview = document.createElement('img'); |
| imgPreview.src = URL.createObjectURL(file); |
| imgPreview.className = 'preview-image mb-2'; |
| contentDiv.appendChild(imgPreview); |
| } |
| |
| if (text) { |
| const textNode = document.createElement('p'); |
| textNode.textContent = text; |
| contentDiv.appendChild(textNode); |
| } |
| |
| messageDiv.appendChild(contentDiv); |
| messagesArea.appendChild(messageDiv); |
| |
| |
| messagesArea.scrollTop = messagesArea.scrollHeight; |
| } |
| |
| |
| function generateAgentResponse(userMessage) { |
| let response = ''; |
| |
| if (currentAgent === 'agent1') { |
| |
| if (userMessage.toLowerCase().includes('wall') || userMessage.toLowerCase().includes('ceiling')) { |
| response = "It appears there is mould growth near the ceiling. This might be due to high humidity or a leak. I recommend checking for water seepage and using a dehumidifier."; |
| } else if (userMessage.toLowerCase().includes('floor') || userMessage.toLowerCase().includes('tile')) { |
| response = "I notice some cracked tiles in the flooring. This could be due to improper installation or structural movement. You might want to consult a flooring specialist to assess the damage."; |
| } else if (selectedFile) { |
| response = "From the image you've shared, I can identify several potential issues:\n1. Signs of water damage near the window frame\n2. Peeling paint indicating possible moisture problems\n3. A small crack in the corner that should be monitored\nWould you like more specific recommendations for any of these?"; |
| } else if (userMessage.toLowerCase().includes('light') || userMessage.toLowerCase().includes('dark')) { |
| response = "The lighting appears insufficient in this area. Consider adding additional light fixtures or using higher wattage bulbs. For a more permanent solution, you might want to consult an electrician about installing new lighting points."; |
| } else { |
| response = "Thank you for sharing the information. To better assist you, could you provide more details about the issue you're observing? For example:\n- When did you first notice the problem?\n- Has it been getting worse over time?\n- Are there any specific areas of concern?"; |
| } |
| } else { |
| |
| if (userMessage.toLowerCase().includes('notice') || userMessage.toLowerCase().includes('vacat')) { |
| response = "In most jurisdictions, tenants are required to give at least 30 days' notice before vacating a rental property. However, this can vary by location. Please let me know your city or region for more accurate information."; |
| } else if (userMessage.toLowerCase().includes('rent') || userMessage.toLowerCase().includes('increase')) { |
| response = "Generally, landlords cannot increase rent midway through a fixed-term lease unless the agreement specifically allows for it. For month-to-month tenancies, most areas require 30-60 days notice for rent increases. The exact rules depend on local tenancy laws."; |
| } else if (userMessage.toLowerCase().includes('deposit') || userMessage.toLowerCase().includes('security')) { |
| response = "If your landlord is not returning your deposit without valid reasons, you should:\n1. Send a formal written request\n2. Check your local tenancy board's procedures\n3. Consider filing a dispute if unresolved\nCould you specify your location for more tailored advice?"; |
| } else if (userMessage.toLowerCase().includes('evict') || userMessage.toLowerCase().includes('remove')) { |
| response = "Landlords typically need valid reasons and proper notice to evict a tenant, except in cases of emergency (like non-payment or illegal activity). Common valid reasons include:\n- Non-payment of rent\n- Property damage\n- Lease violations\n- Owner moving in (in some areas)"; |
| } else { |
| response = "I can help with questions about:\n- Rental agreements and contracts\n- Tenant rights and responsibilities\n- Security deposits\n- Rent increases\n- Repairs and maintenance obligations\n- Eviction processes\nWhat specific tenancy question can I answer for you?"; |
| } |
| } |
| |
| addMessage('agent', response); |
| } |
| |
| |
| setTimeout(() => { |
| addMessage('agent', "I'm here to help with all your real estate questions. You can switch between Property Inspection and Tenancy FAQ modes using the buttons above. What would you like assistance with today?"); |
| }, 500); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=jhparmar/multi-agentic-real-estate-chatbot-image-text-based" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |