|
<!DOCTYPE html> |
|
<html lang="fr"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Mariam AI</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet"> |
|
<style> |
|
.message-transition { |
|
transition: all 0.3s ease-in-out; |
|
} |
|
.gradient-background { |
|
background: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%); |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-50 min-h-screen"> |
|
<div class="container mx-auto px-4 py-8 max-w-4xl"> |
|
|
|
<div class="text-center mb-8"> |
|
<h1 class="text-4xl font-bold text-gray-800 mb-2">Mariam AI</h1> |
|
<p class="text-gray-600">Votre assistant intelligent personnel</p> |
|
</div> |
|
|
|
|
|
<div class="mb-6 p-4 bg-white rounded-lg shadow-md"> |
|
<div class="flex items-center justify-between"> |
|
<div class="flex items-center space-x-4"> |
|
<label class="flex items-center space-x-2 cursor-pointer"> |
|
<input type="checkbox" id="webSearchToggle" class="form-checkbox h-5 w-5 text-blue-600"> |
|
<span class="text-gray-700">Activer la recherche web</span> |
|
</label> |
|
</div> |
|
<div class="relative"> |
|
<input type="file" id="fileInput" class="hidden" accept="image/*,.pdf,.txt"> |
|
<button onclick="document.getElementById('fileInput').click()" class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg transition duration-200"> |
|
<i class="fas fa-upload mr-2"></i>Télécharger un fichier |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="bg-white rounded-lg shadow-md h-[600px] flex flex-col"> |
|
|
|
<div id="chatMessages" class="flex-1 overflow-y-auto p-4 space-y-4"> |
|
|
|
</div> |
|
|
|
|
|
<div class="border-t p-4"> |
|
<form id="chatForm" class="flex space-x-2"> |
|
<input type="text" id="messageInput" class="flex-1 border rounded-lg px-4 py-2 focus:outline-none focus:border-blue-500" placeholder="Posez votre question..."> |
|
<button type="submit" class="bg-blue-500 hover:bg-blue-600 text-white px-6 py-2 rounded-lg transition duration-200"> |
|
<i class="fas fa-paper-plane"></i> |
|
</button> |
|
</form> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
let currentFile = null; |
|
|
|
document.getElementById('fileInput').addEventListener('change', async (e) => { |
|
const file = e.target.files[0]; |
|
if (!file) return; |
|
|
|
const formData = new FormData(); |
|
formData.append('file', file); |
|
|
|
try { |
|
const response = await fetch('/upload', { |
|
method: 'POST', |
|
body: formData |
|
}); |
|
const data = await response.json(); |
|
|
|
if (data.success) { |
|
currentFile = data.filename; |
|
alert('Fichier téléchargé avec succès !'); |
|
} else { |
|
alert('Erreur lors du téléchargement du fichier'); |
|
} |
|
} catch (error) { |
|
console.error('Error:', error); |
|
alert('Erreur lors du téléchargement du fichier'); |
|
} |
|
}); |
|
|
|
document.getElementById('chatForm').addEventListener('submit', async (e) => { |
|
e.preventDefault(); |
|
|
|
const messageInput = document.getElementById('messageInput'); |
|
const message = messageInput.value.trim(); |
|
if (!message) return; |
|
|
|
|
|
addMessage('user', message); |
|
messageInput.value = ''; |
|
|
|
|
|
addTypingIndicator(); |
|
|
|
try { |
|
const response = await fetch('/chat', { |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
}, |
|
body: JSON.stringify({ |
|
message: message, |
|
web_search: document.getElementById('webSearchToggle').checked, |
|
file: currentFile |
|
}), |
|
}); |
|
|
|
const data = await response.json(); |
|
|
|
|
|
removeTypingIndicator(); |
|
|
|
if (data.error) { |
|
addMessage('assistant', `Erreur: ${data.error}`); |
|
} else { |
|
addMessage('assistant', data.response); |
|
} |
|
|
|
|
|
currentFile = null; |
|
} catch (error) { |
|
removeTypingIndicator(); |
|
addMessage('assistant', 'Désolé, une erreur est survenue.'); |
|
} |
|
}); |
|
|
|
function addMessage(role, content) { |
|
const messagesContainer = document.getElementById('chatMessages'); |
|
const messageDiv = document.createElement('div'); |
|
messageDiv.className = `flex ${role === 'user' ? 'justify-end' : 'justify-start'} message-transition`; |
|
|
|
const messageBubble = document.createElement('div'); |
|
messageBubble.className = `max-w-[70%] p-3 rounded-lg ${ |
|
role === 'user' |
|
? 'bg-blue-500 text-white rounded-br-none' |
|
: 'bg-gray-100 text-gray-800 rounded-bl-none' |
|
}`; |
|
messageBubble.textContent = content; |
|
|
|
messageDiv.appendChild(messageBubble); |
|
messagesContainer.appendChild(messageDiv); |
|
messagesContainer.scrollTop = messagesContainer.scrollHeight; |
|
} |
|
|
|
function addTypingIndicator() { |
|
const messagesContainer = document.getElementById('chatMessages'); |
|
const indicatorDiv = document.createElement('div'); |
|
indicatorDiv.id = 'typingIndicator'; |
|
indicatorDiv.className = 'flex justify-start message-transition'; |
|
indicatorDiv.innerHTML = ` |
|
<div class="bg-gray-100 p-3 rounded-lg rounded-bl-none"> |
|
<div class="flex space-x-2"> |
|
<div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce"></div> |
|
<div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style="animation-delay: 0.2s"></div> |
|
<div class="w-2 h-2 bg-gray-400 rounded-full animate-bounce" style="animation-delay: 0.4s"></div> |
|
</div> |
|
</div> |
|
`; |
|
messagesContainer.appendChild(indicatorDiv); |
|
messagesContainer.scrollTop = messagesContainer.scrollHeight; |
|
} |
|
|
|
function removeTypingIndicator() { |
|
const indicator = document.getElementById('typingIndicator'); |
|
if (indicator) { |
|
indicator.remove(); |
|
} |
|
} |
|
</script> |
|
</body> |
|
</html> |