946 lines
28 KiB
HTML
946 lines
28 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Industrial File Manager - Hybrid UI Component</title>
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: 'Roboto Mono', monospace;
|
|
background: #0a0a0a;
|
|
color: #e0e0e0;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
min-height: 100vh;
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
/* Industrial Grid Background */
|
|
body::before {
|
|
content: '';
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-image:
|
|
linear-gradient(rgba(255,165,0,0.05) 1px, transparent 1px),
|
|
linear-gradient(90deg, rgba(255,165,0,0.05) 1px, transparent 1px);
|
|
background-size: 50px 50px;
|
|
pointer-events: none;
|
|
animation: gridShift 20s linear infinite;
|
|
}
|
|
|
|
@keyframes gridShift {
|
|
0% { transform: translate(0, 0); }
|
|
100% { transform: translate(50px, 50px); }
|
|
}
|
|
|
|
/* Main Container */
|
|
.file-manager {
|
|
width: 90%;
|
|
max-width: 1200px;
|
|
height: 80vh;
|
|
background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
|
|
border: 2px solid #ff6600;
|
|
border-radius: 0;
|
|
position: relative;
|
|
display: grid;
|
|
grid-template-columns: 1fr 2fr 1fr;
|
|
gap: 2px;
|
|
box-shadow:
|
|
0 0 50px rgba(255,102,0,0.3),
|
|
inset 0 0 100px rgba(255,102,0,0.1);
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Industrial Corner Brackets */
|
|
.file-manager::before,
|
|
.file-manager::after,
|
|
.corner-bracket-top,
|
|
.corner-bracket-bottom {
|
|
content: '';
|
|
position: absolute;
|
|
width: 30px;
|
|
height: 30px;
|
|
border: 3px solid #ff6600;
|
|
z-index: 10;
|
|
}
|
|
|
|
.file-manager::before {
|
|
top: -5px;
|
|
left: -5px;
|
|
border-right: none;
|
|
border-bottom: none;
|
|
}
|
|
|
|
.file-manager::after {
|
|
top: -5px;
|
|
right: -5px;
|
|
border-left: none;
|
|
border-bottom: none;
|
|
}
|
|
|
|
.corner-bracket-top {
|
|
bottom: -5px;
|
|
left: -5px;
|
|
border-right: none;
|
|
border-top: none;
|
|
}
|
|
|
|
.corner-bracket-bottom {
|
|
bottom: -5px;
|
|
right: -5px;
|
|
border-left: none;
|
|
border-top: none;
|
|
}
|
|
|
|
/* Panel Styles */
|
|
.panel {
|
|
background: #1a1a1a;
|
|
border: 1px solid #333;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.panel-header {
|
|
background: linear-gradient(90deg, #2a2a2a 0%, #3a3a3a 100%);
|
|
padding: 15px;
|
|
border-bottom: 2px solid #ff6600;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
position: relative;
|
|
}
|
|
|
|
.panel-header::after {
|
|
content: '';
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 2px;
|
|
background: linear-gradient(90deg, transparent, #ff6600, transparent);
|
|
animation: scanLine 3s linear infinite;
|
|
}
|
|
|
|
@keyframes scanLine {
|
|
0% { transform: translateX(-100%); }
|
|
100% { transform: translateX(100%); }
|
|
}
|
|
|
|
.panel-title {
|
|
font-size: 14px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 2px;
|
|
color: #ff6600;
|
|
font-weight: 700;
|
|
}
|
|
|
|
/* Left Panel - File Browser */
|
|
.file-browser {
|
|
grid-column: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.file-list {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
padding: 10px;
|
|
}
|
|
|
|
.file-item {
|
|
background: #222;
|
|
border: 1px solid #444;
|
|
padding: 12px;
|
|
margin-bottom: 8px;
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.file-item::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: -100%;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: linear-gradient(90deg, transparent, rgba(255,102,0,0.3), transparent);
|
|
transition: left 0.5s;
|
|
}
|
|
|
|
.file-item:hover::before {
|
|
left: 100%;
|
|
}
|
|
|
|
.file-item:hover {
|
|
border-color: #ff6600;
|
|
transform: translateX(5px);
|
|
box-shadow: -5px 0 10px rgba(255,102,0,0.3);
|
|
}
|
|
|
|
.file-item.active {
|
|
background: #333;
|
|
border-color: #ff6600;
|
|
box-shadow: inset 0 0 20px rgba(255,102,0,0.2);
|
|
}
|
|
|
|
.file-icon {
|
|
display: inline-block;
|
|
width: 20px;
|
|
height: 20px;
|
|
margin-right: 10px;
|
|
background: #ff6600;
|
|
clip-path: polygon(0 0, 80% 0, 100% 20%, 100% 100%, 0 100%);
|
|
}
|
|
|
|
.file-name {
|
|
font-size: 12px;
|
|
color: #ccc;
|
|
}
|
|
|
|
.file-size {
|
|
font-size: 10px;
|
|
color: #666;
|
|
float: right;
|
|
}
|
|
|
|
/* Center Panel - Upload Zone */
|
|
.upload-zone {
|
|
grid-column: 2;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.drop-area {
|
|
flex: 1;
|
|
margin: 20px;
|
|
border: 3px dashed #666;
|
|
background: #0f0f0f;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
overflow: hidden;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.drop-area.dragover {
|
|
border-color: #ff6600;
|
|
background: #1a1a1a;
|
|
box-shadow: inset 0 0 50px rgba(255,102,0,0.2);
|
|
}
|
|
|
|
.drop-area::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
width: 200%;
|
|
height: 200%;
|
|
background: conic-gradient(
|
|
from 0deg,
|
|
transparent 0deg,
|
|
rgba(255,102,0,0.1) 90deg,
|
|
transparent 180deg
|
|
);
|
|
transform: translate(-50%, -50%);
|
|
animation: radar 4s linear infinite;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
@keyframes radar {
|
|
0% { transform: translate(-50%, -50%) rotate(0deg); }
|
|
100% { transform: translate(-50%, -50%) rotate(360deg); }
|
|
}
|
|
|
|
.upload-icon {
|
|
width: 80px;
|
|
height: 80px;
|
|
margin-bottom: 20px;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.gear {
|
|
width: 100%;
|
|
height: 100%;
|
|
border: 3px solid #ff6600;
|
|
border-radius: 50%;
|
|
position: relative;
|
|
animation: gearRotate 10s linear infinite;
|
|
}
|
|
|
|
.gear::before,
|
|
.gear::after {
|
|
content: '';
|
|
position: absolute;
|
|
background: #ff6600;
|
|
}
|
|
|
|
.gear::before {
|
|
width: 30%;
|
|
height: 30%;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.gear::after {
|
|
width: 100%;
|
|
height: 100%;
|
|
top: 0;
|
|
left: 0;
|
|
background: repeating-conic-gradient(
|
|
from 0deg,
|
|
#ff6600 0deg 20deg,
|
|
transparent 20deg 40deg
|
|
);
|
|
-webkit-mask: radial-gradient(circle at center, transparent 30%, black 30%, black 40%, transparent 40%);
|
|
mask: radial-gradient(circle at center, transparent 30%, black 30%, black 40%, transparent 40%);
|
|
}
|
|
|
|
@keyframes gearRotate {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
|
|
.upload-text {
|
|
font-size: 16px;
|
|
color: #ccc;
|
|
text-align: center;
|
|
z-index: 1;
|
|
}
|
|
|
|
.upload-subtext {
|
|
font-size: 12px;
|
|
color: #666;
|
|
margin-top: 10px;
|
|
}
|
|
|
|
/* Progress Bars Container */
|
|
.progress-container {
|
|
padding: 20px;
|
|
max-height: 200px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.progress-item {
|
|
background: #1a1a1a;
|
|
border: 1px solid #333;
|
|
padding: 15px;
|
|
margin-bottom: 10px;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.progress-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.progress-filename {
|
|
font-size: 12px;
|
|
color: #ff6600;
|
|
}
|
|
|
|
.progress-percent {
|
|
font-size: 12px;
|
|
color: #ccc;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.progress-bar {
|
|
height: 10px;
|
|
background: #0a0a0a;
|
|
border: 1px solid #444;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.progress-fill {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, #ff6600 0%, #ff8800 100%);
|
|
width: 0%;
|
|
transition: width 0.3s;
|
|
position: relative;
|
|
}
|
|
|
|
.progress-fill::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
width: 20px;
|
|
height: 100%;
|
|
background: white;
|
|
opacity: 0.5;
|
|
animation: progressPulse 1s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes progressPulse {
|
|
0%, 100% { opacity: 0.5; }
|
|
50% { opacity: 1; }
|
|
}
|
|
|
|
/* Right Panel - Preview & Validation */
|
|
.preview-panel {
|
|
grid-column: 3;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.preview-area {
|
|
flex: 1;
|
|
padding: 20px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
}
|
|
|
|
.preview-content {
|
|
width: 100%;
|
|
height: 100%;
|
|
background: #0f0f0f;
|
|
border: 2px solid #333;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.preview-image {
|
|
max-width: 100%;
|
|
max-height: 100%;
|
|
object-fit: contain;
|
|
}
|
|
|
|
.preview-placeholder {
|
|
text-align: center;
|
|
color: #666;
|
|
}
|
|
|
|
.preview-icon {
|
|
font-size: 48px;
|
|
margin-bottom: 10px;
|
|
color: #444;
|
|
}
|
|
|
|
/* Validation Section */
|
|
.validation-section {
|
|
padding: 20px;
|
|
border-top: 2px solid #333;
|
|
}
|
|
|
|
.validation-item {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 10px;
|
|
padding: 8px;
|
|
background: #1a1a1a;
|
|
border: 1px solid #333;
|
|
transition: all 0.3s;
|
|
}
|
|
|
|
.validation-item.valid {
|
|
border-color: #00ff00;
|
|
box-shadow: inset 0 0 10px rgba(0,255,0,0.1);
|
|
}
|
|
|
|
.validation-item.invalid {
|
|
border-color: #ff0000;
|
|
box-shadow: inset 0 0 10px rgba(255,0,0,0.1);
|
|
}
|
|
|
|
.validation-icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
margin-right: 10px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.validation-icon::before {
|
|
content: '⚙';
|
|
font-size: 16px;
|
|
color: #666;
|
|
animation: validationSpin 2s linear infinite;
|
|
}
|
|
|
|
.validation-item.valid .validation-icon::before {
|
|
content: '✓';
|
|
color: #00ff00;
|
|
animation: none;
|
|
}
|
|
|
|
.validation-item.invalid .validation-icon::before {
|
|
content: '✗';
|
|
color: #ff0000;
|
|
animation: none;
|
|
}
|
|
|
|
@keyframes validationSpin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
|
|
.validation-text {
|
|
font-size: 12px;
|
|
color: #ccc;
|
|
}
|
|
|
|
/* Status Bar */
|
|
.status-bar {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 30px;
|
|
background: #1a1a1a;
|
|
border-top: 2px solid #ff6600;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 20px;
|
|
font-size: 11px;
|
|
color: #666;
|
|
}
|
|
|
|
.status-indicator {
|
|
width: 8px;
|
|
height: 8px;
|
|
background: #00ff00;
|
|
border-radius: 50%;
|
|
margin-right: 10px;
|
|
animation: statusPulse 2s ease-in-out infinite;
|
|
}
|
|
|
|
@keyframes statusPulse {
|
|
0%, 100% { opacity: 0.5; }
|
|
50% { opacity: 1; }
|
|
}
|
|
|
|
/* File Input */
|
|
#fileInput {
|
|
display: none;
|
|
}
|
|
|
|
/* Scrollbar Styling */
|
|
::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: #0a0a0a;
|
|
border: 1px solid #333;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: #ff6600;
|
|
border: 1px solid #333;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: #ff8800;
|
|
}
|
|
|
|
/* Responsive */
|
|
@media (max-width: 768px) {
|
|
.file-manager {
|
|
grid-template-columns: 1fr;
|
|
grid-template-rows: 1fr 2fr 1fr;
|
|
height: 90vh;
|
|
}
|
|
|
|
.file-browser,
|
|
.upload-zone,
|
|
.preview-panel {
|
|
grid-column: 1;
|
|
}
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="corner-bracket-top"></div>
|
|
<div class="corner-bracket-bottom"></div>
|
|
|
|
<div class="file-manager">
|
|
<!-- Left Panel - File Browser -->
|
|
<div class="panel file-browser">
|
|
<div class="panel-header">
|
|
<div class="panel-title">FILE DIRECTORY</div>
|
|
<div style="font-size: 10px; color: #666;">SYSTEM://LOCAL</div>
|
|
</div>
|
|
<div class="file-list" id="fileList">
|
|
<!-- Files will be added here -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Center Panel - Upload Zone -->
|
|
<div class="panel upload-zone">
|
|
<div class="panel-header">
|
|
<div class="panel-title">UPLOAD INTERFACE</div>
|
|
<div style="font-size: 10px; color: #666;">DRAG & DROP ENABLED</div>
|
|
</div>
|
|
<div class="drop-area" id="dropArea">
|
|
<div class="upload-icon">
|
|
<div class="gear"></div>
|
|
</div>
|
|
<div class="upload-text">DROP FILES HERE</div>
|
|
<div class="upload-subtext">or click to browse</div>
|
|
</div>
|
|
<div class="progress-container" id="progressContainer">
|
|
<!-- Progress bars will be added here -->
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right Panel - Preview & Validation -->
|
|
<div class="panel preview-panel">
|
|
<div class="panel-header">
|
|
<div class="panel-title">PREVIEW & VALIDATION</div>
|
|
<div style="font-size: 10px; color: #666;">ANALYSIS MODULE</div>
|
|
</div>
|
|
<div class="preview-area">
|
|
<div class="preview-content" id="previewContent">
|
|
<div class="preview-placeholder">
|
|
<div class="preview-icon">⚙</div>
|
|
<div>No file selected</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="validation-section" id="validationSection">
|
|
<div class="validation-item" id="validationType">
|
|
<div class="validation-icon"></div>
|
|
<div class="validation-text">File Type: Waiting...</div>
|
|
</div>
|
|
<div class="validation-item" id="validationSize">
|
|
<div class="validation-icon"></div>
|
|
<div class="validation-text">File Size: Waiting...</div>
|
|
</div>
|
|
<div class="validation-item" id="validationFormat">
|
|
<div class="validation-icon"></div>
|
|
<div class="validation-text">Format Check: Waiting...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Status Bar -->
|
|
<div class="status-bar">
|
|
<div class="status-indicator"></div>
|
|
<div id="statusText">SYSTEM READY - AWAITING INPUT</div>
|
|
</div>
|
|
</div>
|
|
|
|
<input type="file" id="fileInput" multiple>
|
|
|
|
<script>
|
|
// File Manager State
|
|
const fileManager = {
|
|
files: [],
|
|
selectedFile: null,
|
|
uploads: new Map()
|
|
};
|
|
|
|
// Elements
|
|
const dropArea = document.getElementById('dropArea');
|
|
const fileInput = document.getElementById('fileInput');
|
|
const fileList = document.getElementById('fileList');
|
|
const progressContainer = document.getElementById('progressContainer');
|
|
const previewContent = document.getElementById('previewContent');
|
|
const validationSection = document.getElementById('validationSection');
|
|
const statusText = document.getElementById('statusText');
|
|
|
|
// Drag and Drop Events
|
|
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
|
dropArea.addEventListener(eventName, preventDefaults, false);
|
|
document.body.addEventListener(eventName, preventDefaults, false);
|
|
});
|
|
|
|
function preventDefaults(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
|
|
['dragenter', 'dragover'].forEach(eventName => {
|
|
dropArea.addEventListener(eventName, highlight, false);
|
|
});
|
|
|
|
['dragleave', 'drop'].forEach(eventName => {
|
|
dropArea.addEventListener(eventName, unhighlight, false);
|
|
});
|
|
|
|
function highlight(e) {
|
|
dropArea.classList.add('dragover');
|
|
}
|
|
|
|
function unhighlight(e) {
|
|
dropArea.classList.remove('dragover');
|
|
}
|
|
|
|
// Handle Drop
|
|
dropArea.addEventListener('drop', handleDrop, false);
|
|
dropArea.addEventListener('click', () => fileInput.click());
|
|
fileInput.addEventListener('change', handleFileSelect);
|
|
|
|
function handleDrop(e) {
|
|
const dt = e.dataTransfer;
|
|
const files = dt.files;
|
|
handleFiles([...files]);
|
|
}
|
|
|
|
function handleFileSelect(e) {
|
|
const files = e.target.files;
|
|
handleFiles([...files]);
|
|
}
|
|
|
|
function handleFiles(files) {
|
|
files.forEach(uploadFile);
|
|
updateStatus(`PROCESSING ${files.length} FILE(S)`);
|
|
}
|
|
|
|
function uploadFile(file) {
|
|
const id = Date.now() + Math.random();
|
|
|
|
// Add to file manager
|
|
fileManager.files.push({
|
|
id,
|
|
name: file.name,
|
|
size: file.size,
|
|
type: file.type,
|
|
file: file,
|
|
progress: 0
|
|
});
|
|
|
|
// Create progress item
|
|
const progressItem = createProgressItem(file.name, id);
|
|
progressContainer.appendChild(progressItem);
|
|
|
|
// Simulate upload
|
|
simulateUpload(id, file);
|
|
|
|
// Add to file list
|
|
addToFileList(id, file);
|
|
}
|
|
|
|
function createProgressItem(filename, id) {
|
|
const item = document.createElement('div');
|
|
item.className = 'progress-item';
|
|
item.id = `progress-${id}`;
|
|
item.innerHTML = `
|
|
<div class="progress-header">
|
|
<div class="progress-filename">${filename}</div>
|
|
<div class="progress-percent">0%</div>
|
|
</div>
|
|
<div class="progress-bar">
|
|
<div class="progress-fill"></div>
|
|
</div>
|
|
`;
|
|
return item;
|
|
}
|
|
|
|
function simulateUpload(id, file) {
|
|
let progress = 0;
|
|
const interval = setInterval(() => {
|
|
progress += Math.random() * 15;
|
|
if (progress > 100) {
|
|
progress = 100;
|
|
clearInterval(interval);
|
|
setTimeout(() => {
|
|
const progressItem = document.getElementById(`progress-${id}`);
|
|
if (progressItem) {
|
|
progressItem.style.opacity = '0';
|
|
setTimeout(() => progressItem.remove(), 300);
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
updateProgress(id, progress);
|
|
}, 200);
|
|
}
|
|
|
|
function updateProgress(id, progress) {
|
|
const fileData = fileManager.files.find(f => f.id === id);
|
|
if (fileData) {
|
|
fileData.progress = progress;
|
|
}
|
|
|
|
const progressItem = document.getElementById(`progress-${id}`);
|
|
if (progressItem) {
|
|
const fill = progressItem.querySelector('.progress-fill');
|
|
const percent = progressItem.querySelector('.progress-percent');
|
|
fill.style.width = `${progress}%`;
|
|
percent.textContent = `${Math.round(progress)}%`;
|
|
}
|
|
}
|
|
|
|
function addToFileList(id, file) {
|
|
const fileItem = document.createElement('div');
|
|
fileItem.className = 'file-item';
|
|
fileItem.dataset.id = id;
|
|
fileItem.innerHTML = `
|
|
<span class="file-icon"></span>
|
|
<span class="file-name">${file.name}</span>
|
|
<span class="file-size">${formatFileSize(file.size)}</span>
|
|
`;
|
|
|
|
fileItem.addEventListener('click', () => selectFile(id));
|
|
fileList.appendChild(fileItem);
|
|
}
|
|
|
|
function selectFile(id) {
|
|
// Update selected state
|
|
document.querySelectorAll('.file-item').forEach(item => {
|
|
item.classList.remove('active');
|
|
});
|
|
|
|
const fileItem = document.querySelector(`[data-id="${id}"]`);
|
|
if (fileItem) {
|
|
fileItem.classList.add('active');
|
|
}
|
|
|
|
// Get file data
|
|
const fileData = fileManager.files.find(f => f.id === id);
|
|
if (fileData) {
|
|
fileManager.selectedFile = fileData;
|
|
showPreview(fileData);
|
|
validateFile(fileData);
|
|
updateStatus(`SELECTED: ${fileData.name}`);
|
|
}
|
|
}
|
|
|
|
function showPreview(fileData) {
|
|
const file = fileData.file;
|
|
|
|
if (file.type.startsWith('image/')) {
|
|
const reader = new FileReader();
|
|
reader.onload = (e) => {
|
|
previewContent.innerHTML = `<img src="${e.target.result}" class="preview-image" alt="${file.name}">`;
|
|
};
|
|
reader.readAsDataURL(file);
|
|
} else if (file.type.startsWith('text/')) {
|
|
const reader = new FileReader();
|
|
reader.onload = (e) => {
|
|
const text = e.target.result.substring(0, 1000);
|
|
previewContent.innerHTML = `
|
|
<div style="padding: 20px; font-size: 12px; color: #ccc; white-space: pre-wrap; overflow: auto; width: 100%; height: 100%;">
|
|
${text}${e.target.result.length > 1000 ? '...' : ''}
|
|
</div>
|
|
`;
|
|
};
|
|
reader.readAsText(file);
|
|
} else {
|
|
previewContent.innerHTML = `
|
|
<div class="preview-placeholder">
|
|
<div class="preview-icon">📄</div>
|
|
<div>${file.name}</div>
|
|
<div style="font-size: 12px; color: #666; margin-top: 10px;">${file.type || 'Unknown type'}</div>
|
|
</div>
|
|
`;
|
|
}
|
|
}
|
|
|
|
function validateFile(fileData) {
|
|
const file = fileData.file;
|
|
const validations = {
|
|
type: document.getElementById('validationType'),
|
|
size: document.getElementById('validationSize'),
|
|
format: document.getElementById('validationFormat')
|
|
};
|
|
|
|
// Reset validations
|
|
Object.values(validations).forEach(v => {
|
|
v.classList.remove('valid', 'invalid');
|
|
});
|
|
|
|
// Validate after delay (simulate processing)
|
|
setTimeout(() => {
|
|
// File type validation
|
|
const allowedTypes = ['image/', 'text/', 'application/pdf'];
|
|
const isValidType = allowedTypes.some(type => file.type.startsWith(type));
|
|
validations.type.classList.add(isValidType ? 'valid' : 'invalid');
|
|
validations.type.querySelector('.validation-text').textContent =
|
|
`File Type: ${file.type || 'Unknown'} ${isValidType ? '✓' : '✗'}`;
|
|
|
|
// File size validation (max 10MB)
|
|
const maxSize = 10 * 1024 * 1024;
|
|
const isValidSize = file.size <= maxSize;
|
|
validations.size.classList.add(isValidSize ? 'valid' : 'invalid');
|
|
validations.size.querySelector('.validation-text').textContent =
|
|
`File Size: ${formatFileSize(file.size)} ${isValidSize ? '✓' : '✗'}`;
|
|
|
|
// Format validation
|
|
const hasExtension = file.name.includes('.');
|
|
validations.format.classList.add(hasExtension ? 'valid' : 'invalid');
|
|
validations.format.querySelector('.validation-text').textContent =
|
|
`Format Check: ${hasExtension ? 'Valid extension' : 'No extension'} ${hasExtension ? '✓' : '✗'}`;
|
|
}, 500);
|
|
}
|
|
|
|
function formatFileSize(bytes) {
|
|
if (bytes === 0) return '0 Bytes';
|
|
const k = 1024;
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
}
|
|
|
|
function updateStatus(message) {
|
|
statusText.textContent = message.toUpperCase();
|
|
}
|
|
|
|
// Add some demo files
|
|
setTimeout(() => {
|
|
const demoFiles = [
|
|
{ name: 'system.config', size: 2048, type: 'text/plain' },
|
|
{ name: 'blueprint.pdf', size: 1048576, type: 'application/pdf' },
|
|
{ name: 'component.png', size: 524288, type: 'image/png' }
|
|
];
|
|
|
|
demoFiles.forEach((demo, index) => {
|
|
const id = `demo-${index}`;
|
|
const fakeFile = new File([''], demo.name, { type: demo.type });
|
|
|
|
fileManager.files.push({
|
|
id,
|
|
name: demo.name,
|
|
size: demo.size,
|
|
type: demo.type,
|
|
file: fakeFile,
|
|
progress: 100
|
|
});
|
|
|
|
const fileItem = document.createElement('div');
|
|
fileItem.className = 'file-item';
|
|
fileItem.dataset.id = id;
|
|
fileItem.innerHTML = `
|
|
<span class="file-icon"></span>
|
|
<span class="file-name">${demo.name}</span>
|
|
<span class="file-size">${formatFileSize(demo.size)}</span>
|
|
`;
|
|
|
|
fileItem.addEventListener('click', () => selectFile(id));
|
|
fileList.appendChild(fileItem);
|
|
});
|
|
|
|
updateStatus('SYSTEM READY - 3 FILES LOADED');
|
|
}, 1000);
|
|
</script>
|
|
</body>
|
|
</html> |