jhparmar's picture
undefined - Initial Deployment
0b19438 verified
Raw
History Blame Contribute Delete
18 kB
<!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">
<!-- Developer Info -->
<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">
<!-- Header -->
<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>
<!-- Chat Container -->
<div id="chatContainer" class="chat-container bg-white rounded-xl shadow-lg overflow-hidden flex flex-col">
<!-- Chat Header -->
<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>
<!-- Messages Area -->
<div id="messagesArea" class="flex-1 overflow-y-auto p-4 space-y-4">
<!-- Welcome Message -->
<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>
<!-- Input Area -->
<div class="border-t p-4 bg-gray-50">
<!-- Image Preview -->
<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>
<!-- Typing Indicator -->
<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>
<!-- Input Form -->
<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>
// DOM Elements
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');
// State
let currentAgent = 'agent1';
let selectedFile = null;
// Agent Switch
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.');
});
// File Handling
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');
});
// Form Submission
chatForm.addEventListener('submit', (e) => {
e.preventDefault();
const message = messageInput.value.trim();
if (message || selectedFile) {
// Add user message
addMessage('user', message, selectedFile);
// Clear input
messageInput.value = '';
if (selectedFile) {
fileInput.value = '';
selectedFile = null;
imagePreviewContainer.classList.add('hidden');
}
// Show typing indicator
typingIndicator.classList.remove('hidden');
// Simulate agent response after delay
setTimeout(() => {
typingIndicator.classList.add('hidden');
generateAgentResponse(message);
}, 1500);
}
});
// Auto-resize textarea
messageInput.addEventListener('input', () => {
messageInput.style.height = 'auto';
messageInput.style.height = (messageInput.scrollHeight) + 'px';
});
// Add message to chat
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);
// Scroll to bottom
messagesArea.scrollTop = messagesArea.scrollHeight;
}
// Generate agent response
function generateAgentResponse(userMessage) {
let response = '';
if (currentAgent === 'agent1') {
// Property Inspector responses
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 {
// Tenancy FAQ responses
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);
}
// Initial welcome message
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>