create-jinmankn-app 1.0.11 → 1.0.13

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 (89) hide show
  1. package/package.json +1 -1
  2. package/templates/EPMS(Employee Payroll Managment System)/backend/routes/protectedRoutes.js +10 -0
  3. package/templates/EPMS(Employee Payroll Managment System)/backend/server.js +2 -0
  4. package/templates/EPMS(Employee Payroll Managment System)/frontend/src/App.jsx +2 -1
  5. package/templates/EPMS(Employee Payroll Managment System)/frontend/src/components/ProtectedRoute.jsx +8 -0
  6. package/templates/EPMS(Employee Payroll Managment System)/package-lock.json +13 -0
  7. package/templates/Faisal Hospital Managment System (FHMS) mysql/backend/routes/secureRoutes.js +14 -0
  8. package/templates/Faisal Hospital Managment System (FHMS) mysql/backend/server.js +2 -0
  9. package/templates/Faisal Hospital Managment System (FHMS) mysql/frontend/src/components/ProtectedRoute.jsx +2 -3
  10. package/templates/Faisal Hospital Managment System (FHMS) mysql/frontend/src/utils/auth.js +13 -0
  11. package/templates/LMS(Library Managment System)/backend/controllers/authController.js +32 -0
  12. package/templates/LMS(Library Managment System)/backend/routes/authRoutes.js +2 -1
  13. package/templates/LMS(Library Managment System)/backend/routes/protectedRoutes.js +19 -0
  14. package/templates/LMS(Library Managment System)/backend/server.js +2 -0
  15. package/templates/LMS(Library Managment System)/frontend/src/App.jsx +74 -15
  16. package/templates/LMS(Library Managment System)/frontend/src/ProtectedRoute.jsx +13 -0
  17. package/templates/LMS(Library Managment System)/frontend/src/pages/Login.jsx +4 -1
  18. package/templates/LMS(Library Managment System)/frontend/src/pages/Register.jsx +87 -0
  19. package/templates/SCMS(Supply Chain Managment System)/backend/routes/protectedRoutes.js +10 -0
  20. package/templates/SCMS(Supply Chain Managment System)/backend/server.js +2 -0
  21. package/templates/SCMS(Supply Chain Managment System)/frontend/src/App.jsx +2 -1
  22. package/templates/SCMS(Supply Chain Managment System)/frontend/src/components/ProtectedRoute.jsx +30 -0
  23. package/templates/SFM(School Fee Managment)/backend/middleware/protectedRoutes.js +10 -0
  24. package/templates/SFM(School Fee Managment)/frontend/src/App.jsx +7 -5
  25. package/templates/SFM(School Fee Managment)/frontend/src/components/ProtectedRoute.jsx +13 -0
  26. package/templates/SIMS(Stock Inventory Managment System)/backend/controllers/protectedController.js +14 -0
  27. package/templates/SIMS(Stock Inventory Managment System)/backend/routes/protectedRoutes.js +10 -0
  28. package/templates/SIMS(Stock Inventory Managment System)/backend/server.js +2 -1
  29. package/templates/SIMS(Stock Inventory Managment System)/frontend/src/App.jsx +57 -7
  30. package/templates/SIMS(Stock Inventory Managment System)/frontend/src/components/ProtectedRoute.jsx +8 -0
  31. package/templates/SMS(Stock Managment System)/backend-project/routes/protectedRoutes.js +18 -0
  32. package/templates/SMS(Stock Managment System)/backend-project/server.js +3 -1
  33. package/templates/SMS(Stock Managment System)/frontend-project/src/App.jsx +36 -7
  34. package/templates/SMS(Stock Managment System)/frontend-project/src/components/AppLayout.jsx +1 -1
  35. package/templates/SMS(Stock Managment System)/frontend-project/src/components/ProtectedRoute.jsx +13 -0
  36. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Login.jsx +1 -1
  37. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Product.jsx +211 -78
  38. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Profile.jsx +1 -1
  39. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Register.jsx +1 -1
  40. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Reports.jsx +1 -1
  41. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Sales.jsx +6 -6
  42. package/templates/SMS(Stock Managment System)/frontend-project/src/pages/Warehouse.jsx +150 -44
  43. package/templates/SMS(Stock Managment System)/package-lock.json +13 -0
  44. package/templates/SRMS(Sales Record Management System)/backend/routes/protectedRoutes.js +13 -0
  45. package/templates/SRMS(Sales Record Management System)/backend/server.js +2 -0
  46. package/templates/SRMS(Sales Record Management System)/frontend/src/App.jsx +2 -1
  47. package/templates/SRMS(Sales Record Management System)/frontend/src/components/ProtectedRoute.jsx +22 -0
  48. package/templates/index/README.md +34 -0
  49. package/templates/index/backend/config/db.js +12 -0
  50. package/templates/index/backend/controllers/authController.js +88 -0
  51. package/templates/index/backend/controllers/departmentController.js +74 -0
  52. package/templates/index/backend/controllers/employeeController.js +204 -0
  53. package/templates/index/backend/controllers/positionController.js +78 -0
  54. package/templates/index/backend/controllers/reportController.js +45 -0
  55. package/templates/index/backend/middleware/auth.js +27 -0
  56. package/templates/index/backend/models/Department.js +15 -0
  57. package/templates/index/backend/models/Employee.js +73 -0
  58. package/templates/index/backend/models/Position.js +20 -0
  59. package/templates/index/backend/models/User.js +32 -0
  60. package/templates/index/backend/package-lock.json +2190 -0
  61. package/templates/index/backend/package.json +22 -0
  62. package/templates/index/backend/routes/authRoutes.js +11 -0
  63. package/templates/index/backend/routes/departmentRoutes.js +17 -0
  64. package/templates/index/backend/routes/employeeRoutes.js +19 -0
  65. package/templates/index/backend/routes/positionRoutes.js +17 -0
  66. package/templates/index/backend/routes/protectedRoutes.js +10 -0
  67. package/templates/index/backend/routes/reportRoutes.js +9 -0
  68. package/templates/index/backend/server.js +30 -0
  69. package/templates/index/frontend/README.md +16 -0
  70. package/templates/index/frontend/eslint.config.js +21 -0
  71. package/templates/index/frontend/index.html +13 -0
  72. package/templates/index/frontend/package-lock.json +3095 -0
  73. package/templates/index/frontend/package.json +31 -0
  74. package/templates/index/frontend/public/favicon.svg +1 -0
  75. package/templates/index/frontend/src/App.css +0 -0
  76. package/templates/index/frontend/src/App.jsx +35 -0
  77. package/templates/index/frontend/src/assets/hero.png +0 -0
  78. package/templates/index/frontend/src/components/DashboardLayout.jsx +90 -0
  79. package/templates/index/frontend/src/components/ProtectedRoute.jsx +9 -0
  80. package/templates/index/frontend/src/index.css +59 -0
  81. package/templates/index/frontend/src/main.jsx +11 -0
  82. package/templates/index/frontend/src/pages/DashboardHome.jsx +58 -0
  83. package/templates/index/frontend/src/pages/Department.jsx +150 -0
  84. package/templates/index/frontend/src/pages/Employee.jsx +366 -0
  85. package/templates/index/frontend/src/pages/Login.jsx +81 -0
  86. package/templates/index/frontend/src/pages/Position.jsx +169 -0
  87. package/templates/index/frontend/src/pages/Register.jsx +102 -0
  88. package/templates/index/frontend/src/pages/Reports.jsx +94 -0
  89. package/templates/index/frontend/vite.config.js +7 -0
