Ultronprime commited on
Commit
6ccdb68
·
verified ·
1 Parent(s): 2b45bb5

Create app.js

Browse files
Files changed (1) hide show
  1. app.js +166 -0
app.js ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener('DOMContentLoaded', () => {
2
+
3
+ // --- DATA & STATE MANAGEMENT ---
4
+
5
+ const initialState = {
6
+ materials: [
7
+ { name: "5mm Copper Wire", unit: "meters", maxStock: 500, currentStock: 500 },
8
+ { name: "RG-58 Coaxial Cable", unit: "meters", maxStock: 200, currentStock: 200 },
9
+ { name: "N-Type Connector", unit: "units", maxStock: 1000, currentStock: 1000 },
10
+ { name: "Plastic Insulator", unit: "units", maxStock: 4000, currentStock: 4000 },
11
+ ]
12
+ };
13
+
14
+ const productRecipes = {
15
+ "Yagi-Uda Model 5": {
16
+ "5mm Copper Wire": 10,
17
+ "RG-58 Coaxial Cable": 5,
18
+ "N-Type Connector": 1,
19
+ "Plastic Insulator": 8,
20
+ },
21
+ "Basic Dipole Antenna": {
22
+ "5mm Copper Wire": 5,
23
+ "RG-58 Coaxial Cable": 2,
24
+ "N-Type Connector": 1,
25
+ "Plastic Insulator": 2,
26
+ }
27
+ };
28
+
29
+ let appState;
30
+
31
+ function saveState() {
32
+ localStorage.setItem('antennaTrackerState', JSON.stringify(appState));
33
+ }
34
+
35
+ function loadState() {
36
+ const savedState = localStorage.getItem('antennaTrackerState');
37
+ if (savedState) {
38
+ appState = JSON.parse(savedState);
39
+ } else {
40
+ // Use a deep copy to avoid modifying the initialState object
41
+ appState = JSON.parse(JSON.stringify(initialState));
42
+ }
43
+ }
44
+
45
+ // --- UI RENDERING ---
46
+
47
+ function renderInventory() {
48
+ appState.materials.forEach(material => {
49
+ const card = document.querySelector(`.material-card[data-material-name="${material.name}"]`);
50
+ if (!card) return;
51
+
52
+ const currentStockEl = card.querySelector('.current-stock');
53
+ const progressBarEl = card.querySelector('.progress-bar');
54
+
55
+ currentStockEl.textContent = material.currentStock;
56
+
57
+ const stockPercentage = (material.currentStock / material.maxStock) * 100;
58
+ progressBarEl.style.width = `${stockPercentage}%`;
59
+
60
+ // Update status colors
61
+ card.classList.remove('status-ok', 'status-warning', 'status-critical');
62
+ progressBarEl.classList.remove('progress-ok', 'progress-warning', 'progress-critical');
63
+
64
+ if (stockPercentage > 50) {
65
+ card.classList.add('status-ok');
66
+ progressBarEl.classList.add('progress-ok');
67
+ } else if (stockPercentage > 20) {
68
+ card.classList.add('status-warning');
69
+ progressBarEl.classList.add('progress-warning');
70
+ } else {
71
+ card.classList.add('status-critical');
72
+ progressBarEl.classList.add('progress-critical');
73
+ }
74
+ });
75
+ }
76
+
77
+ // --- EVENT HANDLERS & LOGIC ---
78
+
79
+ function handleUpdateStock(productName, quantity) {
80
+ if (quantity <= 0) return;
81
+
82
+ const recipe = productRecipes[productName];
83
+ if (!recipe) {
84
+ alert(`Error: No recipe found for ${productName}.`);
85
+ return;
86
+ }
87
+
88
+ // 1. Check if there are enough materials
89
+ let canProduce = true;
90
+ let missingMaterials = [];
91
+ for (const materialName in recipe) {
92
+ const required = recipe[materialName] * quantity;
93
+ const material = appState.materials.find(m => m.name === materialName);
94
+ if (!material || material.currentStock < required) {
95
+ canProduce = false;
96
+ missingMaterials.push(`${required} ${material.unit} of ${materialName} (have ${material.currentStock})`);
97
+ }
98
+ }
99
+
100
+ // 2. If not enough, show an alert
101
+ if (!canProduce) {
102
+ alert(`Insufficient materials to produce ${quantity} of ${productName}.\n\nNeeded:\n- ${missingMaterials.join('\n- ')}`);
103
+ return;
104
+ }
105
+
106
+ // 3. If enough, deduct materials
107
+ for (const materialName in recipe) {
108
+ const required = recipe[materialName] * quantity;
109
+ const material = appState.materials.find(m => m.name === materialName);
110
+ material.currentStock -= required;
111
+ }
112
+
113
+ // 4. Save state and re-render
114
+ saveState();
115
+ renderInventory();
116
+
117
+ // 5. Clear the input field for this product
118
+ const productCard = document.querySelector(`.product-card[data-product-name="${productName}"]`);
119
+ if(productCard) {
120
+ productCard.querySelector('input').value = '0';
121
+ }
122
+ }
123
+
124
+ function handleResetData() {
125
+ if (confirm('Are you sure you want to reset all inventory data? This action cannot be undone.')) {
126
+ localStorage.removeItem('antennaTrackerState');
127
+ init(); // Re-initialize the application
128
+ }
129
+ }
130
+
131
+ // Modal logic
132
+ const resetModal = document.getElementById('reset-modal');
133
+ const showResetModalBtn = document.getElementById('show-reset-modal-btn');
134
+ const cancelResetBtn = document.getElementById('cancel-reset-btn');
135
+ const confirmResetBtn = document.getElementById('confirm-reset-btn');
136
+
137
+ showResetModalBtn.addEventListener('click', () => resetModal.classList.remove('hidden'));
138
+ cancelResetBtn.addEventListener('click', () => resetModal.classList.add('hidden'));
139
+ confirmResetBtn.addEventListener('click', () => {
140
+ localStorage.removeItem('antennaTrackerState');
141
+ init();
142
+ resetModal.classList.add('hidden');
143
+ });
144
+
145
+
146
+ // --- INITIALIZATION ---
147
+
148
+ function init() {
149
+ loadState();
150
+ renderInventory();
151
+
152
+ // Attach event listeners to all "Update Stock" buttons
153
+ document.querySelectorAll('.product-card').forEach(card => {
154
+ const updateBtn = card.querySelector('.update-btn');
155
+ const input = card.querySelector('input');
156
+ const productName = card.dataset.productName;
157
+
158
+ updateBtn.addEventListener('click', () => {
159
+ const quantity = parseInt(input.value, 10);
160
+ handleUpdateStock(productName, quantity);
161
+ });
162
+ });
163
+ }
164
+
165
+ init(); // Start the app
166
+ });