infinite-agents-public/themed_hybrids/ui_hybrid_4.html

1032 lines
36 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 Design File Manager</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Roboto Mono', monospace;
background: #1a1a1a;
color: #e0e0e0;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background-image:
repeating-linear-gradient(
0deg,
rgba(255,255,255,0.03) 0px,
transparent 1px,
transparent 2px,
rgba(255,255,255,0.03) 3px
);
}
main {
width: 100%;
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
h1 {
text-align: center;
margin-bottom: 30px;
font-size: 2.5em;
text-transform: uppercase;
letter-spacing: 3px;
color: #ffd600;
text-shadow: 0 0 20px rgba(255, 214, 0, 0.5);
}
.hybrid-component {
background: #2a2a2a;
border: 3px solid #444;
border-radius: 0;
padding: 30px;
box-shadow:
inset 0 0 30px rgba(0,0,0,0.5),
0 0 50px rgba(0,0,0,0.8);
position: relative;
overflow: hidden;
}
.hybrid-component::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, #666, #888, #666);
z-index: -1;
}
/* Loading Dock Upload Area */
.loading-dock {
background: linear-gradient(135deg, #333 0%, #444 100%);
border: 2px solid #666;
border-radius: 0;
padding: 40px;
margin-bottom: 30px;
position: relative;
overflow: hidden;
box-shadow:
inset 0 2px 5px rgba(0,0,0,0.5),
0 2px 10px rgba(0,0,0,0.3);
}
.loading-dock::before {
content: 'LOADING DOCK - DROP ZONE';
position: absolute;
top: 10px;
left: 20px;
font-size: 12px;
color: #ffd600;
letter-spacing: 2px;
font-weight: bold;
}
.loading-dock::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 10px;
background: repeating-linear-gradient(
-45deg,
#ffd600,
#ffd600 10px,
#333 10px,
#333 20px
);
animation: hazardStripe 1s linear infinite;
}
@keyframes hazardStripe {
0% { transform: translateX(0); }
100% { transform: translateX(20px); }
}
.upload-area {
margin-top: 20px;
border: 3px dashed #666;
padding: 60px 20px;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
background: rgba(0,0,0,0.2);
position: relative;
}
.upload-area:hover {
border-color: #ffd600;
background: rgba(255, 214, 0, 0.1);
box-shadow: inset 0 0 30px rgba(255, 214, 0, 0.2);
}
.upload-area.active {
border-color: #00ff00;
background: rgba(0, 255, 0, 0.1);
animation: pulse 0.5s ease-in-out;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.02); }
}
.upload-icon {
font-size: 48px;
margin-bottom: 20px;
display: block;
}
/* Mechanical Gauges Progress */
.gauge-panel {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.gauge {
background: #222;
border: 3px solid #555;
border-radius: 10px;
padding: 20px;
position: relative;
box-shadow:
inset 0 5px 15px rgba(0,0,0,0.5),
0 3px 10px rgba(0,0,0,0.3);
}
.gauge-meter {
width: 150px;
height: 150px;
margin: 0 auto 15px;
position: relative;
background:
radial-gradient(circle at center, #111 40%, transparent 40%),
conic-gradient(from -90deg, #00ff00 0deg, #ffd600 180deg, #ff0000 360deg);
border-radius: 50%;
box-shadow:
inset 0 0 20px rgba(0,0,0,0.5),
0 0 20px rgba(0,0,0,0.3);
}
.gauge-needle {
position: absolute;
width: 4px;
height: 60px;
background: #fff;
top: 50%;
left: 50%;
transform-origin: bottom center;
transform: translateX(-50%) translateY(-100%) rotate(-90deg);
transition: transform 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
box-shadow: 0 0 10px rgba(255,255,255,0.5);
}
.gauge-needle::after {
content: '';
position: absolute;
width: 20px;
height: 20px;
background: #666;
border-radius: 50%;
bottom: -10px;
left: 50%;
transform: translateX(-50%);
box-shadow: inset 0 0 5px rgba(0,0,0,0.5);
}
.gauge-label {
text-align: center;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
color: #999;
}
.gauge-value {
text-align: center;
font-size: 24px;
font-weight: bold;
color: #ffd600;
margin-top: 5px;
}
/* Inspection Window Preview */
.inspection-window {
background: #1a1a1a;
border: 3px solid #555;
padding: 20px;
margin-bottom: 30px;
position: relative;
min-height: 300px;
box-shadow: inset 0 0 30px rgba(0,0,0,0.5);
}
.inspection-header {
background: linear-gradient(90deg, #444 0%, #555 50%, #444 100%);
margin: -20px -20px 20px;
padding: 15px 20px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2px solid #666;
}
.inspection-title {
font-weight: bold;
text-transform: uppercase;
letter-spacing: 2px;
color: #ffd600;
}
.inspection-controls {
display: flex;
gap: 10px;
}
.control-led {
width: 12px;
height: 12px;
border-radius: 50%;
background: #00ff00;
box-shadow: 0 0 10px currentColor;
animation: ledBlink 2s infinite;
}
.control-led.warning {
background: #ffd600;
animation-duration: 1s;
}
.control-led.error {
background: #ff0000;
animation-duration: 0.5s;
}
@keyframes ledBlink {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
.preview-content {
background: #222;
border: 1px solid #444;
padding: 20px;
min-height: 200px;
position: relative;
overflow: auto;
font-family: monospace;
box-shadow: inset 0 0 20px rgba(0,0,0,0.3);
}
.preview-content img {
max-width: 100%;
height: auto;
display: block;
margin: 0 auto;
}
.preview-grid {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-image:
repeating-linear-gradient(0deg, rgba(255,255,255,0.03) 0px, transparent 1px, transparent 19px, rgba(255,255,255,0.03) 20px),
repeating-linear-gradient(90deg, rgba(255,255,255,0.03) 0px, transparent 1px, transparent 19px, rgba(255,255,255,0.03) 20px);
pointer-events: none;
}
/* Quality Control Validation */
.quality-control {
background: #2a2a2a;
border: 2px solid #555;
padding: 20px;
margin-bottom: 30px;
position: relative;
}
.qc-header {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 20px;
}
.qc-status {
width: 30px;
height: 30px;
border-radius: 50%;
background: #333;
position: relative;
box-shadow:
inset 0 2px 5px rgba(0,0,0,0.5),
0 0 20px rgba(0,0,0,0.3);
}
.qc-status.pass {
background: #00ff00;
box-shadow:
inset 0 2px 5px rgba(0,0,0,0.3),
0 0 20px rgba(0, 255, 0, 0.5);
}
.qc-status.fail {
background: #ff0000;
box-shadow:
inset 0 2px 5px rgba(0,0,0,0.3),
0 0 20px rgba(255, 0, 0, 0.5);
}
.qc-checks {
display: grid;
gap: 10px;
}
.qc-check {
display: flex;
align-items: center;
gap: 10px;
padding: 10px;
background: rgba(0,0,0,0.2);
border-left: 3px solid #444;
transition: all 0.3s ease;
}
.qc-check.pass {
border-color: #00ff00;
}
.qc-check.fail {
border-color: #ff0000;
}
.qc-check-icon {
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
}
/* Warehouse Inventory Browser */
.inventory-system {
background: #1a1a1a;
border: 3px solid #555;
padding: 0;
position: relative;
box-shadow: inset 0 0 30px rgba(0,0,0,0.5);
}
.inventory-header {
background: linear-gradient(90deg, #333 0%, #444 50%, #333 100%);
padding: 15px 20px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2px solid #666;
}
.inventory-search {
background: #222;
border: 1px solid #555;
padding: 8px 15px;
color: #fff;
font-family: monospace;
width: 300px;
outline: none;
transition: all 0.3s ease;
}
.inventory-search:focus {
border-color: #ffd600;
box-shadow: 0 0 20px rgba(255, 214, 0, 0.2);
}
.inventory-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
gap: 15px;
padding: 20px;
max-height: 400px;
overflow-y: auto;
}
.inventory-item {
background: #222;
border: 2px solid #444;
padding: 15px;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.inventory-item:hover {
border-color: #ffd600;
transform: translateY(-2px);
box-shadow: 0 5px 20px rgba(255, 214, 0, 0.3);
}
.inventory-item.selected {
border-color: #00ff00;
background: rgba(0, 255, 0, 0.1);
}
.inventory-icon {
font-size: 36px;
margin-bottom: 10px;
display: block;
}
.inventory-name {
font-size: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.inventory-size {
font-size: 10px;
color: #999;
margin-top: 5px;
}
/* Conveyor Belt Animation */
.conveyor-belt {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background: #333;
overflow: hidden;
display: none;
}
.conveyor-belt.active {
display: block;
}
.conveyor-track {
position: absolute;
top: 50%;
left: -100%;
width: 200%;
height: 20px;
background: repeating-linear-gradient(
90deg,
#555 0px,
#555 20px,
#666 20px,
#666 40px
);
animation: conveyorMove 2s linear infinite;
transform: translateY(-50%);
}
@keyframes conveyorMove {
0% { transform: translateX(0) translateY(-50%); }
100% { transform: translateX(40px) translateY(-50%); }
}
.file-package {
position: absolute;
width: 60px;
height: 30px;
background: #ffd600;
border: 2px solid #333;
top: 50%;
transform: translateY(-50%);
animation: packageMove 3s linear;
box-shadow: 0 2px 10px rgba(0,0,0,0.3);
}
@keyframes packageMove {
0% { left: -60px; }
100% { left: 100%; }
}
/* Utility Classes */
.hidden {
display: none;
}
.btn {
background: #444;
border: 2px solid #666;
color: #fff;
padding: 10px 20px;
cursor: pointer;
text-transform: uppercase;
letter-spacing: 1px;
font-weight: bold;
transition: all 0.3s ease;
outline: none;
}
.btn:hover {
background: #555;
border-color: #ffd600;
box-shadow: 0 0 20px rgba(255, 214, 0, 0.3);
}
.btn:active {
transform: translateY(1px);
}
/* Scrollbar Styling */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}
::-webkit-scrollbar-track {
background: #222;
border: 1px solid #444;
}
::-webkit-scrollbar-thumb {
background: #555;
border: 1px solid #666;
}
::-webkit-scrollbar-thumb:hover {
background: #666;
}
</style>
</head>
<body>
<main>
<h1>File Manager - Industrial Design Theme</h1>
<div class="hybrid-component">
<!-- Loading Dock Upload Area -->
<div class="loading-dock">
<div class="upload-area" id="uploadArea">
<span class="upload-icon">📦</span>
<p style="font-size: 18px; font-weight: bold; margin-bottom: 10px;">DROP CARGO HERE</p>
<p style="color: #999;">or click to select files</p>
<input type="file" id="fileInput" multiple style="display: none;">
</div>
<div class="conveyor-belt" id="conveyorBelt">
<div class="conveyor-track"></div>
</div>
</div>
<!-- Mechanical Gauges Progress Panel -->
<div class="gauge-panel" id="gaugePanel" style="display: none;">
<div class="gauge">
<div class="gauge-meter">
<div class="gauge-needle" id="uploadGauge"></div>
</div>
<div class="gauge-label">Upload Progress</div>
<div class="gauge-value" id="uploadValue">0%</div>
</div>
<div class="gauge">
<div class="gauge-meter">
<div class="gauge-needle" id="speedGauge"></div>
</div>
<div class="gauge-label">Transfer Speed</div>
<div class="gauge-value" id="speedValue">0 MB/s</div>
</div>
<div class="gauge">
<div class="gauge-meter">
<div class="gauge-needle" id="qualityGauge"></div>
</div>
<div class="gauge-label">Quality Score</div>
<div class="gauge-value" id="qualityValue">100%</div>
</div>
</div>
<!-- Inspection Window Preview -->
<div class="inspection-window" id="inspectionWindow" style="display: none;">
<div class="inspection-header">
<div class="inspection-title">INSPECTION VIEWPORT</div>
<div class="inspection-controls">
<div class="control-led" id="statusLed"></div>
<div class="control-led warning"></div>
<div class="control-led error"></div>
</div>
</div>
<div class="preview-content" id="previewContent">
<div class="preview-grid"></div>
<p style="color: #666; text-align: center; line-height: 160px;">No file selected for inspection</p>
</div>
</div>
<!-- Quality Control Validation -->
<div class="quality-control" id="qualityControl" style="display: none;">
<div class="qc-header">
<div class="qc-status" id="qcStatus"></div>
<h3 style="text-transform: uppercase; letter-spacing: 2px;">QUALITY CONTROL CHECKPOINT</h3>
</div>
<div class="qc-checks" id="qcChecks">
<div class="qc-check" id="sizeCheck">
<span class="qc-check-icon">⚙️</span>
<span>File Size: <span id="sizeCheckValue">--</span></span>
</div>
<div class="qc-check" id="typeCheck">
<span class="qc-check-icon">📋</span>
<span>File Type: <span id="typeCheckValue">--</span></span>
</div>
<div class="qc-check" id="nameCheck">
<span class="qc-check-icon">🏷️</span>
<span>File Name: <span id="nameCheckValue">--</span></span>
</div>
<div class="qc-check" id="integrityCheck">
<span class="qc-check-icon">🔒</span>
<span>Integrity: <span id="integrityCheckValue">--</span></span>
</div>
</div>
</div>
<!-- Warehouse Inventory Browser -->
<div class="inventory-system">
<div class="inventory-header">
<h3 style="text-transform: uppercase; letter-spacing: 2px; color: #ffd600;">WAREHOUSE INVENTORY</h3>
<input type="text" class="inventory-search" id="inventorySearch" placeholder="SEARCH INVENTORY...">
</div>
<div class="inventory-grid" id="inventoryGrid">
<!-- Inventory items will be dynamically added here -->
</div>
</div>
</div>
</main>
<script>
// Industrial File Manager System
class IndustrialFileManager {
constructor() {
this.files = [];
this.selectedFiles = new Set();
this.uploadProgress = 0;
this.initializeComponents();
this.bindEvents();
this.loadSampleInventory();
this.playMechanicalSound();
}
initializeComponents() {
this.uploadArea = document.getElementById('uploadArea');
this.fileInput = document.getElementById('fileInput');
this.conveyorBelt = document.getElementById('conveyorBelt');
this.gaugePanel = document.getElementById('gaugePanel');
this.inspectionWindow = document.getElementById('inspectionWindow');
this.qualityControl = document.getElementById('qualityControl');
this.inventoryGrid = document.getElementById('inventoryGrid');
this.inventorySearch = document.getElementById('inventorySearch');
this.previewContent = document.getElementById('previewContent');
// Gauge elements
this.uploadGauge = document.getElementById('uploadGauge');
this.speedGauge = document.getElementById('speedGauge');
this.qualityGauge = document.getElementById('qualityGauge');
this.uploadValue = document.getElementById('uploadValue');
this.speedValue = document.getElementById('speedValue');
this.qualityValue = document.getElementById('qualityValue');
// QC elements
this.qcStatus = document.getElementById('qcStatus');
this.qcChecks = {
size: document.getElementById('sizeCheck'),
type: document.getElementById('typeCheck'),
name: document.getElementById('nameCheck'),
integrity: document.getElementById('integrityCheck')
};
}
bindEvents() {
// Upload area events
this.uploadArea.addEventListener('click', () => this.fileInput.click());
this.fileInput.addEventListener('change', (e) => this.handleFileSelect(e));
// Drag and drop
this.uploadArea.addEventListener('dragover', (e) => {
e.preventDefault();
this.uploadArea.classList.add('active');
});
this.uploadArea.addEventListener('dragleave', () => {
this.uploadArea.classList.remove('active');
});
this.uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
this.uploadArea.classList.remove('active');
this.handleFileSelect({ target: { files: e.dataTransfer.files } });
});
// Inventory search
this.inventorySearch.addEventListener('input', (e) => {
this.filterInventory(e.target.value);
});
}
handleFileSelect(event) {
const files = Array.from(event.target.files);
if (files.length === 0) return;
// Start conveyor belt animation
this.startConveyorBelt();
// Show progress gauges
this.gaugePanel.style.display = 'grid';
// Process each file
files.forEach((file, index) => {
setTimeout(() => {
this.processFile(file);
}, index * 1000);
});
// Simulate upload progress
this.simulateUpload();
}
startConveyorBelt() {
this.conveyorBelt.classList.add('active');
// Add package animation
const package = document.createElement('div');
package.className = 'file-package';
this.conveyorBelt.appendChild(package);
setTimeout(() => {
package.remove();
this.conveyorBelt.classList.remove('active');
}, 3000);
}
processFile(file) {
// Add to inventory
this.addToInventory(file);
// Show inspection window
this.inspectionWindow.style.display = 'block';
this.inspectFile(file);
// Run quality control
this.qualityControl.style.display = 'block';
this.runQualityControl(file);
}
simulateUpload() {
let progress = 0;
const interval = setInterval(() => {
progress += Math.random() * 15;
if (progress > 100) progress = 100;
// Update upload gauge
const uploadAngle = (progress / 100) * 270 - 135;
this.uploadGauge.style.transform = `translateX(-50%) translateY(-100%) rotate(${uploadAngle}deg)`;
this.uploadValue.textContent = `${Math.round(progress)}%`;
// Update speed gauge (simulate varying speeds)
const speed = Math.random() * 50 + 10;
const speedAngle = (speed / 60) * 270 - 135;
this.speedGauge.style.transform = `translateX(-50%) translateY(-100%) rotate(${speedAngle}deg)`;
this.speedValue.textContent = `${speed.toFixed(1)} MB/s`;
// Update quality gauge
const quality = 90 + Math.random() * 10;
const qualityAngle = (quality / 100) * 270 - 135;
this.qualityGauge.style.transform = `translateX(-50%) translateY(-100%) rotate(${qualityAngle}deg)`;
this.qualityValue.textContent = `${Math.round(quality)}%`;
if (progress >= 100) {
clearInterval(interval);
this.playSuccessSound();
}
}, 200);
}
inspectFile(file) {
const previewContent = document.getElementById('previewContent');
previewContent.innerHTML = '<div class="preview-grid"></div>';
if (file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
const img = document.createElement('img');
img.src = e.target.result;
previewContent.appendChild(img);
};
reader.readAsDataURL(file);
} else if (file.type.startsWith('text/')) {
const reader = new FileReader();
reader.onload = (e) => {
const pre = document.createElement('pre');
pre.style.color = '#0f0';
pre.style.fontSize = '12px';
pre.textContent = e.target.result.substring(0, 1000) + '...';
previewContent.appendChild(pre);
};
reader.readAsText(file);
} else {
previewContent.innerHTML += `
<div style="text-align: center; padding: 40px;">
<div style="font-size: 64px; margin-bottom: 20px;">📄</div>
<p style="font-size: 18px; color: #ffd600;">${file.name}</p>
<p style="color: #999; margin-top: 10px;">Type: ${file.type || 'Unknown'}</p>
<p style="color: #999;">Size: ${this.formatFileSize(file.size)}</p>
</div>
`;
}
}
runQualityControl(file) {
const checks = {
size: file.size < 10 * 1024 * 1024, // Less than 10MB
type: this.isValidFileType(file.type),
name: this.isValidFileName(file.name),
integrity: Math.random() > 0.1 // Simulate integrity check
};
// Update size check
document.getElementById('sizeCheckValue').textContent = this.formatFileSize(file.size);
this.updateCheckStatus('size', checks.size);
// Update type check
document.getElementById('typeCheckValue').textContent = file.type || 'Unknown';
this.updateCheckStatus('type', checks.type);
// Update name check
document.getElementById('nameCheckValue').textContent = file.name;
this.updateCheckStatus('name', checks.name);
// Update integrity check
document.getElementById('integrityCheckValue').textContent = checks.integrity ? 'PASSED' : 'FAILED';
this.updateCheckStatus('integrity', checks.integrity);
// Update overall QC status
const allPassed = Object.values(checks).every(check => check);
this.qcStatus.className = `qc-status ${allPassed ? 'pass' : 'fail'}`;
// Update status LED
const statusLed = document.getElementById('statusLed');
statusLed.className = `control-led ${allPassed ? '' : 'error'}`;
}
updateCheckStatus(checkName, passed) {
const checkElement = this.qcChecks[checkName];
checkElement.className = `qc-check ${passed ? 'pass' : 'fail'}`;
const icon = checkElement.querySelector('.qc-check-icon');
icon.textContent = passed ? '✓' : '✗';
}
isValidFileType(type) {
const validTypes = [
'image/', 'text/', 'application/pdf',
'application/zip', 'application/json'
];
return validTypes.some(validType => type.startsWith(validType));
}
isValidFileName(name) {
// Check for invalid characters
const invalidChars = /[<>:"|?*]/;
return !invalidChars.test(name) && name.length < 255;
}
addToInventory(file) {
const fileId = Date.now() + Math.random();
const fileData = {
id: fileId,
name: file.name,
size: file.size,
type: file.type,
icon: this.getFileIcon(file.type),
timestamp: new Date()
};
this.files.push(fileData);
this.renderInventoryItem(fileData);
}
loadSampleInventory() {
const sampleFiles = [
{ name: 'blueprint.pdf', size: 2048000, type: 'application/pdf', icon: '📐' },
{ name: 'specs.txt', size: 15360, type: 'text/plain', icon: '📝' },
{ name: 'motor.jpg', size: 512000, type: 'image/jpeg', icon: '🖼️' },
{ name: 'data.json', size: 8192, type: 'application/json', icon: '📊' },
{ name: 'archive.zip', size: 4096000, type: 'application/zip', icon: '📦' },
{ name: 'manual.pdf', size: 1024000, type: 'application/pdf', icon: '📚' }
];
sampleFiles.forEach((file, index) => {
const fileData = {
id: index,
...file,
timestamp: new Date(Date.now() - Math.random() * 86400000)
};
this.files.push(fileData);
this.renderInventoryItem(fileData);
});
}
renderInventoryItem(fileData) {
const item = document.createElement('div');
item.className = 'inventory-item';
item.dataset.fileId = fileData.id;
item.innerHTML = `
<span class="inventory-icon">${fileData.icon}</span>
<div class="inventory-name" title="${fileData.name}">${fileData.name}</div>
<div class="inventory-size">${this.formatFileSize(fileData.size)}</div>
`;
item.addEventListener('click', () => {
this.selectInventoryItem(item, fileData);
});
this.inventoryGrid.appendChild(item);
}
selectInventoryItem(item, fileData) {
// Toggle selection
if (item.classList.contains('selected')) {
item.classList.remove('selected');
this.selectedFiles.delete(fileData.id);
} else {
item.classList.add('selected');
this.selectedFiles.add(fileData.id);
}
// Trigger mechanical sound
this.playClickSound();
// Update preview if single selection
if (this.selectedFiles.size === 1) {
this.inspectFile(fileData);
}
}
filterInventory(searchTerm) {
const items = this.inventoryGrid.querySelectorAll('.inventory-item');
const term = searchTerm.toLowerCase();
items.forEach(item => {
const name = item.querySelector('.inventory-name').textContent.toLowerCase();
if (name.includes(term)) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
});
}
getFileIcon(type) {
if (type.startsWith('image/')) return '🖼️';
if (type.startsWith('text/')) return '📝';
if (type.includes('pdf')) return '📄';
if (type.includes('zip')) return '📦';
if (type.includes('json')) return '📊';
return '📎';
}
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];
}
// Sound effects (simulated with console logs)
playMechanicalSound() {
console.log('🔧 *mechanical whirring*');
}
playClickSound() {
console.log('⚙️ *click*');
}
playSuccessSound() {
console.log('✅ *ding!*');
}
}
// Initialize the industrial file manager
const fileManager = new IndustrialFileManager();
</script>
</body>
</html>