@@ -0,0 +1,204 @@
1
+ const Employee = require('../models/Employee');
2
+ const Department = require('../models/Department');
3
+ const Position = require('../models/Position');
4
+ const User = require('../models/User');
5
+
6
+ exports.addEmployee = async (req, res) => {
7
+ try {
8
+ const {
9
+ userName,
10
+ firstName,
11
+ lastName,
12
+ email,
13
+ gender,
14
+ dateOfBirth,
15
+ telephone,
16
+ address,
17
+ hireDate,
18
+ status,
19
+ department,
20
+ position,
21
+ } = req.body;
22
+
23
+ if (
24
+ !firstName ||
25
+ !lastName ||
26
+ !email ||
27
+ !gender ||
28
+ !dateOfBirth ||
29
+ !telephone ||
30
+ !address ||
31
+ !hireDate ||
32
+ !status ||
33
+ !department ||
34
+ !position
35
+ ) {
36
+ return res.status(400).json({ message: 'All employee fields are required' });
37
+ }
38
+
39
+ const existing = await Employee.findOne({ email: email.toLowerCase() });
40
+ if (existing) {
41
+ return res.status(409).json({ message: 'Employee email already exists' });
42
+ }
43
+
44
+ const departmentExists = await Department.findById(department);
45
+ if (!departmentExists) {
46
+ return res.status(404).json({ message: 'Department not found' });
47
+ }
48
+
49
+ const positionExists = await Position.findById(position);
50
+ if (!positionExists) {
51
+ return res.status(404).json({ message: 'Position not found' });
52
+ }
53
+
54
+ const employee = await Employee.create({
55
+ userName,
56
+ firstName: firstName.trim(),
57
+ lastName: lastName.trim(),
58
+ email: email.toLowerCase(),
59
+ gender,
60
+ dateOfBirth,
61
+ telephone: telephone.trim(),
62
+ address: address.trim(),
63
+ hireDate,
64
+ status,
65
+ department,
66
+ position,
67
+ });
68
+
69
+ if (email) {
70
+ const user = await User.findOne({ email: email.toLowerCase() });
71
+ if (user) {
72
+ user.employee = employee._id;
73
+ await user.save();
74
+ }
75
+ }
76
+
77
+ res.status(201).json(employee);
78
+ } catch (err) {
79
+ res.status(500).json({ message: err.message });
80
+ }
81
+ };
82
+
83
+ exports.getEmployees = async (req, res) => {
84
+ try {
85
+ const employees = await Employee.find().populate('department position');
86
+ res.json(employees);
87
+ } catch (err) {
88
+ res.status(500).json({ message: err.message });
89
+ }
90
+ };
91
+
92
+ exports.getEmployee = async (req, res) => {
93
+ try {
94
+ const employee = await Employee.findById(req.params.id).populate('department position');
95
+ if (!employee) {
96
+ return res.status(404).json({ message: 'Employee not found' });
97
+ }
98
+ res.json(employee);
99
+ } catch (err) {
100
+ res.status(500).json({ message: err.message });
101
+ }
102
+ };
103
+
104
+ exports.updateEmployee = async (req, res) => {
105
+ try {
106
+ const employee = await Employee.findById(req.params.id);
107
+ if (!employee) {
108
+ return res.status(404).json({ message: 'Employee not found' });
109
+ }
110
+
111
+ const {
112
+ userName,
113
+ firstName,
114
+ lastName,
115
+ email,
116
+ gender,
117
+ dateOfBirth,
118
+ telephone,
119
+ address,
120
+ hireDate,
121
+ status,
122
+ department,
123
+ position,
124
+ } = req.body;
125
+
126
+ if (
127
+ !firstName ||
128
+ !lastName ||
129
+ !email ||
130
+ !gender ||
131
+ !dateOfBirth ||
132
+ !telephone ||
133
+ !address ||
134
+ !hireDate ||
135
+ !status ||
136
+ !department ||
137
+ !position
138
+ ) {
139
+ return res.status(400).json({ message: 'All employee fields are required' });
140
+ }
141
+
142
+ const existing = await Employee.findOne({
143
+ email: email.toLowerCase(),
144
+ _id: { $ne: req.params.id },
145
+ });
146
+ if (existing) {
147
+ return res.status(409).json({ message: 'Employee email already exists' });
148
+ }
149
+
150
+ const departmentExists = await Department.findById(department);
151
+ if (!departmentExists) {
152
+ return res.status(404).json({ message: 'Department not found' });
153
+ }
154
+
155
+ const positionExists = await Position.findById(position);
156
+ if (!positionExists) {
157
+ return res.status(404).json({ message: 'Position not found' });
158
+ }
159
+
160
+ const oldEmail = employee.email;
161
+
162
+ employee.userName = userName;
163
+ employee.firstName = firstName.trim();
164
+ employee.lastName = lastName.trim();
165
+ employee.email = email.toLowerCase();
166
+ employee.gender = gender;
167
+ employee.dateOfBirth = dateOfBirth;
168
+ employee.telephone = telephone.trim();
169
+ employee.address = address.trim();
170
+ employee.hireDate = hireDate;
171
+ employee.status = status;
172
+ employee.department = department;
173
+ employee.position = position;
174
+
175
+ await employee.save();
176
+
177
+ if (oldEmail !== email.toLowerCase()) {
178
+ const user = await User.findOne({ email: oldEmail });
179
+ if (user) {
180
+ user.email = email.toLowerCase();
181
+ await user.save();
182
+ }
183
+ }
184
+
185
+ const updatedEmployee = await Employee.findById(req.params.id).populate('department position');
186
+ res.json(updatedEmployee);
187
+ } catch (err) {
188
+ res.status(500).json({ message: err.message });
189
+ }
190
+ };
191
+
192
+ exports.deleteEmployee = async (req, res) => {
193
+ try {
194
+ const employee = await Employee.findById(req.params.id);
195
+ if (!employee) {
196
+ return res.status(404).json({ message: 'Employee not found' });
197
+ }
198
+
199
+ await Employee.findByIdAndDelete(req.params.id);
200
+ res.json({ message: 'Employee deleted successfully' });
201
+ } catch (err) {
202
+ res.status(500).json({ message: err.message });
203
+ }
204
+ };
@@ -0,0 +1,78 @@
1
+ const Position = require('../models/Position');
2
+
3
+ exports.addPosition = async (req, res) => {
4
+ try {
5
+ const { posName, requiredQualification } = req.body;
6
+
7
+ if (!posName || !requiredQualification) {
8
+ return res.status(400).json({ message: 'Position name and qualification are required' });
9
+ }
10
+
11
+ const existing = await Position.findOne({ posName: posName.trim() });
12
+ if (existing) {
13
+ return res.status(409).json({ message: 'Position already exists' });
14
+ }
15
+
16
+ const position = await Position.create({
17
+ posName: posName.trim(),
18
+ requiredQualification: requiredQualification.trim(),
19
+ });
20
+ res.status(201).json(position);
21
+ } catch (err) {
22
+ res.status(500).json({ message: err.message });
23
+ }
24
+ };
25
+
26
+ exports.getPositions = async (req, res) => {
27
+ try {
28
+ const positions = await Position.find();
29
+ res.json(positions);
30
+ } catch (err) {
31
+ res.status(500).json({ message: err.message });
32
+ }
33
+ };
34
+
35
+ exports.updatePosition = async (req, res) => {
36
+ try {
37
+ const { posName, requiredQualification } = req.body;
38
+
39
+ if (!posName || !requiredQualification) {
40
+ return res.status(400).json({ message: 'Position name and qualification are required' });
41
+ }
42
+
43
+ const position = await Position.findById(req.params.id);
44
+ if (!position) {
45
+ return res.status(404).json({ message: 'Position not found' });
46
+ }
47
+
48
+ const existing = await Position.findOne({
49
+ posName: posName.trim(),
50
+ _id: { $ne: req.params.id },
51
+ });
52
+ if (existing) {
53
+ return res.status(409).json({ message: 'Position already exists' });
54
+ }
55
+
56
+ position.posName = posName.trim();
57
+ position.requiredQualification = requiredQualification.trim();
58
+ await position.save();
59
+
60
+ res.json(position);
61
+ } catch (err) {
62
+ res.status(500).json({ message: err.message });
63
+ }
64
+ };
65
+
66
+ exports.deletePosition = async (req, res) => {
67
+ try {
68
+ const position = await Position.findById(req.params.id);
69
+ if (!position) {
70
+ return res.status(404).json({ message: 'Position not found' });
71
+ }
72
+
73
+ await Position.findByIdAndDelete(req.params.id);
74
+ res.json({ message: 'Position deleted successfully' });
75
+ } catch (err) {
76
+ res.status(500).json({ message: err.message });
77
+ }
78
+ };
@@ -0,0 +1,45 @@
1
+ const Employee = require('../models/Employee');
2
+
3
+ const ON_LEAVE_STATUS = 'on leave';
4
+
5
+ exports.getOnLeaveByDepartment = async (req, res) => {
6
+ try {
7
+ const onLeaveEmployees = await Employee.find({ status: ON_LEAVE_STATUS })
8
+ .populate('department position')
9
+ .sort({ lastName: 1, firstName: 1 });
10
+
11
+ const byDepartment = {};
12
+
13
+ onLeaveEmployees.forEach((employee) => {
14
+ const deptName = employee.department?.departmentName || 'Unassigned';
15
+ if (!byDepartment[deptName]) {
16
+ byDepartment[deptName] = [];
17
+ }
18
+ byDepartment[deptName].push({
19
+ id: employee._id,
20
+ firstName: employee.firstName,
21
+ lastName: employee.lastName,
22
+ email: employee.email,
23
+ telephone: employee.telephone,
24
+ position: employee.position?.posName || 'N/A',
25
+ status: employee.status,
26
+ });
27
+ });
28
+
29
+ const departments = Object.keys(byDepartment)
30
+ .sort()
31
+ .map((departmentName) => ({
32
+ departmentName,
33
+ employees: byDepartment[departmentName],
34
+ count: byDepartment[departmentName].length,
35
+ }));
36
+
37
+ res.json({
38
+ reportTitle: 'Employee Status Report — On Leave',
39
+ totalOnLeave: onLeaveEmployees.length,
40
+ departments,
41
+ });
42
+ } catch (err) {
43
+ res.status(500).json({ message: err.message });
44
+ }
45
+ };
@@ -0,0 +1,27 @@
1
+
2
+ const jwt = require('jsonwebtoken');
3
+ const User = require('../models/User');
4
+ const JWT_SECRET = 'change_this_to_a_long_random_secret';
5
+
6
+ exports.protect = async (req, res, next) => {
7
+ try {
8
+ const header = req.headers.authorization;
9
+
10
+ if (!header || !header.startsWith('Bearer ')) {
11
+ return res.status(401).json({ message: 'Not authorized' });
12
+ }
13
+
14
+ const token = header.split(' ')[1];
15
+ const decoded = jwt.verify(token, JWT_SECRET);
16
+ const user = await User.findById(decoded.userId).select('-password');
17
+
18
+ if (!user) {
19
+ return res.status(401).json({ message: 'Not authorized' });
20
+ }
21
+
22
+ req.user = user;
23
+ next();
24
+ } catch (err) {
25
+ return res.status(401).json({ message: 'Not authorized' });
26
+ }
27
+ };
@@ -0,0 +1,15 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const departmentSchema = new mongoose.Schema(
4
+ {
5
+ departmentName: {
6
+ type: String,
7
+ required: true,
8
+ unique: true,
9
+ trim: true,
10
+ },
11
+ },
12
+ { timestamps: true }
13
+ );
14
+
15
+ module.exports = mongoose.model('Department', departmentSchema);
@@ -0,0 +1,73 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const EMPLOYEE_STATUSES = ['on leave', 'left', 'blacklisted', 'deceased', 'on mission'];
4
+
5
+ const employeeSchema = new mongoose.Schema(
6
+ {
7
+ userName: {
8
+ type: String,
9
+ trim: true,
10
+ },
11
+ firstName: {
12
+ type: String,
13
+ required: true,
14
+ trim: true,
15
+ },
16
+ lastName: {
17
+ type: String,
18
+ required: true,
19
+ trim: true,
20
+ },
21
+ email: {
22
+ type: String,
23
+ required: true,
24
+ unique: true,
25
+ lowercase: true,
26
+ trim: true,
27
+ },
28
+ gender: {
29
+ type: String,
30
+ required: true,
31
+ trim: true,
32
+ },
33
+ dateOfBirth: {
34
+ type: Date,
35
+ required: true,
36
+ },
37
+ telephone: {
38
+ type: String,
39
+ required: true,
40
+ trim: true,
41
+ },
42
+ address: {
43
+ type: String,
44
+ required: true,
45
+ trim: true,
46
+ },
47
+ hireDate: {
48
+ type: Date,
49
+ required: true,
50
+ },
51
+ status: {
52
+ type: String,
53
+ required: true,
54
+ enum: EMPLOYEE_STATUSES,
55
+ default: 'on mission',
56
+ },
57
+ department: {
58
+ type: mongoose.Schema.Types.ObjectId,
59
+ ref: 'Department',
60
+ required: true,
61
+ },
62
+ position: {
63
+ type: mongoose.Schema.Types.ObjectId,
64
+ ref: 'Position',
65
+ required: true,
66
+ },
67
+ },
68
+ { timestamps: true }
69
+ );
70
+
71
+ employeeSchema.statics.STATUSES = EMPLOYEE_STATUSES;
72
+
73
+ module.exports = mongoose.model('Employee', employeeSchema);
@@ -0,0 +1,20 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const positionSchema = new mongoose.Schema(
4
+ {
5
+ posName: {
6
+ type: String,
7
+ required: true,
8
+ unique: true,
9
+ trim: true,
10
+ },
11
+ requiredQualification: {
12
+ type: String,
13
+ required: true,
14
+ trim: true,
15
+ },
16
+ },
17
+ { timestamps: true }
18
+ );
19
+
20
+ module.exports = mongoose.model('Position', positionSchema);
@@ -0,0 +1,32 @@
1
+ const mongoose = require('mongoose');
2
+
3
+ const userSchema = new mongoose.Schema(
4
+ {
5
+ name: {
6
+ type: String,
7
+ required: true,
8
+ trim: true,
9
+ },
10
+ email: {
11
+ type: String,
12
+ required: true,
13
+ unique: true,
14
+ lowercase: true,
15
+ trim: true,
16
+ },
17
+ password: {
18
+ type: String,
19
+ required: true,
20
+ minlength: 6,
21
+ },
22
+ employee: {
23
+ type: mongoose.Schema.Types.ObjectId,
24
+ ref: 'Employee',
25
+ },
26
+ },
27
+ { timestamps: true }
28
+ );
29
+
30
+ const User = mongoose.model('User', userSchema);
31
+
32
+ module.exports = User;