AI Chat - Asystent Bielik
<HTML>
<div id="custom-ai-chat-messages"></div>
<div id="custom-ai-chat-input-area">
<div id="custom-ai-chat-progress" style="display: none;">
<div class="progress-bar">
<div class="progress-fill"></div>
</div>
<span class="progress-text">Odpowiadam...</span>
</div>
<form id="custom-ai-chat-form">
<textarea id="custom-ai-chat-input" placeholder="Zadaj pytanie..." rows="3"></textarea>
<div class="chat-buttons">
<button type="button" id="clear-history" title="Wyczyść historię">
<svg viewBox="0 0 24 24"><path d="M12,4C14.1,4 16.1,4.8 17.6,6.3C20.7,9.4 20.7,14.5 17.6,17.6C15.8,19.5 13.3,20.2 10.9,19.9L11.4,17.9C13.1,18.1 14.9,17.5 16.2,16.2C18.5,13.9 18.5,10.1 16.2,7.7C15.1,6.6 13.5,6 12,6V10.6L7,5.6L12,0.6V4M6.3,17.6C3.7,15 3.3,11 5.1,7.9L6.6,9.4C5.5,11.6 5.9,14.4 7.8,16.2C8.3,16.7 8.9,17.1 9.6,17.4L9,19.4C8,19 7.1,18.4 6.3,17.6Z" /></svg>
</button>
<button type="submit" id="send-message" title="Wyślij">
<svg viewBox="0 0 24 24"><path d="M2,21L23,12L2,3V10L17,12L2,14V21Z" /></svg>
</button>
</div>
</form>
</div>
<style> #custom-ai-chat-container {
max-width: 1200px; margin: 0 auto; background: #ffffff; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); overflow: hidden; height: 700px; display: flex; flex-direction: column;
}
#custom-ai-chat-messages {
flex: 1; padding: 20px; overflow-y: auto; background: linear-gradient(to bottom, #f8f9fa, #ffffff); scroll-behavior: smooth;
}
.message {
margin-bottom: 20px; display: flex; align-items: flex-start; gap: 12px; animation: slideIn 0.3s ease-out;
}
.message.user {
flex-direction: row-reverse;
}
.message-avatar {
width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; color: white; flex-shrink: 0;
}
.message.user .message-avatar {
background: linear-gradient(45deg, #4f46e5, #7c3aed);
}
.message.ai .message-avatar {
background: linear-gradient(45deg, #059669, #0d9488);
}
.message-content {
max-width: 70%; padding: 15px 20px; border-radius: 18px; position: relative; word-wrap: break-word;
}
.message.user .message-content {
background: linear-gradient(45deg, #4f46e5, #7c3aed); color: white; border-bottom-right-radius: 6px;
}
.message.ai .message-content {
background: #f3f4f6; color: #374151; border: 1px solid #e5e7eb; border-bottom-left-radius: 6px;
}
.message-content h1, .message-content h2, .message-content h3, .message-content h4, .message-content h5, .message-content h6 {
margin-top: 0; margin-bottom: 10px; color: inherit;
}
.message-content p {
margin: 0 0 10px 0;
}
.message-content p:last-child {
margin-bottom: 0;
}
.message-content ul, .message-content ol {
margin: 10px 0; padding-left: 20px;
}
.message-content li {
margin-bottom: 5px;
}
.message-content a {
color: #2563eb; text-decoration: none;
}
.message-content a:hover {
text-decoration: underline;
}
.message.user .message-content a {
color: #bfdbfe;
}
.sources {
margin-top: 12px; padding-top: 12px; border-top: 1px solid #e5e7eb; font-size: 0.9em;
}
.sources strong {
display: block; margin-bottom: 8px; color: #374151;
}
.sources ul {
list-style: none; padding: 0; margin: 0;
}
.sources li {
margin: 0 0 6px 0;
}
.sources a {
color: #059669; text-decoration: none; font-weight: 500;
}
.sources a:hover {
text-decoration: underline;
}
#custom-ai-chat-input-area {
padding: 20px; background: white; border-top: 1px solid #e5e7eb;
}
#custom-ai-chat-progress {
margin-bottom: 15px; text-align: center;
}
.progress-bar {
width: 100%; height: 4px; background: #e5e7eb; border-radius: 2px; overflow: hidden; margin-bottom: 8px;
}
.progress-fill {
height: 100%; background: linear-gradient(45deg, #059669, #0d9488); animation: progress-slide 2s ease-in-out infinite; width: 30%;
}
@keyframes progress-slide {
0% { transform: translateX(-100%); }
100% { transform: translateX(400%); }
}
.progress-text {
color: #6b7280; font-size: 14px; font-style: italic;
}
#custom-ai-chat-form {
display: flex; gap: 12px; align-items: flex-end;
}
#custom-ai-chat-input {
flex: 1; padding: 12px 16px; border: 2px solid #e5e7eb; border-radius: 12px; font-size: 16px; font-family: inherit; resize: none; outline: none; transition: border-color 0.2s, box-shadow 0.2s; min-height: 48px; max-height: 120px;
}
#custom-ai-chat-input:focus {
border-color: #059669; box-shadow: 0 0 0 3px rgba(5, 150, 105, 0.1);
}
.chat-buttons {
display: flex; gap: 8px;
}
.chat-buttons button {
width: 48px; height: 48px; border: none; border-radius: 12px; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s;
}
#clear-history {
background: #f3f4f6; color: #6b7280;
}
#clear-history:hover {
background: #e5e7eb; color: #374151;
}
#send-message {
background: linear-gradient(45deg, #059669, #0d9488); color: white;
}
#send-message:hover {
background: linear-gradient(45deg, #047857, #0f766e); transform: translateY(-1px); box-shadow: 0 4px 12px rgba(5, 150, 105, 0.3);
}
.chat-buttons svg {
width: 20px; height: 20px; fill: currentColor;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* Responsive design */ @media (max-width: 768px) {
#custom-ai-chat-container {
height: calc(100vh - 100px);
margin: 10px;
border-radius: 8px;
}
.message-content {
max-width: 85%;
}
#custom-ai-chat-input-area {
padding: 15px;
}
}
/* Dark mode support */ @media (prefers-color-scheme: dark) {
#custom-ai-chat-container {
background: #1f2937;
box-shadow: 0 4px 20px rgba(0,0,0,0.3);
}
#custom-ai-chat-messages {
background: linear-gradient(to bottom, #374151, #1f2937);
}
.message.ai .message-content {
background: #374151;
color: #f3f4f6;
border-color: #4b5563;
}
#custom-ai-chat-input-area {
background: #1f2937;
border-top-color: #4b5563;
}
#custom-ai-chat-input {
background: #374151;
color: #f3f4f6;
border-color: #4b5563;
}
#custom-ai-chat-input:focus {
border-color: #10b981;
}
#clear-history {
background: #374151;
color: #9ca3af;
}
#clear-history:hover {
background: #4b5563;
color: #f3f4f6;
}
} </style>
<script> document.addEventListener('DOMContentLoaded', function() {
const messagesContainer = document.getElementById('custom-ai-chat-messages');
const form = document.getElementById('custom-ai-chat-form');
const input = document.getElementById('custom-ai-chat-input');
const progress = document.getElementById('custom-ai-chat-progress');
const clearBtn = document.getElementById('clear-history');
let chatHistory = [];
// Auto-resize textarea
input.addEventListener('input', function() {
this.style.height = 'auto';
this.style.height = Math.min(this.scrollHeight, 120) + 'px';
});
// Initial welcome message
addMessage('ai', 'Witaj! Jestem Bielik, Twój asystent AI. Jak mogę Ci pomóc?');
// Load chat history from sessionStorage
loadChatHistory();
// Handle form submission
form.addEventListener('submit', async function(e) {
e.preventDefault();
const message = input.value.trim();
if (!message) return;
// Add user message
addMessage('user', message);
input.value = '';
input.style.height = 'auto';
// Show progress
progress.style.display = 'block';
try {
const response = await sendToAPI(message);
// Hide progress
progress.style.display = 'none';
// Add AI response
addMessage('ai', response.answer, response.sources);
// Save to history
chatHistory.push([response.question, response.answer, response.sources]);
saveChatHistory();
} catch (error) {
progress.style.display = 'none';
addMessage('ai', 'Przepraszam, wystąpił błąd podczas przetwarzania Twojego pytania. Spróbuj ponownie.');
console.error('Error:', error);
}
});
// Handle Enter key (submit) and Shift+Enter (new line)
input.addEventListener('keydown', function(e) {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
form.dispatchEvent(new Event('submit'));
}
});
// Clear history button
clearBtn.addEventListener('click', function() {
if (confirm('Czy na pewno chcesz wyczyścić historię czatu?')) {
messagesContainer.innerHTML = '';
chatHistory = [];
sessionStorage.removeItem('ai-chat-history-custom');
addMessage('ai', 'Historia czatu została wyczyszczona. Jak mogę Ci pomóc?');
}
});
function addMessage(type, content, sources = null) {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${type}`;
const avatar = document.createElement('div');
avatar.className = 'message-avatar';
avatar.textContent = type === 'user' ? 'Ty' : 'AI';
const contentDiv = document.createElement('div');
contentDiv.className = 'message-content';
if (type === 'ai') {
contentDiv.innerHTML = content; // AI messages can contain HTML
} else {
contentDiv.textContent = content; // User messages are plain text
}
// Add sources if provided
if (sources && sources.length > 0) {
const sourcesDiv = document.createElement('div');
sourcesDiv.className = 'sources';
sourcesDiv.innerHTML = '<strong>Źródła:</strong>';
const sourcesList = document.createElement('ul');
sources.forEach(source => {
const li = document.createElement('li');
const link = document.createElement('a');
link.href = source.url;
link.textContent = source.title;
link.title = `${source.page} (wynik: ${source.score})`;
li.appendChild(link);
sourcesList.appendChild(li);
});
sourcesDiv.appendChild(sourcesList);
contentDiv.appendChild(sourcesDiv);
}
messageDiv.appendChild(avatar);
messageDiv.appendChild(contentDiv);
messagesContainer.appendChild(messageDiv);
// Smooth scroll to bottom without affecting page scroll
setTimeout(() => {
messagesContainer.scrollTop = messagesContainer.scrollHeight;
}, 100);
}
async function sendToAPI(message) {
const formData = new FormData();
formData.append('call', 'aichat');
formData.append('question', message);
formData.append('history', JSON.stringify(chatHistory));
const response = await fetch(DOKU_BASE + 'lib/exe/ajax.php', {
method: 'POST',
body: formData
});
if (!response.ok) {
throw new Error('Network response was not ok');
}
return await response.json();
}
function saveChatHistory() {
sessionStorage.setItem('ai-chat-history-custom', JSON.stringify(chatHistory));
}
function loadChatHistory() {
const saved = sessionStorage.getItem('ai-chat-history-custom');
if (saved) {
try {
chatHistory = JSON.parse(saved);
chatHistory.forEach(([question, answer, sources]) => {
addMessage('user', question);
addMessage('ai', answer, sources);
});
} catch (e) {
console.warn('Could not load chat history:', e);
}
}
}
}); </script> </HTML>