Ultronprime commited on
Commit
75e2df2
·
verified ·
1 Parent(s): e2f2b65

Update ui.js

Browse files
Files changed (1) hide show
  1. ui.js +52 -38
ui.js CHANGED
@@ -1,15 +1,18 @@
1
- // ui.js - Renders all UI components
2
 
3
  import { appState } from './state.js';
4
  import { attachAllListeners } from './events.js';
5
  import { getMonthlyProductionSummary, getMonthlyMaterialUsage } from './reportService.js';
6
 
 
7
  let productionChart = null;
8
  let inventoryChart = null;
9
 
 
10
  Chart.defaults.color = 'hsl(210, 14%, 66%)';
11
  Chart.defaults.borderColor = 'hsl(220, 13%, 30%)';
12
 
 
13
  export function refreshUI() {
14
  renderKpiCards();
15
  renderCharts();
@@ -109,32 +112,39 @@ function renderProductionHistoryChart() {
109
  data.push(totalProduced);
110
  }
111
 
 
 
112
  if (productionChart) {
113
- productionChart.destroy();
114
- }
115
- productionChart = new Chart(ctx, {
116
- type: 'bar',
117
- data: {
118
- labels: labels,
119
- datasets: [{
120
- label: 'Complete Units Produced',
121
- data: data,
122
- backgroundColor: 'rgba(66, 153, 225, 0.5)',
123
- borderColor: 'rgba(66, 153, 225, 1)',
124
- borderWidth: 1,
125
- borderRadius: 4,
126
- }]
127
- },
128
- options: {
129
- responsive: true,
130
- maintainAspectRatio: false,
131
- plugins: { legend: { display: false } },
132
- scales: {
133
- y: { beginAtZero: true, grid: { color: 'hsl(220, 13%, 30%)' } },
134
- x: { grid: { display: false } }
 
 
 
 
135
  }
136
- }
137
- });
 
138
  }
139
 
140
  function renderInventoryStatusChart() {
@@ -158,18 +168,22 @@ function renderInventoryStatusChart() {
158
  }]
159
  };
160
 
 
161
  if (inventoryChart) {
162
- inventoryChart.destroy();
 
 
 
 
 
 
 
 
 
 
 
163
  }
164
- inventoryChart = new Chart(ctx, {
165
- type: 'doughnut',
166
- data: data,
167
- options: {
168
- responsive: true,
169
- maintainAspectRatio: false,
170
- plugins: { legend: { position: 'top', labels: { color: 'hsl(210, 14%, 66%)' } } }
171
- }
172
- });
173
  }
174
 
