erma-interface / index.html
mfirat007's picture
Add 2 files
d39c397 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PhD Scholar 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">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
academic: {
blue: '#1a365d',
gold: '#d4af37',
gray: '#4a5568',
}
}
}
}
}
</script>
<style>
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
}
::-webkit-scrollbar-thumb {
background: #888;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* Chat bubble animation */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.chat-bubble {
animation: fadeIn 0.3s ease-out;
}
/* Pulse animation for AI typing indicator */
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.typing-dot {
animation: pulse 1.5s infinite ease-in-out;
}
.typing-dot:nth-child(1) {
animation-delay: 0s;
}
.typing-dot:nth-child(2) {
animation-delay: 0.3s;
}
.typing-dot:nth-child(3) {
animation-delay: 0.6s;
}
</style>
</head>
<body class="bg-gray-100 font-sans">
<div class="container mx-auto max-w-6xl p-4">
<!-- Header -->
<header class="bg-academic-blue text-white rounded-lg shadow-md p-6 mb-6">
<div class="flex justify-between items-center">
<div>
<h1 class="text-3xl font-bold"><i class="fas fa-graduation-cap mr-3"></i>PhD Scholar Assistant</h1>
<p class="mt-2 text-academic-gold">Your AI-powered research companion</p>
</div>
<div class="flex space-x-4">
<button id="save-chat-btn" class="bg-academic-gold hover:bg-yellow-600 text-academic-blue font-semibold py-2 px-4 rounded-lg flex items-center">
<i class="fas fa-save mr-2"></i> Save Chat
</button>
<button id="load-chat-btn" class="bg-white hover:bg-gray-200 text-academic-blue font-semibold py-2 px-4 rounded-lg flex items-center">
<i class="fas fa-folder-open mr-2"></i> Load Chat
</button>
</div>
</div>
</header>
<!-- Main Content -->
<div class="flex flex-col lg:flex-row gap-6">
<!-- Sidebar -->
<div class="w-full lg:w-1/4 bg-white rounded-lg shadow-md p-4 h-fit">
<h2 class="text-xl font-semibold text-academic-blue mb-4 flex items-center">
<i class="fas fa-book mr-2"></i> Research Tools
</h2>
<div class="space-y-3">
<button class="quick-prompt-btn w-full bg-gray-100 hover:bg-gray-200 text-academic-gray p-3 rounded-lg text-left flex items-center" data-prompt="Help me structure my literature review">
<i class="fas fa-book-reader mr-3 text-academic-blue"></i>
Literature Review
</button>
<button class="quick-prompt-btn w-full bg-gray-100 hover:bg-gray-200 text-academic-gray p-3 rounded-lg text-left flex items-center" data-prompt="Suggest methodologies for my research on [topic]">
<i class="fas fa-flask mr-3 text-academic-blue"></i>
Methodology
</button>
<button class="quick-prompt-btn w-full bg-gray-100 hover:bg-gray-200 text-academic-gray p-3 rounded-lg text-left flex items-center" data-prompt="Help me analyze this data: [describe your data]">
<i class="fas fa-chart-bar mr-3 text-academic-blue"></i>
Data Analysis
</button>
<button class="quick-prompt-btn w-full bg-gray-100 hover:bg-gray-200 text-academic-gray p-3 rounded-lg text-left flex items-center" data-prompt="Help me write an abstract for my paper on [topic]">
<i class="fas fa-file-alt mr-3 text-academic-blue"></i>
Paper Writing
</button>
<button class="quick-prompt-btn w-full bg-gray-100 hover:bg-gray-200 text-academic-gray p-3 rounded-lg text-left flex items-center" data-prompt="Suggest academic conferences in [field] for 2024">
<i class="fas fa-users mr-3 text-academic-blue"></i>
Conferences
</button>
</div>
<div class="mt-6 pt-4 border-t border-gray-200">
<h3 class="font-semibold text-academic-blue mb-3 flex items-center">
<i class="fas fa-save mr-2"></i> Saved Chats
</h3>
<div id="saved-chats-list" class="space-y-2 max-h-60 overflow-y-auto">
<!-- Saved chats will appear here -->
<div class="text-gray-500 italic text-center py-4">No saved chats yet</div>
</div>
</div>
</div>
<!-- Chat Container -->
<div class="w-full lg:w-3/4 bg-white rounded-lg shadow-md overflow-hidden flex flex-col">
<!-- Chat Header -->
<div class="bg-academic-blue text-white p-4 flex justify-between items-center">
<h2 class="text-xl font-semibold flex items-center">
<i class="fas fa-comments mr-2"></i> Research Assistant
</h2>
<div class="flex items-center space-x-2">
<span id="word-count" class="text-sm bg-academic-gold text-academic-blue px-2 py-1 rounded">0 words</span>
<button id="clear-chat-btn" class="text-white hover:text-academic-gold">
<i class="fas fa-trash-alt"></i>
</button>
</div>
</div>
<!-- Chat Messages -->
<div id="chat-container" class="flex-1 p-4 overflow-y-auto max-h-[60vh]">
<!-- Welcome message -->
<div class="chat-bubble mb-6">
<div class="flex items-start">
<div class="bg-academic-blue text-white rounded-full w-10 h-10 flex items-center justify-center mr-3">
<i class="fas fa-robot"></i>
</div>
<div class="bg-gray-100 rounded-lg p-4 max-w-[85%]">
<h3 class="font-semibold text-academic-blue mb-1">PhD Research Assistant</h3>
<p class="text-gray-800">Hello! I'm your AI research assistant. How can I help you with your PhD journey today? I can assist with:</p>
<ul class="list-disc pl-5 mt-2 space-y-1">
<li>Literature review guidance</li>
<li>Research methodology suggestions</li>
<li>Data analysis strategies</li>
<li>Academic writing tips</li>
<li>Citation and reference help</li>
</ul>
<p class="mt-2 text-gray-800">Try clicking one of the quick prompts on the left or type your question below.</p>
</div>
</div>
</div>
</div>
<!-- Typing Indicator (hidden by default) -->
<div id="typing-indicator" class="hidden px-4 pb-4">
<div class="flex items-start">
<div class="bg-academic-blue text-white rounded-full w-10 h-10 flex items-center justify-center mr-3">
<i class="fas fa-robot"></i>
</div>
<div class="bg-gray-100 rounded-lg p-4">
<div class="flex space-x-2">
<div class="typing-dot w-2 h-2 bg-gray-500 rounded-full"></div>
<div class="typing-dot w-2 h-2 bg-gray-500 rounded-full"></div>
<div class="typing-dot w-2 h-2 bg-gray-500 rounded-full"></div>
</div>
</div>
</div>
</div>
<!-- Input Area -->
<div class="border-t border-gray-200 p-4 bg-gray-50">
<form id="chat-form" class="flex space-x-2">
<div class="flex-1 relative">
<textarea id="user-input" rows="1" class="w-full border border-gray-300 rounded-lg p-3 pr-10 focus:outline-none focus:ring-2 focus:ring-academic-blue resize-none" placeholder="Ask your research question..."></textarea>
<button type="button" id="voice-input-btn" class="absolute right-2 bottom-2 text-gray-500 hover:text-academic-blue">
<i class="fas fa-microphone"></i>
</button>
</div>
<button type="submit" class="bg-academic-blue hover:bg-blue-800 text-white rounded-lg p-3 px-4">
<i class="fas fa-paper-plane"></i>
</button>
</form>
<div class="mt-2 flex justify-between items-center text-xs text-gray-500">
<div>
<button id="citation-btn" class="hover:text-academic-blue mr-3">
<i class="fas fa-quote-right mr-1"></i> Citation Help
</button>
<button id="format-btn" class="hover:text-academic-blue">
<i class="fas fa-align-left mr-1"></i> Format Text
</button>
</div>
<div>
<span id="char-count">0/1000</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Save Chat Modal -->
<div id="save-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
<div class="bg-white rounded-lg p-6 w-full max-w-md">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold text-academic-blue">Save Chat Session</h3>
<button id="close-save-modal" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="mb-4">
<label for="chat-title" class="block text-gray-700 mb-2">Title:</label>
<input type="text" id="chat-title" class="w-full border border-gray-300 rounded-lg p-2 focus:outline-none focus:ring-2 focus:ring-academic-blue" placeholder="e.g., Literature Review Discussion">
</div>
<div class="mb-4">
<label for="chat-tags" class="block text-gray-700 mb-2">Tags (comma separated):</label>
<input type="text" id="chat-tags" class="w-full border border-gray-300 rounded-lg p-2 focus:outline-none focus:ring-2 focus:ring-academic-blue" placeholder="e.g., methodology, qualitative, interviews">
</div>
<div class="flex justify-end space-x-3">
<button id="cancel-save" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-semibold py-2 px-4 rounded-lg">
Cancel
</button>
<button id="confirm-save" class="bg-academic-blue hover:bg-blue-800 text-white font-semibold py-2 px-4 rounded-lg">
Save
</button>
</div>
</div>
</div>
<!-- Load Chat Modal -->
<div id="load-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
<div class="bg-white rounded-lg p-6 w-full max-w-2xl">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-semibold text-academic-blue">Load Saved Chat</h3>
<button id="close-load-modal" class="text-gray-500 hover:text-gray-700">
<i class="fas fa-times"></i>
</button>
</div>
<div class="mb-4">
<input type="text" id="search-saved" class="w-full border border-gray-300 rounded-lg p-2 focus:outline-none focus:ring-2 focus:ring-academic-blue" placeholder="Search saved chats...">
</div>
<div id="saved-chats-modal-list" class="max-h-96 overflow-y-auto">
<!-- Saved chats will appear here -->
<div class="text-gray-500 italic text-center py-8">No saved chats found</div>
</div>
<div class="flex justify-end mt-4">
<button id="cancel-load" class="bg-gray-200 hover:bg-gray-300 text-gray-800 font-semibold py-2 px-4 rounded-lg">
Close
</button>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// DOM Elements
const chatForm = document.getElementById('chat-form');
const userInput = document.getElementById('user-input');
const chatContainer = document.getElementById('chat-container');
const typingIndicator = document.getElementById('typing-indicator');
const saveChatBtn = document.getElementById('save-chat-btn');
const loadChatBtn = document.getElementById('load-chat-btn');
const clearChatBtn = document.getElementById('clear-chat-btn');
const saveModal = document.getElementById('save-modal');
const loadModal = document.getElementById('load-modal');
const closeSaveModal = document.getElementById('close-save-modal');
const closeLoadModal = document.getElementById('close-load-modal');
const cancelSave = document.getElementById('cancel-save');
const confirmSave = document.getElementById('confirm-save');
const cancelLoad = document.getElementById('cancel-load');
const quickPromptBtns = document.querySelectorAll('.quick-prompt-btn');
const charCount = document.getElementById('char-count');
const wordCount = document.getElementById('word-count');
const voiceInputBtn = document.getElementById('voice-input-btn');
const citationBtn = document.getElementById('citation-btn');
const formatBtn = document.getElementById('format-btn');
// Sample saved chats data (in a real app, this would come from localStorage or a database)
let savedChats = [];
// Auto-resize textarea
userInput.addEventListener('input', function() {
this.style.height = 'auto';
this.style.height = (this.scrollHeight) + 'px';
// Update character count
const currentLength = this.value.length;
charCount.textContent = `${currentLength}/1000`;
// Update word count (for the entire chat)
updateWordCount();
});
// Update word count function
function updateWordCount() {
const text = chatContainer.textContent || '';
const words = text.trim() ? text.trim().split(/\s+/).length : 0;
wordCount.textContent = `${words} words`;
}
// Chat form submission
chatForm.addEventListener('submit', function(e) {
e.preventDefault();
const message = userInput.value.trim();
if (message) {
// Add user message to chat
addMessageToChat('user', message);
userInput.value = '';
userInput.style.height = 'auto';
charCount.textContent = '0/1000';
// Show typing indicator
typingIndicator.classList.remove('hidden');
chatContainer.scrollTop = chatContainer.scrollHeight;
// Simulate AI response after a delay
setTimeout(() => {
typingIndicator.classList.add('hidden');
const aiResponse = generateAIResponse(message);
addMessageToChat('assistant', aiResponse);
}, 1500);
}
});
// Add message to chat function
function addMessageToChat(role, content) {
const messageDiv = document.createElement('div');
messageDiv.className = 'chat-bubble mb-6';
if (role === 'user') {
messageDiv.innerHTML = `
<div class="flex items-start justify-end">
<div class="bg-academic-blue text-white rounded-lg p-4 max-w-[85%]">
<p class="text-white">${content}</p>
</div>
<div class="bg-academic-gold text-academic-blue rounded-full w-10 h-10 flex items-center justify-center ml-3">
<i class="fas fa-user-graduate"></i>
</div>
</div>
`;
} else {
messageDiv.innerHTML = `
<div class="flex items-start">
<div class="bg-academic-blue text-white rounded-full w-10 h-10 flex items-center justify-center mr-3">
<i class="fas fa-robot"></i>
</div>
<div class="bg-gray-100 rounded-lg p-4 max-w-[85%]">
<h3 class="font-semibold text-academic-blue mb-1">PhD Research Assistant</h3>
<p class="text-gray-800">${content}</p>
<div class="mt-3 flex space-x-3 text-sm">
<button class="copy-btn text-academic-blue hover:text-blue-800 flex items-center">
<i class="fas fa-copy mr-1"></i> Copy
</button>
<button class="save-excerpt-btn text-academic-blue hover:text-blue-800 flex items-center">
<i class="fas fa-save mr-1"></i> Save Excerpt
</button>
</div>
</div>
</div>
`;
}
chatContainer.appendChild(messageDiv);
chatContainer.scrollTop = chatContainer.scrollHeight;
updateWordCount();
// Add event listeners to new buttons
if (role === 'assistant') {
const copyBtn = messageDiv.querySelector('.copy-btn');
const saveExcerptBtn = messageDiv.querySelector('.save-excerpt-btn');
copyBtn.addEventListener('click', function() {
navigator.clipboard.writeText(content);
const originalText = copyBtn.innerHTML;
copyBtn.innerHTML = '<i class="fas fa-check mr-1"></i> Copied!';
setTimeout(() => {
copyBtn.innerHTML = originalText;
}, 2000);
});
saveExcerptBtn.addEventListener('click', function() {
alert('Excerpt saved to your research notes!');
// In a real app, this would save to a database or localStorage
});
}
}
// Generate AI response (simulated)
function generateAIResponse(userMessage) {
// In a real app, this would call an API
const responses = {
'help me structure my literature review': `A well-structured literature review typically includes these sections:
1. Introduction: State your research question and the scope of the review
2. Theoretical Framework: Discuss key theories relevant to your study
3. Empirical Review: Summarize and critique previous studies
4. Gaps in Literature: Identify what hasn't been addressed
5. Conclusion: Synthesize findings and connect to your research
Would you like me to elaborate on any of these sections or help you find sources for a specific part?`,
'suggest methodologies for my research on': `The methodology depends on your research questions and field. Here are some options:
For qualitative research:
- Case studies
- Ethnography
- Phenomenology
- Grounded theory
For quantitative research:
- Surveys
- Experiments
- Longitudinal studies
- Statistical modeling
Mixed methods combine both approaches. Could you share more about your specific topic and research objectives so I can provide more tailored suggestions?`,
'help me analyze this data': `Data analysis requires careful planning. Here's a general approach:
1. Clean your data (remove outliers, handle missing values)
2. Choose appropriate analysis methods based on your data type
3. For qualitative data: thematic analysis, content analysis
4. For quantitative data: descriptive stats, regression, ANOVA
5. Interpret results in context of your research questions
Would you like to share more details about your data type and research goals?`,
'help me write an abstract for my paper on': `A strong abstract typically includes:
1. Context/Background (1-2 sentences)
2. Research problem/gap (1 sentence)
3. Methods (1-2 sentences)
4. Key findings (1-2 sentences)
5. Significance/Implications (1 sentence)
Example structure:
"This study examines [topic] in the context of [field]. Despite [gap in literature], little research has addressed [specific aspect]. Using [methods], we analyze [data] to [research goal]. Findings suggest [key results], contributing to [field] by [significance]."
Would you like me to generate a draft based on your specific details?`,
'suggest academic conferences in': `Here are some notable conferences in various fields for 2024:
Humanities/Social Sciences:
- International Congress of Qualitative Inquiry (May 2024)
- Annual Meeting of the American Anthropological Association (November 2024)
STEM:
- IEEE International Conference (varies by specialty)
- ACM SIGCHI Conference on Human Factors in Computing Systems (April 2024)
Interdisciplinary:
- International Conference on Interdisciplinary Social Sciences (July 2024)
- World Congress of Humanities (August 2024)
Would you like me to search for conferences in a specific discipline or region?`
};
// Check for quick prompt matches
const lowerMessage = userMessage.toLowerCase();
for (const [key, value] of Object.entries(responses)) {
if (lowerMessage.includes(key.toLowerCase())) {
return value;
}
}
// Default response for unmatched queries
return `Thank you for your question about "${userMessage}". As a PhD research assistant, I can help you with:
1. Breaking down complex research problems
2. Identifying relevant literature
3. Developing appropriate methodologies
4. Analyzing and interpreting data
5. Academic writing and editing
Could you please provide more details about your specific needs regarding this topic? This will help me give you more targeted assistance.`;
}
// Quick prompt buttons
quickPromptBtns.forEach(btn => {
btn.addEventListener('click', function() {
const prompt = this.getAttribute('data-prompt');
userInput.value = prompt;
userInput.focus();
});
});
// Save chat functionality
saveChatBtn.addEventListener('click', function() {
saveModal.classList.remove('hidden');
});
closeSaveModal.addEventListener('click', function() {
saveModal.classList.add('hidden');
});
cancelSave.addEventListener('click', function() {
saveModal.classList.add('hidden');
});
confirmSave.addEventListener('click', function() {
const title = document.getElementById('chat-title').value.trim();
const tags = document.getElementById('chat-tags').value.trim();
if (!title) {
alert('Please enter a title for your chat session');
return;
}
// Create chat object
const chat = {
id: Date.now(),
title: title,
tags: tags.split(',').map(tag => tag.trim()),
date: new Date().toLocaleString(),
content: chatContainer.innerHTML
};
// Save to "database"
savedChats.push(chat);
updateSavedChatsList();
// Clear and close modal
document.getElementById('chat-title').value = '';
document.getElementById('chat-tags').value = '';
saveModal.classList.add('hidden');
// Show success message
alert('Chat session saved successfully!');
});
// Load chat functionality
loadChatBtn.addEventListener('click', function() {
loadModal.classList.remove('hidden');
updateSavedChatsModalList();
});
closeLoadModal.addEventListener('click', function() {
loadModal.classList.add('hidden');
});
cancelLoad.addEventListener('click', function() {
loadModal.classList.add('hidden');
});
// Update saved chats list in sidebar
function updateSavedChatsList() {
const savedChatsList = document.getElementById('saved-chats-list');
if (savedChats.length === 0) {
savedChatsList.innerHTML = '<div class="text-gray-500 italic text-center py-4">No saved chats yet</div>';
return;
}
savedChatsList.innerHTML = '';
savedChats.slice().reverse().forEach(chat => {
const chatElement = document.createElement('div');
chatElement.className = 'bg-gray-50 hover:bg-gray-100 rounded-lg p-3 cursor-pointer border border-gray-200';
chatElement.innerHTML = `
<div class="font-medium text-academic-blue truncate">${chat.title}</div>
<div class="text-xs text-gray-500 mt-1 flex justify-between">
<span>${chat.date}</span>
<span>${chat.tags.slice(0, 2).map(tag => `#${tag}`).join(' ')}</span>
</div>
`;
chatElement.addEventListener('click', function() {
if (confirm('Load this chat? Your current chat will be cleared.')) {
chatContainer.innerHTML = chat.content;
loadModal.classList.add('hidden');
updateWordCount();
// Reattach event listeners to all assistant messages
document.querySelectorAll('.chat-bubble').forEach(bubble => {
const assistantDiv = bubble.querySelector('.bg-gray-100');
if (assistantDiv) {
const copyBtn = bubble.querySelector('.copy-btn');
const saveExcerptBtn = bubble.querySelector('.save-excerpt-btn');
if (copyBtn) {
copyBtn.addEventListener('click', function() {
const content = assistantDiv.querySelector('p').textContent;
navigator.clipboard.writeText(content);
const originalText = copyBtn.innerHTML;
copyBtn.innerHTML = '<i class="fas fa-check mr-1"></i> Copied!';
setTimeout(() => {
copyBtn.innerHTML = originalText;
}, 2000);
});
}
if (saveExcerptBtn) {
saveExcerptBtn.addEventListener('click', function() {
alert('Excerpt saved to your research notes!');
});
}
}
});
}
});
savedChatsList.appendChild(chatElement);
});
}
// Update saved chats list in modal
function updateSavedChatsModalList() {
const savedChatsModalList = document.getElementById('saved-chats-modal-list');
if (savedChats.length === 0) {
savedChatsModalList.innerHTML = '<div class="text-gray-500 italic text-center py-8">No saved chats found</div>';
return;
}
savedChatsModalList.innerHTML = '';
savedChats.slice().reverse().forEach(chat => {
const chatElement = document.createElement('div');
chatElement.className = 'border-b border-gray-200 py-4';
chat
</html>