npms-exam-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/bin/exam-kit.js +357 -0
  2. package/package.json +25 -0
  3. package/projects/CRPMS-main/backend-project/config/db.js +12 -0
  4. package/projects/CRPMS-main/backend-project/config/initDb.js +92 -0
  5. package/projects/CRPMS-main/backend-project/middleware/auth.js +8 -0
  6. package/projects/CRPMS-main/backend-project/package-lock.json +1429 -0
  7. package/projects/CRPMS-main/backend-project/package.json +21 -0
  8. package/projects/CRPMS-main/backend-project/routes/auth.js +26 -0
  9. package/projects/CRPMS-main/backend-project/routes/cars.js +36 -0
  10. package/projects/CRPMS-main/backend-project/routes/payments.js +69 -0
  11. package/projects/CRPMS-main/backend-project/routes/reports.js +58 -0
  12. package/projects/CRPMS-main/backend-project/routes/serviceRecords.js +91 -0
  13. package/projects/CRPMS-main/backend-project/routes/services.js +36 -0
  14. package/projects/CRPMS-main/backend-project/server.js +44 -0
  15. package/projects/CRPMS-main/database.sql +59 -0
  16. package/projects/CRPMS-main/frontend-project/README.md +16 -0
  17. package/projects/CRPMS-main/frontend-project/eslint.config.js +21 -0
  18. package/projects/CRPMS-main/frontend-project/index.html +13 -0
  19. package/projects/CRPMS-main/frontend-project/package-lock.json +3356 -0
  20. package/projects/CRPMS-main/frontend-project/package.json +32 -0
  21. package/projects/CRPMS-main/frontend-project/public/favicon.svg +1 -0
  22. package/projects/CRPMS-main/frontend-project/public/icons.svg +24 -0
  23. package/projects/CRPMS-main/frontend-project/src/App.css +184 -0
  24. package/projects/CRPMS-main/frontend-project/src/App.jsx +72 -0
  25. package/projects/CRPMS-main/frontend-project/src/api/axios.js +8 -0
  26. package/projects/CRPMS-main/frontend-project/src/assets/hero.png +0 -0
  27. package/projects/CRPMS-main/frontend-project/src/assets/react.svg +1 -0
  28. package/projects/CRPMS-main/frontend-project/src/assets/vite.svg +1 -0
  29. package/projects/CRPMS-main/frontend-project/src/components/Navbar.jsx +54 -0
  30. package/projects/CRPMS-main/frontend-project/src/components/ProtectedRoute.jsx +9 -0
  31. package/projects/CRPMS-main/frontend-project/src/context/AuthContext.jsx +35 -0
  32. package/projects/CRPMS-main/frontend-project/src/index.css +14 -0
  33. package/projects/CRPMS-main/frontend-project/src/main.jsx +10 -0
  34. package/projects/CRPMS-main/frontend-project/src/pages/Bill.jsx +227 -0
  35. package/projects/CRPMS-main/frontend-project/src/pages/Cars.jsx +112 -0
  36. package/projects/CRPMS-main/frontend-project/src/pages/Login.jsx +78 -0
  37. package/projects/CRPMS-main/frontend-project/src/pages/Payments.jsx +153 -0
  38. package/projects/CRPMS-main/frontend-project/src/pages/Reports.jsx +199 -0
  39. package/projects/CRPMS-main/frontend-project/src/pages/ServiceRecords.jsx +182 -0
  40. package/projects/CRPMS-main/frontend-project/src/pages/Services.jsx +125 -0
  41. package/projects/CRPMS-main/frontend-project/vite.config.js +10 -0
  42. package/projects/SIMS-master/backend-project/.env.example +6 -0
  43. package/projects/SIMS-master/backend-project/config/db.js +12 -0
  44. package/projects/SIMS-master/backend-project/middleware/auth.js +8 -0
  45. package/projects/SIMS-master/backend-project/package-lock.json +1221 -0
  46. package/projects/SIMS-master/backend-project/package.json +23 -0
  47. package/projects/SIMS-master/backend-project/routes/auth.js +29 -0
  48. package/projects/SIMS-master/backend-project/routes/reports.js +51 -0
  49. package/projects/SIMS-master/backend-project/routes/spareParts.js +34 -0
  50. package/projects/SIMS-master/backend-project/routes/stockIn.js +53 -0
  51. package/projects/SIMS-master/backend-project/routes/stockOut.js +146 -0
  52. package/projects/SIMS-master/backend-project/seed.js +20 -0
  53. package/projects/SIMS-master/backend-project/server.js +43 -0
  54. package/projects/SIMS-master/database.sql +43 -0
  55. package/projects/SIMS-master/frontend-project/index.html +12 -0
  56. package/projects/SIMS-master/frontend-project/package-lock.json +3352 -0
  57. package/projects/SIMS-master/frontend-project/package.json +27 -0
  58. package/projects/SIMS-master/frontend-project/postcss.config.js +6 -0
  59. package/projects/SIMS-master/frontend-project/src/App.jsx +53 -0
  60. package/projects/SIMS-master/frontend-project/src/components/Navbar.jsx +103 -0
  61. package/projects/SIMS-master/frontend-project/src/index.css +3 -0
  62. package/projects/SIMS-master/frontend-project/src/main.jsx +10 -0
  63. package/projects/SIMS-master/frontend-project/src/pages/Login.jsx +92 -0
  64. package/projects/SIMS-master/frontend-project/src/pages/Reports.jsx +279 -0
  65. package/projects/SIMS-master/frontend-project/src/pages/SparePart.jsx +185 -0
  66. package/projects/SIMS-master/frontend-project/src/pages/StockIn.jsx +170 -0
  67. package/projects/SIMS-master/frontend-project/src/pages/StockOut.jsx +288 -0
  68. package/projects/SIMS-master/frontend-project/tailwind.config.js +11 -0
  69. package/projects/SIMS-master/frontend-project/vite.config.js +9 -0
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "backend-project",
3
+ "version": "1.0.0",
4
+ "description": "SmartPark SIMS Backend",
5
+ "main": "server.js",
6
+ "scripts": {
7
+ "start": "node server.js",
8
+ "dev": "nodemon server.js",
9
+ "seed": "node seed.js"
10
+ },
11
+ "dependencies": {
12
+ "bcryptjs": "^2.4.3",
13
+ "body-parser": "^1.20.2",
14
+ "cors": "^2.8.5",
15
+ "dotenv": "^16.3.1",
16
+ "express": "^4.18.2",
17
+ "express-session": "^1.17.3",
18
+ "mysql2": "^3.6.5"
19
+ },
20
+ "devDependencies": {
21
+ "nodemon": "^3.0.2"
22
+ }
23
+ }
@@ -0,0 +1,29 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+
4
+ router.post('/login', (req, res) => {
5
+ const { username, password } = req.body;
6
+ if (!username || !password) {
7
+ return res.status(400).json({ message: 'Username and password are required' });
8
+ }
9
+ req.session.user = { id: 1, username };
10
+ res.json({ message: 'Login successful', username });
11
+ });
12
+
13
+ router.post('/logout', (req, res) => {
14
+ req.session.destroy((err) => {
15
+ if (err) return res.status(500).json({ message: 'Logout failed' });
16
+ res.clearCookie('connect.sid');
17
+ res.json({ message: 'Logged out successfully' });
18
+ });
19
+ });
20
+
21
+ router.get('/check', (req, res) => {
22
+ if (req.session && req.session.user) {
23
+ res.json({ authenticated: true, username: req.session.user.username });
24
+ } else {
25
+ res.json({ authenticated: false });
26
+ }
27
+ });
28
+
29
+ module.exports = router;
@@ -0,0 +1,51 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const db = require('../config/db');
4
+ const requireAuth = require('../middleware/auth');
5
+
6
+ // Daily StockOut Report
7
+ router.get('/daily-stockout', requireAuth, async (req, res) => {
8
+ const { date } = req.query;
9
+ const reportDate = date || new Date().toISOString().split('T')[0];
10
+ try {
11
+ const [rows] = await db.query(`
12
+ SELECT so.StockOutID, sp.Name AS SparepartName, sp.Category,
13
+ so.StockOutQuantity, so.StockOutUnitPrice, so.StockOutTotalPrice, so.StockOutDate
14
+ FROM Stock_Out so
15
+ JOIN Spare_Part sp ON so.SparePartID = sp.SparePartID
16
+ WHERE DATE(so.StockOutDate) = ?
17
+ ORDER BY so.StockOutID DESC
18
+ `, [reportDate]);
19
+ res.json(rows);
20
+ } catch (err) {
21
+ console.error(err);
22
+ res.status(500).json({ message: 'Server error' });
23
+ }
24
+ });
25
+
26
+ // Daily Stock Status Report
27
+ router.get('/stock-status', requireAuth, async (req, res) => {
28
+ const { date } = req.query;
29
+ const reportDate = date || new Date().toISOString().split('T')[0];
30
+ try {
31
+ const [rows] = await db.query(`
32
+ SELECT
33
+ sp.SparePartID,
34
+ sp.Name AS SparepartName,
35
+ sp.Category,
36
+ sp.Quantity + COALESCE(SUM(CASE WHEN DATE(so.StockOutDate) = ? THEN so.StockOutQuantity ELSE 0 END), 0) AS StoredQuantity,
37
+ COALESCE(SUM(CASE WHEN DATE(so.StockOutDate) = ? THEN so.StockOutQuantity ELSE 0 END), 0) AS DailyStockOut,
38
+ sp.Quantity AS RemainingQuantity
39
+ FROM Spare_Part sp
40
+ LEFT JOIN Stock_Out so ON sp.SparePartID = so.SparePartID
41
+ GROUP BY sp.SparePartID, sp.Name, sp.Category, sp.Quantity
42
+ ORDER BY sp.Name
43
+ `, [reportDate, reportDate]);
44
+ res.json(rows);
45
+ } catch (err) {
46
+ console.error(err);
47
+ res.status(500).json({ message: 'Server error' });
48
+ }
49
+ });
50
+
51
+ module.exports = router;
@@ -0,0 +1,34 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const db = require('../config/db');
4
+ const requireAuth = require('../middleware/auth');
5
+
6
+ router.get('/', requireAuth, async (req, res) => {
7
+ try {
8
+ const [rows] = await db.query('SELECT * FROM Spare_Part ORDER BY CreatedAt DESC');
9
+ res.json(rows);
10
+ } catch (err) {
11
+ console.error(err);
12
+ res.status(500).json({ message: 'Server error' });
13
+ }
14
+ });
15
+
16
+ router.post('/', requireAuth, async (req, res) => {
17
+ const { Name, Category, Quantity, UnitPrice } = req.body;
18
+ if (!Name || !Category || !Quantity || !UnitPrice) {
19
+ return res.status(400).json({ message: 'All fields are required' });
20
+ }
21
+ const TotalPrice = parseFloat(Quantity) * parseFloat(UnitPrice);
22
+ try {
23
+ const [result] = await db.query(
24
+ 'INSERT INTO Spare_Part (Name, Category, Quantity, UnitPrice, TotalPrice) VALUES (?, ?, ?, ?, ?)',
25
+ [Name, Category, parseInt(Quantity), parseFloat(UnitPrice), TotalPrice]
26
+ );
27
+ res.status(201).json({ message: 'Spare part added successfully', id: result.insertId });
28
+ } catch (err) {
29
+ console.error(err);
30
+ res.status(500).json({ message: 'Server error' });
31
+ }
32
+ });
33
+
34
+ module.exports = router;
@@ -0,0 +1,53 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const db = require('../config/db');
4
+ const requireAuth = require('../middleware/auth');
5
+
6
+ router.get('/', requireAuth, async (req, res) => {
7
+ try {
8
+ const [rows] = await db.query(`
9
+ SELECT si.StockInID, si.SparePartID, si.StockInQuantity, si.StockInDate,
10
+ sp.Name AS SparepartName, sp.Category
11
+ FROM Stock_In si
12
+ JOIN Spare_Part sp ON si.SparePartID = sp.SparePartID
13
+ ORDER BY si.StockInDate DESC, si.StockInID DESC
14
+ `);
15
+ res.json(rows);
16
+ } catch (err) {
17
+ console.error(err);
18
+ res.status(500).json({ message: 'Server error' });
19
+ }
20
+ });
21
+
22
+ router.post('/', requireAuth, async (req, res) => {
23
+ const { SparePartID, StockInQuantity, StockInDate } = req.body;
24
+ if (!SparePartID || !StockInQuantity || !StockInDate) {
25
+ return res.status(400).json({ message: 'All fields are required' });
26
+ }
27
+ const conn = await db.getConnection();
28
+ try {
29
+ await conn.beginTransaction();
30
+ await conn.query(
31
+ 'INSERT INTO Stock_In (SparePartID, StockInQuantity, StockInDate) VALUES (?, ?, ?)',
32
+ [SparePartID, parseInt(StockInQuantity), StockInDate]
33
+ );
34
+ await conn.query(
35
+ 'UPDATE Spare_Part SET Quantity = Quantity + ? WHERE SparePartID = ?',
36
+ [parseInt(StockInQuantity), SparePartID]
37
+ );
38
+ await conn.query(
39
+ 'UPDATE Spare_Part SET TotalPrice = Quantity * UnitPrice WHERE SparePartID = ?',
40
+ [SparePartID]
41
+ );
42
+ await conn.commit();
43
+ res.status(201).json({ message: 'Stock in recorded successfully' });
44
+ } catch (err) {
45
+ await conn.rollback();
46
+ console.error(err);
47
+ res.status(500).json({ message: 'Server error' });
48
+ } finally {
49
+ conn.release();
50
+ }
51
+ });
52
+
53
+ module.exports = router;
@@ -0,0 +1,146 @@
1
+ const express = require('express');
2
+ const router = express.Router();
3
+ const db = require('../config/db');
4
+ const requireAuth = require('../middleware/auth');
5
+
6
+ router.get('/', requireAuth, async (req, res) => {
7
+ try {
8
+ const [rows] = await db.query(`
9
+ SELECT so.StockOutID, so.SparePartID, so.StockOutQuantity,
10
+ so.StockOutUnitPrice, so.StockOutTotalPrice, so.StockOutDate,
11
+ sp.Name AS SparepartName, sp.Category
12
+ FROM Stock_Out so
13
+ JOIN Spare_Part sp ON so.SparePartID = sp.SparePartID
14
+ ORDER BY so.StockOutDate DESC, so.StockOutID DESC
15
+ `);
16
+ res.json(rows);
17
+ } catch (err) {
18
+ console.error(err);
19
+ res.status(500).json({ message: 'Server error' });
20
+ }
21
+ });
22
+
23
+ router.post('/', requireAuth, async (req, res) => {
24
+ const { SparePartID, StockOutQuantity, StockOutUnitPrice, StockOutDate } = req.body;
25
+ if (!SparePartID || !StockOutQuantity || !StockOutUnitPrice || !StockOutDate) {
26
+ return res.status(400).json({ message: 'All fields are required' });
27
+ }
28
+ const StockOutTotalPrice = parseFloat(StockOutQuantity) * parseFloat(StockOutUnitPrice);
29
+ const conn = await db.getConnection();
30
+ try {
31
+ await conn.beginTransaction();
32
+ const [parts] = await conn.query('SELECT Quantity FROM Spare_Part WHERE SparePartID = ?', [SparePartID]);
33
+ if (parts.length === 0) {
34
+ await conn.rollback();
35
+ return res.status(404).json({ message: 'Spare part not found' });
36
+ }
37
+ if (parts[0].Quantity < parseInt(StockOutQuantity)) {
38
+ await conn.rollback();
39
+ return res.status(400).json({ message: `Insufficient stock. Available: ${parts[0].Quantity}` });
40
+ }
41
+ await conn.query(
42
+ 'INSERT INTO Stock_Out (SparePartID, StockOutQuantity, StockOutUnitPrice, StockOutTotalPrice, StockOutDate) VALUES (?, ?, ?, ?, ?)',
43
+ [SparePartID, parseInt(StockOutQuantity), parseFloat(StockOutUnitPrice), StockOutTotalPrice, StockOutDate]
44
+ );
45
+ await conn.query(
46
+ 'UPDATE Spare_Part SET Quantity = Quantity - ? WHERE SparePartID = ?',
47
+ [parseInt(StockOutQuantity), SparePartID]
48
+ );
49
+ await conn.query(
50
+ 'UPDATE Spare_Part SET TotalPrice = Quantity * UnitPrice WHERE SparePartID = ?',
51
+ [SparePartID]
52
+ );
53
+ await conn.commit();
54
+ res.status(201).json({ message: 'Stock out recorded successfully' });
55
+ } catch (err) {
56
+ await conn.rollback();
57
+ console.error(err);
58
+ res.status(500).json({ message: 'Server error' });
59
+ } finally {
60
+ conn.release();
61
+ }
62
+ });
63
+
64
+ router.put('/:id', requireAuth, async (req, res) => {
65
+ const { id } = req.params;
66
+ const { SparePartID, StockOutQuantity, StockOutUnitPrice, StockOutDate } = req.body;
67
+ if (!SparePartID || !StockOutQuantity || !StockOutUnitPrice || !StockOutDate) {
68
+ return res.status(400).json({ message: 'All fields are required' });
69
+ }
70
+ const StockOutTotalPrice = parseFloat(StockOutQuantity) * parseFloat(StockOutUnitPrice);
71
+ const conn = await db.getConnection();
72
+ try {
73
+ await conn.beginTransaction();
74
+ const [old] = await conn.query('SELECT * FROM Stock_Out WHERE StockOutID = ?', [id]);
75
+ if (old.length === 0) {
76
+ await conn.rollback();
77
+ return res.status(404).json({ message: 'Record not found' });
78
+ }
79
+ const oldRecord = old[0];
80
+ // Restore old quantity to the original spare part
81
+ await conn.query(
82
+ 'UPDATE Spare_Part SET Quantity = Quantity + ? WHERE SparePartID = ?',
83
+ [oldRecord.StockOutQuantity, oldRecord.SparePartID]
84
+ );
85
+ // Check availability for new record
86
+ const [parts] = await conn.query('SELECT Quantity FROM Spare_Part WHERE SparePartID = ?', [SparePartID]);
87
+ if (parts.length === 0 || parts[0].Quantity < parseInt(StockOutQuantity)) {
88
+ await conn.rollback();
89
+ const available = parts.length > 0 ? parts[0].Quantity : 0;
90
+ return res.status(400).json({ message: `Insufficient stock. Available: ${available}` });
91
+ }
92
+ await conn.query(
93
+ 'UPDATE Stock_Out SET SparePartID=?, StockOutQuantity=?, StockOutUnitPrice=?, StockOutTotalPrice=?, StockOutDate=? WHERE StockOutID=?',
94
+ [SparePartID, parseInt(StockOutQuantity), parseFloat(StockOutUnitPrice), StockOutTotalPrice, StockOutDate, id]
95
+ );
96
+ await conn.query(
97
+ 'UPDATE Spare_Part SET Quantity = Quantity - ? WHERE SparePartID = ?',
98
+ [parseInt(StockOutQuantity), SparePartID]
99
+ );
100
+ await conn.query(
101
+ 'UPDATE Spare_Part SET TotalPrice = Quantity * UnitPrice WHERE SparePartID = ?',
102
+ [SparePartID]
103
+ );
104
+ await conn.commit();
105
+ res.json({ message: 'Stock out updated successfully' });
106
+ } catch (err) {
107
+ await conn.rollback();
108
+ console.error(err);
109
+ res.status(500).json({ message: 'Server error' });
110
+ } finally {
111
+ conn.release();
112
+ }
113
+ });
114
+
115
+ router.delete('/:id', requireAuth, async (req, res) => {
116
+ const { id } = req.params;
117
+ const conn = await db.getConnection();
118
+ try {
119
+ await conn.beginTransaction();
120
+ const [old] = await conn.query('SELECT * FROM Stock_Out WHERE StockOutID = ?', [id]);
121
+ if (old.length === 0) {
122
+ await conn.rollback();
123
+ return res.status(404).json({ message: 'Record not found' });
124
+ }
125
+ const oldRecord = old[0];
126
+ await conn.query(
127
+ 'UPDATE Spare_Part SET Quantity = Quantity + ? WHERE SparePartID = ?',
128
+ [oldRecord.StockOutQuantity, oldRecord.SparePartID]
129
+ );
130
+ await conn.query(
131
+ 'UPDATE Spare_Part SET TotalPrice = Quantity * UnitPrice WHERE SparePartID = ?',
132
+ [oldRecord.SparePartID]
133
+ );
134
+ await conn.query('DELETE FROM Stock_Out WHERE StockOutID = ?', [id]);
135
+ await conn.commit();
136
+ res.json({ message: 'Stock out deleted successfully' });
137
+ } catch (err) {
138
+ await conn.rollback();
139
+ console.error(err);
140
+ res.status(500).json({ message: 'Server error' });
141
+ } finally {
142
+ conn.release();
143
+ }
144
+ });
145
+
146
+ module.exports = router;
@@ -0,0 +1,20 @@
1
+ require('dotenv').config();
2
+ const bcrypt = require('bcryptjs');
3
+ const db = require('./config/db');
4
+
5
+ async function seed() {
6
+ try {
7
+ const hashedPassword = await bcrypt.hash('admin123', 10);
8
+ await db.query(
9
+ 'INSERT IGNORE INTO Users (Username, Password) VALUES (?, ?)',
10
+ ['admin', hashedPassword]
11
+ );
12
+ console.log('Default admin user created: admin / admin123');
13
+ process.exit(0);
14
+ } catch (err) {
15
+ console.error('Seed failed:', err.message);
16
+ process.exit(1);
17
+ }
18
+ }
19
+
20
+ seed();
@@ -0,0 +1,43 @@
1
+ const express = require('express');
2
+ const cors = require('cors');
3
+ const session = require('express-session');
4
+ const bodyParser = require('body-parser');
5
+ require('dotenv').config();
6
+
7
+ const authRoutes = require('./routes/auth');
8
+ const sparePartRoutes = require('./routes/spareParts');
9
+ const stockInRoutes = require('./routes/stockIn');
10
+ const stockOutRoutes = require('./routes/stockOut');
11
+ const reportRoutes = require('./routes/reports');
12
+
13
+ const app = express();
14
+
15
+ app.use(cors({
16
+ origin: 'http://localhost:5173',
17
+ credentials: true
18
+ }));
19
+
20
+ app.use(bodyParser.json());
21
+ app.use(bodyParser.urlencoded({ extended: true }));
22
+
23
+ app.use(session({
24
+ secret: process.env.SESSION_SECRET || 'sims-secret-key',
25
+ resave: false,
26
+ saveUninitialized: false,
27
+ cookie: {
28
+ secure: false,
29
+ httpOnly: true,
30
+ maxAge: 24 * 60 * 60 * 1000
31
+ }
32
+ }));
33
+
34
+ app.use('/api/auth', authRoutes);
35
+ app.use('/api/spare-parts', sparePartRoutes);
36
+ app.use('/api/stock-in', stockInRoutes);
37
+ app.use('/api/stock-out', stockOutRoutes);
38
+ app.use('/api/reports', reportRoutes);
39
+
40
+ const PORT = process.env.PORT || 5000;
41
+ app.listen(PORT, () => {
42
+ console.log(`SIMS Backend running on http://localhost:${PORT}`);
43
+ });
@@ -0,0 +1,43 @@
1
+ -- SIMS Database Setup
2
+ -- SmartPark Stock Inventory Management System
3
+
4
+ CREATE DATABASE IF NOT EXISTS SIMS;
5
+ USE SIMS;
6
+
7
+ CREATE TABLE IF NOT EXISTS Users (
8
+ UserID INT AUTO_INCREMENT PRIMARY KEY,
9
+ Username VARCHAR(50) NOT NULL UNIQUE,
10
+ Password VARCHAR(255) NOT NULL,
11
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
12
+ );
13
+
14
+ CREATE TABLE IF NOT EXISTS Spare_Part (
15
+ SparePartID INT AUTO_INCREMENT PRIMARY KEY,
16
+ Name VARCHAR(100) NOT NULL,
17
+ Category VARCHAR(50) NOT NULL,
18
+ Quantity INT NOT NULL DEFAULT 0,
19
+ UnitPrice DECIMAL(10, 2) NOT NULL,
20
+ TotalPrice DECIMAL(10, 2) GENERATED ALWAYS AS (Quantity * UnitPrice) STORED,
21
+ CreatedAt TIMESTAMP DEFAULT CURRENT_TIMESTAMP
22
+ );
23
+
24
+ CREATE TABLE IF NOT EXISTS Stock_In (
25
+ StockInID INT AUTO_INCREMENT PRIMARY KEY,
26
+ SparePartID INT NOT NULL,
27
+ StockInQuantity INT NOT NULL,
28
+ StockInDate DATE NOT NULL,
29
+ FOREIGN KEY (SparePartID) REFERENCES Spare_Part(SparePartID) ON DELETE CASCADE
30
+ );
31
+
32
+ CREATE TABLE IF NOT EXISTS Stock_Out (
33
+ StockOutID INT AUTO_INCREMENT PRIMARY KEY,
34
+ SparePartID INT NOT NULL,
35
+ StockOutQuantity INT NOT NULL,
36
+ StockOutUnitPrice DECIMAL(10, 2) NOT NULL,
37
+ StockOutTotalPrice DECIMAL(10, 2) NOT NULL,
38
+ StockOutDate DATE NOT NULL,
39
+ FOREIGN KEY (SparePartID) REFERENCES Spare_Part(SparePartID) ON DELETE CASCADE
40
+ );
41
+
42
+ -- Run `npm run seed` in backend-project to create default admin user
43
+ -- Default login: admin / admin123
@@ -0,0 +1,12 @@
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>SIMS - SmartPark Stock Inventory</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.jsx"></script>
11
+ </body>
12
+ </html>