Fuadsadik21 commited on
Commit
6504e32
·
verified ·
1 Parent(s): fea905c

make it full stack app that runs locally for sme businesses

Browse files
Files changed (6) hide show
  1. README.md +9 -5
  2. index.html +420 -18
  3. models/Inventory.js +15 -0
  4. package.json +19 -0
  5. routes/inventory.js +36 -0
  6. server.js +38 -0
README.md CHANGED
@@ -1,10 +1,14 @@
1
  ---
2
- title: Undefined
3
- emoji: 🏢
4
- colorFrom: yellow
5
- colorTo: purple
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
1
  ---
2
+ title: undefined
3
+ colorFrom: red
4
+ colorTo: gray
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://deepsite.hf.co).
14
+
index.html CHANGED
@@ -1,19 +1,421 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </html>
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>StockSage | Inventory Dashboard</title>
7
+ <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
8
+ <link rel="stylesheet" href="/css/tailwind.css">
9
+ <script src="/js/feather.min.js"></script>
10
+ <script>
11
+ tailwind.config = {
12
+ theme: {
13
+ extend: {
14
+ colors: {
15
+ primary: {
16
+ 100: '#f5f5f4',
17
+ 200: '#e7e5e4',
18
+ 300: '#d6d3d1',
19
+ 400: '#a8a29e',
20
+ 500: '#78716c',
21
+ 600: '#57534e',
22
+ 700: '#44403c',
23
+ 800: '#292524',
24
+ 900: '#1c1917',
25
+ }
26
+ }
27
+ }
28
+ }
29
+ }
30
+ </script>
31
+ <style>
32
+ .sidebar {
33
+ transition: all 0.3s ease;
34
+ }
35
+ .card:hover {
36
+ transform: translateY(-5px);
37
+ box-shadow: 0 10px 20px rgba(0,0,0,0.1);
38
+ }
39
+ .progress-bar {
40
+ transition: width 1s ease-in-out;
41
+ }
42
+ </style>
43
+ </head>
44
+ <body class="bg-primary-100 min-h-screen font-sans">
45
+ <div class="flex">
46
+ <!-- Sidebar -->
47
+ <div class="sidebar w-64 bg-primary-800 text-white h-screen fixed overflow-y-auto">
48
+ <div class="p-4 flex items-center space-x-2 border-b border-primary-700">
49
+ <i data-feather="box" class="text-primary-400"></i>
50
+ <h1 class="text-xl font-bold">StockSage</h1>
51
+ </div>
52
+ <nav class="p-4">
53
+ <div class="space-y-2">
54
+ <a href="#" class="flex items-center space-x-2 p-2 rounded bg-primary-700 text-white">
55
+ <i data-feather="home"></i>
56
+ <span>Dashboard</span>
57
+ </a>
58
+ <a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-primary-700 text-primary-200">
59
+ <i data-feather="package"></i>
60
+ <span>Inventory</span>
61
+ </a>
62
+ <a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-primary-700 text-primary-200">
63
+ <i data-feather="shopping-cart"></i>
64
+ <span>Orders</span>
65
+ </a>
66
+ <a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-primary-700 text-primary-200">
67
+ <i data-feather="users"></i>
68
+ <span>Suppliers</span>
69
+ </a>
70
+ <a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-primary-700 text-primary-200">
71
+ <i data-feather="bar-chart-2"></i>
72
+ <span>Reports</span>
73
+ </a>
74
+ <a href="#" class="flex items-center space-x-2 p-2 rounded hover:bg-primary-700 text-primary-200">
75
+ <i data-feather="settings"></i>
76
+ <span>Settings</span>
77
+ </a>
78
+ </div>
79
+ </nav>
80
+ <div class="absolute bottom-0 p-4 w-full border-t border-primary-700">
81
+ <div class="flex items-center space-x-2">
82
+ <div class="w-8 h-8 rounded-full bg-primary-600 flex items-center justify-center">
83
+ <i data-feather="user" class="text-sm"></i>
84
+ </div>
85
+ <div>
86
+ <p class="text-sm font-medium">Admin User</p>
87
+ <p class="text-xs text-primary-300">admin@stocksage.com</p>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </div>
92
+
93
+ <!-- Main Content -->
94
+ <div class="ml-64 flex-1 p-8">
95
+ <header class="flex justify-between items-center mb-8">
96
+ <h2 class="text-2xl font-bold text-primary-800">Dashboard Overview</h2>
97
+ <div class="flex items-center space-x-4">
98
+ <div class="relative">
99
+ <i data-feather="search" class="absolute left-3 top-1/2 transform -translate-y-1/2 text-primary-400"></i>
100
+ <input type="text" placeholder="Search..." class="pl-10 pr-4 py-2 rounded-lg border border-primary-300 focus:outline-none focus:ring-2 focus:ring-primary-500">
101
+ </div>
102
+ <div class="relative">
103
+ <i data-feather="bell" class="text-primary-500"></i>
104
+ <span class="absolute -top-1 -right-1 w-4 h-4 bg-red-500 rounded-full text-white text-xs flex items-center justify-center">3</span>
105
+ </div>
106
+ </div>
107
+ </header>
108
+
109
+ <!-- Stats Cards -->
110
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
111
+ <div class="card bg-white rounded-xl shadow-md p-6 flex items-center space-x-4">
112
+ <div class="p-3 rounded-full bg-primary-100 text-primary-600">
113
+ <i data-feather="package" class="w-6 h-6"></i>
114
+ </div>
115
+ <div>
116
+ <p class="text-sm text-primary-500">Total Products</p>
117
+ <h3 class="text-2xl font-bold text-primary-800">1,248</h3>
118
+ <p class="text-xs text-green-500 flex items-center">
119
+ <i data-feather="trending-up" class="w-3 h-3 mr-1"></i> 12% from last month
120
+ </p>
121
+ </div>
122
+ </div>
123
+ <div class="card bg-white rounded-xl shadow-md p-6 flex items-center space-x-4">
124
+ <div class="p-3 rounded-full bg-green-100 text-green-600">
125
+ <i data-feather="shopping-cart" class="w-6 h-6"></i>
126
+ </div>
127
+ <div>
128
+ <p class="text-sm text-primary-500">Today's Orders</p>
129
+ <h3 class="text-2xl font-bold text-primary-800">64</h3>
130
+ <p class="text-xs text-green-500 flex items-center">
131
+ <i data-feather="trending-up" class="w-3 h-3 mr-1"></i> 8% from yesterday
132
+ </p>
133
+ </div>
134
+ </div>
135
+ <div class="card bg-white rounded-xl shadow-md p-6 flex items-center space-x-4">
136
+ <div class="p-3 rounded-full bg-blue-100 text-blue-600">
137
+ <i data-feather="dollar-sign" class="w-6 h-6"></i>
138
+ </div>
139
+ <div>
140
+ <p class="text-sm text-primary-500">Revenue</p>
141
+ <h3 class="text-2xl font-bold text-primary-800">$12,845</h3>
142
+ <p class="text-xs text-red-500 flex items-center">
143
+ <i data-feather="trending-down" class="w-3 h-3 mr-1"></i> 5% from last week
144
+ </p>
145
+ </div>
146
+ </div>
147
+ <div class="card bg-white rounded-xl shadow-md p-6 flex items-center space-x-4">
148
+ <div class="p-3 rounded-full bg-yellow-100 text-yellow-600">
149
+ <i data-feather="alert-circle" class="w-6 h-6"></i>
150
+ </div>
151
+ <div>
152
+ <p class="text-sm text-primary-500">Low Stock</p>
153
+ <h3 class="text-2xl font-bold text-primary-800">27</h3>
154
+ <p class="text-xs text-yellow-500 flex items-center">
155
+ <i data-feather="alert-triangle" class="w-3 h-3 mr-1"></i> Needs attention
156
+ </p>
157
+ </div>
158
+ </div>
159
+ </div>
160
+
161
+ <!-- Main Content Grid -->
162
+ <div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
163
+ <!-- Recent Orders -->
164
+ <div class="lg:col-span-2 bg-white rounded-xl shadow-md overflow-hidden">
165
+ <div class="p-6 border-b border-primary-200">
166
+ <h3 class="font-bold text-primary-800 flex items-center">
167
+ <i data-feather="list" class="mr-2"></i> Recent Orders
168
+ </h3>
169
+ </div>
170
+ <div class="overflow-x-auto">
171
+ <table class="w-full">
172
+ <thead class="bg-primary-50">
173
+ <tr>
174
+ <th class="px-6 py-3 text-left text-xs font-medium text-primary-500 uppercase">Order #</th>
175
+ <th class="px-6 py-3 text-left text-xs font-medium text-primary-500 uppercase">Customer</th>
176
+ <th class="px-6 py-3 text-left text-xs font-medium text-primary-500 uppercase">Status</th>
177
+ <th class="px-6 py-3 text-left text-xs font-medium text-primary-500 uppercase">Amount</th>
178
+ <th class="px-6 py-3 text-left text-xs font-medium text-primary-500 uppercase">Date</th>
179
+ </tr>
180
+ </thead>
181
+ <tbody class="divide-y divide-primary-200">
182
+ <tr class="hover:bg-primary-50">
183
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-primary-800">#ORD-4829</td>
184
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">Acme Corporation</td>
185
+ <td class="px-6 py-4 whitespace-nowrap">
186
+ <span class="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">Completed</span>
187
+ </td>
188
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">$1,245</td>
189
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">Today, 10:45 AM</td>
190
+ </tr>
191
+ <tr class="hover:bg-primary-50">
192
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-primary-800">#ORD-4828</td>
193
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">Beta Solutions</td>
194
+ <td class="px-6 py-4 whitespace-nowrap">
195
+ <span class="px-2 py-1 text-xs rounded-full bg-blue-100 text-blue-800">Processing</span>
196
+ </td>
197
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">$845</td>
198
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">Today, 09:30 AM</td>
199
+ </tr>
200
+ <tr class="hover:bg-primary-50">
201
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-primary-800">#ORD-4827</td>
202
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">Gamma Industries</td>
203
+ <td class="px-6 py-4 whitespace-nowrap">
204
+ <span class="px-2 py-1 text-xs rounded-full bg-yellow-100 text-yellow-800">Pending</span>
205
+ </td>
206
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">$2,145</td>
207
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">Yesterday, 4:20 PM</td>
208
+ </tr>
209
+ <tr class="hover:bg-primary-50">
210
+ <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-primary-800">#ORD-4826</td>
211
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">Delta Systems</td>
212
+ <td class="px-6 py-4 whitespace-nowrap">
213
+ <span class="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">Completed</span>
214
+ </td>
215
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">$560</td>
216
+ <td class="px-6 py-4 whitespace-nowrap text-sm text-primary-600">Yesterday, 2:15 PM</td>
217
+ </tr>
218
+ </tbody>
219
+ </table>
220
+ </div>
221
+ <div class="p-4 border-t border-primary-200 text-center">
222
+ <a href="#" class="text-sm font-medium text-primary-600 hover:text-primary-800">View All Orders</a>
223
+ </div>
224
+ </div>
225
+
226
+ <!-- Inventory Status -->
227
+ <div class="bg-white rounded-xl shadow-md overflow-hidden">
228
+ <div class="p-6 border-b border-primary-200">
229
+ <h3 class="font-bold text-primary-800 flex items-center">
230
+ <i data-feather="alert-circle" class="mr-2"></i> Low Stock Alert
231
+ </h3>
232
+ </div>
233
+ <div class="divide-y divide-primary-200">
234
+ <div class="p-4 hover:bg-primary-50 flex items-center space-x-3">
235
+ <div class="flex-shrink-0">
236
+ <img src="http://static.photos/technology/200x200/1" alt="Product" class="w-10 h-10 rounded-lg object-cover">
237
+ </div>
238
+ <div class="flex-1 min-w-0">
239
+ <p class="text-sm font-medium text-primary-800 truncate">Wireless Earbuds Pro</p>
240
+ <p class="text-xs text-primary-500">SKU: WB-001</p>
241
+ </div>
242
+ <div class="text-right">
243
+ <p class="text-sm font-medium text-red-600">3 left</p>
244
+ <p class="text-xs text-primary-500">Reorder at 5</p>
245
+ </div>
246
+ </div>
247
+ <div class="p-4 hover:bg-primary-50 flex items-center space-x-3">
248
+ <div class="flex-shrink-0">
249
+ <img src="http://static.photos/technology/200x200/2" alt="Product" class="w-10 h-10 rounded-lg object-cover">
250
+ </div>
251
+ <div class="flex-1 min-w-0">
252
+ <p class="text-sm font-medium text-primary-800 truncate">Bluetooth Speaker X7</p>
253
+ <p class="text-xs text-primary-500">SKU: BS-007</p>
254
+ </div>
255
+ <div class="text-right">
256
+ <p class="text-sm font-medium text-yellow-600">5 left</p>
257
+ <p class="text-xs text-primary-500">Reorder at 10</p>
258
+ </div>
259
+ </div>
260
+ <div class="p-4 hover:bg-primary-50 flex items-center space-x-3">
261
+ <div class="flex-shrink-0">
262
+ <img src="http://static.photos/technology/200x200/3" alt="Product" class="w-10 h-10 rounded-lg object-cover">
263
+ </div>
264
+ <div class="flex-1 min-w-0">
265
+ <p class="text-sm font-medium text-primary-800 truncate">USB-C Charging Cable</p>
266
+ <p class="text-xs text-primary-500">SKU: CC-102</p>
267
+ </div>
268
+ <div class="text-right">
269
+ <p class="text-sm font-medium text-red-600">2 left</p>
270
+ <p class="text-xs text-primary-500">Reorder at 15</p>
271
+ </div>
272
+ </div>
273
+ <div class="p-4 hover:bg-primary-50 flex items-center space-x-3">
274
+ <div class="flex-shrink-0">
275
+ <img src="http://static.photos/technology/200x200/4" alt="Product" class="w-10 h-10 rounded-lg object-cover">
276
+ </div>
277
+ <div class="flex-1 min-w-0">
278
+ <p class="text-sm font-medium text-primary-800 truncate">Wireless Mouse M300</p>
279
+ <p class="text-xs text-primary-500">SKU: WM-300</p>
280
+ </div>
281
+ <div class="text-right">
282
+ <p class="text-sm font-medium text-yellow-600">7 left</p>
283
+ <p class="text-xs text-primary-500">Reorder at 12</p>
284
+ </div>
285
+ </div>
286
+ </div>
287
+ <div class="p-4 border-t border-primary-200 text-center">
288
+ <a href="#" class="text-sm font-medium text-primary-600 hover:text-primary-800">View All Alerts</a>
289
+ </div>
290
+ </div>
291
+ </div>
292
+
293
+ <!-- Bottom Section -->
294
+ <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mt-6">
295
+ <!-- Category Distribution -->
296
+ <div class="bg-white rounded-xl shadow-md p-6">
297
+ <div class="flex justify-between items-center mb-4">
298
+ <h3 class="font-bold text-primary-800 flex items-center">
299
+ <i data-feather="pie-chart" class="mr-2"></i> Category Distribution
300
+ </h3>
301
+ <select class="text-sm border border-primary-300 rounded px-3 py-1 focus:outline-none focus:ring-1 focus:ring-primary-500">
302
+ <option>This Month</option>
303
+ <option>Last Month</option>
304
+ <option>This Quarter</option>
305
+ </select>
306
+ </div>
307
+ <div class="h-64">
308
+ <canvas id="categoryChart"></canvas>
309
+ </div>
310
+ </div>
311
+
312
+ <!-- Recent Activities -->
313
+ <div class="bg-white rounded-xl shadow-md p-6">
314
+ <div class="flex justify-between items-center mb-4">
315
+ <h3 class="font-bold text-primary-800 flex items-center">
316
+ <i data-feather="activity" class="mr-2"></i> Recent Activities
317
+ </h3>
318
+ <a href="#" class="text-sm text-primary-600 hover:text-primary-800">View All</a>
319
+ </div>
320
+ <div class="space-y-4">
321
+ <div class="flex items-start space-x-3">
322
+ <div class="flex-shrink-0 p-2 rounded-full bg-primary-100 text-primary-600">
323
+ <i data-feather="plus" class="w-4 h-4"></i>
324
+ </div>
325
+ <div>
326
+ <p class="text-sm font-medium text-primary-800">New product added</p>
327
+ <p class="text-xs text-primary-500">"Wireless Charging Pad" was added to inventory</p>
328
+ <p class="text-xs text-primary-400 mt-1">10 minutes ago</p>
329
+ </div>
330
+ </div>
331
+ <div class="flex items-start space-x-3">
332
+ <div class="flex-shrink-0 p-2 rounded-full bg-green-100 text-green-600">
333
+ <i data-feather="check" class="w-4 h-4"></i>
334
+ </div>
335
+ <div>
336
+ <p class="text-sm font-medium text-primary-800">Order completed</p>
337
+ <p class="text-xs text-primary-500">Order #ORD-4829 was marked as completed</p>
338
+ <p class="text-xs text-primary-400 mt-1">35 minutes ago</p>
339
+ </div>
340
+ </div>
341
+ <div class="flex items-start space-x-3">
342
+ <div class="flex-shrink-0 p-2 rounded-full bg-blue-100 text-blue-600">
343
+ <i data-feather="truck" class="w-4 h-4"></i>
344
+ </div>
345
+ <div>
346
+ <p class="text-sm font-medium text-primary-800">Shipment received</p>
347
+ <p class="text-xs text-primary-500">Received 50 units of "Bluetooth Headphones"</p>
348
+ <p class="text-xs text-primary-400 mt-1">2 hours ago</p>
349
+ </div>
350
+ </div>
351
+ <div class="flex items-start space-x-3">
352
+ <div class="flex-shrink-0 p-2 rounded-full bg-yellow-100 text-yellow-600">
353
+ <i data-feather="alert-triangle" class="w-4 h-4"></i>
354
+ </div>
355
+ <div>
356
+ <p class="text-sm font-medium text-primary-800">Low stock warning</p>
357
+ <p class="text-xs text-primary-500">"USB-C Cable" stock is below threshold</p>
358
+ <p class="text-xs text-primary-400 mt-1">4 hours ago</p>
359
+ </div>
360
+ </div>
361
+ </div>
362
+ </div>
363
+ </div>
364
+ </div>
365
+ </div>
366
+
367
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
368
+ <script>
369
+ feather.replace();
370
+ // Fetch inventory data
371
+ async function fetchInventoryData() {
372
+ try {
373
+ const response = await fetch('/api/inventory');
374
+ const data = await response.json();
375
+ updateDashboard(data);
376
+ } catch (error) {
377
+ console.error('Error fetching inventory data:', error);
378
+ }
379
+ }
380
+
381
+ // Update dashboard with real data
382
+ function updateDashboard(data) {
383
+ // Update your UI elements here with real data
384
+ console.log('Dashboard updated with:', data);
385
+ }
386
+
387
+ // Initialize charts and data
388
+ document.addEventListener('DOMContentLoaded', function() {
389
+ fetchInventoryData();
390
+ // Category Distribution Chart
391
+ const ctx = document.getElementById('categoryChart').getContext('2d');
392
+ const categoryChart = new Chart(ctx, {
393
+ type: 'doughnut',
394
+ data: {
395
+ labels: ['Electronics', 'Furniture', 'Office Supplies', 'Appliances', 'Other'],
396
+ datasets: [{
397
+ data: [35, 25, 20, 15, 5],
398
+ backgroundColor: [
399
+ '#78716c',
400
+ '#a8a29e',
401
+ '#d6d3d1',
402
+ '#e7e5e4',
403
+ '#f5f5f4'
404
+ ],
405
+ borderWidth: 0
406
+ }]
407
+ },
408
+ options: {
409
+ responsive: true,
410
+ maintainAspectRatio: false,
411
+ plugins: {
412
+ legend: {
413
+ position: 'right',
414
+ }
415
+ }
416
+ }
417
+ });
418
+ });
419
+ </script>
420
+ </body>
421
  </html>
