Ultronprime commited on
Commit
7ce9ff0
·
verified ·
1 Parent(s): ef9d00d

Update ui.js

Browse files
Files changed (1) hide show
  1. ui.js +53 -14
ui.js CHANGED
@@ -4,8 +4,8 @@ import { appState } from './state.js';
4
  import { attachAllListeners } from './events.js';
5
  import { getMonthlyProductionSummary, getMonthlyMaterialUsage } from './reportService.js';
6
 
7
- // ... (keep all functions from showToast to renderProductionLog the same) ...
8
- // The only function that needs changing is renderInventory()
9
 
10
  let productionChart = null;
11
  let inventoryChart = null;
@@ -19,9 +19,9 @@ export function refreshUI() {
19
  renderProductInputs();
20
  renderInventory();
21
  renderProductionLog();
22
- renderModals(); // Still needed to create modal structure initially
23
  renderReorderList();
24
- attachAllListeners(); // Attaches non-persistent listeners
25
  }
26
 
27
  export function showToast(message, type = 'info') {
@@ -131,7 +131,7 @@ function renderProductionHistoryChart() {
131
  },
132
  options: {
133
  responsive: true,
134
- maintainAspectRatio: false, // Important for responsive containers
135
  plugins: { legend: { display: false } },
136
  scales: {
137
  y: { beginAtZero: true, grid: { color: 'hsl(220, 13%, 30%)' } },
@@ -149,7 +149,7 @@ function renderInventoryStatusChart() {
149
  let okCount = 0, warningCount = 0, criticalCount = 0;
150
  appState.materials.forEach(m => {
151
  if (m.currentStock <= m.reorderPoint) criticalCount++;
152
- else if (m.currentStock <= m.reorderPoint * 1.5) warningCount++; // Warning when getting close to reorder
153
  else okCount++;
154
  });
155
 
@@ -172,7 +172,7 @@ function renderInventoryStatusChart() {
172
  data: data,
173
  options: {
174
  responsive: true,
175
- maintainAspectRatio: false, // Important for responsive containers
176
  plugins: { legend: { position: 'top', labels: { color: 'hsl(210, 14%, 66%)' } } }
177
  }
178
  });
@@ -229,7 +229,6 @@ function renderInventory() {
229
  if (!container) return;
230
  container.innerHTML = '';
231
  appState.materials.forEach(material => {
232
- // The bar is "full" at 2x the reorder point. Capped at 100%.
233
  const safeStockLevel = material.reorderPoint * 2;
234
  const stockPercentage = Math.min((material.currentStock / safeStockLevel) * 100, 100);
235
 
@@ -278,22 +277,62 @@ function renderReorderList() {
278
  if (!list || !header) return;
279
 
280
  list.innerHTML = '';
281
- header.querySelector('#generate-full-po-btn')?.remove(); // Remove old button
282
 
283
- const itemsToReorder = appState.materials.filter(m => m.currentStock <= m.reorderPoint);
284
 
285
  if (itemsToReorder.length === 0) {
286
  list.innerHTML = `<li class="text-secondary text-center pt-4">All stock levels are healthy.</li>`;
287
  return;
288
  }
289
 
290
- // Add the consolidated button
291
- const poButton = `<button id="generate-full-po-btn" class="btn btn-secondary text-sm">Generate Full Reorder Report</button>`;
292
  header.insertAdjacentHTML('beforeend', poButton);
293
 
294
  itemsToReorder.forEach(item => {
295
- const needed = (item.reorderPoint * 2) - item.currentStock;
296
- const itemHTML = `<li class="p-3 rounded-md text-sm flex justify-between items-center" style="background-color: #f6e05e20;"><div class="flex-grow"><span class="font-semibold">${item.name}</span><span class="text-xs text-secondary block">Stock: ${item.currentStock} / Reorder at: ${item.reorderPoint}</span></div><div class="text-right"><span class="font-bold">Order ${needed}</span><span class="text-xs text-secondary ml-1">${item.unit}</span></div></li>`;
297
  list.insertAdjacentHTML('beforeend', itemHTML);
298
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
299
  }
 
4
  import { attachAllListeners } from './events.js';
5
  import { getMonthlyProductionSummary, getMonthlyMaterialUsage } from './reportService.js';
6
 
7
+ // ... (keep chart variables and all functions from refreshUI down to renderProductionLog) ...
8
+ // We will add one new function and modify renderReorderList.
9
 
10
  let productionChart = null;
11
  let inventoryChart = null;
 
19
  renderProductInputs();
20
  renderInventory();
21
  renderProductionLog();
22
+ renderModals();
23
  renderReorderList();
24
+ attachAllListeners();
25
  }
26
 
27
  export function showToast(message, type = 'info') {
 
131
  },
132
  options: {
133
  responsive: true,
134
+ maintainAspectRatio: false,
135
  plugins: { legend: { display: false } },
136
  scales: {
137
  y: { beginAtZero: true, grid: { color: 'hsl(220, 13%, 30%)' } },
 
149
  let okCount = 0, warningCount = 0, criticalCount = 0;
150
  appState.materials.forEach(m => {
151
  if (m.currentStock <= m.reorderPoint) criticalCount++;
152
+ else if (m.currentStock <= m.reorderPoint * 1.5) warningCount++;
153
  else okCount++;
154
  });
155
 
 
172
  data: data,
173
  options: {
174
  responsive: true,
175
+ maintainAspectRatio: false,
176
  plugins: { legend: { position: 'top', labels: { color: 'hsl(210, 14%, 66%)' } } }
177
  }
178
  });
 
229
  if (!container) return;
230
  container.innerHTML = '';
231
  appState.materials.forEach(material => {
 
232
  const safeStockLevel = material.reorderPoint * 2;
233
  const stockPercentage = Math.min((material.currentStock / safeStockLevel) * 100, 100);
234
 
 
277
  if (!list || !header) return;
278
 
279
  list.innerHTML = '';
280
+ header.querySelector('#open-po-modal-btn')?.remove();
281
 
282
+ const itemsToReorder = appState.materials.filter(m => m.currentStock <= m.reorderPoint * 1.5);
283
 
284
  if (itemsToReorder.length === 0) {
285
  list.innerHTML = `<li class="text-secondary text-center pt-4">All stock levels are healthy.</li>`;
286
  return;
287
  }
288
 
289
+ const poButton = `<button id="open-po-modal-btn" class="btn btn-secondary text-sm">Create Purchase Order</button>`;
 
290
  header.insertAdjacentHTML('beforeend', poButton);
291
 
292
  itemsToReorder.forEach(item => {
293
+ const needed = Math.max(1, (item.reorderPoint * 2) - item.currentStock);
294
+ const itemHTML = `<li class="p-3 rounded-md text-sm flex justify-between items-center" style="background-color: ${item.currentStock <= item.reorderPoint ? '#f5656520' : '#f6e05e20'};"><div class="flex-grow"><span class="font-semibold">${item.name}</span><span class="text-xs text-secondary block">Stock: ${item.currentStock} / Reorder at: ${item.reorderPoint}</span></div><div class="text-right"><span class="font-bold">Suggests ${needed}</span><span class="text-xs text-secondary ml-1">${item.unit}</span></div></li>`;
295
  list.insertAdjacentHTML('beforeend', itemHTML);
296
  });
297
+ }
298
+
299
+ export function renderCustomPOModal(materials) {
300
+ const modal = document.getElementById('custom-po-modal');
301
+ if (!modal) return;
302
+
303
+ const materialRows = materials.map(material => {
304
+ const suggestedQty = Math.max(1, (material.reorderPoint * 2) - material.currentStock);
305
+ return `
306
+ <div class="po-item-row" data-material-name="${material.name}">
307
+ <input type="checkbox" class="po-item-select form-checkbox h-5 w-5 rounded bg-dark border-border-color text-accent-blue focus:ring-accent-blue" checked>
308
+ <div>
309
+ <span class="font-semibold">${material.name}</span>
310
+ <span class="text-xs text-secondary block">Stock: ${material.currentStock} | Reorder: ${material.reorderPoint}</span>
311
+ </div>
312
+ <input type="number" class="po-item-qty input-field w-24 text-right" value="${suggestedQty}" min="0">
313
+ </div>
314
+ `;
315
+ }).join('');
316
+
317
+ modal.innerHTML = `
318
+ <div class="modal-content dashboard-card p-6 max-w-3xl w-full mx-4 flex flex-col">
319
+ <div class="flex justify-between items-center mb-4">
320
+ <h3 class="text-lg font-semibold">Create Custom Purchase Order</h3>
321
+ <button id="cancel-po-btn" class="text-secondary hover:text-primary text-2xl">×</button>
322
+ </div>
323
+ <div class="mb-4">
324
+ <label for="supplier-name" class="block text-sm font-medium text-secondary mb-1">Supplier Name (Optional)</label>
325
+ <input type="text" id="supplier-name" class="input-field w-full" placeholder="Enter supplier name...">
326
+ </div>
327
+ <div id="po-item-list" class="flex-grow overflow-y-auto pr-2" style="max-height: 40vh;">
328
+ ${materialRows}
329
+ </div>
330
+ <div class="flex justify-end space-x-2 mt-6">
331
+ <button id="cancel-po-btn-footer" class="btn btn-secondary">Cancel</button>
332
+ <button id="confirm-po-generation-btn" class="btn btn-primary">Generate PO PDF</button>
333
+ </div>
334
+ </div>
335
+ `;
336
+
337
+ modal.classList.remove('hidden');
338
  }