NPS-ChatAgentBot / frontend /admin.html
YADUUG's picture
Base 1.0
4e06012
Raw History Blame Contribute Delete
7.91 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NPS Admin Panel</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa;
}
.container {
margin-top: 50px;
}
#status {
margin-top: 15px;
}
.home-link {
margin-top: 20px;
}
</style>
</head>
<body>
<div class="container">
<div class="card">
<div class="card-header">
<h1>🏛️ NPS Admin Panel</h1>
</div>
<div class="card-body">
<h2>Existing Files</h2>
<ul id="file-list" class="list-group mb-3"></ul>
<div id="status"></div>
<h2 class="mt-4">Upload New File</h2>
<form id="upload-form" enctype="multipart/form-data">
<div class="input-group mb-3">
<input type="file" class="form-control" id="file-input" name="file" accept=".pdf,.txt,.md,.docx"
required>
<button class="btn btn-primary" type="submit" id="upload-button">Upload</button>
</div>
</form>
<a href="/" class="btn btn-secondary home-link">Back to Chat</a>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const fileList = document.getElementById('file-list');
const uploadForm = document.getElementById('upload-form');
const fileInput = document.getElementById('file-input');
const status = document.getElementById('status');
let credentials = null;
const getCredentials = () => {
const username = prompt("Enter username:");
const password = prompt("Enter password:");
if (username && password) {
credentials = btoa(`${username}:${password}`);
return true;
}
return false;
};
const fetchWithAuth = async (url, options = {}) => {
if (!credentials) {
if (!getCredentials()) {
status.innerHTML = '<div class="alert alert-danger">Authentication required.</div>';
return null;
}
}
const headers = { ...options.headers, 'Authorization': `Basic ${credentials}` };
let response = await fetch(url, { ...options, headers });
if (response.status === 401) {
status.innerHTML = '<div class="alert alert-danger">Authentication failed. Please try again.</div>';
credentials = null; // Reset credentials
if (getCredentials()) {
const newHeaders = { ...options.headers, 'Authorization': `Basic ${credentials}` };
response = await fetch(url, { ...options, headers: newHeaders });
} else {
status.innerHTML = '<div class="alert alert-danger">Authentication required.</div>';
return null;
}
}
return response;
};
const fetchFiles = async () => {
status.innerHTML = '<div class="alert alert-info">Loading files...</div>';
try {
const response = await fetchWithAuth('/admin/files');
if (!response) return;
if (response.ok) {
const files = await response.json();
fileList.innerHTML = '';
if (files.length === 0) {
fileList.innerHTML = '<li class="list-group-item">No files found.</li>';
} else {
files.forEach(file => {
const li = document.createElement('li');
li.className = 'list-group-item d-flex justify-content-between align-items-center';
li.textContent = file;
const deleteBtn = document.createElement('button');
deleteBtn.textContent = 'Delete';
deleteBtn.className = 'btn btn-danger btn-sm';
deleteBtn.onclick = () => deleteFile(file);
li.appendChild(deleteBtn);
fileList.appendChild(li);
});
}
status.innerHTML = '';
} else {
status.innerHTML = '<div class="alert alert-danger">Error loading files.</div>';
}
} catch (error) {
status.innerHTML = '<div class="alert alert-danger">Error loading files.</div>';
console.error('Error fetching files:', error);
}
};
const deleteFile = async (filename) => {
if (!confirm(`Are you sure you want to delete ${filename}?`)) return;
status.innerHTML = `<div class="alert alert-info">Deleting ${filename}...</div>`;
try {
const response = await fetchWithAuth(`/admin/files/${filename}`, { method: 'DELETE' });
if (!response) return;
if (response.ok) {
status.innerHTML = `<div class="alert alert-success">File '${filename}' deleted.</div>`;
fetchFiles();
} else {
const error = await response.json();
throw new Error(error.detail || 'Failed to delete file.');
}
} catch (error) {
status.innerHTML = `<div class="alert alert-danger">Error deleting file: ${error.message}</div>`;
console.error('Error deleting file:', error);
}
};
uploadForm.addEventListener('submit', async (event) => {
event.preventDefault();
const file = fileInput.files[0];
if (!file) return;
const formData = new FormData();
formData.append('file', file);
status.innerHTML = `<div class="alert alert-info">Uploading ${file.name}...</div>`;
try {
const response = await fetchWithAuth('/admin/files', {
method: 'POST',
body: formData,
});
if (!response) return;
if (response.ok) {
status.innerHTML = `<div class="alert alert-success">File '${file.name}' uploaded successfully.</div>`;
fileInput.value = '';
fetchFiles();
} else {
const error = await response.json();
throw new Error(error.detail || 'Failed to upload file.');
}
} catch (error) {
status.innerHTML = `<div class="alert alert-danger">Error uploading file: ${error.message}</div>`;
console.error('Error uploading file:', error);
}
});
fetchFiles();
});
</script>
</body>
</html>