models/Inventory.js ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```javascript
2
+ const mongoose = require('mongoose');
3
+
4
+ const inventorySchema = new mongoose.Schema({
5
+ name: { type: String, required: true },
6
+ sku: { type: String, required: true, unique: true },
7
+ quantity: { type: Number, required: true },
8
+ price: { type: Number, required: true },
9
+ category: { type: String, required: true },
10
+ threshold: { type: Number, required: true },
11
+ lastUpdated: { type: Date, default: Date.now }
12
+ });
13
+
14
+ module.exports = mongoose.model('Inventory', inventorySchema);
15
+ ```
package.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```json
2
+ {
3
+ "name": "stocksage-pro",
4
+ "version": "1.0.0",
5
+ "description": "Local inventory management for SMEs",
6
+ "main": "server.js",
7
+ "scripts": {
8
+ "start": "node server.js",
9
+ "dev": "nodemon server.js",
10
+ "test": "echo \"Error: no test specified\" && exit 1"
11
+ },
12
+ "dependencies": {
13
+ "express": "^4.17.1",
14
+ "mongoose": "^5.12.3",
15
+ "body-parser": "^1.19.0",
16
+ "nodemon": "^2.0.7"
17
+ }
18
+ }
19
+ ```
routes/inventory.js ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```javascript
2
+ const express = require('express');
3
+ const router = express.Router();
4
+ const Inventory = require('../models/Inventory');
5
+
6
+ // Get all inventory items
7
+ router.get('/', async (req, res) => {
8
+ try {
9
+ const inventory = await Inventory.find();
10
+ res.json(inventory);
11
+ } catch (err) {
12
+ res.status(500).json({ message: err.message });
13
+ }
14
+ });
15
+
16
+ // Add new inventory item
17
+ router.post('/', async (req, res) => {
18
+ const inventory = new Inventory({
19
+ name: req.body.name,
20
+ sku: req.body.sku,
21
+ quantity: req.body.quantity,
22
+ price: req.body.price,
23
+ category: req.body.category,
24
+ threshold: req.body.threshold
25
+ });
26
+
27
+ try {
28
+ const newInventory = await inventory.save();
29
+ res.status(201).json(newInventory);
30
+ } catch (err) {
31
+ res.status(400).json({ message: err.message });
32
+ }
33
+ });
34
+
35
+ module.exports = router;
36
+ ```
server.js ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```javascript
2
+ const express = require('express');
3
+ const mongoose = require('mongoose');
4
+ const bodyParser = require('body-parser');
5
+ const path = require('path');
6
+ const app = express();
7
+
8
+ // MongoDB Connection
9
+ mongoose.connect('mongodb://localhost:27017/stocksage', {
10
+ useNewUrlParser: true,
11
+ useUnifiedTopology: true
12
+ })
13
+ .then(() => console.log('MongoDB Connected'))
14
+ .catch(err => console.log(err));
15
+
16
+ // Middleware
17
+ app.use(bodyParser.json());
18
+ app.use(express.static(path.join(__dirname, 'public')));
19
+
20
+ // Routes
21
+ const inventoryRouter = require('./routes/inventory');
22
+ const ordersRouter = require('./routes/orders');
23
+ const suppliersRouter = require('./routes/suppliers');
24
+ const reportsRouter = require('./routes/reports');
25
+
26
+ app.use('/api/inventory', inventoryRouter);
27
+ app.use('/api/orders', ordersRouter);
28
+ app.use('/api/suppliers', suppliersRouter);
29
+ app.use('/api/reports', reportsRouter);
30
+
31
+ // Serve HTML
32
+ app.get('*', (req, res) => {
33
+ res.sendFile(path.join(__dirname, 'public', 'index.html'));
34
+ });
35
+
36
+ const PORT = process.env.PORT || 3000;
37
+ app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
38
+ ```