Spaces:
Running
Running
<!-- templates/index.html --> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>AI Tutor - Doubt Solver</title> | |
<style> | |
body { | |
font-family: Arial, sans-serif; | |
max-width: 800px; | |
margin: 0 auto; | |
padding: 20px; | |
} | |
h1 { | |
color: #333; | |
} | |
.control-bar { | |
display: flex; | |
justify-content: space-between; | |
align-items: center; | |
margin-bottom: 15px; | |
} | |
.chat-container { | |
border: 1px solid #ddd; | |
border-radius: 8px; | |
padding: 20px; | |
height: 500px; | |
overflow-y: auto; | |
margin-bottom: 20px; | |
background-color: #f9f9f9; | |
} | |
.message { | |
margin-bottom: 15px; | |
padding: 10px; | |
border-radius: 5px; | |
max-width: 80%; | |
} | |
.user { | |
background-color: #e3f2fd; | |
margin-left: auto; | |
text-align: right; | |
} | |
.model { | |
background-color: #f0f0f0; | |
} | |
/* Preserve raw Markdown formatting */ | |
.message pre { | |
margin: 0; | |
white-space: pre-wrap; /* preserve line breaks and wrap */ | |
font-family: inherit; | |
} | |
.input-form { | |
display: flex; | |
gap: 10px; | |
align-items: center; | |
} | |
.input-form input[type="text"] { | |
flex-grow: 1; | |
padding: 10px; | |
border: 1px solid #ddd; | |
border-radius: 5px; | |
} | |
.input-form input[type="file"] { | |
display: none; | |
} | |
.file-upload-label { | |
display: inline-block; | |
padding: 8px 12px; | |
background-color: #f0f0f0; | |
border: 1px solid #ddd; | |
border-radius: 5px; | |
cursor: pointer; | |
} | |
.file-upload-label:hover { | |
background-color: #e3e3e3; | |
} | |
.file-name { | |
margin-left: 10px; | |
font-size: 0.9em; | |
color: #666; | |
} | |
.input-form button { | |
padding: 10px 20px; | |
background-color: #1a73e8; | |
color: white; | |
border: none; | |
border-radius: 5px; | |
cursor: pointer; | |
} | |
.input-form button:hover { | |
background-color: #1558b7; | |
} | |
.tab-buttons { | |
margin-bottom: 15px; | |
} | |
.tab-button { | |
padding: 8px 15px; | |
background-color: #f0f0f0; | |
border: 1px solid #ddd; | |
border-radius: 5px; | |
cursor: pointer; | |
margin-right: 10px; | |
} | |
.tab-button.active { | |
background-color: #e3f2fd; | |
border-color: #1a73e8; | |
} | |
.image-upload-container { | |
display: none; | |
margin-bottom: 10px; | |
} | |
.image-upload-container.active { | |
display: flex; | |
align-items: center; | |
} | |
.image-preview { | |
max-width: 100px; | |
max-height: 100px; | |
margin-left: 10px; | |
border: 1px solid #ddd; | |
display: none; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>AI Tutor - Doubt Solver</h1> | |
<div class="control-bar"> | |
<div class="tab-buttons"> | |
<button id="text-only-tab" class="tab-button active" type="button">Text Only</button> | |
<button id="image-text-tab" class="tab-button" type="button">Image + Text</button> | |
</div> | |
<!-- New Chat button --> | |
<form method="post" action="/new"> | |
<button type="submit">New Chat</button> | |
</form> | |
</div> | |
<div class="chat-container"> | |
{% for message in chat_history %} | |
<div class="message {{ message.role }}"> | |
<pre>{{ message.content }}</pre> | |
</div> | |
{% endfor %} | |
</div> | |
<form id="input-form" class="input-form" method="post" enctype="multipart/form-data"> | |
<div id="image-upload-container" class="image-upload-container"> | |
<label for="image-upload" class="file-upload-label">Upload Image</label> | |
<input id="image-upload" type="file" name="image" accept="image/*"> | |
<span id="file-name" class="file-name"></span> | |
<img id="image-preview" class="image-preview" src="#" alt="Preview"> | |
</div> | |
<input type="text" name="user_input" placeholder="Type your message..." required> | |
<button type="submit">Send</button> | |
</form> | |
<script> | |
// Auto-scroll to bottom of chat container | |
const chatContainer = document.querySelector('.chat-container'); | |
chatContainer.scrollTop = chatContainer.scrollHeight; | |
// Tab buttons functionality | |
const textOnlyTab = document.getElementById('text-only-tab'); | |
const imageTextTab = document.getElementById('image-text-tab'); | |
const imageUploadContainer = document.getElementById('image-upload-container'); | |
const inputForm = document.getElementById('input-form'); | |
textOnlyTab.addEventListener('click', () => { | |
textOnlyTab.classList.add('active'); | |
imageTextTab.classList.remove('active'); | |
imageUploadContainer.classList.remove('active'); | |
// Reset file input when switching to text-only | |
document.getElementById('image-upload').value = ''; | |
document.getElementById('file-name').textContent = ''; | |
document.getElementById('image-preview').style.display = 'none'; | |
}); | |
imageTextTab.addEventListener('click', () => { | |
imageTextTab.classList.add('active'); | |
textOnlyTab.classList.remove('active'); | |
imageUploadContainer.classList.add('active'); | |
}); | |
// Handle file selection and preview | |
const imageUpload = document.getElementById('image-upload'); | |
const fileName = document.getElementById('file-name'); | |
const imagePreview = document.getElementById('image-preview'); | |
imageUpload.addEventListener('change', (e) => { | |
if (e.target.files.length > 0) { | |
const file = e.target.files[0]; | |
fileName.textContent = file.name; | |
// Create image preview | |
const reader = new FileReader(); | |
reader.onload = function(e) { | |
imagePreview.src = e.target.result; | |
imagePreview.style.display = 'block'; | |
} | |
reader.readAsDataURL(file); | |
} else { | |
fileName.textContent = ''; | |
imagePreview.style.display = 'none'; | |
} | |
}); | |
</script> | |
</body> | |
</html> |