175
  function renderModals() {
@@ -191,7 +205,7 @@ export function renderReport(type) {
191
  headers = ['Material', 'Total Quantity Consumed'];
192
  rows = Object.entries(data).map(([name, qty]) => {
193
  const material = appState.materials.find(m => m.name === name);
194
- return `<tr><td class="border-b border-border-color px-4 py-2">${name}</td><td class="border-b border-border-color px-4 py-2 text-right">${qty} ${material.unit}</td></tr>`;
195
  }).join('');
196
  }
197
  if (Object.keys(data).length === 0) {
@@ -245,7 +259,7 @@ function renderAnalytics() {
245
  const cost = Object.keys(recipe).reduce((sum, matName) => {
246
  const material = appState.materials.find(m => m.name === matName);
247
  const quantity = recipe[matName];
248
- return sum + (quantity * (material.costPerUnit || 0));
249
  }, 0);
250
  productCostsHTML += `<div class="flex justify-between text-sm"><span class="text-secondary">${productName}</span><span class="font-medium">$${cost.toFixed(2)} / unit</span></div>`;
251
  }
@@ -256,7 +270,7 @@ function renderAnalytics() {
256
  function renderReorderList() {
257
  const list = document.getElementById('reorder-list');
258
  list.innerHTML = '';
259
- const itemsToReorder = appState.materials.filter(m => m.currentStock <= (m.reorderPoint || 0));
260
  if (itemsToReorder.length === 0) { list.innerHTML = `<li class="text-secondary text-center pt-4">All stock levels are healthy.</li>`; return; }
261
  itemsToReorder.forEach(item => {
262
  const needed = item.maxStock - item.currentStock;
 
1
+ // ui.js - Renders all UI components (Corrected Chart Logic)
2
 
3
  import { appState } from './state.js';
4
  import { attachAllListeners } from './events.js';
5
  import { getMonthlyProductionSummary, getMonthlyMaterialUsage } from './reportService.js';
6
 
7
+ // Chart instances to prevent re-creation
8
  let productionChart = null;
9
  let inventoryChart = null;
10
 
11
+ // Set Chart.js defaults for our dark theme
12
  Chart.defaults.color = 'hsl(210, 14%, 66%)';
13
  Chart.defaults.borderColor = 'hsl(220, 13%, 30%)';
14
 
15
+ // Master function to update the entire UI
16
  export function refreshUI() {
17
  renderKpiCards();
18
  renderCharts();
 
112
  data.push(totalProduced);
113
  }
114
 
115
+ // ** BUG FIX STARTS HERE **
116
+ // Instead of destroying, we now update the existing chart if it exists.
117
  if (productionChart) {
118
+ productionChart.data.labels = labels;
119
+ productionChart.data.datasets[0].data = data;
120
+ productionChart.update();
121
+ } else {
122
+ // If it doesn't exist (first render), create it.
123
+ productionChart = new Chart(ctx, {
124
+ type: 'bar',
125
+ data: {
126
+ labels: labels,
127
+ datasets: [{
128
+ label: 'Complete Units Produced',
129
+ data: data,
130
+ backgroundColor: 'rgba(66, 153, 225, 0.5)',
131
+ borderColor: 'rgba(66, 153, 225, 1)',
132
+ borderWidth: 1,
133
+ borderRadius: 4,
134
+ }]
135
+ },
136
+ options: {
137
+ responsive: true,
138
+ maintainAspectRatio: false,
139
+ plugins: { legend: { display: false } },
140
+ scales: {
141
+ y: { beginAtZero: true, grid: { color: 'hsl(220, 13%, 30%)' } },
142
+ x: { grid: { display: false } }
143
+ }
144
  }
145
+ });
146
+ }
147
+ // ** BUG FIX ENDS HERE **
148
  }
149
 
150
  function renderInventoryStatusChart() {
 
168
  }]
169
  };
170
 
171
+ // ** BUG FIX STARTS HERE **
172
  if (inventoryChart) {
173
+ inventoryChart.data.datasets[0].data = [okCount, warningCount, criticalCount];
174
+ inventoryChart.update();
175
+ } else {
176
+ inventoryChart = new Chart(ctx, {
177
+ type: 'doughnut',
178
+ data: data,
179
+ options: {
180
+ responsive: true,
181
+ maintainAspectRatio: false,
182
+ plugins: { legend: { position: 'top', labels: { color: 'hsl(210, 14%, 66%)' } } }
183
+ }
184
+ });
185
  }
186
+ // ** BUG FIX ENDS HERE **
 
 
 
 
 
 
 
 
187
  }
188
 
189
  function renderModals() {
 
205
  headers = ['Material', 'Total Quantity Consumed'];
206
  rows = Object.entries(data).map(([name, qty]) => {
207
  const material = appState.materials.find(m => m.name === name);
208
+ return `<tr><td class="border-b border-border-color px-4 py-2">${name}</td><td class="border-b border-border-color px-4 py-2 text-right">${qty} ${material?.unit || ''}</td></tr>`;
209
  }).join('');
210
  }
211
  if (Object.keys(data).length === 0) {
 
259
  const cost = Object.keys(recipe).reduce((sum, matName) => {
260
  const material = appState.materials.find(m => m.name === matName);
261
  const quantity = recipe[matName];
262
+ return sum + (quantity * (material?.costPerUnit || 0));
263
  }, 0);
264
  productCostsHTML += `<div class="flex justify-between text-sm"><span class="text-secondary">${productName}</span><span class="font-medium">$${cost.toFixed(2)} / unit</span></div>`;
265
  }
 
270
  function renderReorderList() {
271
  const list = document.getElementById('reorder-list');
272
  list.innerHTML = '';
273
+ const itemsToReorder = appState.materials.filter(m => m.currentStock <= m.reorderPoint);
274
  if (itemsToReorder.length === 0) { list.innerHTML = `<li class="text-secondary text-center pt-4">All stock levels are healthy.</li>`; return; }
275
  itemsToReorder.forEach(item => {
276
  const needed = item.maxStock - item.currentStock;