1032 lines
36 KiB
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> |