Spaces:
Sleeping
Sleeping
Aryanshh commited on
Commit ·
f5ce3e8
1
Parent(s): 831a6aa
feat: Implement Logistics Cart and refined console layout
Browse files- dashboard/app.js +27 -11
- dashboard/style.css +48 -5
dashboard/app.js
CHANGED
|
@@ -7,7 +7,7 @@ const SPECS = {
|
|
| 7 |
rail: { cost: 2.5, carbon: 0.5 }
|
| 8 |
};
|
| 9 |
|
| 10 |
-
// Tutorial Content
|
| 11 |
const TUTORIAL_STEPS = [
|
| 12 |
{
|
| 13 |
title: "Mission: NetZero-Nav",
|
|
@@ -15,33 +15,34 @@ const TUTORIAL_STEPS = [
|
|
| 15 |
target: "header"
|
| 16 |
},
|
| 17 |
{
|
| 18 |
-
title: "
|
| 19 |
-
text: "Select a component
|
| 20 |
target: "#section-order"
|
| 21 |
},
|
| 22 |
{
|
| 23 |
title: "The Impact Preview",
|
| 24 |
-
text: "Watch this box! Whenever you change a transport mode, we calculate the <strong>Financial Cost</strong> and <strong>Carbon Footprint</strong> in real-time
|
| 25 |
target: "#impact-preview"
|
| 26 |
},
|
| 27 |
{
|
| 28 |
title: "Starting Production",
|
| 29 |
-
text: "Once inventory arrives,
|
| 30 |
target: "#section-produce"
|
| 31 |
},
|
| 32 |
{
|
| 33 |
-
title: "
|
| 34 |
-
text: "
|
| 35 |
-
target: "
|
| 36 |
},
|
| 37 |
{
|
| 38 |
title: "Time Management",
|
| 39 |
-
text: "Use <strong>'Advance to Next Day'</strong> to process shipments
|
| 40 |
target: ".time-controls"
|
| 41 |
}
|
| 42 |
];
|
| 43 |
|
| 44 |
let currentTutStep = 0;
|
|
|
|
| 45 |
|
| 46 |
// State Management
|
| 47 |
async function updateState() {
|
|
@@ -50,6 +51,8 @@ async function updateState() {
|
|
| 50 |
if (!response.ok) throw new Error('API Unreachable');
|
| 51 |
const data = await response.json();
|
| 52 |
|
|
|
|
|
|
|
| 53 |
const status = document.getElementById('connection-status');
|
| 54 |
status.textContent = 'ONLINE';
|
| 55 |
status.className = 'status-badge status-online';
|
|
@@ -59,6 +62,20 @@ async function updateState() {
|
|
| 59 |
document.getElementById('chips-count').textContent = data.inventory.chips;
|
| 60 |
document.getElementById('sensors-count').textContent = data.inventory.sensors;
|
| 61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
const newsAlert = document.getElementById('news-alert');
|
| 63 |
if (data.news) {
|
| 64 |
document.getElementById('news-text').textContent = data.news;
|
|
@@ -110,7 +127,7 @@ function log(message, type = 'system') {
|
|
| 110 |
box.prepend(entry);
|
| 111 |
}
|
| 112 |
|
| 113 |
-
// Global Execute Function
|
| 114 |
window.execute = async function(type) {
|
| 115 |
document.querySelector('main').classList.add('transitioning');
|
| 116 |
|
|
@@ -164,7 +181,6 @@ function showStep(step) {
|
|
| 164 |
document.getElementById('tut-prev').classList.toggle('hidden', step === 0);
|
| 165 |
document.getElementById('tut-next').textContent = step === TUTORIAL_STEPS.length - 1 ? "Start Mission" : "Next";
|
| 166 |
|
| 167 |
-
// Static Centering logic maintained
|
| 168 |
const modalOverlay = document.getElementById('tutorial-modal');
|
| 169 |
modalOverlay.style.alignItems = 'center';
|
| 170 |
modalOverlay.style.paddingTop = '0';
|
|
|
|
| 7 |
rail: { cost: 2.5, carbon: 0.5 }
|
| 8 |
};
|
| 9 |
|
| 10 |
+
// Tutorial Content
|
| 11 |
const TUTORIAL_STEPS = [
|
| 12 |
{
|
| 13 |
title: "Mission: NetZero-Nav",
|
|
|
|
| 15 |
target: "header"
|
| 16 |
},
|
| 17 |
{
|
| 18 |
+
title: "Supply Logistics",
|
| 19 |
+
text: "Select a component and Transport Mode on the left, then click <strong>'Order'</strong> in the center. SEA is green but takes 10 full days!",
|
| 20 |
target: "#section-order"
|
| 21 |
},
|
| 22 |
{
|
| 23 |
title: "The Impact Preview",
|
| 24 |
+
text: "Watch this box! Whenever you change a transport mode, we calculate the <strong>Financial Cost</strong> and <strong>Carbon Footprint</strong> in real-time.",
|
| 25 |
target: "#impact-preview"
|
| 26 |
},
|
| 27 |
{
|
| 28 |
title: "Starting Production",
|
| 29 |
+
text: "Once inventory arrives, click <strong>'Start Run'</strong>. This consumes parts and fulfills active orders for revenue.",
|
| 30 |
target: "#section-produce"
|
| 31 |
},
|
| 32 |
{
|
| 33 |
+
title: "Logistics Cart",
|
| 34 |
+
text: "Track your pending shipments here! See exactly what's coming, how much, and the exact <strong>Estimated Arrival Day</strong>.",
|
| 35 |
+
target: ".shipment-cart-section"
|
| 36 |
},
|
| 37 |
{
|
| 38 |
title: "Time Management",
|
| 39 |
+
text: "Use <strong>'Advance to Next Day'</strong> to process shipments and grow your empire. Good luck!",
|
| 40 |
target: ".time-controls"
|
| 41 |
}
|
| 42 |
];
|
| 43 |
|
| 44 |
let currentTutStep = 0;
|
| 45 |
+
let currentDay = 0;
|
| 46 |
|
| 47 |
// State Management
|
| 48 |
async function updateState() {
|
|
|
|
| 51 |
if (!response.ok) throw new Error('API Unreachable');
|
| 52 |
const data = await response.json();
|
| 53 |
|
| 54 |
+
currentDay = data.step; // Track current step for arrival calculation
|
| 55 |
+
|
| 56 |
const status = document.getElementById('connection-status');
|
| 57 |
status.textContent = 'ONLINE';
|
| 58 |
status.className = 'status-badge status-online';
|
|
|
|
| 62 |
document.getElementById('chips-count').textContent = data.inventory.chips;
|
| 63 |
document.getElementById('sensors-count').textContent = data.inventory.sensors;
|
| 64 |
|
| 65 |
+
// Update Cart (Active Shipments)
|
| 66 |
+
const cartContainer = document.getElementById('cart-container');
|
| 67 |
+
if (data.active_shipments && data.active_shipments.length > 0) {
|
| 68 |
+
cartContainer.innerHTML = data.active_shipments.map(ship => `
|
| 69 |
+
<div class="cart-item">
|
| 70 |
+
<div class="cart-type">${ship.part} (x${ship.quantity})</div>
|
| 71 |
+
<div class="cart-meta">Mode: ${ship.mode.toUpperCase()}</div>
|
| 72 |
+
<div class="arrival-day">Arrives Day: ${currentDay + ship.eta}</div>
|
| 73 |
+
</div>
|
| 74 |
+
`).join('');
|
| 75 |
+
} else {
|
| 76 |
+
cartContainer.innerHTML = '<p class="placeholder">No active shipments in transit.</p>';
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
const newsAlert = document.getElementById('news-alert');
|
| 80 |
if (data.news) {
|
| 81 |
document.getElementById('news-text').textContent = data.news;
|
|
|
|
| 127 |
box.prepend(entry);
|
| 128 |
}
|
| 129 |
|
| 130 |
+
// Global Execute Function
|
| 131 |
window.execute = async function(type) {
|
| 132 |
document.querySelector('main').classList.add('transitioning');
|
| 133 |
|
|
|
|
| 181 |
document.getElementById('tut-prev').classList.toggle('hidden', step === 0);
|
| 182 |
document.getElementById('tut-next').textContent = step === TUTORIAL_STEPS.length - 1 ? "Start Mission" : "Next";
|
| 183 |
|
|
|
|
| 184 |
const modalOverlay = document.getElementById('tutorial-modal');
|
| 185 |
modalOverlay.style.alignItems = 'center';
|
| 186 |
modalOverlay.style.paddingTop = '0';
|
dashboard/style.css
CHANGED
|
@@ -188,15 +188,58 @@ header {
|
|
| 188 |
|
| 189 |
.op-row {
|
| 190 |
display: flex;
|
| 191 |
-
|
| 192 |
align-items: center;
|
|
|
|
| 193 |
}
|
| 194 |
|
| 195 |
-
.op-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
flex-grow: 1;
|
| 199 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
}
|
| 201 |
|
| 202 |
select {
|
|
|
|
| 188 |
|
| 189 |
.op-row {
|
| 190 |
display: flex;
|
| 191 |
+
justify-content: space-between;
|
| 192 |
align-items: center;
|
| 193 |
+
gap: 2rem;
|
| 194 |
}
|
| 195 |
|
| 196 |
+
.op-inputs {
|
| 197 |
+
display: flex;
|
| 198 |
+
gap: 1.2rem;
|
| 199 |
flex-grow: 1;
|
| 200 |
+
justify-content: flex-start;
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
.op-actions {
|
| 204 |
+
min-width: 150px;
|
| 205 |
+
display: flex;
|
| 206 |
+
justify-content: center;
|
| 207 |
+
}
|
| 208 |
+
|
| 209 |
+
.cart-grid {
|
| 210 |
+
display: grid;
|
| 211 |
+
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
| 212 |
+
gap: 1.5rem;
|
| 213 |
+
margin-top: 1rem;
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
.cart-item {
|
| 217 |
+
background: white;
|
| 218 |
+
padding: 1rem;
|
| 219 |
+
border-radius: 12px;
|
| 220 |
+
border: 1px solid var(--border-tan);
|
| 221 |
+
display: flex;
|
| 222 |
+
flex-direction: column;
|
| 223 |
+
gap: 0.5rem;
|
| 224 |
+
box-shadow: 0 4px 15px rgba(0,0,0,0.02);
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
.cart-item .cart-type {
|
| 228 |
+
font-weight: 700;
|
| 229 |
+
color: var(--primary-green);
|
| 230 |
+
font-size: 0.9rem;
|
| 231 |
+
text-transform: uppercase;
|
| 232 |
+
}
|
| 233 |
+
|
| 234 |
+
.cart-item .cart-meta {
|
| 235 |
+
font-size: 0.8rem;
|
| 236 |
+
color: var(--text-muted);
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
.cart-item .arrival-day {
|
| 240 |
+
color: var(--deep-forest);
|
| 241 |
+
font-weight: 600;
|
| 242 |
+
font-size: 0.85rem;
|
| 243 |
}
|
| 244 |
|
| 245 |
select {
|