create-ishvexa-app 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.
- package/index.js +62 -0
- package/package.json +14 -0
- package/templates/epms-app/.env +7 -0
- package/templates/epms-app/README.md +113 -0
- package/templates/epms-app/backend-mongodb/.env +3 -0
- package/templates/epms-app/backend-mongodb/.env.example +3 -0
- package/templates/epms-app/backend-mongodb/config/db.js +29 -0
- package/templates/epms-app/backend-mongodb/controllers/authController.js +93 -0
- package/templates/epms-app/backend-mongodb/controllers/departmentController.js +24 -0
- package/templates/epms-app/backend-mongodb/controllers/employeeController.js +39 -0
- package/templates/epms-app/backend-mongodb/controllers/reportController.js +57 -0
- package/templates/epms-app/backend-mongodb/controllers/salaryController.js +101 -0
- package/templates/epms-app/backend-mongodb/middleware/auth.js +16 -0
- package/templates/epms-app/backend-mongodb/models/Counter.js +13 -0
- package/templates/epms-app/backend-mongodb/models/Department.js +11 -0
- package/templates/epms-app/backend-mongodb/models/Employee.js +18 -0
- package/templates/epms-app/backend-mongodb/models/Salary.js +19 -0
- package/templates/epms-app/backend-mongodb/models/User.js +9 -0
- package/templates/epms-app/backend-mongodb/package-lock.json +1571 -0
- package/templates/epms-app/backend-mongodb/package.json +22 -0
- package/templates/epms-app/backend-mongodb/routes/authRoutes.js +8 -0
- package/templates/epms-app/backend-mongodb/routes/departmentRoutes.js +6 -0
- package/templates/epms-app/backend-mongodb/routes/employeeRoutes.js +6 -0
- package/templates/epms-app/backend-mongodb/routes/reportRoutes.js +5 -0
- package/templates/epms-app/backend-mongodb/routes/salaryRoutes.js +8 -0
- package/templates/epms-app/backend-mongodb/server.js +39 -0
- package/templates/epms-app/backend-mysql/.env +7 -0
- package/templates/epms-app/backend-mysql/.env.example +7 -0
- package/templates/epms-app/backend-mysql/config/db.js +33 -0
- package/templates/epms-app/backend-mysql/controllers/authController.js +98 -0
- package/templates/epms-app/backend-mysql/controllers/departmentController.js +25 -0
- package/templates/epms-app/backend-mysql/controllers/employeeController.js +39 -0
- package/templates/epms-app/backend-mysql/controllers/reportController.js +41 -0
- package/templates/epms-app/backend-mysql/controllers/salaryController.js +93 -0
- package/templates/epms-app/backend-mysql/database/schema.sql +7 -0
- package/templates/epms-app/backend-mysql/middleware/auth.js +16 -0
- package/templates/epms-app/backend-mysql/package-lock.json +1486 -0
- package/templates/epms-app/backend-mysql/package.json +23 -0
- package/templates/epms-app/backend-mysql/routes/authRoutes.js +8 -0
- package/templates/epms-app/backend-mysql/routes/departmentRoutes.js +6 -0
- package/templates/epms-app/backend-mysql/routes/employeeRoutes.js +6 -0
- package/templates/epms-app/backend-mysql/routes/reportRoutes.js +5 -0
- package/templates/epms-app/backend-mysql/routes/salaryRoutes.js +8 -0
- package/templates/epms-app/backend-mysql/server.js +39 -0
- package/templates/epms-app/frontend/README.md +16 -0
- package/templates/epms-app/frontend/eslint.config.js +21 -0
- package/templates/epms-app/frontend/index.html +12 -0
- package/templates/epms-app/frontend/package-lock.json +3033 -0
- package/templates/epms-app/frontend/package.json +23 -0
- package/templates/epms-app/frontend/public/favicon.svg +1 -0
- package/templates/epms-app/frontend/public/icons.svg +24 -0
- package/templates/epms-app/frontend/src/App.css +184 -0
- package/templates/epms-app/frontend/src/App.jsx +31 -0
- package/templates/epms-app/frontend/src/api/authApi.js +7 -0
- package/templates/epms-app/frontend/src/api/client.js +11 -0
- package/templates/epms-app/frontend/src/api/departmentApi.js +5 -0
- package/templates/epms-app/frontend/src/api/employeeApi.js +4 -0
- package/templates/epms-app/frontend/src/api/reportApi.js +4 -0
- package/templates/epms-app/frontend/src/api/salaryApi.js +6 -0
- package/templates/epms-app/frontend/src/api/sparePartsApi.js +3 -0
- package/templates/epms-app/frontend/src/api/usersApi.js +4 -0
- package/templates/epms-app/frontend/src/assets/hero.png +0 -0
- package/templates/epms-app/frontend/src/assets/react.svg +1 -0
- package/templates/epms-app/frontend/src/assets/vite.svg +1 -0
- package/templates/epms-app/frontend/src/components/AppLayout.jsx +49 -0
- package/templates/epms-app/frontend/src/context/AuthContext.jsx +41 -0
- package/templates/epms-app/frontend/src/hooks/.gitkeep +0 -0
- package/templates/epms-app/frontend/src/index.css +2 -0
- package/templates/epms-app/frontend/src/main.jsx +16 -0
- package/templates/epms-app/frontend/src/pages/DepartmentPage.jsx +165 -0
- package/templates/epms-app/frontend/src/pages/DepartmentsPage.jsx +119 -0
- package/templates/epms-app/frontend/src/pages/EmployeePage.jsx +212 -0
- package/templates/epms-app/frontend/src/pages/EmployeesPage.jsx +217 -0
- package/templates/epms-app/frontend/src/pages/ForgotPassword.jsx +103 -0
- package/templates/epms-app/frontend/src/pages/LoginPage.jsx +105 -0
- package/templates/epms-app/frontend/src/pages/RegisterPage.jsx +84 -0
- package/templates/epms-app/frontend/src/pages/ReportsPage.jsx +192 -0
- package/templates/epms-app/frontend/src/pages/ResetPasswordPage.jsx +83 -0
- package/templates/epms-app/frontend/src/pages/SalariesPage.jsx +274 -0
- package/templates/epms-app/frontend/src/pages/SalaryPage.jsx +254 -0
- package/templates/epms-app/frontend/vite.config.js +8 -0
- package/templates/lms-app/.env +9 -0
- package/templates/lms-app/README.md +89 -0
- package/templates/lms-app/backend-mongodb/.env +5 -0
- package/templates/lms-app/backend-mongodb/.env.example +5 -0
- package/templates/lms-app/backend-mongodb/package-lock.json +1583 -0
- package/templates/lms-app/backend-mongodb/package.json +26 -0
- package/templates/lms-app/backend-mongodb/src/config/db.js +10 -0
- package/templates/lms-app/backend-mongodb/src/config/env.js +28 -0
- package/templates/lms-app/backend-mongodb/src/controllers/authController.js +86 -0
- package/templates/lms-app/backend-mongodb/src/controllers/bookController.js +101 -0
- package/templates/lms-app/backend-mongodb/src/controllers/borrowController.js +106 -0
- package/templates/lms-app/backend-mongodb/src/controllers/dashboardController.js +40 -0
- package/templates/lms-app/backend-mongodb/src/controllers/reportController.js +47 -0
- package/templates/lms-app/backend-mongodb/src/controllers/studentController.js +92 -0
- package/templates/lms-app/backend-mongodb/src/ensureSeedData.js +72 -0
- package/templates/lms-app/backend-mongodb/src/middleware/auth.js +29 -0
- package/templates/lms-app/backend-mongodb/src/models/Book.js +14 -0
- package/templates/lms-app/backend-mongodb/src/models/Borrow.js +16 -0
- package/templates/lms-app/backend-mongodb/src/models/Student.js +14 -0
- package/templates/lms-app/backend-mongodb/src/models/User.js +13 -0
- package/templates/lms-app/backend-mongodb/src/routes/authRoutes.js +12 -0
- package/templates/lms-app/backend-mongodb/src/routes/bookRoutes.js +13 -0
- package/templates/lms-app/backend-mongodb/src/routes/borrowRoutes.js +11 -0
- package/templates/lms-app/backend-mongodb/src/routes/dashboardRoutes.js +9 -0
- package/templates/lms-app/backend-mongodb/src/routes/reportRoutes.js +12 -0
- package/templates/lms-app/backend-mongodb/src/routes/studentRoutes.js +13 -0
- package/templates/lms-app/backend-mongodb/src/seed.js +16 -0
- package/templates/lms-app/backend-mongodb/src/server.js +66 -0
- package/templates/lms-app/backend-mysql/.env +9 -0
- package/templates/lms-app/backend-mysql/.env.example +9 -0
- package/templates/lms-app/backend-mysql/database/schema.sql +45 -0
- package/templates/lms-app/backend-mysql/package-lock.json +1462 -0
- package/templates/lms-app/backend-mysql/package.json +23 -0
- package/templates/lms-app/backend-mysql/src/config/db.js +33 -0
- package/templates/lms-app/backend-mysql/src/config/env.js +21 -0
- package/templates/lms-app/backend-mysql/src/controllers/authController.js +87 -0
- package/templates/lms-app/backend-mysql/src/controllers/bookController.js +106 -0
- package/templates/lms-app/backend-mysql/src/controllers/borrowController.js +113 -0
- package/templates/lms-app/backend-mysql/src/controllers/dashboardController.js +33 -0
- package/templates/lms-app/backend-mysql/src/controllers/reportController.js +40 -0
- package/templates/lms-app/backend-mysql/src/controllers/studentController.js +95 -0
- package/templates/lms-app/backend-mysql/src/ensureSeedData.js +54 -0
- package/templates/lms-app/backend-mysql/src/middleware/auth.js +28 -0
- package/templates/lms-app/backend-mysql/src/routes/authRoutes.js +12 -0
- package/templates/lms-app/backend-mysql/src/routes/bookRoutes.js +13 -0
- package/templates/lms-app/backend-mysql/src/routes/borrowRoutes.js +11 -0
- package/templates/lms-app/backend-mysql/src/routes/dashboardRoutes.js +9 -0
- package/templates/lms-app/backend-mysql/src/routes/reportRoutes.js +12 -0
- package/templates/lms-app/backend-mysql/src/routes/studentRoutes.js +13 -0
- package/templates/lms-app/backend-mysql/src/server.js +69 -0
- package/templates/lms-app/backend-mysql/src/utils/mappers.js +73 -0
- package/templates/lms-app/frontend/.env.example +5 -0
- package/templates/lms-app/frontend/index.html +13 -0
- package/templates/lms-app/frontend/package-lock.json +1592 -0
- package/templates/lms-app/frontend/package.json +23 -0
- package/templates/lms-app/frontend/public/favicon.svg +4 -0
- package/templates/lms-app/frontend/src/App.jsx +107 -0
- package/templates/lms-app/frontend/src/api/authApi.js +5 -0
- package/templates/lms-app/frontend/src/api/booksApi.js +6 -0
- package/templates/lms-app/frontend/src/api/borrowsApi.js +5 -0
- package/templates/lms-app/frontend/src/api/client.js +8 -0
- package/templates/lms-app/frontend/src/api/dashboardApi.js +3 -0
- package/templates/lms-app/frontend/src/api/reportsApi.js +6 -0
- package/templates/lms-app/frontend/src/api/studentsApi.js +6 -0
- package/templates/lms-app/frontend/src/components/AppLayout.jsx +63 -0
- package/templates/lms-app/frontend/src/index.css +34 -0
- package/templates/lms-app/frontend/src/main.jsx +13 -0
- package/templates/lms-app/frontend/src/pages/BooksPage.jsx +206 -0
- package/templates/lms-app/frontend/src/pages/BorrowPage.jsx +134 -0
- package/templates/lms-app/frontend/src/pages/DashboardPage.jsx +42 -0
- package/templates/lms-app/frontend/src/pages/ForgotPassword.jsx +112 -0
- package/templates/lms-app/frontend/src/pages/LoginPage.jsx +71 -0
- package/templates/lms-app/frontend/src/pages/ReportsPage.jsx +176 -0
- package/templates/lms-app/frontend/src/pages/ReturnPage.jsx +75 -0
- package/templates/lms-app/frontend/src/pages/SearchPage.jsx +156 -0
- package/templates/lms-app/frontend/src/pages/StudentsPage.jsx +204 -0
- package/templates/lms-app/frontend/vite.config.js +26 -0
- package/templates/scms-app/.env +7 -0
- package/templates/scms-app/README.md +80 -0
- package/templates/scms-app/backend-mongodb/.env +3 -0
- package/templates/scms-app/backend-mongodb/.env.example +3 -0
- package/templates/scms-app/backend-mongodb/config/db.js +29 -0
- package/templates/scms-app/backend-mongodb/controllers/authController.js +93 -0
- package/templates/scms-app/backend-mongodb/controllers/deliveryController.js +65 -0
- package/templates/scms-app/backend-mongodb/controllers/reportController.js +51 -0
- package/templates/scms-app/backend-mongodb/controllers/shipmentController.js +65 -0
- package/templates/scms-app/backend-mongodb/controllers/supplierController.js +27 -0
- package/templates/scms-app/backend-mongodb/middleware/auth.js +16 -0
- package/templates/scms-app/backend-mongodb/models/Delivery.js +14 -0
- package/templates/scms-app/backend-mongodb/models/Shipment.js +14 -0
- package/templates/scms-app/backend-mongodb/models/Supplier.js +14 -0
- package/templates/scms-app/backend-mongodb/models/User.js +9 -0
- package/templates/scms-app/backend-mongodb/package-lock.json +1571 -0
- package/templates/scms-app/backend-mongodb/package.json +22 -0
- package/templates/scms-app/backend-mongodb/routes/authRoutes.js +8 -0
- package/templates/scms-app/backend-mongodb/routes/deliveryRoutes.js +8 -0
- package/templates/scms-app/backend-mongodb/routes/reportRoutes.js +5 -0
- package/templates/scms-app/backend-mongodb/routes/shipmentRoutes.js +8 -0
- package/templates/scms-app/backend-mongodb/routes/supplierRoutes.js +6 -0
- package/templates/scms-app/backend-mongodb/server.js +39 -0
- package/templates/scms-app/backend-mysql/.env +7 -0
- package/templates/scms-app/backend-mysql/.env.example +7 -0
- package/templates/scms-app/backend-mysql/config/db.js +33 -0
- package/templates/scms-app/backend-mysql/controllers/authController.js +98 -0
- package/templates/scms-app/backend-mysql/controllers/deliveryController.js +62 -0
- package/templates/scms-app/backend-mysql/controllers/reportController.js +39 -0
- package/templates/scms-app/backend-mysql/controllers/shipmentController.js +62 -0
- package/templates/scms-app/backend-mysql/controllers/supplierController.js +28 -0
- package/templates/scms-app/backend-mysql/database/schema.sql +7 -0
- package/templates/scms-app/backend-mysql/middleware/auth.js +16 -0
- package/templates/scms-app/backend-mysql/package-lock.json +1486 -0
- package/templates/scms-app/backend-mysql/package.json +23 -0
- package/templates/scms-app/backend-mysql/routes/authRoutes.js +8 -0
- package/templates/scms-app/backend-mysql/routes/deliveryRoutes.js +8 -0
- package/templates/scms-app/backend-mysql/routes/reportRoutes.js +5 -0
- package/templates/scms-app/backend-mysql/routes/shipmentRoutes.js +8 -0
- package/templates/scms-app/backend-mysql/routes/supplierRoutes.js +6 -0
- package/templates/scms-app/backend-mysql/server.js +39 -0
- package/templates/scms-app/frontend/index.html +12 -0
- package/templates/scms-app/frontend/package-lock.json +1634 -0
- package/templates/scms-app/frontend/package.json +23 -0
- package/templates/scms-app/frontend/src/App.jsx +31 -0
- package/templates/scms-app/frontend/src/api/client.js +11 -0
- package/templates/scms-app/frontend/src/components/AppLayout.jsx +49 -0
- package/templates/scms-app/frontend/src/context/AuthContext.jsx +41 -0
- package/templates/scms-app/frontend/src/hooks/.gitkeep +0 -0
- package/templates/scms-app/frontend/src/index.css +2 -0
- package/templates/scms-app/frontend/src/main.jsx +16 -0
- package/templates/scms-app/frontend/src/pages/DeliveriesPage.jsx +265 -0
- package/templates/scms-app/frontend/src/pages/ForgotPassword.jsx +103 -0
- package/templates/scms-app/frontend/src/pages/LoginPage.jsx +105 -0
- package/templates/scms-app/frontend/src/pages/ReportsPage.jsx +192 -0
- package/templates/scms-app/frontend/src/pages/ShipmentsPage.jsx +259 -0
- package/templates/scms-app/frontend/src/pages/SuppliersPage.jsx +168 -0
- package/templates/scms-app/frontend/vite.config.js +8 -0
- package/templates/sfms-app/.env +7 -0
- package/templates/sfms-app/README.md +72 -0
- package/templates/sfms-app/backend-mongodb/.env +3 -0
- package/templates/sfms-app/backend-mongodb/.env.example +3 -0
- package/templates/sfms-app/backend-mongodb/package-lock.json +1580 -0
- package/templates/sfms-app/backend-mongodb/package.json +23 -0
- package/templates/sfms-app/backend-mongodb/src/config/database.js +7 -0
- package/templates/sfms-app/backend-mongodb/src/config/env.js +35 -0
- package/templates/sfms-app/backend-mongodb/src/middleware/authMiddleware.js +32 -0
- package/templates/sfms-app/backend-mongodb/src/models/Payment.js +12 -0
- package/templates/sfms-app/backend-mongodb/src/models/Student.js +12 -0
- package/templates/sfms-app/backend-mongodb/src/models/User.js +14 -0
- package/templates/sfms-app/backend-mongodb/src/routes/authRoutes.js +140 -0
- package/templates/sfms-app/backend-mongodb/src/routes/paymentRoutes.js +117 -0
- package/templates/sfms-app/backend-mongodb/src/routes/reportRoutes.js +59 -0
- package/templates/sfms-app/backend-mongodb/src/routes/studentRoutes.js +79 -0
- package/templates/sfms-app/backend-mongodb/src/server.js +34 -0
- package/templates/sfms-app/backend-mysql/.env +7 -0
- package/templates/sfms-app/backend-mysql/.env.example +7 -0
- package/templates/sfms-app/backend-mysql/database/schema.sql +29 -0
- package/templates/sfms-app/backend-mysql/package-lock.json +1467 -0
- package/templates/sfms-app/backend-mysql/package.json +24 -0
- package/templates/sfms-app/backend-mysql/src/config/.gitkeep +0 -0
- package/templates/sfms-app/backend-mysql/src/config/db.js +31 -0
- package/templates/sfms-app/backend-mysql/src/config/env.js +20 -0
- package/templates/sfms-app/backend-mysql/src/middleware/.gitkeep +0 -0
- package/templates/sfms-app/backend-mysql/src/middleware/authMiddleware.js +26 -0
- package/templates/sfms-app/backend-mysql/src/models/.gitkeep +0 -0
- package/templates/sfms-app/backend-mysql/src/routes/.gitkeep +0 -0
- package/templates/sfms-app/backend-mysql/src/routes/authRoutes.js +131 -0
- package/templates/sfms-app/backend-mysql/src/routes/paymentRoutes.js +92 -0
- package/templates/sfms-app/backend-mysql/src/routes/reportRoutes.js +41 -0
- package/templates/sfms-app/backend-mysql/src/routes/studentRoutes.js +75 -0
- package/templates/sfms-app/backend-mysql/src/server.js +39 -0
- package/templates/sfms-app/backend-mysql/src/utils/mappers.js +43 -0
- package/templates/sfms-app/frontend/.env.example +9 -0
- package/templates/sfms-app/frontend/index.html +19 -0
- package/templates/sfms-app/frontend/package-lock.json +2667 -0
- package/templates/sfms-app/frontend/package.json +23 -0
- package/templates/sfms-app/frontend/postcss.config.js +6 -0
- package/templates/sfms-app/frontend/public/favicon.svg +4 -0
- package/templates/sfms-app/frontend/src/App.jsx +38 -0
- package/templates/sfms-app/frontend/src/api/apiClient.js +54 -0
- package/templates/sfms-app/frontend/src/components/AppLayout.jsx +61 -0
- package/templates/sfms-app/frontend/src/context/AuthContext.jsx +87 -0
- package/templates/sfms-app/frontend/src/index.css +7 -0
- package/templates/sfms-app/frontend/src/main.jsx +16 -0
- package/templates/sfms-app/frontend/src/pages/DashboardPage.jsx +78 -0
- package/templates/sfms-app/frontend/src/pages/ForgotPassword.jsx +114 -0
- package/templates/sfms-app/frontend/src/pages/LoginPage.jsx +141 -0
- package/templates/sfms-app/frontend/src/pages/PaymentsPage.jsx +309 -0
- package/templates/sfms-app/frontend/src/pages/ReportsPage.jsx +123 -0
- package/templates/sfms-app/frontend/src/pages/StudentsPage.jsx +281 -0
- package/templates/sfms-app/frontend/tailwind.config.js +21 -0
- package/templates/sfms-app/frontend/vite.config.js +61 -0
- package/templates/sims-app/README.md +138 -0
- package/templates/sims-app/backend/.env +4 -0
- package/templates/sims-app/backend/.env.example +4 -0
- package/templates/sims-app/backend/package.json +22 -0
- package/templates/sims-app/backend/src/config/db.js +9 -0
- package/templates/sims-app/backend/src/controllers/authController.js +115 -0
- package/templates/sims-app/backend/src/controllers/simsReportController.js +94 -0
- package/templates/sims-app/backend/src/controllers/sparePartController.js +41 -0
- package/templates/sims-app/backend/src/controllers/stockInController.js +45 -0
- package/templates/sims-app/backend/src/controllers/stockOutController.js +123 -0
- package/templates/sims-app/backend/src/middleware/auth.js +8 -0
- package/templates/sims-app/backend/src/models/SparePart.js +17 -0
- package/templates/sims-app/backend/src/models/StockIn.js +16 -0
- package/templates/sims-app/backend/src/models/StockOut.js +18 -0
- package/templates/sims-app/backend/src/models/User.js +12 -0
- package/templates/sims-app/backend/src/routes/authRoutes.js +12 -0
- package/templates/sims-app/backend/src/routes/simsReportRoutes.js +8 -0
- package/templates/sims-app/backend/src/routes/sparePartRoutes.js +8 -0
- package/templates/sims-app/backend/src/routes/stockInRoutes.js +8 -0
- package/templates/sims-app/backend/src/routes/stockOutRoutes.js +10 -0
- package/templates/sims-app/backend/src/server.js +62 -0
- package/templates/sims-app/backend/src/utils/passwordPolicy.js +10 -0
- package/templates/sims-app/backend/src/utils/sparePartHelpers.js +5 -0
- package/templates/sims-app/frontend/index.html +13 -0
- package/templates/sims-app/frontend/package.json +31 -0
- package/templates/sims-app/frontend/src/App.jsx +110 -0
- package/templates/sims-app/frontend/src/api/authApi.js +7 -0
- package/templates/sims-app/frontend/src/api/client.js +8 -0
- package/templates/sims-app/frontend/src/api/simsReportApi.js +5 -0
- package/templates/sims-app/frontend/src/api/sparePartsApi.js +4 -0
- package/templates/sims-app/frontend/src/api/stockInApi.js +4 -0
- package/templates/sims-app/frontend/src/api/stockOutApi.js +6 -0
- package/templates/sims-app/frontend/src/api/usersApi.js +3 -0
- package/templates/sims-app/frontend/src/components/AppLayout.jsx +47 -0
- package/templates/sims-app/frontend/src/index.css +7 -0
- package/templates/sims-app/frontend/src/main.jsx +13 -0
- package/templates/sims-app/frontend/src/pages/ForgotPassword.jsx +111 -0
- package/templates/sims-app/frontend/src/pages/LoginPage.jsx +71 -0
- package/templates/sims-app/frontend/src/pages/RegisterPage.jsx +99 -0
- package/templates/sims-app/frontend/src/pages/ReportsPage.jsx +120 -0
- package/templates/sims-app/frontend/src/pages/SparePartPage.jsx +148 -0
- package/templates/sims-app/frontend/src/pages/StockInPage.jsx +122 -0
- package/templates/sims-app/frontend/src/pages/StockOutPage.jsx +252 -0
- package/templates/sims-app/frontend/src/utils/passwordPolicy.js +8 -0
- package/templates/sims-app/frontend/vite.config.js +8 -0
- package/templates/smartshop-app/README.md +61 -0
- package/templates/smartshop-app/backend/.env +7 -0
- package/templates/smartshop-app/backend/.env.example +7 -0
- package/templates/smartshop-app/backend/database/schema.sql +46 -0
- package/templates/smartshop-app/backend/package-lock.json +1487 -0
- package/templates/smartshop-app/backend/package.json +26 -0
- package/templates/smartshop-app/backend/src/app.js +57 -0
- package/templates/smartshop-app/backend/src/config/db.js +52 -0
- package/templates/smartshop-app/backend/src/controllers/authController.js +98 -0
- package/templates/smartshop-app/backend/src/controllers/customerController.js +26 -0
- package/templates/smartshop-app/backend/src/controllers/productController.js +21 -0
- package/templates/smartshop-app/backend/src/controllers/reportController.js +29 -0
- package/templates/smartshop-app/backend/src/controllers/saleController.js +11 -0
- package/templates/smartshop-app/backend/src/middleware/authMiddleware.js +22 -0
- package/templates/smartshop-app/backend/src/models/authModel.js +24 -0
- package/templates/smartshop-app/backend/src/models/customerModel.js +43 -0
- package/templates/smartshop-app/backend/src/models/productModel.js +37 -0
- package/templates/smartshop-app/backend/src/models/reportModel.js +56 -0
- package/templates/smartshop-app/backend/src/models/saleModel.js +54 -0
- package/templates/smartshop-app/backend/src/routes/authRoutes.js +10 -0
- package/templates/smartshop-app/backend/src/routes/customerRoutes.js +16 -0
- package/templates/smartshop-app/backend/src/routes/productRoutes.js +16 -0
- package/templates/smartshop-app/backend/src/routes/reportRoutes.js +18 -0
- package/templates/smartshop-app/backend/src/routes/saleRoutes.js +9 -0
- package/templates/smartshop-app/backend/src/server.js +19 -0
- package/templates/smartshop-app/frontend/README.md +18 -0
- package/templates/smartshop-app/frontend/eslint.config.js +21 -0
- package/templates/smartshop-app/frontend/index.html +13 -0
- package/templates/smartshop-app/frontend/package-lock.json +3415 -0
- package/templates/smartshop-app/frontend/package.json +34 -0
- package/templates/smartshop-app/frontend/public/favicon.svg +1 -0
- package/templates/smartshop-app/frontend/public/icons.svg +24 -0
- package/templates/smartshop-app/frontend/src/App.css +184 -0
- package/templates/smartshop-app/frontend/src/App.jsx +41 -0
- package/templates/smartshop-app/frontend/src/assets/hero.png +0 -0
- package/templates/smartshop-app/frontend/src/assets/react.svg +1 -0
- package/templates/smartshop-app/frontend/src/assets/vite.svg +1 -0
- package/templates/smartshop-app/frontend/src/components/AppLayout.jsx +71 -0
- package/templates/smartshop-app/frontend/src/components/FormCard.jsx +12 -0
- package/templates/smartshop-app/frontend/src/components/StatCard.jsx +10 -0
- package/templates/smartshop-app/frontend/src/index.css +28 -0
- package/templates/smartshop-app/frontend/src/main.jsx +13 -0
- package/templates/smartshop-app/frontend/src/pages/CustomersPage.jsx +175 -0
- package/templates/smartshop-app/frontend/src/pages/DashboardPage.jsx +30 -0
- package/templates/smartshop-app/frontend/src/pages/ForgotPassword.jsx +102 -0
- package/templates/smartshop-app/frontend/src/pages/LoginPage.jsx +142 -0
- package/templates/smartshop-app/frontend/src/pages/ProductsPage.jsx +165 -0
- package/templates/smartshop-app/frontend/src/pages/ReportsPage.jsx +204 -0
- package/templates/smartshop-app/frontend/src/pages/SalesPage.jsx +153 -0
- package/templates/smartshop-app/frontend/src/services/api.js +15 -0
- package/templates/smartshop-app/frontend/vite.config.js +13 -0
- package/templates/srms-app/.env +7 -0
- package/templates/srms-app/README.md +82 -0
- package/templates/srms-app/backend-mongodb/.env +3 -0
- package/templates/srms-app/backend-mongodb/.env.example +3 -0
- package/templates/srms-app/backend-mongodb/config/db.js +29 -0
- package/templates/srms-app/backend-mongodb/controllers/authController.js +93 -0
- package/templates/srms-app/backend-mongodb/controllers/customerController.js +27 -0
- package/templates/srms-app/backend-mongodb/controllers/productController.js +26 -0
- package/templates/srms-app/backend-mongodb/controllers/reportController.js +44 -0
- package/templates/srms-app/backend-mongodb/controllers/saleController.js +72 -0
- package/templates/srms-app/backend-mongodb/middleware/auth.js +16 -0
- package/templates/srms-app/backend-mongodb/models/Customer.js +14 -0
- package/templates/srms-app/backend-mongodb/models/Product.js +13 -0
- package/templates/srms-app/backend-mongodb/models/Sale.js +15 -0
- package/templates/srms-app/backend-mongodb/models/User.js +9 -0
- package/templates/srms-app/backend-mongodb/package-lock.json +1571 -0
- package/templates/srms-app/backend-mongodb/package.json +22 -0
- package/templates/srms-app/backend-mongodb/routes/authRoutes.js +8 -0
- package/templates/srms-app/backend-mongodb/routes/customerRoutes.js +6 -0
- package/templates/srms-app/backend-mongodb/routes/productRoutes.js +6 -0
- package/templates/srms-app/backend-mongodb/routes/reportRoutes.js +5 -0
- package/templates/srms-app/backend-mongodb/routes/saleRoutes.js +8 -0
- package/templates/srms-app/backend-mongodb/server.js +39 -0
- package/templates/srms-app/backend-mysql/.env +7 -0
- package/templates/srms-app/backend-mysql/.env.example +7 -0
- package/templates/srms-app/backend-mysql/config/db.js +33 -0
- package/templates/srms-app/backend-mysql/controllers/authController.js +98 -0
- package/templates/srms-app/backend-mysql/controllers/customerController.js +28 -0
- package/templates/srms-app/backend-mysql/controllers/productController.js +27 -0
- package/templates/srms-app/backend-mysql/controllers/reportController.js +29 -0
- package/templates/srms-app/backend-mysql/controllers/saleController.js +68 -0
- package/templates/srms-app/backend-mysql/database/schema.sql +7 -0
- package/templates/srms-app/backend-mysql/middleware/auth.js +16 -0
- package/templates/srms-app/backend-mysql/package-lock.json +1486 -0
- package/templates/srms-app/backend-mysql/package.json +23 -0
- package/templates/srms-app/backend-mysql/routes/authRoutes.js +8 -0
- package/templates/srms-app/backend-mysql/routes/customerRoutes.js +6 -0
- package/templates/srms-app/backend-mysql/routes/productRoutes.js +6 -0
- package/templates/srms-app/backend-mysql/routes/reportRoutes.js +5 -0
- package/templates/srms-app/backend-mysql/routes/saleRoutes.js +8 -0
- package/templates/srms-app/backend-mysql/server.js +39 -0
- package/templates/srms-app/frontend/index.html +12 -0
- package/templates/srms-app/frontend/package-lock.json +1634 -0
- package/templates/srms-app/frontend/package.json +23 -0
- package/templates/srms-app/frontend/src/App.jsx +31 -0
- package/templates/srms-app/frontend/src/api/client.js +11 -0
- package/templates/srms-app/frontend/src/components/AppLayout.jsx +40 -0
- package/templates/srms-app/frontend/src/context/AuthContext.jsx +41 -0
- package/templates/srms-app/frontend/src/hooks/.gitkeep +0 -0
- package/templates/srms-app/frontend/src/index.css +2 -0
- package/templates/srms-app/frontend/src/main.jsx +16 -0
- package/templates/srms-app/frontend/src/pages/CustomersPage.jsx +160 -0
- package/templates/srms-app/frontend/src/pages/ForgotPassword.jsx +103 -0
- package/templates/srms-app/frontend/src/pages/LoginPage.jsx +105 -0
- package/templates/srms-app/frontend/src/pages/ProductsPage.jsx +158 -0
- package/templates/srms-app/frontend/src/pages/ReportsPage.jsx +192 -0
- package/templates/srms-app/frontend/src/pages/SalesPage.jsx +310 -0
- package/templates/srms-app/frontend/vite.config.js +8 -0
- package/templates/stockhub-sms-app/.env +7 -0
- package/templates/stockhub-sms-app/README.md +82 -0
- package/templates/stockhub-sms-app/backend-mongodb/.env +3 -0
- package/templates/stockhub-sms-app/backend-mongodb/.env.example +3 -0
- package/templates/stockhub-sms-app/backend-mongodb/config/db.js +29 -0
- package/templates/stockhub-sms-app/backend-mongodb/controllers/authController.js +93 -0
- package/templates/stockhub-sms-app/backend-mongodb/controllers/productController.js +29 -0
- package/templates/stockhub-sms-app/backend-mongodb/controllers/reportController.js +53 -0
- package/templates/stockhub-sms-app/backend-mongodb/controllers/transactionController.js +74 -0
- package/templates/stockhub-sms-app/backend-mongodb/controllers/warehouseController.js +25 -0
- package/templates/stockhub-sms-app/backend-mongodb/middleware/auth.js +16 -0
- package/templates/stockhub-sms-app/backend-mongodb/models/Counter.js +13 -0
- package/templates/stockhub-sms-app/backend-mongodb/models/Product.js +16 -0
- package/templates/stockhub-sms-app/backend-mongodb/models/StockTransaction.js +19 -0
- package/templates/stockhub-sms-app/backend-mongodb/models/User.js +9 -0
- package/templates/stockhub-sms-app/backend-mongodb/models/Warehouse.js +12 -0
- package/templates/stockhub-sms-app/backend-mongodb/package-lock.json +1571 -0
- package/templates/stockhub-sms-app/backend-mongodb/package.json +22 -0
- package/templates/stockhub-sms-app/backend-mongodb/routes/authRoutes.js +8 -0
- package/templates/stockhub-sms-app/backend-mongodb/routes/productRoutes.js +6 -0
- package/templates/stockhub-sms-app/backend-mongodb/routes/reportRoutes.js +5 -0
- package/templates/stockhub-sms-app/backend-mongodb/routes/transactionRoutes.js +8 -0
- package/templates/stockhub-sms-app/backend-mongodb/routes/warehouseRoutes.js +6 -0
- package/templates/stockhub-sms-app/backend-mongodb/server.js +39 -0
- package/templates/stockhub-sms-app/backend-mysql/.env +7 -0
- package/templates/stockhub-sms-app/backend-mysql/.env.example +7 -0
- package/templates/stockhub-sms-app/backend-mysql/config/db.js +33 -0
- package/templates/stockhub-sms-app/backend-mysql/controllers/authController.js +98 -0
- package/templates/stockhub-sms-app/backend-mysql/controllers/productController.js +30 -0
- package/templates/stockhub-sms-app/backend-mysql/controllers/reportController.js +53 -0
- package/templates/stockhub-sms-app/backend-mysql/controllers/transactionController.js +70 -0
- package/templates/stockhub-sms-app/backend-mysql/controllers/warehouseController.js +26 -0
- package/templates/stockhub-sms-app/backend-mysql/database/schema.sql +40 -0
- package/templates/stockhub-sms-app/backend-mysql/middleware/auth.js +16 -0
- package/templates/stockhub-sms-app/backend-mysql/package-lock.json +1486 -0
- package/templates/stockhub-sms-app/backend-mysql/package.json +23 -0
- package/templates/stockhub-sms-app/backend-mysql/routes/authRoutes.js +8 -0
- package/templates/stockhub-sms-app/backend-mysql/routes/productRoutes.js +6 -0
- package/templates/stockhub-sms-app/backend-mysql/routes/reportRoutes.js +5 -0
- package/templates/stockhub-sms-app/backend-mysql/routes/transactionRoutes.js +8 -0
- package/templates/stockhub-sms-app/backend-mysql/routes/warehouseRoutes.js +6 -0
- package/templates/stockhub-sms-app/backend-mysql/server.js +39 -0
- package/templates/stockhub-sms-app/frontend/index.html +12 -0
- package/templates/stockhub-sms-app/frontend/package-lock.json +1634 -0
- package/templates/stockhub-sms-app/frontend/package.json +23 -0
- package/templates/stockhub-sms-app/frontend/src/App.jsx +31 -0
- package/templates/stockhub-sms-app/frontend/src/api/client.js +11 -0
- package/templates/stockhub-sms-app/frontend/src/components/AppLayout.jsx +40 -0
- package/templates/stockhub-sms-app/frontend/src/context/AuthContext.jsx +41 -0
- package/templates/stockhub-sms-app/frontend/src/hooks/.gitkeep +0 -0
- package/templates/stockhub-sms-app/frontend/src/index.css +13 -0
- package/templates/stockhub-sms-app/frontend/src/main.jsx +16 -0
- package/templates/stockhub-sms-app/frontend/src/pages/ForgotPassword.jsx +103 -0
- package/templates/stockhub-sms-app/frontend/src/pages/LoginPage.jsx +105 -0
- package/templates/stockhub-sms-app/frontend/src/pages/ProductsPage.jsx +132 -0
- package/templates/stockhub-sms-app/frontend/src/pages/ReportsPage.jsx +177 -0
- package/templates/stockhub-sms-app/frontend/src/pages/TransactionsPage.jsx +270 -0
- package/templates/stockhub-sms-app/frontend/src/pages/WarehousesPage.jsx +116 -0
- package/templates/stockhub-sms-app/frontend/vite.config.js +8 -0
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { createStudent, deleteStudent, listStudents, updateStudent } from "../api/studentsApi";
|
|
3
|
+
|
|
4
|
+
const GENDERS = ["Male", "Female", "Other"];
|
|
5
|
+
const empty = { fullName: "", gender: "Male", className: "", phone: "", email: "" };
|
|
6
|
+
|
|
7
|
+
const validateStudent = (form) => {
|
|
8
|
+
const errors = {};
|
|
9
|
+
if (!form.fullName.trim()) errors.fullName = "Full name is required.";
|
|
10
|
+
if (!form.gender) errors.gender = "Select gender.";
|
|
11
|
+
else if (!GENDERS.includes(form.gender)) errors.gender = "Select a valid gender.";
|
|
12
|
+
if (!form.className.trim()) errors.className = "Class is required.";
|
|
13
|
+
if (!form.phone.trim()) errors.phone = "Phone is required.";
|
|
14
|
+
else if (!/^[0-9+\-\s]{7,15}$/.test(form.phone.trim())) {
|
|
15
|
+
errors.phone = "Enter a valid phone number (7–15 digits).";
|
|
16
|
+
}
|
|
17
|
+
if (!form.email.trim()) errors.email = "Email is required.";
|
|
18
|
+
else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.email.trim())) {
|
|
19
|
+
errors.email = "Enter a valid email address.";
|
|
20
|
+
}
|
|
21
|
+
return errors;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default function StudentsPage() {
|
|
25
|
+
const [rows, setRows] = useState([]);
|
|
26
|
+
const [form, setForm] = useState(empty);
|
|
27
|
+
const [editId, setEditId] = useState(null);
|
|
28
|
+
const [fieldErrors, setFieldErrors] = useState({});
|
|
29
|
+
const [err, setErr] = useState("");
|
|
30
|
+
|
|
31
|
+
const load = () =>
|
|
32
|
+
listStudents()
|
|
33
|
+
.then(({ data }) => setRows(data))
|
|
34
|
+
.catch((e) => setErr(e.response?.data?.message || "Load failed"));
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
load();
|
|
38
|
+
}, []);
|
|
39
|
+
|
|
40
|
+
const setField = (key, value) => {
|
|
41
|
+
setForm((prev) => ({ ...prev, [key]: value }));
|
|
42
|
+
setFieldErrors((prev) => ({ ...prev, [key]: "" }));
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const inputClass = (key) =>
|
|
46
|
+
`border bg-lms-dark px-3 py-2 text-lms-paper ${fieldErrors[key] ? "border-red-500" : "border-lms-dark"}`;
|
|
47
|
+
|
|
48
|
+
const save = async (e) => {
|
|
49
|
+
e.preventDefault();
|
|
50
|
+
setErr("");
|
|
51
|
+
const errors = validateStudent(form);
|
|
52
|
+
if (Object.keys(errors).length) {
|
|
53
|
+
setFieldErrors(errors);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
if (editId) await updateStudent(editId, form);
|
|
58
|
+
else await createStudent(form);
|
|
59
|
+
setForm(empty);
|
|
60
|
+
setEditId(null);
|
|
61
|
+
setFieldErrors({});
|
|
62
|
+
await load();
|
|
63
|
+
} catch (e2) {
|
|
64
|
+
setErr(e2.response?.data?.message || "Save failed");
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const edit = (r) => {
|
|
69
|
+
setEditId(r._id);
|
|
70
|
+
setForm({
|
|
71
|
+
fullName: r.fullName,
|
|
72
|
+
gender: r.gender,
|
|
73
|
+
className: r.className,
|
|
74
|
+
phone: r.phone,
|
|
75
|
+
email: r.email,
|
|
76
|
+
});
|
|
77
|
+
setFieldErrors({});
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const remove = async (id) => {
|
|
81
|
+
if (!confirm("Delete this student?")) return;
|
|
82
|
+
setErr("");
|
|
83
|
+
try {
|
|
84
|
+
await deleteStudent(id);
|
|
85
|
+
await load();
|
|
86
|
+
} catch (e2) {
|
|
87
|
+
setErr(e2.response?.data?.message || "Delete failed");
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<div>
|
|
93
|
+
<h1 className="mb-4 text-xl font-bold text-lms-paper">Students</h1>
|
|
94
|
+
{err && <p className="mb-3 border border-lms-accent px-3 py-2 text-sm text-lms-accent">{err}</p>}
|
|
95
|
+
<form onSubmit={save} className="mb-6 border border-lms-panel bg-lms-panel p-4">
|
|
96
|
+
<h2 className="mb-3 text-sm font-semibold text-lms-accent">{editId ? "Edit" : "Add"} student</h2>
|
|
97
|
+
<div className="grid gap-3 sm:grid-cols-2">
|
|
98
|
+
<div>
|
|
99
|
+
<input
|
|
100
|
+
className={inputClass("fullName")}
|
|
101
|
+
placeholder="Full name"
|
|
102
|
+
value={form.fullName}
|
|
103
|
+
onChange={(e) => setField("fullName", e.target.value)}
|
|
104
|
+
/>
|
|
105
|
+
{fieldErrors.fullName && <p className="mt-1 text-xs text-red-400">{fieldErrors.fullName}</p>}
|
|
106
|
+
</div>
|
|
107
|
+
<div>
|
|
108
|
+
<select
|
|
109
|
+
className={inputClass("gender")}
|
|
110
|
+
value={form.gender}
|
|
111
|
+
onChange={(e) => setField("gender", e.target.value)}
|
|
112
|
+
>
|
|
113
|
+
{GENDERS.map((g) => (
|
|
114
|
+
<option key={g}>{g}</option>
|
|
115
|
+
))}
|
|
116
|
+
</select>
|
|
117
|
+
{fieldErrors.gender && <p className="mt-1 text-xs text-red-400">{fieldErrors.gender}</p>}
|
|
118
|
+
</div>
|
|
119
|
+
<div>
|
|
120
|
+
<input
|
|
121
|
+
className={inputClass("className")}
|
|
122
|
+
placeholder="Class"
|
|
123
|
+
value={form.className}
|
|
124
|
+
onChange={(e) => setField("className", e.target.value)}
|
|
125
|
+
/>
|
|
126
|
+
{fieldErrors.className && <p className="mt-1 text-xs text-red-400">{fieldErrors.className}</p>}
|
|
127
|
+
</div>
|
|
128
|
+
<div>
|
|
129
|
+
<input
|
|
130
|
+
className={inputClass("phone")}
|
|
131
|
+
placeholder="Phone"
|
|
132
|
+
value={form.phone}
|
|
133
|
+
onChange={(e) => setField("phone", e.target.value)}
|
|
134
|
+
/>
|
|
135
|
+
{fieldErrors.phone && <p className="mt-1 text-xs text-red-400">{fieldErrors.phone}</p>}
|
|
136
|
+
</div>
|
|
137
|
+
<div className="sm:col-span-2">
|
|
138
|
+
<input
|
|
139
|
+
className={inputClass("email")}
|
|
140
|
+
placeholder="Email"
|
|
141
|
+
type="email"
|
|
142
|
+
value={form.email}
|
|
143
|
+
onChange={(e) => setField("email", e.target.value)}
|
|
144
|
+
/>
|
|
145
|
+
{fieldErrors.email && <p className="mt-1 text-xs text-red-400">{fieldErrors.email}</p>}
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
<div className="mt-3 flex gap-2">
|
|
149
|
+
<button type="submit" className="border border-lms-accent bg-lms-accent px-4 py-2 text-lms-paper">
|
|
150
|
+
Save
|
|
151
|
+
</button>
|
|
152
|
+
{editId && (
|
|
153
|
+
<button
|
|
154
|
+
type="button"
|
|
155
|
+
className="border border-lms-paper/40 px-4 py-2 text-lms-paper"
|
|
156
|
+
onClick={() => {
|
|
157
|
+
setEditId(null);
|
|
158
|
+
setForm(empty);
|
|
159
|
+
setFieldErrors({});
|
|
160
|
+
}}
|
|
161
|
+
>
|
|
162
|
+
Cancel
|
|
163
|
+
</button>
|
|
164
|
+
)}
|
|
165
|
+
</div>
|
|
166
|
+
</form>
|
|
167
|
+
|
|
168
|
+
<div className="overflow-x-auto border border-lms-panel">
|
|
169
|
+
<table className="w-full text-left text-sm text-lms-paper">
|
|
170
|
+
<thead className="bg-lms-panel text-lms-paper/70">
|
|
171
|
+
<tr>
|
|
172
|
+
<th className="p-2">Name</th>
|
|
173
|
+
<th className="p-2">Gender</th>
|
|
174
|
+
<th className="p-2">Class</th>
|
|
175
|
+
<th className="p-2">Phone</th>
|
|
176
|
+
<th className="p-2">Email</th>
|
|
177
|
+
<th className="p-2">Actions</th>
|
|
178
|
+
</tr>
|
|
179
|
+
</thead>
|
|
180
|
+
<tbody>
|
|
181
|
+
{rows.map((r) => (
|
|
182
|
+
<tr key={r._id} className="border-t border-lms-dark">
|
|
183
|
+
<td className="p-2">{r.fullName}</td>
|
|
184
|
+
<td className="p-2">{r.gender}</td>
|
|
185
|
+
<td className="p-2">{r.className}</td>
|
|
186
|
+
<td className="p-2">{r.phone}</td>
|
|
187
|
+
<td className="p-2">{r.email}</td>
|
|
188
|
+
<td className="p-2">
|
|
189
|
+
<button type="button" className="text-lms-accent hover:underline" onClick={() => edit(r)}>
|
|
190
|
+
Edit
|
|
191
|
+
</button>
|
|
192
|
+
{" · "}
|
|
193
|
+
<button type="button" className="text-lms-accent hover:underline" onClick={() => remove(r._id)}>
|
|
194
|
+
Delete
|
|
195
|
+
</button>
|
|
196
|
+
</td>
|
|
197
|
+
</tr>
|
|
198
|
+
))}
|
|
199
|
+
</tbody>
|
|
200
|
+
</table>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
);
|
|
204
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { defineConfig, loadEnv } from "vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
4
|
+
|
|
5
|
+
const DEFAULT_WEB = 5828;
|
|
6
|
+
const DEFAULT_API = 5827;
|
|
7
|
+
|
|
8
|
+
export default defineConfig(({ mode }) => {
|
|
9
|
+
const env = loadEnv(mode, process.cwd(), "");
|
|
10
|
+
const port =
|
|
11
|
+
Number(env.VITE_DEV_SERVER_PORT || env.LMS_FRONTEND_PORT || String(DEFAULT_WEB)) ||
|
|
12
|
+
DEFAULT_WEB;
|
|
13
|
+
const proxyTarget =
|
|
14
|
+
env.VITE_API_PROXY_TARGET || env.LMS_API_URL || `http://localhost:${DEFAULT_API}`;
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
plugins: [react(), tailwindcss()],
|
|
18
|
+
server: {
|
|
19
|
+
port,
|
|
20
|
+
strictPort: true,
|
|
21
|
+
proxy: {
|
|
22
|
+
"/api": { target: proxyTarget, changeOrigin: true },
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Supply Chain Management System (SCMS)
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
cd backend-mysql && npm install
|
|
7
|
+
cd ../backend-mongodb && npm install
|
|
8
|
+
cd ../frontend && npm install
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Database Setup (MySQL)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cd backend-mysql
|
|
15
|
+
cp .env.example .env
|
|
16
|
+
npm run db:init
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Run Development Server
|
|
20
|
+
|
|
21
|
+
MySQL API (port 5555):
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
cd backend-mysql && npm run dev
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
MongoDB API (port 5555 — run one backend at a time):
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
cd backend-mongodb && npm run dev
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Frontend (port 5173):
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cd frontend && npm run dev
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Default login: `admin` / `admin123`
|
|
40
|
+
|
|
41
|
+
## Environment Variables
|
|
42
|
+
|
|
43
|
+
### backend-mysql
|
|
44
|
+
|
|
45
|
+
| Variable | Description |
|
|
46
|
+
|----------|-------------|
|
|
47
|
+
| PORT | API port (5555) |
|
|
48
|
+
| JWT_SECRET | Secret for JWT tokens |
|
|
49
|
+
| DB_HOST | MySQL host |
|
|
50
|
+
| DB_USER | MySQL user |
|
|
51
|
+
| DB_PASSWORD | MySQL password |
|
|
52
|
+
| DB_NAME | Database name (SCMS) |
|
|
53
|
+
| DB_PORT | MySQL port |
|
|
54
|
+
|
|
55
|
+
### backend-mongodb
|
|
56
|
+
|
|
57
|
+
| Variable | Description |
|
|
58
|
+
|----------|-------------|
|
|
59
|
+
| PORT | API port (5555) |
|
|
60
|
+
| JWT_SECRET | Secret for JWT tokens |
|
|
61
|
+
| MONGO_URI | MongoDB connection string |
|
|
62
|
+
|
|
63
|
+
## API Endpoints
|
|
64
|
+
|
|
65
|
+
- POST /api/auth/register
|
|
66
|
+
- POST /api/auth/login
|
|
67
|
+
- GET/POST /api/suppliers
|
|
68
|
+
- GET/POST/PUT/DELETE /api/shipments
|
|
69
|
+
- GET/POST/PUT/DELETE /api/deliveries
|
|
70
|
+
- GET /api/reports?period=daily|weekly|monthly&date=&startDate=&endDate=&month=
|
|
71
|
+
|
|
72
|
+
## Folder Structure
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
undefined/
|
|
76
|
+
├── README.md
|
|
77
|
+
├── frontend/
|
|
78
|
+
├── backend-mysql/
|
|
79
|
+
└── backend-mongodb/
|
|
80
|
+
```
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import mongoose from "mongoose";
|
|
2
|
+
import dotenv from "dotenv";
|
|
3
|
+
import User from "../models/User.js";
|
|
4
|
+
|
|
5
|
+
dotenv.config();
|
|
6
|
+
|
|
7
|
+
const ADMIN_HASH = "$2b$10$aULsUjp9bb9lf5CZZyY.7./KhwsocVO0duyPlqu0Qnte75xHBdG5C";
|
|
8
|
+
|
|
9
|
+
export const connectDatabase = async () => {
|
|
10
|
+
try {
|
|
11
|
+
await mongoose.connect(process.env.MONGO_URI || "mongodb://localhost:27017/SCMS");
|
|
12
|
+
console.log("Database Connected Successfully");
|
|
13
|
+
const count = await User.countDocuments();
|
|
14
|
+
if (count === 0) {
|
|
15
|
+
await User.create({
|
|
16
|
+
username: "admin",
|
|
17
|
+
email: "admin@exam.local",
|
|
18
|
+
password: ADMIN_HASH,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
return true;
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.log("Database Connection Failed");
|
|
24
|
+
console.error(error.message);
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default mongoose;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import bcrypt from "bcryptjs";
|
|
2
|
+
import jwt from "jsonwebtoken";
|
|
3
|
+
import User from "../models/User.js";
|
|
4
|
+
|
|
5
|
+
const signToken = (user) =>
|
|
6
|
+
jwt.sign(
|
|
7
|
+
{ id: user._id, username: user.username },
|
|
8
|
+
process.env.JWT_SECRET || "exam_secret",
|
|
9
|
+
{ expiresIn: "8h" }
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
const normalizeEmail = (email) => String(email || "").trim().toLowerCase();
|
|
13
|
+
|
|
14
|
+
export const register = async (req, res) => {
|
|
15
|
+
try {
|
|
16
|
+
const { username, email, password } = req.body;
|
|
17
|
+
if (!username || !email || !password) {
|
|
18
|
+
return res.status(400).json({ message: "Username, email and password are required." });
|
|
19
|
+
}
|
|
20
|
+
const emailNorm = normalizeEmail(email);
|
|
21
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailNorm)) {
|
|
22
|
+
return res.status(400).json({ message: "Enter a valid email address." });
|
|
23
|
+
}
|
|
24
|
+
const existingUser = await User.findOne({ username: username.trim() });
|
|
25
|
+
if (existingUser) {
|
|
26
|
+
return res.status(409).json({ message: "Username already exists." });
|
|
27
|
+
}
|
|
28
|
+
const existingEmail = await User.findOne({ email: emailNorm });
|
|
29
|
+
if (existingEmail) {
|
|
30
|
+
return res.status(409).json({ message: "Email already registered." });
|
|
31
|
+
}
|
|
32
|
+
const hash = await bcrypt.hash(password, 10);
|
|
33
|
+
await User.create({ username: username.trim(), email: emailNorm, password: hash });
|
|
34
|
+
return res.status(201).json({ message: "Account created successfully." });
|
|
35
|
+
} catch {
|
|
36
|
+
return res.status(500).json({ message: "Server error during registration." });
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const login = async (req, res) => {
|
|
41
|
+
try {
|
|
42
|
+
const { username, password } = req.body;
|
|
43
|
+
if (!username || !password) {
|
|
44
|
+
return res.status(400).json({ message: "Username and password are required." });
|
|
45
|
+
}
|
|
46
|
+
const user = await User.findOne({ username: username.trim() });
|
|
47
|
+
if (!user) {
|
|
48
|
+
return res.status(401).json({ message: "Invalid credentials." });
|
|
49
|
+
}
|
|
50
|
+
const match = await bcrypt.compare(password, user.password);
|
|
51
|
+
if (!match) {
|
|
52
|
+
return res.status(401).json({ message: "Invalid credentials." });
|
|
53
|
+
}
|
|
54
|
+
return res.json({
|
|
55
|
+
message: "Login successful.",
|
|
56
|
+
token: signToken(user),
|
|
57
|
+
user: { id: user._id, username: user.username, email: user.email },
|
|
58
|
+
});
|
|
59
|
+
} catch {
|
|
60
|
+
return res.status(500).json({ message: "Server error during login." });
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const forgotPassword = async (req, res) => {
|
|
65
|
+
try {
|
|
66
|
+
const { email, newPassword, confirmPassword } = req.body;
|
|
67
|
+
if (!email) {
|
|
68
|
+
return res.status(400).json({ success: false, message: "Email is required." });
|
|
69
|
+
}
|
|
70
|
+
if (!newPassword) {
|
|
71
|
+
return res.status(400).json({ success: false, message: "New password is required." });
|
|
72
|
+
}
|
|
73
|
+
if (!confirmPassword) {
|
|
74
|
+
return res.status(400).json({ success: false, message: "Confirm password is required." });
|
|
75
|
+
}
|
|
76
|
+
if (newPassword !== confirmPassword) {
|
|
77
|
+
return res.status(400).json({
|
|
78
|
+
success: false,
|
|
79
|
+
message: "New password and confirm password must match.",
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const emailNorm = normalizeEmail(email);
|
|
83
|
+
const user = await User.findOne({ email: emailNorm });
|
|
84
|
+
if (!user) {
|
|
85
|
+
return res.status(404).json({ success: false, message: "User not found" });
|
|
86
|
+
}
|
|
87
|
+
user.password = await bcrypt.hash(newPassword, 10);
|
|
88
|
+
await user.save();
|
|
89
|
+
return res.json({ success: true, message: "Password reset successfully" });
|
|
90
|
+
} catch {
|
|
91
|
+
return res.status(500).json({ success: false, message: "Server error." });
|
|
92
|
+
}
|
|
93
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import Delivery from "../models/Delivery.js";
|
|
2
|
+
import Shipment from "../models/Shipment.js";
|
|
3
|
+
|
|
4
|
+
export const create = async (req, res) => {
|
|
5
|
+
try {
|
|
6
|
+
if (req.body.deliveryCode === undefined || req.body.deliveryCode === "") return res.status(400).json({ message: "Delivery Code is required." });
|
|
7
|
+
if (req.body.deliveryDate === undefined || req.body.deliveryDate === "") return res.status(400).json({ message: "Delivery Date is required." });
|
|
8
|
+
if (req.body.quantityDelivered === undefined || req.body.quantityDelivered === "") return res.status(400).json({ message: "Quantity Delivered is required." });
|
|
9
|
+
if (req.body.deliveryStatus === undefined || req.body.deliveryStatus === "") return res.status(400).json({ message: "Delivery Status is required." });
|
|
10
|
+
if (req.body.shipmentNumber === undefined || req.body.shipmentNumber === "") return res.status(400).json({ message: "Shipment Number is required." });
|
|
11
|
+
const shipment = await Shipment.findOne({ shipment_number: req.body.shipmentNumber });
|
|
12
|
+
if (!shipment) return res.status(400).json({ message: "Selected shipment does not exist." });
|
|
13
|
+
await Delivery.create({ delivery_code: req.body.deliveryCode, delivery_date: req.body.deliveryDate, quantity_delivered: req.body.quantityDelivered, delivery_status: req.body.deliveryStatus, shipment_number: req.body.shipmentNumber });
|
|
14
|
+
return res.status(201).json({ message: "Delivery added successfully." });
|
|
15
|
+
} catch (error) {
|
|
16
|
+
if (error.code === 11000) {
|
|
17
|
+
return res.status(409).json({ message: "Delivery already exists." });
|
|
18
|
+
}
|
|
19
|
+
return res.status(500).json({ message: "Failed to add delivery." });
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const getAll = async (_req, res) => {
|
|
24
|
+
try {
|
|
25
|
+
const rows = await Delivery.find().sort({ delivery_code: -1 }).lean();
|
|
26
|
+
return res.json(rows.map((r) => { const { _id, __v, ...rest } = r; return rest; }));
|
|
27
|
+
} catch {
|
|
28
|
+
return res.status(500).json({ message: "Failed to fetch delivery records." });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const update = async (req, res) => {
|
|
33
|
+
try {
|
|
34
|
+
if (req.body.deliveryCode === undefined || req.body.deliveryCode === "") return res.status(400).json({ message: "Delivery Code is required." });
|
|
35
|
+
if (req.body.deliveryDate === undefined || req.body.deliveryDate === "") return res.status(400).json({ message: "Delivery Date is required." });
|
|
36
|
+
if (req.body.quantityDelivered === undefined || req.body.quantityDelivered === "") return res.status(400).json({ message: "Quantity Delivered is required." });
|
|
37
|
+
if (req.body.deliveryStatus === undefined || req.body.deliveryStatus === "") return res.status(400).json({ message: "Delivery Status is required." });
|
|
38
|
+
if (req.body.shipmentNumber === undefined || req.body.shipmentNumber === "") return res.status(400).json({ message: "Shipment Number is required." });
|
|
39
|
+
const shipment = await Shipment.findOne({ shipment_number: req.body.shipmentNumber });
|
|
40
|
+
if (!shipment) return res.status(400).json({ message: "Selected shipment does not exist." });
|
|
41
|
+
const updated = await Delivery.findOneAndUpdate(
|
|
42
|
+
{ delivery_code: req.params.id },
|
|
43
|
+
{ delivery_code: req.body.deliveryCode, delivery_date: req.body.deliveryDate, quantity_delivered: req.body.quantityDelivered, delivery_status: req.body.deliveryStatus, shipment_number: req.body.shipmentNumber },
|
|
44
|
+
{ new: true }
|
|
45
|
+
);
|
|
46
|
+
if (!updated) {
|
|
47
|
+
return res.status(404).json({ message: "Delivery not found." });
|
|
48
|
+
}
|
|
49
|
+
return res.json({ message: "Delivery updated successfully." });
|
|
50
|
+
} catch {
|
|
51
|
+
return res.status(500).json({ message: "Failed to update delivery." });
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const remove = async (req, res) => {
|
|
56
|
+
try {
|
|
57
|
+
const deleted = await Delivery.findOneAndDelete({ delivery_code: req.params.id });
|
|
58
|
+
if (!deleted) {
|
|
59
|
+
return res.status(404).json({ message: "Delivery not found." });
|
|
60
|
+
}
|
|
61
|
+
return res.json({ message: "Delivery deleted successfully." });
|
|
62
|
+
} catch {
|
|
63
|
+
return res.status(500).json({ message: "Failed to delete delivery." });
|
|
64
|
+
}
|
|
65
|
+
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import Supplier from "../models/Supplier.js";
|
|
2
|
+
import Shipment from "../models/Shipment.js";
|
|
3
|
+
import Delivery from "../models/Delivery.js";
|
|
4
|
+
|
|
5
|
+
const clean = (rows) => rows.map((r) => {
|
|
6
|
+
const { _id, __v, ...rest } = r;
|
|
7
|
+
return rest;
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const monthBounds = (month) => {
|
|
11
|
+
const start = new Date(`${month}-01T00:00:00`);
|
|
12
|
+
const end = new Date(start.getFullYear(), start.getMonth() + 1, 0, 23, 59, 59, 999);
|
|
13
|
+
return { start, end };
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const getReports = async (req, res) => {
|
|
17
|
+
try {
|
|
18
|
+
const period = req.query.period || "daily";
|
|
19
|
+
const date = req.query.date || new Date().toISOString().slice(0, 10);
|
|
20
|
+
const startDate = req.query.startDate;
|
|
21
|
+
const endDate = req.query.endDate;
|
|
22
|
+
const month = req.query.month || date.slice(0, 7);
|
|
23
|
+
|
|
24
|
+
const suppliers = clean(await Supplier.find().lean());
|
|
25
|
+
let shipments;
|
|
26
|
+
let deliveries;
|
|
27
|
+
|
|
28
|
+
if (period === "daily") {
|
|
29
|
+
const start = new Date(`${date}T00:00:00`);
|
|
30
|
+
const end = new Date(`${date}T23:59:59`);
|
|
31
|
+
shipments = clean(await Shipment.find({ shipment_date: { $gte: start, $lte: end } }).lean());
|
|
32
|
+
deliveries = clean(await Delivery.find({ delivery_date: { $gte: start, $lte: end } }).lean());
|
|
33
|
+
} else if (period === "weekly") {
|
|
34
|
+
if (!startDate || !endDate) {
|
|
35
|
+
return res.status(400).json({ message: "Start date and end date are required for weekly reports." });
|
|
36
|
+
}
|
|
37
|
+
const start = new Date(`${startDate}T00:00:00`);
|
|
38
|
+
const end = new Date(`${endDate}T23:59:59`);
|
|
39
|
+
shipments = clean(await Shipment.find({ shipment_date: { $gte: start, $lte: end } }).lean());
|
|
40
|
+
deliveries = clean(await Delivery.find({ delivery_date: { $gte: start, $lte: end } }).lean());
|
|
41
|
+
} else {
|
|
42
|
+
const { start, end } = monthBounds(month);
|
|
43
|
+
shipments = clean(await Shipment.find({ shipment_date: { $gte: start, $lte: end } }).lean());
|
|
44
|
+
deliveries = clean(await Delivery.find({ delivery_date: { $gte: start, $lte: end } }).lean());
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return res.json({ period, reports: { suppliers, shipments, deliveries } });
|
|
48
|
+
} catch {
|
|
49
|
+
return res.status(500).json({ message: "Failed to generate reports." });
|
|
50
|
+
}
|
|
51
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import Shipment from "../models/Shipment.js";
|
|
2
|
+
import Supplier from "../models/Supplier.js";
|
|
3
|
+
|
|
4
|
+
export const create = async (req, res) => {
|
|
5
|
+
try {
|
|
6
|
+
if (req.body.shipmentNumber === undefined || req.body.shipmentNumber === "") return res.status(400).json({ message: "Shipment Number is required." });
|
|
7
|
+
if (req.body.shipmentDate === undefined || req.body.shipmentDate === "") return res.status(400).json({ message: "Shipment Date is required." });
|
|
8
|
+
if (req.body.shipmentStatus === undefined || req.body.shipmentStatus === "") return res.status(400).json({ message: "Status is required." });
|
|
9
|
+
if (req.body.destination === undefined || req.body.destination === "") return res.status(400).json({ message: "Destination is required." });
|
|
10
|
+
if (req.body.supplierCode === undefined || req.body.supplierCode === "") return res.status(400).json({ message: "Supplier Code is required." });
|
|
11
|
+
const supplier = await Supplier.findOne({ supplier_code: req.body.supplierCode });
|
|
12
|
+
if (!supplier) return res.status(400).json({ message: "Selected supplier does not exist." });
|
|
13
|
+
await Shipment.create({ shipment_number: req.body.shipmentNumber, shipment_date: req.body.shipmentDate, shipment_status: req.body.shipmentStatus, destination: req.body.destination, supplier_code: req.body.supplierCode });
|
|
14
|
+
return res.status(201).json({ message: "Shipment added successfully." });
|
|
15
|
+
} catch (error) {
|
|
16
|
+
if (error.code === 11000) {
|
|
17
|
+
return res.status(409).json({ message: "Shipment already exists." });
|
|
18
|
+
}
|
|
19
|
+
return res.status(500).json({ message: "Failed to add shipment." });
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const getAll = async (_req, res) => {
|
|
24
|
+
try {
|
|
25
|
+
const rows = await Shipment.find().sort({ shipment_number: -1 }).lean();
|
|
26
|
+
return res.json(rows.map((r) => { const { _id, __v, ...rest } = r; return rest; }));
|
|
27
|
+
} catch {
|
|
28
|
+
return res.status(500).json({ message: "Failed to fetch shipment records." });
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const update = async (req, res) => {
|
|
33
|
+
try {
|
|
34
|
+
if (req.body.shipmentNumber === undefined || req.body.shipmentNumber === "") return res.status(400).json({ message: "Shipment Number is required." });
|
|
35
|
+
if (req.body.shipmentDate === undefined || req.body.shipmentDate === "") return res.status(400).json({ message: "Shipment Date is required." });
|
|
36
|
+
if (req.body.shipmentStatus === undefined || req.body.shipmentStatus === "") return res.status(400).json({ message: "Status is required." });
|
|
37
|
+
if (req.body.destination === undefined || req.body.destination === "") return res.status(400).json({ message: "Destination is required." });
|
|
38
|
+
if (req.body.supplierCode === undefined || req.body.supplierCode === "") return res.status(400).json({ message: "Supplier Code is required." });
|
|
39
|
+
const supplier = await Supplier.findOne({ supplier_code: req.body.supplierCode });
|
|
40
|
+
if (!supplier) return res.status(400).json({ message: "Selected supplier does not exist." });
|
|
41
|
+
const updated = await Shipment.findOneAndUpdate(
|
|
42
|
+
{ shipment_number: req.params.id },
|
|
43
|
+
{ shipment_number: req.body.shipmentNumber, shipment_date: req.body.shipmentDate, shipment_status: req.body.shipmentStatus, destination: req.body.destination, supplier_code: req.body.supplierCode },
|
|
44
|
+
{ new: true }
|
|
45
|
+
);
|
|
46
|
+
if (!updated) {
|
|
47
|
+
return res.status(404).json({ message: "Shipment not found." });
|
|
48
|
+
}
|
|
49
|
+
return res.json({ message: "Shipment updated successfully." });
|
|
50
|
+
} catch {
|
|
51
|
+
return res.status(500).json({ message: "Failed to update shipment." });
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const remove = async (req, res) => {
|
|
56
|
+
try {
|
|
57
|
+
const deleted = await Shipment.findOneAndDelete({ shipment_number: req.params.id });
|
|
58
|
+
if (!deleted) {
|
|
59
|
+
return res.status(404).json({ message: "Shipment not found." });
|
|
60
|
+
}
|
|
61
|
+
return res.json({ message: "Shipment deleted successfully." });
|
|
62
|
+
} catch {
|
|
63
|
+
return res.status(500).json({ message: "Failed to delete shipment." });
|
|
64
|
+
}
|
|
65
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import Supplier from "../models/Supplier.js";
|
|
2
|
+
|
|
3
|
+
export const create = async (req, res) => {
|
|
4
|
+
try {
|
|
5
|
+
if (req.body.supplierCode === undefined || req.body.supplierCode === "") return res.status(400).json({ message: "Supplier Code is required." });
|
|
6
|
+
if (req.body.supplierName === undefined || req.body.supplierName === "") return res.status(400).json({ message: "Supplier Name is required." });
|
|
7
|
+
if (req.body.telephone === undefined || req.body.telephone === "") return res.status(400).json({ message: "Telephone is required." });
|
|
8
|
+
if (req.body.address === undefined || req.body.address === "") return res.status(400).json({ message: "Address is required." });
|
|
9
|
+
if (req.body.email === undefined || req.body.email === "") return res.status(400).json({ message: "Email is required." });
|
|
10
|
+
await Supplier.create({ supplier_code: req.body.supplierCode, supplier_name: req.body.supplierName, telephone: req.body.telephone, address: req.body.address, email: req.body.email });
|
|
11
|
+
return res.status(201).json({ message: "Supplier added successfully." });
|
|
12
|
+
} catch (error) {
|
|
13
|
+
if (error.code === 11000) {
|
|
14
|
+
return res.status(409).json({ message: "Supplier already exists." });
|
|
15
|
+
}
|
|
16
|
+
return res.status(500).json({ message: "Failed to add supplier." });
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const getAll = async (_req, res) => {
|
|
21
|
+
try {
|
|
22
|
+
const rows = await Supplier.find().sort({ supplier_code: -1 }).lean();
|
|
23
|
+
return res.json(rows.map((r) => { const { _id, __v, ...rest } = r; return rest; }));
|
|
24
|
+
} catch {
|
|
25
|
+
return res.status(500).json({ message: "Failed to fetch supplier records." });
|
|
26
|
+
}
|
|
27
|
+
};
|