filetest / templates /index.html
arcticaurora's picture
Create templates/index.html
7f52215 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>File System Test App</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<!-- TinyMCE -->
<script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/6/tinymce.min.js" referrerpolicy="origin"></script>
<style>
body {
background-color: #f8f9fa;
}
.main-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.card {
margin-bottom: 20px;
border: none;
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
}
.card-header {
background-color: #f8f9fa;
border-bottom: 1px solid #e9ecef;
}
.file-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #e9ecef;
}
.file-item:last-child {
border-bottom: none;
}
.system-info-content {
max-height: 500px;
overflow-y: auto;
font-family: monospace;
font-size: 14px;
background-color: #f8f9fa;
padding: 15px;
border-radius: 4px;
}
.test-btn {
margin: 5px;
}
</style>
</head>
<body>
<div class="main-container">
<h1 class="mb-4">File System Test App</h1>
<div class="row">
<!-- Text Editor Card -->
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Create & Save Text File</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label for="filename" class="form-label">Filename</label>
<input type="text" class="form-control" id="filename" placeholder="Enter filename">
</div>
<div class="mb-3">
<label class="form-label">Content</label>
<textarea id="editor" rows="10" class="form-control"></textarea>
</div>
<button id="save-btn" class="btn btn-primary">Save File</button>
</div>
</div>
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Upload File</h5>
</div>
<div class="card-body">
<form id="upload-form">
<div class="mb-3">
<label for="file-upload" class="form-label">Select a file</label>
<input class="form-control" type="file" id="file-upload">
</div>
<button type="submit" class="btn btn-primary">Upload</button>
</form>
</div>
</div>
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">Testing Tools</h5>
</div>
<div class="card-body">
<button id="system-info-btn" class="btn btn-info test-btn">
<i class="fas fa-info-circle"></i> System Info
</button>
<button id="binary-file-btn" class="btn btn-warning test-btn">
<i class="fas fa-file-binary"></i> Create Binary File
</button>
<button id="command-output-btn" class="btn btn-secondary test-btn">
<i class="fas fa-terminal"></i> Test Command Output
</button>
<button id="large-file-btn" class="btn btn-danger test-btn">
<i class="fas fa-file-alt"></i> Create Large File (10MB)
</button>
</div>
</div>
</div>
<!-- Files List Card -->
<div class="col-md-6">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">Files</h5>
<button id="refresh-files-btn" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-sync-alt"></i> Refresh
</button>
</div>
<div class="card-body p-0">
<div id="files-list" class="list-group list-group-flush">
<div class="text-center py-4">
<i class="fas fa-spinner fa-spin"></i> Loading files...
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h5 class="card-title mb-0">System Information</h5>
</div>
<div class="card-body">
<div id="system-info" class="system-info-content">
<p>Click the "System Info" button to load system details...</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Toast container for notifications -->
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<div id="toast" class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto" id="toast-title">Notification</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body" id="toast-message">
Message goes here
</div>
</div>
</div>
<!-- Bootstrap & jQuery -->
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Initialize TinyMCE
tinymce.init({
selector: '#editor',
height: 300,
menubar: false,
plugins: 'lists link image table code',
toolbar: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright | bullist numlist | link image | table | code',
content_style: 'body { font-family: -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif; font-size: 14px; }'
});
// Show toast notification
function showToast(title, message, type = 'success') {
const toast = document.getElementById('toast');
document.getElementById('toast-title').textContent = title;
document.getElementById('toast-message').textContent = message;
// Remove previous color classes
toast.classList.remove('bg-success', 'bg-danger', 'bg-warning', 'text-white');
// Add appropriate color class
if (type === 'success') {
toast.classList.add('bg-success', 'text-white');
} else if (type === 'error') {
toast.classList.add('bg-danger', 'text-white');
} else if (type === 'warning') {
toast.classList.add('bg-warning');
}
// Show the toast
const bsToast = new bootstrap.Toast(toast);
bsToast.show();
}
// Load file list
function loadFiles() {
fetch('/list-files')
.then(response => response.json())
.then(data => {
if (data.success) {
const filesList = document.getElementById('files-list');
if (data.files.length === 0) {
filesList.innerHTML = '<div class="text-center py-4">No files found</div>';
return;
}
filesList.innerHTML = '';
data.files.forEach(file => {
const fileItem = document.createElement('div');
fileItem.className = 'file-item';
fileItem.innerHTML = `
<div>
<div><strong>${file.name}</strong></div>
<small class="text-muted">${file.size_readable} - ${file.modified}</small>
</div>
<div>
<a href="${file.url}" class="btn btn-sm btn-outline-primary" target="_blank">
<i class="fas fa-download"></i>
</a>
<button class="btn btn-sm btn-outline-danger delete-file" data-filename="${file.name}">
<i class="fas fa-trash"></i>
</button>
</div>
`;
filesList.appendChild(fileItem);
});
// Add delete event listeners
document.querySelectorAll('.delete-file').forEach(button => {
button.addEventListener('click', function() {
const filename = this.getAttribute('data-filename');
deleteFile(filename);
});
});
} else {
showToast('Error', data.message, 'error');
}
})
.catch(error => {
console.error('Error loading files:', error);
showToast('Error', 'Failed to load files', 'error');
});
}
// Delete file
function deleteFile(filename) {
if (confirm(`Are you sure you want to delete ${filename}?`)) {
fetch(`/delete-file/${filename}`, {
method: 'DELETE'
})
.then(response => response.json())
.then(data => {
if (data.success) {
showToast('Success', `File ${filename} deleted successfully`);
loadFiles();
} else {
showToast('Error', data.message, 'error');
}
})
.catch(error => {
console.error('Error deleting file:', error);
showToast('Error', 'Failed to delete file', 'error');
});
}
}
// Save file
document.getElementById('save-btn').addEventListener('click', function() {
const filename = document.getElementById('filename').value;
if (!filename) {
showToast('Error', 'Please enter a filename', 'error');
return;
}
const content = tinymce.get('editor').getContent();
const formData = new FormData();
formData.append('filename', filename);
formData.append('content', content);
fetch('/save-file', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
showToast('Success', 'File saved successfully');
loadFiles();
} else {
showToast('Error', data.message, 'error');
}
})
.catch(error => {
console.error('Error saving file:', error);
showToast('Error', 'Failed to save file', 'error');
});
});
// Upload file
document.getElementById('upload-form').addEventListener('submit', function(e) {
e.preventDefault();
const fileInput = document.getElementById('file-upload');
if (!fileInput.files[0]) {
showToast('Error', 'Please select a file to upload', 'error');
return;
}
const formData = new FormData();
formData.append('file', fileInput.files[0]);
fetch('/upload-file', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.success) {
showToast('Success', 'File uploaded successfully');
loadFiles();
fileInput.value = '';
} else {
showToast('Error', data.message, 'error');
}
})
.catch(error => {
console.error('Error uploading file:', error);
showToast('Error', 'Failed to upload file', 'error');
});
});
// Refresh files list
document.getElementById('refresh-files-btn').addEventListener('click', loadFiles);
// System info
document.getElementById('system-info-btn').addEventListener('click', function() {
fetch('/system-info')
.then(response => response.json())
.then(data => {
if (data.success) {
const systemInfo = document.getElementById('system-info');
systemInfo.innerHTML = `<pre>${JSON.stringify(data, null, 2)}</pre>`;
showToast('Success', 'System information loaded');
} else {
showToast('Error', data.message, 'error');
}
})
.catch(error => {
console.error('Error getting system info:', error);
showToast('Error', 'Failed to get system info', 'error');
});
});
// Binary file test
document.getElementById('binary-file-btn').addEventListener('click', function() {
fetch('/test-binary-file')
.then(response => response.json())
.then(data => {
if (data.success) {
showToast('Success', `Binary file created: ${data.file_size} bytes`);
loadFiles();
} else {
showToast('Error', data.message, 'error');
}
})
.catch(error => {
console.error('Error creating binary file:', error);
showToast('Error', 'Failed to create binary file', 'error');
});
});
// Command output test
document.getElementById('command-output-btn').addEventListener('click', function() {
fetch('/test-command-output')
.then(response => response.json())
.then(data => {
if (data.success) {
showToast('Success', 'Command output saved to files');
loadFiles();
} else {
showToast('Error', data.message, 'error');
}
})
.catch(error => {
console.error('Error testing command output:', error);
showToast('Error', 'Failed to test command output', 'error');
});
});
// Load files on page load
document.addEventListener('DOMContentLoaded', loadFiles);
</script>
</body>
</html>