Spaces:
Sleeping
Sleeping
Download frontend/admin.html from YADUUG/NPS-ChatAgentBot: direct link, hf CLI and curl.
- Browser
- Download file 7.91 kB
-
https://huggingface.co/spaces/YADUUG/NPS-ChatAgentBot/resolve/main/frontend/admin.html
- Command line
-
hf download hf://spaces/YADUUG/NPS-ChatAgentBot/frontend/admin.html
-
curl -L -o admin.html https://huggingface.co/spaces/YADUUG/NPS-ChatAgentBot/resolve/main/frontend/admin.html
7.91 kB
| <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> |