ai-doc / index.html
kamstar's picture
Add 3 files
bc386ab verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI Doctor Consultation</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>
.typing-indicator::after {
content: '...';
animation: typing 1.5s infinite;
}
@keyframes typing {
0% { content: '.'; }
33% { content: '..'; }
66% { content: '...'; }
}
.chat-container {
height: calc(100vh - 200px);
}
@media (max-width: 640px) {
.chat-container {
height: calc(100vh - 160px);
}
}
.message-animation {
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.pulse {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { opacity: 0.6; }
50% { opacity: 1; }
100% { opacity: 0.6; }
}
</style>
</head>
<body class="bg-gray-100 font-sans">
<div class="container mx-auto max-w-4xl px-4 py-8">
<!-- Header -->
<header class="bg-white rounded-xl shadow-md p-6 mb-6 flex items-center">
<div class="w-16 h-16 rounded-full bg-blue-100 flex items-center justify-center mr-4">
<i class="fas fa-robot text-blue-500 text-2xl"></i>
</div>
<div>
<h1 class="text-2xl font-bold text-gray-800">AI Medical Assistant</h1>
<p class="text-gray-600">Powered by HealthGPT</p>
<div class="flex items-center mt-1">
<span class="text-yellow-400 mr-1">
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
<i class="fas fa-star"></i>
</span>
<span class="text-gray-500 text-sm">4.9 (2,457 reviews)</span>
</div>
</div>
<div class="ml-auto">
<div class="flex items-center bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm">
<div class="w-2 h-2 bg-green-500 rounded-full mr-2"></div>
Online now
</div>
</div>
</header>
<!-- Chat Container -->
<div class="bg-white rounded-xl shadow-md overflow-hidden">
<!-- Chat Header -->
<div class="bg-blue-600 text-white p-4 flex items-center">
<i class="fas fa-comment-medical mr-3"></i>
<h2 class="font-semibold">AI Medical Consultation</h2>
<div class="ml-auto flex space-x-2">
<button class="p-2 rounded-full hover:bg-blue-500 transition" title="Connect to human doctor">
<i class="fas fa-user-md"></i>
</button>
<button class="p-2 rounded-full hover:bg-blue-500 transition" title="Emergency contact">
<i class="fas fa-ambulance"></i>
</button>
</div>
</div>
<!-- Messages -->
<div class="chat-container overflow-y-auto p-4 space-y-4" id="chatMessages">
<!-- AI's initial message -->
<div class="flex items-start message-animation">
<div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center mr-3">
<i class="fas fa-robot text-blue-500"></i>
</div>
<div class="max-w-xs md:max-w-md bg-blue-100 text-gray-800 p-3 rounded-xl rounded-tl-none">
<p>Hello! I'm your AI medical assistant. I can help answer your health questions, but please remember:</p>
<ul class="list-disc pl-5 mt-2 text-sm">
<li>I'm not a substitute for professional medical advice</li>
<li>For emergencies, call your local emergency number</li>
<li>Always consult with a healthcare provider for diagnosis</li>
</ul>
<p class="mt-2">How can I assist you today?</p>
<p class="text-xs text-gray-500 mt-1">10:02 AM</p>
</div>
</div>
<!-- Typing indicator -->
<div class="flex items-start hidden" id="typingIndicator">
<div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center mr-3">
<i class="fas fa-robot text-blue-500"></i>
</div>
<div class="max-w-xs md:max-w-md bg-blue-100 text-gray-800 p-3 rounded-xl rounded-tl-none">
<p class="typing-indicator"></p>
</div>
</div>
</div>
<!-- Input Area -->
<div class="border-t border-gray-200 p-4 bg-gray-50">
<div class="flex items-center">
<button class="p-2 text-gray-500 hover:text-blue-500 mr-2" id="voiceButton">
<i class="fas fa-microphone"></i>
</button>
<input type="text" placeholder="Describe your symptoms or ask a question..."
class="flex-1 border border-gray-300 rounded-full py-2 px-4 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"
id="messageInput">
<button class="ml-2 p-2 bg-blue-500 text-white rounded-full hover:bg-blue-600 transition"
id="sendButton">
<i class="fas fa-paper-plane"></i>
</button>
</div>
<div class="mt-3 flex flex-wrap justify-center gap-2">
<button class="text-xs bg-gray-200 hover:bg-gray-300 text-gray-700 px-3 py-1 rounded-full flex items-center quick-prompt" data-prompt="I have a headache">
<i class="fas fa-head-side-cough mr-1"></i> Headache
</button>
<button class="text-xs bg-gray-200 hover:bg-gray-300 text-gray-700 px-3 py-1 rounded-full flex items-center quick-prompt" data-prompt="I have a fever">
<i class="fas fa-temperature-high mr-1"></i> Fever
</button>
<button class="text-xs bg-gray-200 hover:bg-gray-300 text-gray-700 px-3 py-1 rounded-full flex items-center quick-prompt" data-prompt="I have stomach pain">
<i class="fas fa-stomach mr-1"></i> Stomach pain
</button>
<button class="text-xs bg-gray-200 hover:bg-gray-300 text-gray-700 px-3 py-1 rounded-full flex items-center quick-prompt" data-prompt="I have a sore throat">
<i class="fas fa-lungs mr-1"></i> Sore throat
</button>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="mt-6 grid grid-cols-2 md:grid-cols-4 gap-4">
<button class="bg-white p-4 rounded-xl shadow-sm hover:shadow-md transition flex flex-col items-center">
<div class="w-12 h-12 bg-green-100 rounded-full flex items-center justify-center mb-2">
<i class="fas fa-file-prescription text-green-500 text-xl"></i>
</div>
<span class="text-sm font-medium">Medication Info</span>
</button>
<button class="bg-white p-4 rounded-xl shadow-sm hover:shadow-md transition flex flex-col items-center">
<div class="w-12 h-12 bg-purple-100 rounded-full flex items-center justify-center mb-2">
<i class="fas fa-vial text-purple-500 text-xl"></i>
</div>
<span class="text-sm font-medium">Test Explanations</span>
</button>
<button class="bg-white p-4 rounded-xl shadow-sm hover:shadow-md transition flex flex-col items-center">
<div class="w-12 h-12 bg-yellow-100 rounded-full flex items-center justify-center mb-2">
<i class="fas fa-procedures text-yellow-500 text-xl"></i>
</div>
<span class="text-sm font-medium">Find Specialists</span>
</button>
<button class="bg-white p-4 rounded-xl shadow-sm hover:shadow-md transition flex flex-col items-center">
<div class="w-12 h-12 bg-red-100 rounded-full flex items-center justify-center mb-2">
<i class="fas fa-first-aid text-red-500 text-xl"></i>
</div>
<span class="text-sm font-medium">First Aid Guide</span>
</button>
</div>
<!-- Disclaimer -->
<div class="mt-6 bg-white p-4 rounded-lg shadow-sm text-xs text-gray-500">
<p class="font-medium mb-1">Important Disclaimer:</p>
<p>This AI assistant provides general health information and is not a substitute for professional medical advice, diagnosis, or treatment. Always seek the advice of your physician or other qualified health provider with any questions you may have regarding a medical condition.</p>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const chatMessages = document.getElementById('chatMessages');
const messageInput = document.getElementById('messageInput');
const sendButton = document.getElementById('sendButton');
const typingIndicator = document.getElementById('typingIndicator');
const voiceButton = document.getElementById('voiceButton');
// Simulate API call to LLM endpoint
async function callMedicalLLM(prompt, conversationHistory) {
// In a real implementation, this would be an actual API call
// For this demo, we'll simulate different types of responses
// Simulate API delay
await new Promise(resolve => setTimeout(resolve, 1000 + Math.random() * 2000));
// Analyze the prompt to generate a contextual response
const lowerPrompt = prompt.toLowerCase();
if (lowerPrompt.includes('headache')) {
return generateHeadacheResponse(prompt);
} else if (lowerPrompt.includes('fever') || lowerPrompt.includes('temperature')) {
return generateFeverResponse(prompt);
} else if (lowerPrompt.includes('stomach') || lowerPrompt.includes('abdominal')) {
return generateStomachResponse(prompt);
} else if (lowerPrompt.includes('throat') || lowerPrompt.includes('sore throat')) {
return generateThroatResponse(prompt);
} else if (lowerPrompt.includes('emergency') || lowerPrompt.includes('help')) {
return {
text: "Based on your description, this may require immediate medical attention. Please call emergency services or go to the nearest emergency room if you're experiencing: severe pain, difficulty breathing, chest pain, or any life-threatening symptoms.",
suggestions: [
"Call 911 (or your local emergency number)",
"Find nearest emergency room",
"Contact your primary care physician"
]
};
} else {
// Generic response for other queries
return {
text: `I understand you're asking about "${prompt}". Could you please provide more details about:\n\n1. When the symptoms started\n2. The severity (mild, moderate, severe)\n3. Any other associated symptoms\n4. Any medications you're currently taking\n\nThis will help me provide more accurate information.`,
suggestions: [
"How long have you had these symptoms?",
"Can you describe the pain?",
"Have you taken any medication for this?"
]
};
}
}
// Generate headache-specific response
function generateHeadacheResponse(prompt) {
const responses = [
`Headaches can have various causes. Could you describe:\n\n- Location of the pain (forehead, temples, back of head, etc.)\n- Type of pain (throbbing, dull, sharp)\n- Duration of the headache\n- Any triggers you've noticed\n\nThis will help determine possible causes and remedies.`,
`For headaches, consider these possibilities:\n\n1. Tension headache: Often caused by stress, with dull pressure\n2. Migraine: Typically throbbing pain, often with nausea\n3. Cluster headache: Severe pain around one eye\n\nHave you noticed any patterns with your headaches?`,
`Some general advice for headaches:\n\n- Stay hydrated\n- Rest in a quiet, dark room\n- Apply a cool compress\n- Consider OTC pain relievers (if no contraindications)\n\nHowever, if headaches are severe, persistent, or accompanied by vision changes, seek medical attention.`
];
return {
text: responses[Math.floor(Math.random() * responses.length)],
suggestions: [
"Does light or sound make it worse?",
"Have you had headaches before?",
"Any recent head injury?"
]
};
}
// Generate fever-specific response
function generateFeverResponse(prompt) {
return {
text: `Fever is often a sign of infection. Important factors to consider:\n\n- Temperature reading if available\n- Duration of the fever\n- Associated symptoms (cough, rash, pain)\n- Age of the patient (children may need different care)\n\nFor adults, fever under 102°F (38.9°C) can often be managed with rest and fluids, but higher fevers or those lasting more than 3 days should be evaluated.`,
suggestions: [
"How high is the fever?",
"Any other symptoms?",
"Any recent travel?"
]
};
}
// Generate stomach-specific response
function generateStomachResponse(prompt) {
return {
text: `Abdominal pain can stem from many causes. Please describe:\n\n- Exact location of pain\n- Character (cramping, sharp, dull)\n- Relation to eating\n- Any nausea, vomiting, or diarrhea\n\nFor severe, persistent pain or if accompanied by fever or vomiting blood, seek immediate care.`,
suggestions: [
"When did the pain start?",
"Have you eaten anything unusual?",
"Any bowel movement changes?"
]
};
}
// Generate throat-specific response
function generateThroatResponse(prompt) {
return {
text: `Sore throat causes include:\n\n1. Viral infections (most common)\n2. Strep throat (bacterial, needs testing)\n3. Allergies or irritants\n\nKey indicators:\n- Fever?\n- White patches on tonsils?\n- Difficulty swallowing?\n\nFor persistent sore throat >48 hours or with fever, consider seeing a doctor for possible strep test.`,
suggestions: [
"Do you have swollen glands?",
"Any fever?",
"Difficulty swallowing?"
]
};
}
// Send message function
async function sendMessage() {
const messageText = messageInput.value.trim();
if (messageText === '') return;
// Add patient message
addMessage(messageText, 'patient');
messageInput.value = '';
// Show typing indicator
typingIndicator.classList.remove('hidden');
chatMessages.scrollTop = chatMessages.scrollHeight;
try {
// Simulate API call to LLM
const response = await callMedicalLLM(messageText, getConversationHistory());
// Hide typing indicator
typingIndicator.classList.add('hidden');
// Add AI response
addMessage(response.text, 'ai');
// Add suggestions if available
if (response.suggestions && response.suggestions.length > 0) {
addSuggestions(response.suggestions);
}
} catch (error) {
typingIndicator.classList.add('hidden');
addMessage("I'm having trouble processing your request. Please try again or contact a healthcare provider directly.", 'ai');
console.error('Error calling LLM:', error);
}
}
// Get conversation history
function getConversationHistory() {
const messages = chatMessages.querySelectorAll('.flex.items-start');
const history = [];
messages.forEach(msg => {
if (msg.querySelector('.bg-blue-500')) {
history.push({
role: 'user',
content: msg.querySelector('.bg-blue-500 p').textContent
});
} else if (msg.querySelector('.bg-blue-100') && !msg.id === 'typingIndicator') {
history.push({
role: 'assistant',
content: msg.querySelector('.bg-blue-100 p').textContent
});
}
});
return history;
}
// Add message to chat
function addMessage(text, sender) {
const now = new Date();
const timeString = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
const messageDiv = document.createElement('div');
messageDiv.className = `flex items-start ${sender === 'patient' ? 'justify-end' : ''} message-animation`;
if (sender === 'patient') {
messageDiv.innerHTML = `
<div class="max-w-xs md:max-w-md bg-blue-500 text-white p-3 rounded-xl rounded-tr-none">
<p>${text}</p>
<p class="text-xs text-blue-100 mt-1">${timeString}</p>
</div>
<div class="w-10 h-10 rounded-full bg-gray-200 flex items-center justify-center ml-3">
<i class="fas fa-user text-gray-600"></i>
</div>
`;
} else {
// AI message
messageDiv.innerHTML = `
<div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center mr-3">
<i class="fas fa-robot text-blue-500"></i>
</div>
<div class="max-w-xs md:max-w-md bg-blue-100 text-gray-800 p-3 rounded-xl rounded-tl-none">
<p class="whitespace-pre-line">${text}</p>
<p class="text-xs text-gray-500 mt-1">${timeString}</p>
</div>
`;
}
chatMessages.appendChild(messageDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// Add suggestion buttons
function addSuggestions(suggestions) {
const suggestionsDiv = document.createElement('div');
suggestionsDiv.className = 'mt-3 flex flex-wrap justify-start gap-2';
suggestions.forEach(suggestion => {
const button = document.createElement('button');
button.className = 'text-xs bg-gray-200 hover:bg-gray-300 text-gray-700 px-3 py-1 rounded-full flex items-center suggestion-button';
button.innerHTML = `<i class="fas fa-reply mr-1 text-xs"></i> ${suggestion}`;
button.addEventListener('click', () => {
messageInput.value = suggestion;
suggestionsDiv.remove();
});
suggestionsDiv.appendChild(button);
});
chatMessages.appendChild(suggestionsDiv);
chatMessages.scrollTop = chatMessages.scrollHeight;
}
// Event listeners
sendButton.addEventListener('click', sendMessage);
messageInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
sendMessage();
}
});
// Quick prompt buttons
document.querySelectorAll('.quick-prompt').forEach(button => {
button.addEventListener('click', function() {
messageInput.value = this.dataset.prompt;
messageInput.focus();
});
});
// Voice input simulation
let voiceRecognitionActive = false;
voiceButton.addEventListener('click', function() {
if (voiceRecognitionActive) {
// Stop listening
voiceRecognitionActive = false;
voiceButton.innerHTML = '<i class="fas fa-microphone"></i>';
voiceButton.classList.remove('text-red-500', 'pulse');
} else {
// Start listening
voiceRecognitionActive = true;
voiceButton.innerHTML = '<i class="fas fa-microphone-slash"></i>';
voiceButton.classList.add('text-red-500', 'pulse');
// Simulate voice recognition after delay
setTimeout(() => {
if (voiceRecognitionActive) {
const samplePhrases = [
"I've had a headache for two days",
"My temperature is 101 degrees",
"I have pain in my lower right abdomen",
"It hurts when I swallow"
];
const randomPhrase = samplePhrases[Math.floor(Math.random() * samplePhrases.length)];
messageInput.value = randomPhrase;
// Stop listening after "hearing" something
voiceRecognitionActive = false;
voiceButton.innerHTML = '<i class="fas fa-microphone"></i>';
voiceButton.classList.remove('text-red-500', 'pulse');
}
}, 1500 + Math.random() * 2000);
}
});
});
</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=kamstar/ai-doc" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>