Aryanshh commited on
Commit
f5ce3e8
·
1 Parent(s): 831a6aa

feat: Implement Logistics Cart and refined console layout

Browse files
Files changed (2) hide show
  1. dashboard/app.js +27 -11
  2. 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 - Updated with detailed button instructions
11
  const TUTORIAL_STEPS = [
12
  {
13
  title: "Mission: NetZero-Nav",
@@ -15,33 +15,34 @@ const TUTORIAL_STEPS = [
15
  target: "header"
16
  },
17
  {
18
- title: "Ordering Parts",
19
- text: "Select a component (Chips/Sensors) and a Transport Mode. Click the <strong>'Order'</strong> button to dispatch a shipment. 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 before you commit.",
25
  target: "#impact-preview"
26
  },
27
  {
28
  title: "Starting Production",
29
- text: "Once inventory arrives, use the <strong>'Start Run'</strong> button. This consumes parts and fulfills active orders, generating revenue for your fleet.",
30
  target: "#section-produce"
31
  },
32
  {
33
- title: "Buying Offsets",
34
- text: "Exceeding your carbon quota? Click <strong>'Buy Offset'</strong> to trade capital for carbon credits and keep the gauges in the green zone.",
35
- target: "#section-offset"
36
  },
37
  {
38
  title: "Time Management",
39
- text: "Use <strong>'Advance to Next Day'</strong> to process shipments. If you're feeling daring, trigger a <strong>Suez Jam</strong> to see if your strategy can survive a global crisis.",
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 (exposed to onclick in HTML)
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
- gap: 1.2rem;
192
  align-items: center;
 
193
  }
194
 
195
- .op-text {
196
- font-size: 0.95rem;
197
- color: var(--text-main);
198
  flex-grow: 1;
199
- font-weight: 500;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 {